[SeaBIOS] [PATCH 6/6] Run ahci code entirely in 32bit mode.

Kevin O'Connor kevin at koconnor.net
Thu Oct 3 03:41:05 CEST 2013


The ahci driver needs to jump into 32bit mode in order to access
portions of the ahci controllers PCI config space.  Instead of jumping
into 32bit mode just to toggle the ahci registers, jump into 32bit
mode for all of the driver interactions.  This shrinks the size of the
overall code and can lead to further cleanups.

Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
 Makefile          |  4 ++--
 src/block.c       | 13 ++++++++++---
 src/hw/ahci.c     | 15 ++++-----------
 src/hw/blockcmd.c |  5 +++--
 4 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/Makefile b/Makefile
index 3218970..baa0be2 100644
--- a/Makefile
+++ b/Makefile
@@ -32,13 +32,13 @@ SRCBOTH=misc.c stacks.c output.c string.c x86.c block.c cdrom.c mouse.c kbd.c \
     hw/pci.c hw/timer.c hw/rtc.c hw/dma.c hw/pic.c hw/ps2port.c \
     hw/usb.c hw/usb-uhci.c hw/usb-ohci.c hw/usb-ehci.c hw/usb-xhci.c \
     hw/usb-hid.c hw/usb-msc.c hw/usb-uas.c \
-    hw/blockcmd.c hw/floppy.c hw/ata.c hw/ahci.c hw/ramdisk.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 \
     hw/lsi-scsi.c hw/esp-scsi.c hw/megasas.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/usb-hub.c \
+    hw/ahci.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
diff --git a/src/block.c b/src/block.c
index 55d15d2..a41e662 100644
--- a/src/block.c
+++ b/src/block.c
@@ -333,7 +333,7 @@ process_scsi_op(struct disk_op_s *op)
     }
 }
 
-static int
+int VISIBLE32FLAT
 process_atapi_op(struct disk_op_s *op)
 {
     switch (op->command) {
@@ -363,10 +363,17 @@ process_op(struct disk_op_s *op)
     case DTYPE_VIRTIO_BLK:
         return process_virtio_blk_op(op);
     case DTYPE_AHCI:
-        return process_ahci_op(op);
+        op->drive_g = (void*)op->drive_g + BUILD_BIOS_ADDR;
+        extern void _cfunc32flat_process_ahci_op(void);
+        return call32(_cfunc32flat_process_ahci_op
+                      , (u32)MAKE_FLATPTR(GET_SEG(SS), op), DISK_RET_EPARAM);
     case DTYPE_ATA_ATAPI:
-    case DTYPE_AHCI_ATAPI:
         return process_atapi_op(op);
+    case DTYPE_AHCI_ATAPI:
+        op->drive_g = (void*)op->drive_g + BUILD_BIOS_ADDR;
+        extern void _cfunc32flat_process_atapi_op(void);
+        return call32(_cfunc32flat_process_atapi_op
+                      , (u32)MAKE_FLATPTR(GET_SEG(SS), op), DISK_RET_EPARAM);
     case DTYPE_USB:
     case DTYPE_UAS:
     case DTYPE_VIRTIO_SCSI:
diff --git a/src/hw/ahci.c b/src/hw/ahci.c
index 9c2b390..82a6194 100644
--- a/src/hw/ahci.c
+++ b/src/hw/ahci.c
@@ -23,10 +23,6 @@
 #define AHCI_RESET_TIMEOUT     500 // 500 miliseconds
 #define AHCI_LINK_TIMEOUT       10 // 10 miliseconds
 
-/****************************************************************
- * these bits must run in both 16bit and 32bit modes
- ****************************************************************/
-
 // prepare sata command fis
 static void sata_prep_simple(struct sata_cmd_fis *fis, u8 command)
 {
@@ -76,13 +72,13 @@ static void sata_prep_atapi(struct sata_cmd_fis *fis, u16 blocksize)
 static u32 ahci_ctrl_readl(struct ahci_ctrl_s *ctrl, u32 reg)
 {
     u32 addr = GET_GLOBALFLAT(ctrl->iobase) + reg;
-    return pci_readl(addr);
+    return readl((void*)addr);
 }
 
 static void ahci_ctrl_writel(struct ahci_ctrl_s *ctrl, u32 reg, u32 val)
 {
     u32 addr = GET_GLOBALFLAT(ctrl->iobase) + reg;
-    pci_writel(addr, val);
+    writel((void*)addr, val);
 }
 
 static u32 ahci_port_to_ctrl(u32 pnr, u32 port_reg)
@@ -300,7 +296,8 @@ ahci_disk_readwrite(struct disk_op_s *op, int iswrite)
 }
 
 // command demuxer
-int process_ahci_op(struct disk_op_s *op)
+int VISIBLE32FLAT
+process_ahci_op(struct disk_op_s *op)
 {
     if (!CONFIG_AHCI)
         return 0;
@@ -322,10 +319,6 @@ int process_ahci_op(struct disk_op_s *op)
     }
 }
 
-/****************************************************************
- * everything below is pure 32bit code
- ****************************************************************/
-
 static void
 ahci_port_reset(struct ahci_ctrl_s *ctrl, u32 pnr)
 {
diff --git a/src/hw/blockcmd.c b/src/hw/blockcmd.c
index 635954d..90b8cf3 100644
--- a/src/hw/blockcmd.c
+++ b/src/hw/blockcmd.c
@@ -34,8 +34,6 @@ cdb_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize)
         return usb_cmd_data(op, cdbcmd, blocksize);
     case DTYPE_UAS:
         return uas_cmd_data(op, cdbcmd, blocksize);
-    case DTYPE_AHCI_ATAPI:
-        return ahci_cmd_data(op, cdbcmd, blocksize);
     case DTYPE_VIRTIO_SCSI:
         return virtio_scsi_cmd_data(op, cdbcmd, blocksize);
     case DTYPE_LSI_SCSI:
@@ -44,6 +42,9 @@ 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_AHCI_ATAPI:
+        if (!MODESEGMENT)
+            return ahci_cmd_data(op, cdbcmd, blocksize);
     default:
         op->count = 0;
         return DISK_RET_EPARAM;
-- 
1.8.3.1




More information about the SeaBIOS mailing list