Some further testing code for xhci. This patch set allows the xhci controller to run entirely in 32bit mode, which can lead to further code simplifications and reduces the overall seabios binary size.
I've pushed this to the xhci-testing branch at: https://github.com/KevinOConnor/seabios/tree/xhci-testing
-Kevin
Kevin O'Connor (4): Add call32_params() helper function. Add space between DTYPE_* definitions. xhci: Run the XHCI driver entirely in 32bit mode. Remove pci_writel() and pci_readl() functions.
Makefile | 4 ++-- src/block.c | 2 ++ src/block.h | 32 +++++++++++++++++--------------- src/hw/blockcmd.c | 6 ++++++ src/hw/pci.c | 46 ---------------------------------------------- src/hw/pci.h | 4 ---- 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 + src/stacks.c | 27 +++++++++++++++++++++++++++ src/stacks.h | 1 + 13 files changed, 81 insertions(+), 78 deletions(-)
Add helper function for calling 32bit functions with more than just one parameter.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/stacks.c | 27 +++++++++++++++++++++++++++ src/stacks.h | 1 + 2 files changed, 28 insertions(+)
diff --git a/src/stacks.c b/src/stacks.c index 9c528f5..de71c1d 100644 --- a/src/stacks.c +++ b/src/stacks.c @@ -501,3 +501,30 @@ check_preempt(void) if (CONFIG_THREAD_OPTIONROMS && GET_GLOBAL(CanPreempt) && have_threads()) call32(_cfunc32flat_yield_preempt, 0, 0); } + + +/**************************************************************** + * call32 helper + ****************************************************************/ + +struct call32_params_s { + void *func; + u32 eax, edx, ecx; +}; + +u32 VISIBLE32FLAT +call32_params_helper(struct call32_params_s *params) +{ + return ((u32 (*)(u32, u32, u32))params->func)( + params->eax, params->edx, params->ecx); +} + +u32 +call32_params(void *func, u32 eax, u32 edx, u32 ecx, u32 errret) +{ + ASSERT16(); + struct call32_params_s params = {func, eax, edx, ecx}; + extern void _cfunc32flat_call32_params_helper(void); + return call32(_cfunc32flat_call32_params_helper + , (u32)MAKE_FLATPTR(GET_SEG(SS), ¶ms), errret); +} diff --git a/src/stacks.h b/src/stacks.h index 5ee4adc..9fe8761 100644 --- a/src/stacks.h +++ b/src/stacks.h @@ -30,5 +30,6 @@ void start_preempt(void); void finish_preempt(void); int wait_preempt(void); void check_preempt(void); +u32 call32_params(void *func, u32 eax, u32 edx, u32 ecx, u32 errret);
#endif // stacks.h
Avoi consective numbering on the DTYPE_* definitions.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/block.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/src/block.h b/src/block.h index 9cb25d0..bb57748 100644 --- a/src/block.h +++ b/src/block.h @@ -69,21 +69,21 @@ struct drive_s { #define CDROM_SECTOR_SIZE 2048
#define DTYPE_NONE 0x00 -#define DTYPE_FLOPPY 0x01 -#define DTYPE_ATA 0x02 -#define DTYPE_ATA_ATAPI 0x03 -#define DTYPE_RAMDISK 0x04 -#define DTYPE_CDEMU 0x05 -#define DTYPE_AHCI 0x06 -#define DTYPE_AHCI_ATAPI 0x07 -#define DTYPE_VIRTIO_SCSI 0x08 -#define DTYPE_VIRTIO_BLK 0x09 -#define DTYPE_USB 0x0a -#define DTYPE_UAS 0x0b -#define DTYPE_LSI_SCSI 0x0c -#define DTYPE_ESP_SCSI 0x0d -#define DTYPE_MEGASAS 0x0e -#define DTYPE_PVSCSI 0x0f +#define DTYPE_FLOPPY 0x10 +#define DTYPE_ATA 0x20 +#define DTYPE_ATA_ATAPI 0x21 +#define DTYPE_RAMDISK 0x30 +#define DTYPE_CDEMU 0x40 +#define DTYPE_AHCI 0x50 +#define DTYPE_AHCI_ATAPI 0x51 +#define DTYPE_VIRTIO_SCSI 0x60 +#define DTYPE_VIRTIO_BLK 0x61 +#define DTYPE_USB 0x70 +#define DTYPE_UAS 0x71 +#define DTYPE_LSI_SCSI 0x80 +#define DTYPE_ESP_SCSI 0x81 +#define DTYPE_MEGASAS 0x82 +#define DTYPE_PVSCSI 0x83
#define MAXDESCSIZE 80
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);
These functions are no longer used. Going forward it's better to move a driver to full 32bit mode then to use these functions.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/hw/pci.c | 46 ---------------------------------------------- src/hw/pci.h | 4 ---- 2 files changed, 50 deletions(-)
diff --git a/src/hw/pci.c b/src/hw/pci.c index 6c9aa81..caf9265 100644 --- a/src/hw/pci.c +++ b/src/hw/pci.c @@ -234,49 +234,3 @@ pci_reboot(void) outb(v|6, PORT_PCI_REBOOT); /* Actually do the reset */ udelay(50); } - -// helper functions to access pci mmio bars from real mode - -u32 VISIBLE32FLAT -pci_readl_32(u32 addr) -{ - dprintf(9, "32: pci read : %x\n", addr); - return readl((void*)addr); -} - -u32 pci_readl(u32 addr) -{ - if (MODESEGMENT) { - dprintf(9, "16: pci read : %x\n", addr); - extern void _cfunc32flat_pci_readl_32(u32 addr); - return call32(_cfunc32flat_pci_readl_32, addr, -1); - } else { - return pci_readl_32(addr); - } -} - -struct reg32 { - u32 addr; - u32 data; -}; - -void VISIBLE32FLAT -pci_writel_32(struct reg32 *reg32) -{ - dprintf(9, "32: pci write: %x, %x (%p)\n", reg32->addr, reg32->data, reg32); - writel((void*)(reg32->addr), reg32->data); -} - -void pci_writel(u32 addr, u32 val) -{ - struct reg32 reg32 = { .addr = addr, .data = val }; - if (MODESEGMENT) { - dprintf(9, "16: pci write: %x, %x (%x:%p)\n", - reg32.addr, reg32.data, GET_SEG(SS), ®32); - void *flatptr = MAKE_FLATPTR(GET_SEG(SS), ®32); - extern void _cfunc32flat_pci_writel_32(struct reg32 *reg32); - call32(_cfunc32flat_pci_writel_32, (u32)flatptr, -1); - } else { - pci_writel_32(®32); - } -} diff --git a/src/hw/pci.h b/src/hw/pci.h index 9c7351d..167a027 100644 --- a/src/hw/pci.h +++ b/src/hw/pci.h @@ -118,8 +118,4 @@ struct pci_device *pci_find_init_device(const struct pci_device_id *ids , void *arg); void pci_reboot(void);
-// helper functions to access pci mmio bars from real mode -u32 pci_readl(u32 addr); -void pci_writel(u32 addr, u32 val); - #endif