Not particularly functional, but it's a start...

Build with CONFIG_CSM enabled (and CONFIG_RELOCATE_INIT disabled) and
drop the resulting bios.bin into OvmfPkg/Csm/Csm16/Csm16.bin in your
EDK-II build tree, then build with 'build -D CSM_ENABLE'.

You'll see it initialise SeaBIOS as a CSM as it's starting up, and then
crash in a storm of what Qemu's debug log says is 'hardware INT=0x68'...
which I suppose is what I have to debug next...

Signed-off-by: David Woodhouse <[email protected]>
---
 Makefile        |   2 +-
 src/Kconfig     |   7 +++
 src/csm.c       | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/post.c      |   3 ++
 src/romlayout.S |   7 +++
 src/shadow.c    |   6 +--
 6 files changed, 163 insertions(+), 4 deletions(-)
 create mode 100644 src/csm.c

diff --git a/Makefile b/Makefile
index f28d86c..cb8ecdf 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,7 @@ SRCBOTH=misc.c stacks.c pmm.c output.c util.c block.c 
floppy.c ata.c mouse.c \
     pnpbios.c pirtable.c vgahooks.c ramdisk.c pcibios.c blockcmd.c \
     usb.c usb-uhci.c usb-ohci.c usb-ehci.c usb-hid.c usb-msc.c \
     virtio-ring.c virtio-pci.c virtio-blk.c virtio-scsi.c apm.c ahci.c \
-    usb-uas.c lsi-scsi.c esp-scsi.c megasas.c
+    usb-uas.c lsi-scsi.c esp-scsi.c megasas.c csm.c
 SRC16=$(SRCBOTH) system.c disk.c font.c
 SRC32FLAT=$(SRCBOTH) post.c shadow.c memmap.c coreboot.c boot.c \
     acpi.c smm.c mptable.c smbios.c pciinit.c optionroms.c mtrr.c \
diff --git a/src/Kconfig b/src/Kconfig
index 0b112ed..f35b0f5 100644
--- a/src/Kconfig
+++ b/src/Kconfig
@@ -27,6 +27,13 @@ endchoice
         help
             Configure to be used by xen hvmloader, for a HVM guest.
 
+    config CSM
+       bool "Build as Compatibilty Support Module for EFI BIOS"
+       default n
+       help
+           Configure to be used by EFI firmware as Compatibility Support
+           module (CSM) to provide legacy BIOS services.
+
     config THREADS
         bool "Parallelize hardware init"
         default y
