Since the XHCI driver needs to jump into 32bit mode anyway, it is simpler to just run all of the code in 32bit mode.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- Makefile | 4 ++-- src/block.c | 2 ++ src/block.h | 4 +++- src/hw/blockcmd.c | 6 ++++++ src/hw/usb-msc.c | 5 ++++- src/hw/usb-uas.c | 5 ++++- src/hw/usb-xhci.c | 13 ++++++------- src/hw/usb.c | 13 +++++++++++-- src/hw/usb.h | 1 + 9 files changed, 39 insertions(+), 14 deletions(-)
diff --git a/Makefile b/Makefile index 414c90a..53a238e 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ SRCBOTH=misc.c stacks.c output.c string.c x86.c block.c cdrom.c mouse.c kbd.c \ serial.c clock.c resume.c pnpbios.c vgahooks.c pcibios.c apm.c \ fw/smp.c \ hw/pci.c hw/timer.c hw/rtc.c hw/dma.c hw/pic.c hw/ps2port.c hw/serialio.c \ - hw/usb.c hw/usb-uhci.c hw/usb-ohci.c hw/usb-ehci.c hw/usb-xhci.c \ + hw/usb.c hw/usb-uhci.c hw/usb-ohci.c hw/usb-ehci.c \ hw/usb-hid.c hw/usb-msc.c hw/usb-uas.c \ hw/blockcmd.c hw/floppy.c hw/ata.c hw/ramdisk.c \ hw/virtio-ring.c hw/virtio-pci.c hw/virtio-blk.c hw/virtio-scsi.c \ @@ -38,7 +38,7 @@ SRCBOTH=misc.c stacks.c output.c string.c x86.c block.c cdrom.c mouse.c kbd.c \ SRC16=$(SRCBOTH) system.c disk.c font.c SRC32FLAT=$(SRCBOTH) post.c memmap.c malloc.c pmm.c romfile.c optionroms.c \ boot.c bootsplash.c jpeg.c bmp.c \ - hw/ahci.c hw/pvscsi.c hw/usb-hub.c \ + hw/ahci.c hw/pvscsi.c hw/usb-xhci.c hw/usb-hub.c \ fw/coreboot.c fw/lzmadecode.c fw/csm.c fw/biostables.c \ fw/paravirt.c fw/shadow.c fw/pciinit.c fw/smm.c fw/mtrr.c fw/xen.c \ fw/acpi.c fw/mptable.c fw/pirtable.c fw/smbios.c fw/romfile_loader.c diff --git a/src/block.c b/src/block.c index 898c279..264f376 100644 --- a/src/block.c +++ b/src/block.c @@ -388,6 +388,8 @@ process_op(struct disk_op_s *op) case DTYPE_MEGASAS: ret = process_scsi_op(op); break; + case DTYPE_USB_32: + case DTYPE_UAS_32: case DTYPE_PVSCSI: ; extern void _cfunc32flat_process_scsi_op(void); ret = call32(_cfunc32flat_process_scsi_op diff --git a/src/block.h b/src/block.h index bb57748..5d0afb5 100644 --- a/src/block.h +++ b/src/block.h @@ -79,7 +79,9 @@ struct drive_s { #define DTYPE_VIRTIO_SCSI 0x60 #define DTYPE_VIRTIO_BLK 0x61 #define DTYPE_USB 0x70 -#define DTYPE_UAS 0x71 +#define DTYPE_USB_32 0x71 +#define DTYPE_UAS 0x72 +#define DTYPE_UAS_32 0x73 #define DTYPE_LSI_SCSI 0x80 #define DTYPE_ESP_SCSI 0x81 #define DTYPE_MEGASAS 0x82 diff --git a/src/hw/blockcmd.c b/src/hw/blockcmd.c index db61cbd..eb531d4 100644 --- a/src/hw/blockcmd.c +++ b/src/hw/blockcmd.c @@ -43,6 +43,12 @@ cdb_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize) return esp_scsi_cmd_data(op, cdbcmd, blocksize); case DTYPE_MEGASAS: return megasas_cmd_data(op, cdbcmd, blocksize); + case DTYPE_USB_32: + if (!MODESEGMENT) + return usb_cmd_data(op, cdbcmd, blocksize); + case DTYPE_UAS_32: + if (!MODESEGMENT) + return uas_cmd_data(op, cdbcmd, blocksize); case DTYPE_PVSCSI: if (!MODESEGMENT) return pvscsi_cmd_data(op, cdbcmd, blocksize); diff --git a/src/hw/usb-msc.c b/src/hw/usb-msc.c index 2cf9725..a7af9a7 100644 --- a/src/hw/usb-msc.c +++ b/src/hw/usb-msc.c @@ -147,7 +147,10 @@ usb_msc_lun_setup(struct usb_pipe *inpipe, struct usb_pipe *outpipe, return -1; } memset(drive, 0, sizeof(*drive)); - drive->drive.type = DTYPE_USB; + if (usb_32bit_pipe(inpipe)) + drive->drive.type = DTYPE_USB_32; + else + drive->drive.type = DTYPE_USB; drive->bulkin = inpipe; drive->bulkout = outpipe; drive->lun = lun; diff --git a/src/hw/usb-uas.c b/src/hw/usb-uas.c index 33657ac..9474383 100644 --- a/src/hw/usb-uas.c +++ b/src/hw/usb-uas.c @@ -179,7 +179,10 @@ uas_lun_setup(struct usbdevice_s *usbdev, return -1; } memset(drive, 0, sizeof(*drive)); - drive->drive.type = DTYPE_UAS; + if (usb_32bit_pipe(data_in)) + drive->drive.type = DTYPE_UAS_32; + else + drive->drive.type = DTYPE_UAS; drive->command = command; drive->status = status; drive->data_in = data_in; diff --git a/src/hw/usb-xhci.c b/src/hw/usb-xhci.c index 78ad03c..51ef6f4 100644 --- a/src/hw/usb-xhci.c +++ b/src/hw/usb-xhci.c @@ -309,8 +309,8 @@ static const int eptype_to_xhci_out[] = { static void xhci_doorbell(struct usb_xhci_s *xhci, u32 slotid, u32 value) { struct xhci_db *db = GET_LOWFLAT(xhci->db); - u32 addr = (u32)(&db[slotid].doorbell); - pci_writel(addr, value); + void *addr = &db[slotid].doorbell; + writel(addr, value); }
static void xhci_process_events(struct usb_xhci_s *xhci) @@ -365,10 +365,9 @@ static void xhci_process_events(struct usb_xhci_s *xhci) } SET_LOWFLAT(evts->nidx, nidx); struct xhci_ir *ir = GET_LOWFLAT(xhci->ir); - u32 addr = (u32)(&ir->erdp_low); u32 erdp = (u32)(evts->ring + nidx); - pci_writel(addr, erdp); - pci_writel((u32)(&ir->erdp_high), 0); + writel(&ir->erdp_low, erdp); + writel(&ir->erdp_high, 0); } }
@@ -1062,7 +1061,7 @@ xhci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize return 0; }
-int +int VISIBLE32FLAT xhci_send_bulk(struct usb_pipe *p, int dir, void *data, int datalen) { if (!CONFIG_USB_XHCI) @@ -1081,7 +1080,7 @@ xhci_send_bulk(struct usb_pipe *p, int dir, void *data, int datalen) return 0; }
-int +int VISIBLE32FLAT xhci_poll_intr(struct usb_pipe *p, void *data) { if (!CONFIG_USB_XHCI) diff --git a/src/hw/usb.c b/src/hw/usb.c index e1356f9..8ffddf8 100644 --- a/src/hw/usb.c +++ b/src/hw/usb.c @@ -89,6 +89,8 @@ usb_send_bulk(struct usb_pipe *pipe_fl, int dir, void *data, int datasize) case USB_TYPE_EHCI: return ehci_send_bulk(pipe_fl, dir, data, datasize); case USB_TYPE_XHCI: + if (MODESEGMENT) + return -1; return xhci_send_bulk(pipe_fl, dir, data, datasize); } } @@ -96,6 +98,7 @@ usb_send_bulk(struct usb_pipe *pipe_fl, int dir, void *data, int datasize) int usb_poll_intr(struct usb_pipe *pipe_fl, void *data) { + ASSERT16(); switch (GET_LOWFLAT(pipe_fl->type)) { default: case USB_TYPE_UHCI: @@ -104,11 +107,17 @@ usb_poll_intr(struct usb_pipe *pipe_fl, void *data) return ohci_poll_intr(pipe_fl, data); case USB_TYPE_EHCI: return ehci_poll_intr(pipe_fl, data); - case USB_TYPE_XHCI: - return xhci_poll_intr(pipe_fl, data); + case USB_TYPE_XHCI: ; + extern void _cfunc32flat_xhci_poll_intr(void); + return call32_params(_cfunc32flat_xhci_poll_intr, (u32)pipe_fl + , (u32)MAKE_FLATPTR(GET_SEG(SS), (u32)data), 0, -1); } }
+int usb_32bit_pipe(struct usb_pipe *pipe_fl) +{ + return CONFIG_USB_XHCI && GET_LOWFLAT(pipe_fl->type) == USB_TYPE_XHCI; +}
/**************************************************************** * Helper functions diff --git a/src/hw/usb.h b/src/hw/usb.h index cb5a05c..6196296 100644 --- a/src/hw/usb.h +++ b/src/hw/usb.h @@ -228,6 +228,7 @@ struct usb_pipe *usb_alloc_pipe(struct usbdevice_s *usbdev , struct usb_endpoint_descriptor *epdesc); int usb_send_bulk(struct usb_pipe *pipe, int dir, void *data, int datasize); int usb_poll_intr(struct usb_pipe *pipe, void *data); +int usb_32bit_pipe(struct usb_pipe *pipe_fl); int send_default_control(struct usb_pipe *pipe, const struct usb_ctrlrequest *req , void *data); void free_pipe(struct usb_pipe *pipe);