[SeaBIOS] [PATCH 3/4] xhci: Run the XHCI driver entirely in 32bit mode.

Kevin O'Connor kevin at koconnor.net
Tue Dec 31 04:23:53 CET 2013


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 at 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);
-- 
1.8.3.1




More information about the SeaBIOS mailing list