diff --git a/src/csm.c b/src/csm.c
new file mode 100644
index 0000000..7ff173b
--- /dev/null
+++ b/src/csm.c
@@ -0,0 +1,142 @@
+// CSM table generation (for providing legacy BIOS support to EFI)
+//
+// Copyright © 2012 Intel Corporation
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+#include "config.h" // CONFIG_*
+#include "csm.h"
+#include "util.h" // checksum
+#include "bregs.h"
+
+
+#if CONFIG_CSM
+extern void entry_csm16(void);
+EFI_COMPATIBILITY16_TABLE csm_compat_table VAR16EXPORT __aligned(16) = {
+       .Signature = 0x24454649,
+       .TableChecksum = 0 /* Filled in by checkrom.py */,
+       .TableLength = sizeof(csm_compat_table),
+       .Compatibility16CallSegment = SEG_BIOS,
+       .Compatibility16CallOffset = 0 /* Filled in by checkrom.py */,
+       .OemIdStringPointer = (u32)"SeaBIOS",
+};
+#endif
+
+extern void handle_post(void);
+extern void _cfunc32flat_handle_csm16(struct bregs *);
+
+EFI_TO_COMPATIBILITY16_INIT_TABLE *csm_init_table;
+EFI_TO_COMPATIBILITY16_BOOT_TABLE *csm_boot_table;
+
+/* Legacy16InitializeYourself */
+void handle_csm_0000(struct bregs *regs)
+{
+       dprintf(3, "Legacy16InitializeYourself table %04x:%04x\n", regs->es,
+               regs->bx);
+
+       csm_init_table = MAKE_FLATPTR(regs->es, regs->bx);
+
+       dprintf(3, "BiosLessThan1MB %08x\n", csm_init_table->BiosLessThan1MB);
+       dprintf(3, "HiPmmMemory     %08x\n", csm_init_table->HiPmmMemory);
+       dprintf(3, "HiPmmMemorySize %08x\n", 
csm_init_table->HiPmmMemorySizeInBytes);
+       dprintf(3, "ReverseThunk    %04x:%04x\n", 
csm_init_table->ReverseThunkCallSegment,
+               csm_init_table->ReverseThunkCallOffset);
+       dprintf(3, "NumE820Entries  %08x\n", csm_init_table->NumberE820Entries);
+       dprintf(3, "OsMemoryAbove1M %08x\n", csm_init_table->OsMemoryAbove1Mb);
+       dprintf(3, "ThunkStart      %08x\n", csm_init_table->ThunkStart);
+       dprintf(3, "ThunkSize       %08x\n", csm_init_table->ThunkSizeInBytes);
+       dprintf(3, "LoPmmMemory     %08x\n", csm_init_table->LowPmmMemory);
+       dprintf(3, "LoPmmMemorySize %08x\n", 
csm_init_table->LowPmmMemorySizeInBytes);
+
+       handle_post();
+       regs->ax = 0;
+}
+
+/* Legacy16UpdateBbs */
+void handle_csm_0001(struct bregs *regs)
+{
+       dprintf(3, "Legacy16UpdateBbs table %04x:%04x\n", regs->es, regs->bx);
+
+       csm_boot_table = MAKE_FLATPTR(regs->es, regs->bx);
+       dprintf(3, "MajorVersion %04x\n", csm_boot_table->MajorVersion);
+       dprintf(3, "MinorVersion %04x\n", csm_boot_table->MinorVersion);
+       dprintf(3, "AcpiTable %08x\n", csm_boot_table->AcpiTable);
+       dprintf(3, "SmbiosTable %08x\n", csm_boot_table->SmbiosTable);
+       dprintf(3, "SmbiosTableLength %08x\n", 
csm_boot_table->SmbiosTableLength);
+//     dprintf(3, "SioData %08x\n", csm_boot_table->SioData);
+       dprintf(3, "DevicePathType %04x\n", csm_boot_table->DevicePathType);
+       dprintf(3, "PciIrqMask %04x\n", csm_boot_table->PciIrqMask);
+       dprintf(3, "NumberE820Entries %08x\n", 
csm_boot_table->NumberE820Entries);
+//     dprintf(3, "HddInfo %08x\n", csm_boot_table->HddInfo);
+       dprintf(3, "NumberBbsEntries %08x\n", csm_boot_table->NumberBbsEntries);
+       dprintf(3, "BBsTable %08x\n", csm_boot_table->BbsTable);
+       dprintf(3, "SmmTable %08x\n", csm_boot_table->SmmTable);
+       dprintf(3, "OsMemoryAbove1Mb %08x\n", csm_boot_table->OsMemoryAbove1Mb);
+       dprintf(3, "UnconventionalDeviceTable %08x\n", 
csm_boot_table->UnconventionalDeviceTable);
+
+       regs->ax = 0;
+}
+
+/* Legacy16DispatchOprom */
+void handle_csm_0005(struct bregs *regs)
+{
+       EFI_DISPATCH_OPROM_TABLE *rom = MAKE_FLATPTR(regs->es, regs->bx);
+
+       dprintf(3, "Legacy16DispatchOprom rom %p\n", rom);
+
+       dprintf(3, "OpromSegment   %04x\n", rom->OpromSegment);
+       dprintf(3, "RuntimeSegment %04x\n", rom->RuntimeSegment);
+
+       /* FIXME: Actually do it! */
+
+       regs->ax = 0;
+}
+
+/* Legacy16GetTableAddress */
+void handle_csm_0006(struct bregs *regs)
+{
+       u16 size = regs->cx;
+       u16 align = regs->dx;
+       u16 region = regs->bx; // (1 for F000 seg, 2 for E000 seg, 0 for either)
+       void *chunk;
+
+       /* FIXME: I don't know if we can allocate in the E000 segment at all. */
+       dprintf(3, "Legacy16GetTableAddress size %x align %x region %d\n",
+               size, align, region);
+       chunk = pmm_malloc(&ZoneFSeg, PMM_DEFAULT_HANDLE, size, align);
+       dprintf(3, "Legacy16GetTableAddress size %x align %x region %d yields 
%p\n",
+               size, align, region, chunk);
+       if (chunk) {
+               regs->ds = FLATPTR_TO_SEG(chunk);
+               regs->bx = FLATPTR_TO_OFFSET(chunk);
+               regs->ax = 0;
+       } else {
+               regs->ax = 1;
+       }
+}
+
+void __VISIBLE
+handle_csm16(struct bregs *regs)
+{
+       if (MODESEGMENT) {
+               void *flatptr = MAKE_FLATPTR(GET_SEG(SS), regs);
+               call32(_cfunc32flat_handle_csm16, (u32)flatptr, 0);
+               return;
+       }
+       dprintf(3, "handle_csm16 AX=%04x\n", regs->ax);
+
+       switch(regs->ax) {
+       case 0000: handle_csm_0000(regs); break;
+       case 0001: handle_csm_0001(regs); break;
+//     case 0002: handle_csm_0002(regs); break;
+//     case 0003: handle_csm_0003(regs); break;
+//     case 0004: handle_csm_0004(regs); break;
+       case 0005: handle_csm_0005(regs); break;
+       case 0006: handle_csm_0006(regs); break;
+//     case 0007: handle_csm_0007(regs); break;
+//     case 0008: hamdle_csm_0008(regs); break;
+       default: regs->al = 1;
+       }
+
+       dprintf(3, "handle_csm16 returning AX=%04x\n", regs->ax);
+}
diff --git a/src/post.c b/src/post.c
index f3b56b8..dc07e8b 100644
--- a/src/post.c
+++ b/src/post.c
@@ -225,6 +225,9 @@ maininit(void)
     init_ivt();
     init_bda();
 
+    if (CONFIG_CSM)
+           return;
+
     // Init base pc hardware.
     pic_setup();
     timer_setup();
diff --git a/src/romlayout.S b/src/romlayout.S
index 8125277..f1a276e 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -468,6 +468,13 @@ irqentryarg:
         DECL_IRQ_ENTRY hwpic1
         DECL_IRQ_ENTRY hwpic2
 
+#if CONFIG_CSM
+       EXPORTFUNC entry_csm16
+entry_csm16:
+        ENTRY_ARG handle_csm16
+       iretw
+#endif
+
         // int 18/19 are special - they reset stack and call into 32bit mode.
         DECLFUNC entry_19
 entry_19:
diff --git a/src/shadow.c b/src/shadow.c
index a2195da..881d5a6 100644
--- a/src/shadow.c
+++ b/src/shadow.c
@@ -119,7 +119,7 @@ static const struct pci_device_id 
dram_controller_make_readonly_tbl[] = {
 void
 make_bios_writable(void)
 {
-    if (CONFIG_COREBOOT || usingXen())
+    if (CONFIG_COREBOOT || CONFIG_CSM || usingXen())
         return;
 
     dprintf(3, "enabling shadow ram\n");
@@ -148,7 +148,7 @@ make_bios_writable(void)
 void
 make_bios_readonly(void)
 {
-    if (CONFIG_COREBOOT || usingXen())
+    if (CONFIG_COREBOOT || CONFIG_CSM || usingXen())
         return;
 
     dprintf(3, "locking shadow ram\n");
@@ -161,7 +161,7 @@ make_bios_readonly(void)
 void
 qemu_prep_reset(void)
 {
-    if (CONFIG_COREBOOT)
+    if (CONFIG_COREBOOT || CONFIG_CSM )
         return;
     // QEMU doesn't map 0xc0000-0xfffff back to the original rom on a
     // reset, so do that manually before invoking a hard reset.
-- 
1.8.0.2


-- 
dwmw2

Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
SeaBIOS mailing list
[email protected]
http://www.seabios.org/mailman/listinfo/seabios

Reply via email to