This patch series adds support for using SeaBIOS as a Compatibility Support Module (CSM) to provide "Legacy" BIOS services under UEFI/OVMF.
With a version of OVMF suitably patched to stop it from marking our stack in the 0xE0000 segment as read-only (see README.CSM), it has been tested with various Linux systems, Windows 7, OpenBSD 5.2, FreeBSD 8/9, NetBSD, DragonflyBSD, Solaris 10/11.
It also fixes issues with Windows 2008r2 which rather stupidly invokes INT 10h for video setup even when booted in EFI mode!
I haven't quite finished going through the corporate bureaucracy for releasing this, so it's for review only.
Git tree at git://git.infradead.org/users/dwmw2/seabios.git or gitweb at http://git.infradead.org/users/dwmw2/seabios.git
From: Kevin O'Connor kevin@koconnor.net
Call maininit() and startBoot() from handle_post(). This reduces the chaining of calls during the relocation phase, and allows maininit() to return (which may be useful when using SeaBIOS as a CSM).
This change relies on reloc_init() modifying the maininit() call in handle_post() when relocations are enabled. It technically may not be safe to modify gcc generated code when in that gcc code, but it should be safe in practice.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/pmm.c | 5 +++++ src/post.c | 46 ++++++++++++++++------------------------------ 2 files changed, 21 insertions(+), 30 deletions(-)
diff --git a/src/pmm.c b/src/pmm.c index 653c9e2..77138dc 100644 --- a/src/pmm.c +++ b/src/pmm.c @@ -265,6 +265,11 @@ malloc_fixupreloc(void) return; dprintf(3, "malloc fixup reloc\n");
+ // Move low-memory initial variable content to new location. + extern u8 datalow_start[], datalow_end[], final_datalow_start[]; + memmove(final_datalow_start, datalow_start, datalow_end - datalow_start); + + // Fixup pointers back to ZoneX globals. int i; for (i=0; i<ARRAY_SIZE(Zones); i++) { struct zone_s *zone = Zones[i]; diff --git a/src/post.c b/src/post.c index f3b56b8..6a91f81 100644 --- a/src/post.c +++ b/src/post.c @@ -200,7 +200,7 @@ init_hw(void) }
// Begin the boot process by invoking an int0x19 in 16bit mode. -void VISIBLE32FLAT +static void startBoot(void) { // Clear low-memory allocations (required by PMM spec). @@ -214,9 +214,12 @@ startBoot(void) }
// Main setup code. -static void +void VISIBLE32INIT maininit(void) { + // Running at new code address - do code relocation fixups + malloc_fixupreloc(); + // Setup romfile items. qemu_cfg_romfile_setup(); coreboot_cbfs_setup(); @@ -287,9 +290,6 @@ maininit(void)
// Write protect bios memory. make_bios_readonly(); - - // Invoke int 19 to start boot process. - startBoot(); }
@@ -297,21 +297,6 @@ maininit(void) * POST entry and code relocation ****************************************************************/
-// Relocation fixup code that runs at new address after relocation complete. -static void -afterReloc(void) -{ - // Running at new code address - do code relocation fixups - malloc_fixupreloc(); - - // Move low-memory initial variable content to new location. - extern u8 datalow_start[], datalow_end[], final_datalow_start[]; - memmove(final_datalow_start, datalow_start, datalow_end - datalow_start); - - // Run main code - maininit(); -} - // Update given relocs for the code at 'dest' with a given 'delta' static void updateRelocs(void *dest, u32 *rstart, u32 *rend, u32 delta) @@ -325,10 +310,8 @@ updateRelocs(void *dest, u32 *rstart, u32 *rend, u32 delta) static void reloc_init(void) { - if (!CONFIG_RELOCATE_INIT) { - maininit(); + if (!CONFIG_RELOCATE_INIT) return; - } // Symbols populated by the build. extern u8 code32flat_start[]; extern u8 _reloc_min_align; @@ -359,15 +342,12 @@ reloc_init(void) updateRelocs(codedest, _reloc_rel_start, _reloc_rel_end, -delta); updateRelocs(code32flat_start, _reloc_init_start, _reloc_init_end, delta);
- // Call maininit() in relocated code. - void (*func)(void) = (void*)afterReloc + delta; barrier(); - func(); }
// Setup for code relocation and then call reloc_init void VISIBLE32INIT -dopost(void) +doreloc(void) { HaveRunPost = 1;
@@ -376,7 +356,7 @@ dopost(void) ram_probe(); malloc_setup();
- // Relocate initialization code and call maininit(). + // Relocate initialization code. reloc_init(); }
@@ -404,6 +384,12 @@ handle_post(void) // Allow writes to modify bios area (0xf0000) make_bios_writable();
- // Now that memory is read/writable - start post process. - dopost(); + // Do pre-relocation setup and then relocate initialization code. + doreloc(); + + // Run main code + maininit(); + + // Invoke int 19 to start boot process. + startBoot(); }
From: Kevin O'Connor kevin@koconnor.net
The POST phase has to invoke many initialization functions, and these functions can have complex inter-dependencies. Try to categorize the functions into 4 classes:
preinit - functions called very early in POST where function ordering is very important and the code has limited access to other interfaces.
init - functions that initialize internal interfaces and standard external interfaces. This code is generally not dependent on particular hardware and typically does not communicate directly with any hardware devices.
setup - functions which access hardware or are dependent on particular hardware or platform devices.
prepboot - functions that finalize internal interfaces and that prepare for the boot phase.
This patch attempts to normalize the suffixes - functions that used _init(), _setup(), _finalize(), or similar that did not follow the above pattern were renamed. Other than function name changes, there should be no code impact to this patch.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/acpi.c | 12 ++++---- src/acpi.h | 2 +- src/ahci.c | 14 ++++----- src/ata.c | 4 +-- src/block.c | 2 +- src/blockcmd.c | 2 +- src/blockcmd.h | 2 +- src/boot.c | 8 ++--- src/boot.h | 4 +-- src/cdrom.c | 4 +-- src/clock.c | 12 ++++---- src/coreboot.c | 6 ++-- src/disk.h | 4 +-- src/esp-scsi.c | 4 +-- src/kbd.c | 2 +- src/lsi-scsi.c | 4 +-- src/megasas.c | 4 +-- src/memmap.c | 2 +- src/memmap.h | 2 +- src/misc.c | 2 +- src/mouse.c | 2 +- src/mptable.c | 2 +- src/mptable.h | 2 +- src/optionroms.c | 12 ++++---- src/output.c | 2 +- src/paravirt.c | 6 ++-- src/paravirt.h | 4 +-- src/pci.h | 2 +- src/pcibios.c | 2 +- src/pciinit.c | 52 +++++++++++++++---------------- src/pirtable.c | 2 +- src/pmm.c | 10 +++--- src/pnpbios.c | 2 +- src/post.c | 92 +++++++++++++++++++++++++++---------------------------- src/ps2port.c | 4 +-- src/resume.c | 10 +++--- src/smbios.c | 12 ++++---- src/smbios.h | 2 +- src/smm.c | 10 +++--- src/smp.c | 2 +- src/usb-ehci.c | 12 ++++---- src/usb-ehci.h | 2 +- src/usb-hid.c | 16 +++++----- src/usb-hid.h | 2 +- src/usb-hub.c | 2 +- src/usb-hub.h | 2 +- src/usb-msc.c | 12 ++++---- src/usb-msc.h | 2 +- src/usb-ohci.c | 2 +- src/usb-ohci.h | 2 +- src/usb-uas.c | 14 ++++----- src/usb-uas.h | 2 +- src/usb-uhci.c | 2 +- src/usb-uhci.h | 2 +- src/usb.c | 30 +++++++++--------- src/util.h | 46 +++++++++++++--------------- src/virtio-scsi.c | 4 +-- src/xen.c | 8 ++--- src/xen.h | 8 ++--- vgasrc/bochsvga.c | 4 +-- vgasrc/bochsvga.h | 2 +- vgasrc/clext.c | 6 ++-- vgasrc/clext.h | 2 +- vgasrc/geodevga.c | 10 +++--- vgasrc/geodevga.h | 2 +- vgasrc/stdvga.c | 4 +-- vgasrc/stdvga.h | 2 +- vgasrc/vgabios.c | 4 +-- vgasrc/vgahw.h | 12 ++++---- 69 files changed, 272 insertions(+), 274 deletions(-)
diff --git a/src/acpi.c b/src/acpi.c index 6267d7b..03cda34 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -236,7 +236,7 @@ build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev)
#define PIIX4_PM_INTRRUPT 9 // irq 9
-static void piix4_fadt_init(struct pci_device *pci, void *arg) +static void piix4_fadt_setup(struct pci_device *pci, void *arg) { struct fadt_descriptor_rev1 *fadt = arg;
@@ -262,7 +262,7 @@ static void piix4_fadt_init(struct pci_device *pci, void *arg) }
/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_LPC */ -void ich9_lpc_fadt_init(struct pci_device *dev, void *arg) +void ich9_lpc_fadt_setup(struct pci_device *dev, void *arg) { struct fadt_descriptor_rev1 *fadt = arg;
@@ -290,9 +290,9 @@ void ich9_lpc_fadt_init(struct pci_device *dev, void *arg) static const struct pci_device_id fadt_init_tbl[] = { /* PIIX4 Power Management device (for ACPI) */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, - piix4_fadt_init), + piix4_fadt_setup), PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_LPC, - ich9_lpc_fadt_init), + ich9_lpc_fadt_setup), PCI_DEVICE_END };
@@ -325,7 +325,7 @@ build_fadt(struct pci_device *pci) /* FADT */ memset(fadt, 0, sizeof(*fadt)); fadt->firmware_ctrl = cpu_to_le32((u32)facs); - fadt->dsdt = 0; /* dsdt will be filled later in acpi_bios_init() + fadt->dsdt = 0; /* dsdt will be filled later in acpi_setup() by fill_dsdt() */ pci_init_device(fadt_init_tbl, pci, fadt);
@@ -796,7 +796,7 @@ struct rsdp_descriptor *RsdpAddr;
#define MAX_ACPI_TABLES 20 void -acpi_bios_init(void) +acpi_setup(void) { if (! CONFIG_ACPI) return; diff --git a/src/acpi.h b/src/acpi.h index 715d19d..8bbf25c 100644 --- a/src/acpi.h +++ b/src/acpi.h @@ -3,7 +3,7 @@
#include "types.h" // u32
-void acpi_bios_init(void); +void acpi_setup(void); u32 find_resume_vector(void);
#define RSDP_SIGNATURE 0x2052545020445352LL // "RSD PTR " diff --git a/src/ahci.c b/src/ahci.c index 4a8eafb..879a991 100644 --- a/src/ahci.c +++ b/src/ahci.c @@ -422,7 +422,7 @@ static void ahci_port_release(struct ahci_port_s *port) #define MAXMODEL 40
/* See ahci spec chapter 10.1 "Software Initialization of HBA" */ -static int ahci_port_init(struct ahci_port_s *port) +static int ahci_port_setup(struct ahci_port_s *port) { struct ahci_ctrl_s *ctrl = port->ctrl; u32 pnr = port->pnr; @@ -549,7 +549,7 @@ ahci_port_detect(void *data)
dprintf(2, "AHCI/%d: probing\n", port->pnr); ahci_port_reset(port->ctrl, port->pnr); - rc = ahci_port_init(port); + rc = ahci_port_setup(port); if (rc < 0) ahci_port_release(port); else { @@ -567,7 +567,7 @@ ahci_port_detect(void *data)
// Initialize an ata controller and detect its drives. static void -ahci_init_controller(struct pci_device *pci) +ahci_controller_setup(struct pci_device *pci) { struct ahci_ctrl_s *ctrl = malloc_fseg(sizeof(*ctrl)); struct ahci_port_s *port; @@ -579,7 +579,7 @@ ahci_init_controller(struct pci_device *pci) return; }
- if (bounce_buf_init() < 0) { + if (create_bounce_buf() < 0) { warn_noalloc(); free(ctrl); return; @@ -616,7 +616,7 @@ ahci_init_controller(struct pci_device *pci)
// Locate and init ahci controllers. static void -ahci_init(void) +ahci_scan(void) { // Scan PCI bus for ATA adapters struct pci_device *pci; @@ -625,7 +625,7 @@ ahci_init(void) continue; if (pci->prog_if != 1 /* AHCI rev 1 */) continue; - ahci_init_controller(pci); + ahci_controller_setup(pci); } }
@@ -637,5 +637,5 @@ ahci_setup(void) return;
dprintf(3, "init ahci\n"); - ahci_init(); + ahci_scan(); } diff --git a/src/ata.c b/src/ata.c index f604b37..d1d8dff 100644 --- a/src/ata.c +++ b/src/ata.c @@ -1006,7 +1006,7 @@ static const struct pci_device_id pci_ata_tbl[] = {
// Locate and init ata controllers. static void -ata_init(void) +ata_scan(void) { if (!CONFIG_COREBOOT && !PCIDevices) { // No PCI devices found - probably a QEMU "-M isapc" machine. @@ -1035,7 +1035,7 @@ ata_setup(void) dprintf(3, "init hard drives\n");
SpinupEnd = calc_future_tsc(IDE_TIMEOUT); - ata_init(); + ata_scan();
SET_BDA(disk_control_byte, 0xc0);
diff --git a/src/block.c b/src/block.c index cfe5c33..e5f3038 100644 --- a/src/block.c +++ b/src/block.c @@ -40,7 +40,7 @@ int getDriveId(u8 exttype, struct drive_s *drive_g) return -1; }
-int bounce_buf_init(void) +int create_bounce_buf(void) { if (bounce_buf_fl) return 0; diff --git a/src/blockcmd.c b/src/blockcmd.c index 81b191b..e033ba7 100644 --- a/src/blockcmd.c +++ b/src/blockcmd.c @@ -101,7 +101,7 @@ scsi_is_ready(struct disk_op_s *op)
// Validate drive, find block size / sector count, and register drive. int -scsi_init_drive(struct drive_s *drive, const char *s, int prio) +scsi_drive_setup(struct drive_s *drive, const char *s, int prio) { struct disk_op_s dop; memset(&dop, 0, sizeof(dop)); diff --git a/src/blockcmd.h b/src/blockcmd.h index b45bbb7..8bacfcf 100644 --- a/src/blockcmd.h +++ b/src/blockcmd.h @@ -113,6 +113,6 @@ int cdb_write(struct disk_op_s *op);
int scsi_is_ready(struct disk_op_s *op); struct drive_s; -int scsi_init_drive(struct drive_s *drive, const char *s, int prio); +int scsi_drive_setup(struct drive_s *drive, const char *s, int prio);
#endif // blockcmd.h diff --git a/src/boot.c b/src/boot.c index 56843e3..2cb3b86 100644 --- a/src/boot.c +++ b/src/boot.c @@ -238,7 +238,7 @@ static int DefaultHDPrio = 103; static int DefaultBEVPrio = 104;
void -boot_setup(void) +boot_init(void) { if (! CONFIG_BOOT) return; @@ -476,7 +476,7 @@ add_bev(int type, u32 vector)
// Prepare for boot - show menu and run bcvs. void -boot_prep(void) +boot_prepboot(void) { if (! CONFIG_BOOT) { wait_threads(); @@ -695,7 +695,7 @@ int BootSequence VARLOW = -1; void VISIBLE32FLAT handle_18(void) { - debug_serial_setup(); + debug_serial_preinit(); debug_enter(NULL, DEBUG_HDL_18); int seq = BootSequence + 1; BootSequence = seq; @@ -706,7 +706,7 @@ handle_18(void) void VISIBLE32FLAT handle_19(void) { - debug_serial_setup(); + debug_serial_preinit(); debug_enter(NULL, DEBUG_HDL_19); BootSequence = 0; do_boot(0); diff --git a/src/boot.h b/src/boot.h index afe9f2e..4a93d0f 100644 --- a/src/boot.h +++ b/src/boot.h @@ -3,7 +3,7 @@ #define __BOOT_H
// boot.c -void boot_setup(void); +void boot_init(void); void boot_add_bev(u16 seg, u16 bev, u16 desc, int prio); void boot_add_bcv(u16 seg, u16 ip, u16 desc, int prio); struct drive_s; @@ -11,7 +11,7 @@ void boot_add_floppy(struct drive_s *drive_g, const char *desc, int prio); void boot_add_hd(struct drive_s *drive_g, const char *desc, int prio); void boot_add_cd(struct drive_s *drive_g, const char *desc, int prio); void boot_add_cbfs(void *data, const char *desc, int prio); -void boot_prep(void); +void boot_prepboot(void); struct pci_device; int bootprio_find_pci_device(struct pci_device *pci); int bootprio_find_scsi_device(struct pci_device *pci, int target, int lun); diff --git a/src/cdrom.c b/src/cdrom.c index 42d8e08..81b97f7 100644 --- a/src/cdrom.c +++ b/src/cdrom.c @@ -107,13 +107,13 @@ process_cdemu_op(struct disk_op_s *op) }
void -cdemu_setup(void) +cdrom_prepboot(void) { if (!CONFIG_CDROM_EMU) return; if (!CDCount) return; - if (bounce_buf_init() < 0) + if (create_bounce_buf() < 0) return;
struct drive_s *drive_g = malloc_fseg(sizeof(*drive_g)); diff --git a/src/clock.c b/src/clock.c index 71b913e..3edcaf5 100644 --- a/src/clock.c +++ b/src/clock.c @@ -133,7 +133,7 @@ u16 pmtimer_ioport VAR16VISIBLE; u32 pmtimer_wraps VARLOW; u32 pmtimer_last VARLOW;
-void pmtimer_init(u16 ioport, u32 khz) +void pmtimer_setup(u16 ioport, u32 khz) { if (!CONFIG_PMTIMER) return; @@ -266,7 +266,7 @@ pit_setup(void) }
static void -init_rtc(void) +rtc_setup(void) { outb_cmos(0x26, CMOS_STATUS_A); // 32,768Khz src, 976.5625us updates u8 regB = inb_cmos(CMOS_STATUS_B); @@ -288,7 +288,7 @@ timer_setup(void) calibrate_tsc(); pit_setup();
- init_rtc(); + rtc_setup(); rtc_updating(); u32 seconds = bcd2bin(inb_cmos(CMOS_RTC_SECONDS)); u32 minutes = bcd2bin(inb_cmos(CMOS_RTC_MINUTES)); @@ -393,7 +393,7 @@ handle_1a03(struct bregs *regs) // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1 // My assumption: RegB = ((RegB & 01100000b) | 00000010b) if (rtc_updating()) { - init_rtc(); + rtc_setup(); // fall through as if an update were not in progress } outb_cmos(regs->dh, CMOS_RTC_SECONDS); @@ -447,7 +447,7 @@ handle_1a05(struct bregs *regs) // Bit4 in try#1 flipped in hardware (forced low) due to bit7=1 // My assumption: RegB = (RegB & 01111111b) if (rtc_updating()) { - init_rtc(); + rtc_setup(); set_invalid(regs); return; } @@ -486,7 +486,7 @@ handle_1a06(struct bregs *regs) return; } if (rtc_updating()) { - init_rtc(); + rtc_setup(); // fall through as if an update were not in progress } outb_cmos(regs->dh, CMOS_RTC_SECONDS_ALARM); diff --git a/src/coreboot.c b/src/coreboot.c index e4767f1..5d013cf 100644 --- a/src/coreboot.c +++ b/src/coreboot.c @@ -123,7 +123,7 @@ const char *CBvendor = "", *CBpart = "";
// Populate max ram and e820 map info by scanning for a coreboot table. void -coreboot_setup(void) +coreboot_preinit(void) { dprintf(3, "Attempting to find coreboot table\n");
@@ -204,7 +204,7 @@ scan_tables(u32 start, u32 size) }
void -coreboot_copy_biostable(void) +coreboot_biostable_setup(void) { struct cb_memory *cbm = CBMemTable; if (! CONFIG_COREBOOT || !cbm) @@ -324,7 +324,7 @@ cbfs_copyfile(struct romfile_s *file, void *dst, u32 maxlen) }
void -coreboot_cbfs_setup(void) +coreboot_cbfs_init(void) { if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH) return; diff --git a/src/disk.h b/src/disk.h index 21debec..8e49124 100644 --- a/src/disk.h +++ b/src/disk.h @@ -266,7 +266,7 @@ void map_hd_drive(struct drive_s *drive_g); void map_cd_drive(struct drive_s *drive_g); int process_op(struct disk_op_s *op); int send_disk_op(struct disk_op_s *op); -int bounce_buf_init(void); +int create_bounce_buf(void);
// floppy.c extern struct floppy_ext_dbt_s diskette_param_table2; @@ -281,7 +281,7 @@ extern u8 CDRom_locks[]; extern struct cdemu_s CDEmu; extern struct drive_s *cdemu_drive_gf; int process_cdemu_op(struct disk_op_s *op); -void cdemu_setup(void); +void cdrom_prepboot(void); void cdemu_134b(struct bregs *regs); int cdrom_boot(struct drive_s *drive_g);
diff --git a/src/esp-scsi.c b/src/esp-scsi.c index c43e55b..4d1f7d2 100644 --- a/src/esp-scsi.c +++ b/src/esp-scsi.c @@ -17,7 +17,7 @@ #include "pci_ids.h" // PCI_DEVICE_ID #include "pci_regs.h" // PCI_VENDOR_ID #include "boot.h" // bootprio_find_scsi_device -#include "blockcmd.h" // scsi_init_drive +#include "blockcmd.h" // scsi_drive_setup #include "disk.h"
#define ESP_TCLO 0x00 @@ -174,7 +174,7 @@ esp_scsi_add_lun(struct pci_device *pci, u32 iobase, u8 target, u8 lun) pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf), pci_bdf_to_fn(pci->bdf), target, lun); int prio = bootprio_find_scsi_device(pci, target, lun); - int ret = scsi_init_drive(&llun->drive, name, prio); + int ret = scsi_drive_setup(&llun->drive, name, prio); free(name); if (ret) goto fail; diff --git a/src/kbd.c b/src/kbd.c index e9ea594..05845e5 100644 --- a/src/kbd.c +++ b/src/kbd.c @@ -35,7 +35,7 @@ #define KF2_101KBD (1<<4)
void -kbd_setup(void) +kbd_init(void) { dprintf(3, "init keyboard\n"); u16 x = offsetof(struct bios_data_area_s, kbd_buf); diff --git a/src/lsi-scsi.c b/src/lsi-scsi.c index f8d715b..76e9d1d 100644 --- a/src/lsi-scsi.c +++ b/src/lsi-scsi.c @@ -17,7 +17,7 @@ #include "pci_ids.h" // PCI_DEVICE_ID_VIRTIO_BLK #include "pci_regs.h" // PCI_VENDOR_ID #include "boot.h" // bootprio_find_scsi_device -#include "blockcmd.h" // scsi_init_drive +#include "blockcmd.h" // scsi_drive_setup #include "disk.h"
#define LSI_REG_DSTAT 0x0c @@ -152,7 +152,7 @@ lsi_scsi_add_lun(struct pci_device *pci, u32 iobase, u8 target, u8 lun) pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf), pci_bdf_to_fn(pci->bdf), target, lun); int prio = bootprio_find_scsi_device(pci, target, lun); - int ret = scsi_init_drive(&llun->drive, name, prio); + int ret = scsi_drive_setup(&llun->drive, name, prio); free(name); if (ret) goto fail; diff --git a/src/megasas.c b/src/megasas.c index 3ccdd0a..170700f 100644 --- a/src/megasas.c +++ b/src/megasas.c @@ -17,7 +17,7 @@ #include "pci_ids.h" // PCI_DEVICE_ID_XXX #include "pci_regs.h" // PCI_VENDOR_ID #include "boot.h" // bootprio_find_scsi_device -#include "blockcmd.h" // scsi_init_drive +#include "blockcmd.h" // scsi_drive_setup #include "disk.h"
#define MFI_DB 0x0 // Doorbell @@ -223,7 +223,7 @@ megasas_add_lun(struct pci_device *pci, u32 iobase, u8 target, u8 lun) pci_bdf_to_bus(pci->bdf), pci_bdf_to_dev(pci->bdf), pci_bdf_to_fn(pci->bdf), target, lun); prio = bootprio_find_scsi_device(pci, target, lun); - ret = scsi_init_drive(&mlun->drive, name, prio); + ret = scsi_drive_setup(&mlun->drive, name, prio); free(name); if (ret) { free(mlun->frame); diff --git a/src/memmap.c b/src/memmap.c index 3783518..29ca644 100644 --- a/src/memmap.c +++ b/src/memmap.c @@ -133,7 +133,7 @@ add_e820(u64 start, u64 size, u32 type)
// Report on final memory locations. void -memmap_finalize(void) +memmap_prepboot(void) { dump_map(); } diff --git a/src/memmap.h b/src/memmap.h index 01c7ddb..783a042 100644 --- a/src/memmap.h +++ b/src/memmap.h @@ -17,7 +17,7 @@ struct e820entry { };
void add_e820(u64 start, u64 size, u32 type); -void memmap_finalize(void); +void memmap_prepboot(void);
// A typical OS page size #define PAGE_SIZE 4096 diff --git a/src/misc.c b/src/misc.c index 54d8aef..bcc450a 100644 --- a/src/misc.c +++ b/src/misc.c @@ -61,7 +61,7 @@ handle_02(void) }
void -mathcp_setup(void) +mathcp_init(void) { dprintf(3, "math cp init\n"); // 80x87 coprocessor installed diff --git a/src/mouse.c b/src/mouse.c index 7b28a63..5371cf6 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -12,7 +12,7 @@ #include "usb-hid.h" // usb_mouse_command
void -mouse_setup(void) +mouse_init(void) { if (! CONFIG_MOUSE) return; diff --git a/src/mptable.c b/src/mptable.c index 3aa3427..2d4e441 100644 --- a/src/mptable.c +++ b/src/mptable.c @@ -13,7 +13,7 @@ #include "pci_regs.h"
void -mptable_init(void) +mptable_setup(void) { if (! CONFIG_MPTABLE) return; diff --git a/src/mptable.h b/src/mptable.h index c4e3c51..6252854 100644 --- a/src/mptable.h +++ b/src/mptable.h @@ -75,6 +75,6 @@ struct mpt_intsrc { } PACKED;
// mptable.c -void mptable_init(void); +void mptable_setup(void);
#endif // mptable.h diff --git a/src/optionroms.c b/src/optionroms.c index 00697b2..c79a706 100644 --- a/src/optionroms.c +++ b/src/optionroms.c @@ -40,7 +40,7 @@ __callrom(struct rom_header *rom, u16 offset, u16 bdf) farcall16big(&br); finish_preempt();
- debug_serial_setup(); + debug_serial_preinit(); }
// Execute a given option rom at the standard entry vector. @@ -410,13 +410,13 @@ optionrom_setup(void) * VGA init ****************************************************************/
-static int S3ResumeVgaInit; +static int S3ResumeVga; int ScreenAndDebug; struct rom_header *VgaROM;
// Call into vga code to turn on console. void -vga_setup(void) +vgarom_setup(void) { if (! CONFIG_OPTIONROMS) return; @@ -425,7 +425,7 @@ vga_setup(void)
// Load some config settings that impact VGA. EnforceChecksum = romfile_loadint("etc/optionroms-checksum", 1); - S3ResumeVgaInit = romfile_loadint("etc/s3-resume-vga-init", !CONFIG_COREBOOT); + S3ResumeVga = romfile_loadint("etc/s3-resume-vga-init", !CONFIG_COREBOOT); ScreenAndDebug = romfile_loadint("etc/screen-and-debug", 1);
if (CONFIG_OPTIONROMS_DEPLOYED) { @@ -459,9 +459,9 @@ vga_setup(void) }
void -s3_resume_vga_init(void) +s3_resume_vga(void) { - if (!S3ResumeVgaInit) + if (!S3ResumeVga) return; if (!VgaROM || ! is_valid_rom(VgaROM)) return; diff --git a/src/output.c b/src/output.c index 83de7f4..e623d37 100644 --- a/src/output.c +++ b/src/output.c @@ -26,7 +26,7 @@ struct putcinfo { u16 DebugOutputPort VAR16VISIBLE = 0x402;
void -debug_serial_setup(void) +debug_serial_preinit(void) { if (!CONFIG_DEBUG_SERIAL) return; diff --git a/src/paravirt.c b/src/paravirt.c index 4b5c441..f180261 100644 --- a/src/paravirt.c +++ b/src/paravirt.c @@ -11,7 +11,7 @@ #include "util.h" // dprintf #include "byteorder.h" // be32_to_cpu #include "ioport.h" // outw -#include "paravirt.h" // qemu_cfg_port_probe +#include "paravirt.h" // qemu_cfg_preinit #include "smbios.h" // struct smbios_structure_header
int qemu_cfg_present; @@ -42,7 +42,7 @@ qemu_cfg_read_entry(void *buf, int e, int len) qemu_cfg_read(buf, len); }
-void qemu_cfg_port_probe(void) +void qemu_cfg_preinit(void) { char *sig = "QEMU"; int i; @@ -321,7 +321,7 @@ struct QemuCfgFile { char name[56]; };
-void qemu_cfg_romfile_setup(void) +void qemu_romfile_init(void) { if (CONFIG_COREBOOT || !qemu_cfg_present) return; diff --git a/src/paravirt.h b/src/paravirt.h index a284c41..765a6c1 100644 --- a/src/paravirt.h +++ b/src/paravirt.h @@ -43,7 +43,7 @@ static inline int kvm_para_available(void)
extern int qemu_cfg_present;
-void qemu_cfg_port_probe(void); +void qemu_cfg_preinit(void); int qemu_cfg_show_boot_menu(void); void qemu_cfg_get_uuid(u8 *uuid); int qemu_cfg_irq0_override(void); @@ -64,6 +64,6 @@ struct e820_reservation { }; u32 qemu_cfg_e820_entries(void); void* qemu_cfg_e820_load_next(void *addr); -void qemu_cfg_romfile_setup(void); +void qemu_romfile_init(void);
#endif diff --git a/src/pci.h b/src/pci.h index fe663b8..aa54dd7 100644 --- a/src/pci.h +++ b/src/pci.h @@ -118,7 +118,7 @@ u32 pci_readl(u32 addr); void pci_writel(u32 addr, u32 val);
// pirtable.c -void create_pirtable(void); +void pirtable_setup(void);
/**************************************************************** diff --git a/src/pcibios.c b/src/pcibios.c index e4bd7c0..f084fa1 100644 --- a/src/pcibios.c +++ b/src/pcibios.c @@ -229,7 +229,7 @@ struct bios32_s BIOS32HEADER __aligned(16) VAR16EXPORT = { };
void -bios32_setup(void) +bios32_init(void) { dprintf(3, "init bios32\n");
diff --git a/src/pciinit.c b/src/pciinit.c index a406bbd..34b47b6 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -105,7 +105,7 @@ static int pci_slot_get_irq(struct pci_device *pci, int pin) }
/* PIIX3/PIIX4 PCI to ISA bridge */ -static void piix_isa_bridge_init(struct pci_device *pci, void *arg) +static void piix_isa_bridge_setup(struct pci_device *pci, void *arg) { int i, irq; u8 elcr[2]; @@ -126,7 +126,7 @@ static void piix_isa_bridge_init(struct pci_device *pci, void *arg)
/* ICH9 LPC PCI to ISA bridge */ /* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_LPC */ -void mch_isa_bridge_init(struct pci_device *dev, void *arg) +void mch_isa_bridge_setup(struct pci_device *dev, void *arg) { u16 bdf = dev->bdf; int i, irq; @@ -160,10 +160,10 @@ void mch_isa_bridge_init(struct pci_device *dev, void *arg) /* acpi enable, SCI: IRQ9 000b = irq9*/ pci_config_writeb(bdf, ICH9_LPC_ACPI_CTRL, ICH9_LPC_ACPI_CTRL_ACPI_EN);
- pmtimer_init(PORT_ACPI_PM_BASE + 0x08, PM_TIMER_FREQUENCY / 1000); + pmtimer_setup(PORT_ACPI_PM_BASE + 0x08, PM_TIMER_FREQUENCY / 1000); }
-static void storage_ide_init(struct pci_device *pci, void *arg) +static void storage_ide_setup(struct pci_device *pci, void *arg) { /* IDE: we map it as in ISA mode */ pci_set_io_region_addr(pci, 0, PORT_ATA1_CMD_BASE, 0); @@ -173,27 +173,27 @@ static void storage_ide_init(struct pci_device *pci, void *arg) }
/* PIIX3/PIIX4 IDE */ -static void piix_ide_init(struct pci_device *pci, void *arg) +static void piix_ide_setup(struct pci_device *pci, void *arg) { u16 bdf = pci->bdf; pci_config_writew(bdf, 0x40, 0x8000); // enable IDE0 pci_config_writew(bdf, 0x42, 0x8000); // enable IDE1 }
-static void pic_ibm_init(struct pci_device *pci, void *arg) +static void pic_ibm_setup(struct pci_device *pci, void *arg) { /* PIC, IBM, MPIC & MPIC2 */ pci_set_io_region_addr(pci, 0, 0x80800000 + 0x00040000, 0); }
-static void apple_macio_init(struct pci_device *pci, void *arg) +static void apple_macio_setup(struct pci_device *pci, void *arg) { /* macio bridge */ pci_set_io_region_addr(pci, 0, 0x80800000, 0); }
/* PIIX4 Power Management device (for ACPI) */ -static void piix4_pm_init(struct pci_device *pci, void *arg) +static void piix4_pm_setup(struct pci_device *pci, void *arg) { u16 bdf = pci->bdf; // acpi sci is hardwired to 9 @@ -204,12 +204,12 @@ static void piix4_pm_init(struct pci_device *pci, void *arg) pci_config_writel(bdf, 0x90, PORT_SMB_BASE | 1); pci_config_writeb(bdf, 0xd2, 0x09); /* enable SMBus io space */
- pmtimer_init(PORT_ACPI_PM_BASE + 0x08, PM_TIMER_FREQUENCY / 1000); + pmtimer_setup(PORT_ACPI_PM_BASE + 0x08, PM_TIMER_FREQUENCY / 1000); }
/* ICH9 SMBUS */ /* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_SMBUS */ -void ich9_smbus_init(struct pci_device *dev, void *arg) +void ich9_smbus_setup(struct pci_device *dev, void *arg) { u16 bdf = dev->bdf; /* map smbus into io space */ @@ -223,35 +223,35 @@ void ich9_smbus_init(struct pci_device *dev, void *arg) static const struct pci_device_id pci_device_tbl[] = { /* PIIX3/PIIX4 PCI to ISA bridge */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_0, - piix_isa_bridge_init), + piix_isa_bridge_setup), PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0, - piix_isa_bridge_init), + piix_isa_bridge_setup), PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_LPC, - mch_isa_bridge_init), + mch_isa_bridge_setup),
/* STORAGE IDE */ PCI_DEVICE_CLASS(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371SB_1, - PCI_CLASS_STORAGE_IDE, piix_ide_init), + PCI_CLASS_STORAGE_IDE, piix_ide_setup), PCI_DEVICE_CLASS(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB, - PCI_CLASS_STORAGE_IDE, piix_ide_init), + PCI_CLASS_STORAGE_IDE, piix_ide_setup), PCI_DEVICE_CLASS(PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE, - storage_ide_init), + storage_ide_setup),
/* PIC, IBM, MIPC & MPIC2 */ PCI_DEVICE_CLASS(PCI_VENDOR_ID_IBM, 0x0046, PCI_CLASS_SYSTEM_PIC, - pic_ibm_init), + pic_ibm_setup), PCI_DEVICE_CLASS(PCI_VENDOR_ID_IBM, 0xFFFF, PCI_CLASS_SYSTEM_PIC, - pic_ibm_init), + pic_ibm_setup),
/* PIIX4 Power Management device (for ACPI) */ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, - piix4_pm_init), + piix4_pm_setup), PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_SMBUS, - ich9_smbus_init), + ich9_smbus_setup),
/* 0xff00 */ - PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x0017, 0xff00, apple_macio_init), - PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x0022, 0xff00, apple_macio_init), + PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x0017, 0xff00, apple_macio_setup), + PCI_DEVICE_CLASS(PCI_VENDOR_ID_APPLE, 0x0022, 0xff00, apple_macio_setup),
PCI_DEVICE_END, }; @@ -288,7 +288,7 @@ static void pci_bios_init_devices(void) * Platform device initialization ****************************************************************/
-void i440fx_mem_addr_init(struct pci_device *dev, void *arg) +void i440fx_mem_addr_setup(struct pci_device *dev, void *arg) { if (RamSize <= 0x80000000) pcimem_start = 0x80000000; @@ -296,7 +296,7 @@ void i440fx_mem_addr_init(struct pci_device *dev, void *arg) pcimem_start = 0xc0000000; }
-void mch_mem_addr_init(struct pci_device *dev, void *arg) +void mch_mem_addr_setup(struct pci_device *dev, void *arg) { u64 addr = Q35_HOST_BRIDGE_PCIEXBAR_ADDR; u32 size = Q35_HOST_BRIDGE_PCIEXBAR_SIZE; @@ -316,9 +316,9 @@ void mch_mem_addr_init(struct pci_device *dev, void *arg)
static const struct pci_device_id pci_platform_tbl[] = { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, - i440fx_mem_addr_init), + i440fx_mem_addr_setup), PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_Q35_MCH, - mch_mem_addr_init), + mch_mem_addr_setup), PCI_DEVICE_END };
diff --git a/src/pirtable.c b/src/pirtable.c index 8eadbf0..62b62b8 100644 --- a/src/pirtable.c +++ b/src/pirtable.c @@ -92,7 +92,7 @@ struct pir_table PIR_TABLE __aligned(16) VAR16EXPORT = { #endif // CONFIG_PIRTABLE && !CONFIG_COREBOOT
void -create_pirtable(void) +pirtable_setup(void) { if (! CONFIG_PIRTABLE) return; diff --git a/src/pmm.c b/src/pmm.c index 77138dc..0dbc86e 100644 --- a/src/pmm.c +++ b/src/pmm.c @@ -217,7 +217,7 @@ rom_confirm(u32 size) ****************************************************************/
void -malloc_setup(void) +malloc_preinit(void) { ASSERT32FLAT(); dprintf(3, "malloc setup\n"); @@ -258,7 +258,7 @@ malloc_setup(void)
// Update pointers after code relocation. void -malloc_fixupreloc(void) +malloc_fixupreloc_init(void) { ASSERT32FLAT(); if (!CONFIG_RELOCATE_INIT) @@ -286,7 +286,7 @@ malloc_fixupreloc(void) }
void -malloc_finalize(void) +malloc_prepboot(void) { ASSERT32FLAT(); dprintf(3, "malloc finalize\n"); @@ -554,7 +554,7 @@ handle_pmm(u16 *args) extern void entry_pmm(void);
void -pmm_setup(void) +pmm_init(void) { if (! CONFIG_PMM) return; @@ -567,7 +567,7 @@ pmm_setup(void) }
void -pmm_finalize(void) +pmm_prepboot(void) { if (! CONFIG_PMM) return; diff --git a/src/pnpbios.c b/src/pnpbios.c index b1bebc9..c8bc8f4 100644 --- a/src/pnpbios.c +++ b/src/pnpbios.c @@ -90,7 +90,7 @@ extern void entry_pnp_real(void); extern void entry_pnp_prot(void);
void -pnp_setup(void) +pnp_init(void) { if (! CONFIG_PNPBIOS) return; diff --git a/src/post.c b/src/post.c index 6a91f81..6f5dfef 100644 --- a/src/post.c +++ b/src/post.c @@ -23,7 +23,7 @@ #include "usb.h" // usb_setup #include "smbios.h" // smbios_init #include "paravirt.h" // qemu_cfg_port_probe -#include "xen.h" // xen_probe_hvm_info +#include "xen.h" // xen_preinit #include "ps2port.h" // ps2port_setup #include "virtio-blk.h" // virtio_blk_setup #include "virtio-scsi.h" // virtio_scsi_setup @@ -36,7 +36,7 @@ ****************************************************************/
static void -init_ivt(void) +ivt_init(void) { dprintf(3, "init ivt\n");
@@ -76,7 +76,7 @@ init_ivt(void) }
static void -init_bda(void) +bda_init(void) { dprintf(3, "init bda\n");
@@ -101,13 +101,13 @@ init_bda(void) }
static void -ram_probe(void) +ramsize_preinit(void) { dprintf(3, "Find memory size\n"); if (CONFIG_COREBOOT) { - coreboot_setup(); + coreboot_preinit(); } else if (usingXen()) { - xen_setup(); + xen_ramsize_preinit(); } else { // On emulators, get memory size from nvram. u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16) @@ -158,29 +158,29 @@ ram_probe(void) }
static void -init_bios_tables(void) +biostable_setup(void) { if (CONFIG_COREBOOT) { - coreboot_copy_biostable(); + coreboot_biostable_setup(); return; } if (usingXen()) { - xen_copy_biostables(); + xen_biostable_setup(); return; }
- create_pirtable(); + pirtable_setup();
- mptable_init(); + mptable_setup();
- smbios_init(); + smbios_setup();
- acpi_bios_init(); + acpi_setup(); }
// Initialize hardware devices static void -init_hw(void) +device_hardware_setup(void) { usb_setup(); ps2port_setup(); @@ -218,58 +218,58 @@ void VISIBLE32INIT maininit(void) { // Running at new code address - do code relocation fixups - malloc_fixupreloc(); + malloc_fixupreloc_init();
// Setup romfile items. - qemu_cfg_romfile_setup(); - coreboot_cbfs_setup(); + qemu_romfile_init(); + coreboot_cbfs_init();
// Setup ivt/bda/ebda - init_ivt(); - init_bda(); + ivt_init(); + bda_init();
// Init base pc hardware. pic_setup(); timer_setup(); - mathcp_setup(); + mathcp_init();
// Initialize pci pci_setup(); - smm_init(); + smm_setup();
// Initialize mtrr mtrr_setup();
// Setup Xen hypercalls - xen_init_hypercalls(); + xen_hypercall_setup();
// Initialize internal tables - boot_setup(); + boot_init();
// Start hardware initialization (if optionrom threading) if (CONFIG_THREADS && CONFIG_THREAD_OPTIONROMS) - init_hw(); + device_hardware_setup();
// Find and initialize other cpus - smp_probe(); + smp_setup();
// Setup interfaces that option roms may need - bios32_setup(); - pmm_setup(); - pnp_setup(); - kbd_setup(); - mouse_setup(); - init_bios_tables(); + bios32_init(); + pmm_init(); + pnp_init(); + kbd_init(); + mouse_init(); + biostable_setup();
// Run vga option rom - vga_setup(); + vgarom_setup();
// SMBIOS tables and VGA console are ready, print UUID display_uuid();
// Do hardware initialization (if running synchronously) if (!CONFIG_THREADS || !CONFIG_THREAD_OPTIONROMS) { - init_hw(); + device_hardware_setup(); wait_threads(); }
@@ -277,13 +277,13 @@ maininit(void) optionrom_setup();
// Run BCVs and show optional boot menu - boot_prep(); + boot_prepboot();
// Finalize data structures before boot - cdemu_setup(); - pmm_finalize(); - malloc_finalize(); - memmap_finalize(); + cdrom_prepboot(); + pmm_prepboot(); + malloc_prepboot(); + memmap_prepboot();
// Setup bios checksum. BiosChecksum -= checksum((u8*)BUILD_BIOS_ADDR, BUILD_BIOS_SIZE); @@ -308,7 +308,7 @@ updateRelocs(void *dest, u32 *rstart, u32 *rend, u32 delta)
// Relocate init code and then call maininit() at new address. static void -reloc_init(void) +reloc_preinit(void) { if (!CONFIG_RELOCATE_INIT) return; @@ -352,12 +352,12 @@ doreloc(void) HaveRunPost = 1;
// Detect ram and setup internal malloc. - qemu_cfg_port_probe(); - ram_probe(); - malloc_setup(); + qemu_cfg_preinit(); + ramsize_preinit(); + malloc_preinit();
// Relocate initialization code. - reloc_init(); + reloc_preinit(); }
// Entry point for Power On Self Test (POST) - the BIOS initilization @@ -366,7 +366,7 @@ doreloc(void) void VISIBLE32FLAT handle_post(void) { - debug_serial_setup(); + debug_serial_preinit(); dprintf(1, "Start bios (version %s)\n", VERSION);
// Enable CPU caching @@ -376,10 +376,10 @@ handle_post(void) outb_cmos(0, CMOS_RESET_CODE);
// Make sure legacy DMA isn't running. - init_dma(); + dma_preinit();
// Check if we are running under Xen. - xen_probe(); + xen_preinit();
// Allow writes to modify bios area (0xf0000) make_bios_writable(); diff --git a/src/ps2port.c b/src/ps2port.c index d4626d6..9b760fd 100644 --- a/src/ps2port.c +++ b/src/ps2port.c @@ -417,7 +417,7 @@ done: ****************************************************************/
static void -keyboard_init(void *data) +ps2_keyboard_setup(void *data) { /* flush incoming keys */ int ret = i8042_flush(); @@ -500,5 +500,5 @@ ps2port_setup(void) enable_hwirq(1, FUNC16(entry_09)); enable_hwirq(12, FUNC16(entry_74));
- run_thread(keyboard_init, NULL); + run_thread(ps2_keyboard_setup, NULL); } diff --git a/src/resume.c b/src/resume.c index f1a96ac..99265cd 100644 --- a/src/resume.c +++ b/src/resume.c @@ -19,7 +19,7 @@ int HaveRunPost VAR16VISIBLE;
// Reset DMA controller void -init_dma(void) +dma_preinit(void) { // first reset the DMA controllers outb(0, PORT_DMA1_MASTER_CLEAR); @@ -35,12 +35,12 @@ void VISIBLE16 handle_resume(void) { ASSERT16(); - debug_serial_setup(); + debug_serial_preinit(); int status = inb_cmos(CMOS_RESET_CODE); outb_cmos(0, CMOS_RESET_CODE); dprintf(1, "In resume (status=%d)\n", status);
- init_dma(); + dma_preinit();
switch (status) { case 0x01 ... 0x04: @@ -109,9 +109,9 @@ s3_resume(void) }
pic_setup(); - smm_init(); + smm_setup();
- s3_resume_vga_init(); + s3_resume_vga();
make_bios_readonly();
diff --git a/src/smbios.c b/src/smbios.c index 23713a2..c235564 100644 --- a/src/smbios.c +++ b/src/smbios.c @@ -12,10 +12,10 @@ struct smbios_entry_point *SMBiosAddr;
static void -smbios_entry_point_init(u16 max_structure_size, - u16 structure_table_length, - void *structure_table_address, - u16 number_of_structures) +smbios_entry_point_setup(u16 max_structure_size, + u16 structure_table_length, + void *structure_table_address, + u16 number_of_structures) { struct smbios_entry_point *ep = malloc_fseg(sizeof(*ep)); void *finaltable; @@ -441,7 +441,7 @@ smbios_init_type_127(void *start) #define TEMPSMBIOSSIZE (32 * 1024)
void -smbios_init(void) +smbios_setup(void) { if (! CONFIG_SMBIOS) return; @@ -518,7 +518,7 @@ smbios_init(void)
#undef add_struct
- smbios_entry_point_init(max_struct_size, p - start, start, nr_structs); + smbios_entry_point_setup(max_struct_size, p - start, start, nr_structs); free(start); }
diff --git a/src/smbios.h b/src/smbios.h index 5bf0392..a4c1444 100644 --- a/src/smbios.h +++ b/src/smbios.h @@ -2,7 +2,7 @@ #define __SMBIOS_H
// smbios.c -void smbios_init(void); +void smbios_setup(void);
/* SMBIOS entry point -- must be written to a 16-bit aligned address between 0xf0000 and 0xfffff. diff --git a/src/smm.c b/src/smm.c index 7977ac7..c69f0fd 100644 --- a/src/smm.c +++ b/src/smm.c @@ -112,7 +112,7 @@ smm_relocate_and_restore(void) #define PIIX_APMC_EN (1 << 25)
// This code is hardcoded for PIIX4 Power Management device. -static void piix4_apmc_smm_init(struct pci_device *pci, void *arg) +static void piix4_apmc_smm_setup(struct pci_device *pci, void *arg) { struct pci_device *i440_pci = pci_find_device(PCI_VENDOR_ID_INTEL , PCI_DEVICE_ID_INTEL_82441); @@ -139,7 +139,7 @@ static void piix4_apmc_smm_init(struct pci_device *pci, void *arg) }
/* PCI_VENDOR_ID_INTEL && PCI_DEVICE_ID_INTEL_ICH9_LPC */ -void ich9_lpc_apmc_smm_init(struct pci_device *dev, void *arg) +void ich9_lpc_apmc_smm_setup(struct pci_device *dev, void *arg) { struct pci_device *mch_dev; int mch_bdf; @@ -174,15 +174,15 @@ void ich9_lpc_apmc_smm_init(struct pci_device *dev, void *arg)
static const struct pci_device_id smm_init_tbl[] = { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, - piix4_apmc_smm_init), + piix4_apmc_smm_setup), PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH9_LPC, - ich9_lpc_apmc_smm_init), + ich9_lpc_apmc_smm_setup),
PCI_DEVICE_END, };
void -smm_init(void) +smm_setup(void) { if (CONFIG_COREBOOT) // SMM only supported on emulators. diff --git a/src/smp.c b/src/smp.c index 4975412..18bb05f 100644 --- a/src/smp.c +++ b/src/smp.c @@ -82,7 +82,7 @@ int apic_id_is_present(u8 apic_id)
// find and initialize the CPUs by launching a SIPI to them void -smp_probe(void) +smp_setup(void) { ASSERT32FLAT(); u32 eax, ebx, ecx, cpuid_features; diff --git a/src/usb-ehci.c b/src/usb-ehci.c index 2676615..f28f343 100644 --- a/src/usb-ehci.c +++ b/src/usb-ehci.c @@ -13,8 +13,8 @@ #include "pci_regs.h" // PCI_BASE_ADDRESS_0 #include "usb.h" // struct usb_s #include "biosvar.h" // GET_LOWFLAT -#include "usb-uhci.h" // init_uhci -#include "usb-ohci.h" // init_ohci +#include "usb-uhci.h" // uhci_setup +#include "usb-ohci.h" // ohci_setup
struct usb_ehci_s { struct usb_s usb; @@ -58,13 +58,13 @@ ehci_note_port(struct usb_ehci_s *cntl) if (!pci) break;
- // ohci/uhci_init call pci_config_XXX - don't run from irq handler. + // ohci/uhci_setup call pci_config_X - don't run from irq handler. wait_preempt();
if (pci_classprog(pci) == PCI_CLASS_SERIAL_USB_UHCI) - uhci_init(pci, cntl->usb.busid + i); + uhci_setup(pci, cntl->usb.busid + i); else if (pci_classprog(pci) == PCI_CLASS_SERIAL_USB_OHCI) - ohci_init(pci, cntl->usb.busid + i); + ohci_setup(pci, cntl->usb.busid + i); } }
@@ -327,7 +327,7 @@ fail: }
int -ehci_init(struct pci_device *pci, int busid, struct pci_device *comppci) +ehci_setup(struct pci_device *pci, int busid, struct pci_device *comppci) { if (! CONFIG_USB_EHCI) return -1; diff --git a/src/usb-ehci.h b/src/usb-ehci.h index 32e4109..5672033 100644 --- a/src/usb-ehci.h +++ b/src/usb-ehci.h @@ -2,7 +2,7 @@ #define __USB_EHCI_H
// usb-ehci.c -int ehci_init(struct pci_device *pci, int busid, struct pci_device *comppci); +int ehci_setup(struct pci_device *pci, int busid, struct pci_device *comppci); struct usbdevice_s; struct usb_endpoint_descriptor; struct usb_pipe *ehci_alloc_pipe(struct usbdevice_s *usbdev diff --git a/src/usb-hid.c b/src/usb-hid.c index 8c4b803..0d5f371 100644 --- a/src/usb-hid.c +++ b/src/usb-hid.c @@ -49,8 +49,8 @@ set_idle(struct usb_pipe *pipe, int ms) #define KEYREPEATMS 33
static int -usb_kbd_init(struct usbdevice_s *usbdev - , struct usb_endpoint_descriptor *epdesc) +usb_kbd_setup(struct usbdevice_s *usbdev + , struct usb_endpoint_descriptor *epdesc) { if (! CONFIG_USB_KEYBOARD) return -1; @@ -79,8 +79,8 @@ usb_kbd_init(struct usbdevice_s *usbdev }
static int -usb_mouse_init(struct usbdevice_s *usbdev - , struct usb_endpoint_descriptor *epdesc) +usb_mouse_setup(struct usbdevice_s *usbdev + , struct usb_endpoint_descriptor *epdesc) { if (! CONFIG_USB_MOUSE) return -1; @@ -106,11 +106,11 @@ usb_mouse_init(struct usbdevice_s *usbdev
// Initialize a found USB HID device (if applicable). int -usb_hid_init(struct usbdevice_s *usbdev) +usb_hid_setup(struct usbdevice_s *usbdev) { if (! CONFIG_USB_KEYBOARD || ! CONFIG_USB_MOUSE) return -1; - dprintf(2, "usb_hid_init %p\n", usbdev->defpipe); + dprintf(2, "usb_hid_setup %p\n", usbdev->defpipe);
struct usb_interface_descriptor *iface = usbdev->iface; if (iface->bInterfaceSubClass != USB_INTERFACE_SUBCLASS_BOOT) @@ -126,9 +126,9 @@ usb_hid_init(struct usbdevice_s *usbdev) }
if (iface->bInterfaceProtocol == USB_INTERFACE_PROTOCOL_KEYBOARD) - return usb_kbd_init(usbdev, epdesc); + return usb_kbd_setup(usbdev, epdesc); if (iface->bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE) - return usb_mouse_init(usbdev, epdesc); + return usb_mouse_setup(usbdev, epdesc); return -1; }
diff --git a/src/usb-hid.h b/src/usb-hid.h index bd6445c..ef34e79 100644 --- a/src/usb-hid.h +++ b/src/usb-hid.h @@ -3,7 +3,7 @@
// usb-hid.c struct usbdevice_s; -int usb_hid_init(struct usbdevice_s *usbdev); +int usb_hid_setup(struct usbdevice_s *usbdev); inline int usb_kbd_active(void); inline int usb_kbd_command(int command, u8 *param); inline int usb_mouse_active(void); diff --git a/src/usb-hub.c b/src/usb-hub.c index 6f1aaa1..894ed7d 100644 --- a/src/usb-hub.c +++ b/src/usb-hub.c @@ -158,7 +158,7 @@ static struct usbhub_op_s HubOp = {
// Configure a usb hub and then find devices connected to it. int -usb_hub_init(struct usbdevice_s *usbdev) +usb_hub_setup(struct usbdevice_s *usbdev) { ASSERT32FLAT(); if (!CONFIG_USB_HUB) diff --git a/src/usb-hub.h b/src/usb-hub.h index a75cbda..5b09947 100644 --- a/src/usb-hub.h +++ b/src/usb-hub.h @@ -3,7 +3,7 @@
// usb-hub.c struct usbdevice_s; -int usb_hub_init(struct usbdevice_s *usbdev); +int usb_hub_setup(struct usbdevice_s *usbdev);
/**************************************************************** diff --git a/src/usb-msc.c b/src/usb-msc.c index 83c7397..7b2524d 100644 --- a/src/usb-msc.c +++ b/src/usb-msc.c @@ -6,7 +6,7 @@
#include "util.h" // dprintf #include "config.h" // CONFIG_USB_MSC -#include "usb-msc.h" // usb_msc_init +#include "usb-msc.h" // usb_msc_setup #include "usb.h" // struct usb_s #include "biosvar.h" // GET_GLOBAL #include "blockcmd.h" // cdb_read @@ -135,8 +135,8 @@ usb_msc_maxlun(struct usb_pipe *pipe) }
static int -usb_msc_init_lun(struct usb_pipe *inpipe, struct usb_pipe *outpipe, - struct usbdevice_s *usbdev, int lun) +usb_msc_lun_setup(struct usb_pipe *inpipe, struct usb_pipe *outpipe, + struct usbdevice_s *usbdev, int lun) { // Allocate drive structure. struct usbdrive_s *udrive_g = malloc_fseg(sizeof(*udrive_g)); @@ -151,7 +151,7 @@ usb_msc_init_lun(struct usb_pipe *inpipe, struct usb_pipe *outpipe, udrive_g->lun = lun;
int prio = bootprio_find_usb(usbdev, lun); - int ret = scsi_init_drive(&udrive_g->drive, "USB MSC", prio); + int ret = scsi_drive_setup(&udrive_g->drive, "USB MSC", prio); if (ret) { dprintf(1, "Unable to configure USB MSC drive.\n"); free(udrive_g); @@ -166,7 +166,7 @@ usb_msc_init_lun(struct usb_pipe *inpipe, struct usb_pipe *outpipe,
// Configure a usb msc device. int -usb_msc_init(struct usbdevice_s *usbdev) +usb_msc_setup(struct usbdevice_s *usbdev) { if (!CONFIG_USB_MSC) return -1; @@ -198,7 +198,7 @@ usb_msc_init(struct usbdevice_s *usbdev) int maxlun = usb_msc_maxlun(usbdev->defpipe); int lun, pipesused = 0; for (lun = 0; lun < maxlun + 1; lun++) { - int ret = usb_msc_init_lun(inpipe, outpipe, usbdev, lun); + int ret = usb_msc_lun_setup(inpipe, outpipe, usbdev, lun); if (!ret) pipesused = 1; } diff --git a/src/usb-msc.h b/src/usb-msc.h index 3746b77..c40d755 100644 --- a/src/usb-msc.h +++ b/src/usb-msc.h @@ -5,6 +5,6 @@ struct disk_op_s; int usb_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize); struct usbdevice_s; -int usb_msc_init(struct usbdevice_s *usbdev); +int usb_msc_setup(struct usbdevice_s *usbdev);
#endif // ush-msc.h diff --git a/src/usb-ohci.c b/src/usb-ohci.c index e219c5f..ef6a52c 100644 --- a/src/usb-ohci.c +++ b/src/usb-ohci.c @@ -262,7 +262,7 @@ free: }
void -ohci_init(struct pci_device *pci, int busid) +ohci_setup(struct pci_device *pci, int busid) { if (! CONFIG_USB_OHCI) return; diff --git a/src/usb-ohci.h b/src/usb-ohci.h index 25900a7..ad0ffec 100644 --- a/src/usb-ohci.h +++ b/src/usb-ohci.h @@ -2,7 +2,7 @@ #define __USB_OHCI_H
// usb-ohci.c -void ohci_init(struct pci_device *pci, int busid); +void ohci_setup(struct pci_device *pci, int busid); struct usbdevice_s; struct usb_endpoint_descriptor; struct usb_pipe *ohci_alloc_pipe(struct usbdevice_s *usbdev diff --git a/src/usb-uas.c b/src/usb-uas.c index be153ed..3169389 100644 --- a/src/usb-uas.c +++ b/src/usb-uas.c @@ -164,10 +164,10 @@ fail: }
static int -uas_init_lun(struct usbdevice_s *usbdev, - struct usb_pipe *command, struct usb_pipe *status, - struct usb_pipe *data_in, struct usb_pipe *data_out, - int lun) +uas_lun_setup(struct usbdevice_s *usbdev, + struct usb_pipe *command, struct usb_pipe *status, + struct usb_pipe *data_in, struct usb_pipe *data_out, + int lun) { // Allocate drive structure. struct uasdrive_s *drive = malloc_fseg(sizeof(*drive)); @@ -184,7 +184,7 @@ uas_init_lun(struct usbdevice_s *usbdev, drive->lun = lun;
int prio = bootprio_find_usb(usbdev, lun); - int ret = scsi_init_drive(&drive->drive, "USB UAS", prio); + int ret = scsi_drive_setup(&drive->drive, "USB UAS", prio); if (ret) { free(drive); return -1; @@ -193,7 +193,7 @@ uas_init_lun(struct usbdevice_s *usbdev, }
int -usb_uas_init(struct usbdevice_s *usbdev) +usb_uas_setup(struct usbdevice_s *usbdev) { if (!CONFIG_USB_UAS) return -1; @@ -247,7 +247,7 @@ usb_uas_init(struct usbdevice_s *usbdev) goto fail;
/* TODO: send REPORT LUNS. For now, only LUN 0 is recognized. */ - int ret = uas_init_lun(usbdev, command, status, data_in, data_out, 0); + int ret = uas_lun_setup(usbdev, command, status, data_in, data_out, 0); if (ret < 0) { dprintf(1, "Unable to configure UAS drive.\n"); goto fail; diff --git a/src/usb-uas.h b/src/usb-uas.h index ed1d473..ad91c5f 100644 --- a/src/usb-uas.h +++ b/src/usb-uas.h @@ -4,6 +4,6 @@ struct disk_op_s; int uas_cmd_data(struct disk_op_s *op, void *cdbcmd, u16 blocksize); struct usbdevice_s; -int usb_uas_init(struct usbdevice_s *usbdev); +int usb_uas_setup(struct usbdevice_s *usbdev);
#endif /* __USB_UAS_H */ diff --git a/src/usb-uhci.c b/src/usb-uhci.c index 17145e5..4098bf2 100644 --- a/src/usb-uhci.c +++ b/src/usb-uhci.c @@ -235,7 +235,7 @@ fail: }
void -uhci_init(struct pci_device *pci, int busid) +uhci_setup(struct pci_device *pci, int busid) { if (! CONFIG_USB_UHCI) return; diff --git a/src/usb-uhci.h b/src/usb-uhci.h index 9e3297c..b83c487 100644 --- a/src/usb-uhci.h +++ b/src/usb-uhci.h @@ -2,7 +2,7 @@ #define __USB_UHCI_H
// usb-uhci.c -void uhci_init(struct pci_device *pci, int busid); +void uhci_setup(struct pci_device *pci, int busid); struct usbdevice_s; struct usb_endpoint_descriptor; struct usb_pipe *uhci_alloc_pipe(struct usbdevice_s *usbdev diff --git a/src/usb.c b/src/usb.c index 421d0b8..6e43f13 100644 --- a/src/usb.c +++ b/src/usb.c @@ -9,13 +9,13 @@ #include "config.h" // CONFIG_* #include "pci_regs.h" // PCI_CLASS_REVISION #include "pci_ids.h" // PCI_CLASS_SERIAL_USB_UHCI -#include "usb-uhci.h" // uhci_init -#include "usb-ohci.h" // ohci_init -#include "usb-ehci.h" // ehci_init +#include "usb-uhci.h" // uhci_setup +#include "usb-ohci.h" // ohci_setup +#include "usb-ehci.h" // ehci_setup #include "usb-hid.h" // usb_keyboard_setup -#include "usb-hub.h" // usb_hub_init -#include "usb-msc.h" // usb_msc_init -#include "usb-uas.h" // usb_uas_init +#include "usb-hub.h" // usb_hub_setup +#include "usb-msc.h" // usb_msc_setup +#include "usb-uas.h" // usb_uas_setup #include "usb.h" // struct usb_s #include "biosvar.h" // GET_GLOBAL
@@ -323,14 +323,14 @@ configure_usb_device(struct usbdevice_s *usbdev) usbdev->iface = iface; usbdev->imax = (void*)config + config->wTotalLength - (void*)iface; if (iface->bInterfaceClass == USB_CLASS_HUB) - ret = usb_hub_init(usbdev); + ret = usb_hub_setup(usbdev); else if (iface->bInterfaceClass == USB_CLASS_MASS_STORAGE) { if (iface->bInterfaceProtocol == US_PR_BULK) - ret = usb_msc_init(usbdev); + ret = usb_msc_setup(usbdev); if (iface->bInterfaceProtocol == US_PR_UAS) - ret = usb_uas_init(usbdev); + ret = usb_uas_setup(usbdev); } else - ret = usb_hid_init(usbdev); + ret = usb_hid_setup(usbdev); if (ret) goto fail;
@@ -342,7 +342,7 @@ fail: }
static void -usb_init_hub_port(void *data) +usb_hub_port_setup(void *data) { struct usbdevice_s *usbdev = data; struct usbhub_s *hub = usbdev->hub; @@ -403,7 +403,7 @@ usb_enumerate(struct usbhub_s *hub) memset(usbdev, 0, sizeof(*usbdev)); usbdev->hub = hub; usbdev->port = i; - run_thread(usb_init_hub_port, usbdev); + run_thread(usb_hub_port_setup, usbdev); }
// Wait for threads to complete. @@ -435,7 +435,7 @@ usb_setup(void) for (;;) { if (pci_classprog(ehcipci) == PCI_CLASS_SERIAL_USB_EHCI) { // Found an ehci controller. - int ret = ehci_init(ehcipci, count++, pci); + int ret = ehci_setup(ehcipci, count++, pci); if (ret) // Error break; @@ -454,8 +454,8 @@ usb_setup(void) }
if (pci_classprog(pci) == PCI_CLASS_SERIAL_USB_UHCI) - uhci_init(pci, count++); + uhci_setup(pci, count++); else if (pci_classprog(pci) == PCI_CLASS_SERIAL_USB_OHCI) - ohci_init(pci, count++); + ohci_setup(pci, count++); } } diff --git a/src/util.h b/src/util.h index 7723bb1..eb35d02 100644 --- a/src/util.h +++ b/src/util.h @@ -202,7 +202,7 @@ void check_preempt(void);
// output.c extern u16 DebugOutputPort; -void debug_serial_setup(void); +void debug_serial_preinit(void); void panic(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))) __noreturn; void printf(const char *fmt, ...) @@ -262,19 +262,14 @@ void hexdump(const void *d, int len); __set_code_unimplemented((regs), (code) | (__LINE__ << 8), __func__)
// kbd.c -void kbd_setup(void); +void kbd_init(void); void handle_15c2(struct bregs *regs); void process_key(u8 key);
// mouse.c -void mouse_setup(void); +void mouse_init(void); void process_mouse(u8 data);
-// system.c -extern u32 RamSize; -extern u64 RamSizeOver4G; -void mathcp_setup(void); - // serial.c void serial_setup(void); void lpt_setup(void); @@ -282,7 +277,7 @@ void lpt_setup(void); // clock.c #define PIT_TICK_RATE 1193180 // Underlying HZ of PIT #define PIT_TICK_INTERVAL 65536 // Default interval for 18.2Hz timer -void pmtimer_init(u16 ioport, u32 khz); +void pmtimer_setup(u16 ioport, u32 khz); int check_tsc(u64 end); void timer_setup(void); void ndelay(u32 count); @@ -307,7 +302,7 @@ void handle_1553(struct bregs *regs);
// pcibios.c void handle_1ab1(struct bregs *regs); -void bios32_setup(void); +void bios32_init(void);
// shadow.c void make_bios_writable(void); @@ -319,23 +314,23 @@ extern const u8 pci_irqs[4]; void pci_setup(void);
// smm.c -void smm_init(void); +void smm_setup(void);
// smp.c extern u32 CountCPUs; extern u32 MaxCountCPUs; void wrmsr_smp(u32 index, u64 val); -void smp_probe(void); +void smp_setup(void); int apic_id_is_present(u8 apic_id);
// coreboot.c extern const char *CBvendor, *CBpart; struct cbfs_file; void cbfs_run_payload(struct cbfs_file *file); -void coreboot_copy_biostable(void); +void coreboot_biostable_setup(void); void cbfs_payload_setup(void); -void coreboot_setup(void); -void coreboot_cbfs_setup(void); +void coreboot_preinit(void); +void coreboot_cbfs_init(void);
// biostable.c void copy_table(void *pos); @@ -348,8 +343,8 @@ void vgahook_setup(struct pci_device *pci); // optionroms.c void call_bcv(u16 seg, u16 ip); void optionrom_setup(void); -void vga_setup(void); -void s3_resume_vga_init(void); +void vgarom_setup(void); +void s3_resume_vga(void); extern int ScreenAndDebug;
// bootsplash.c @@ -359,12 +354,12 @@ void disable_bootsplash(void);
// resume.c extern int HaveRunPost; -void init_dma(void); +void dma_preinit(void);
// pnpbios.c #define PNP_SIGNATURE 0x506e5024 // $PnP u16 get_pnp_offset(void); -void pnp_setup(void); +void pnp_init(void);
// pmm.c extern struct zone_s ZoneLow, ZoneHigh, ZoneFSeg, ZoneTmpLow, ZoneTmpHigh; @@ -372,13 +367,13 @@ u32 rom_get_top(void); u32 rom_get_last(void); struct rom_header *rom_reserve(u32 size); int rom_confirm(u32 size); -void malloc_setup(void); -void malloc_fixupreloc(void); -void malloc_finalize(void); +void malloc_preinit(void); +void malloc_fixupreloc_init(void); +void malloc_prepboot(void); void *pmm_malloc(struct zone_s *zone, u32 handle, u32 size, u32 align); int pmm_free(void *data); -void pmm_setup(void); -void pmm_finalize(void); +void pmm_init(void); +void pmm_prepboot(void); #define PMM_DEFAULT_HANDLE 0xFFFFFFFF // Minimum alignment of malloc'd memory #define MALLOC_MIN_ALIGN 16 @@ -451,6 +446,9 @@ u64 romfile_loadint(const char *name, u64 defval); void reset_vector(void) __noreturn;
// misc.c +void mathcp_init(void); +extern u32 RamSize; +extern u64 RamSizeOver4G; extern u8 BiosChecksum;
// version (auto generated file out/version.c) diff --git a/src/virtio-scsi.c b/src/virtio-scsi.c index ab74729..4bbff8f 100644 --- a/src/virtio-scsi.c +++ b/src/virtio-scsi.c @@ -14,7 +14,7 @@ #include "pci_ids.h" // PCI_DEVICE_ID_VIRTIO_BLK #include "pci_regs.h" // PCI_VENDOR_ID #include "boot.h" // bootprio_find_scsi_device -#include "blockcmd.h" // scsi_init_drive +#include "blockcmd.h" // scsi_drive_setup #include "virtio-pci.h" #include "virtio-ring.h" #include "virtio-scsi.h" @@ -114,7 +114,7 @@ virtio_scsi_add_lun(struct pci_device *pci, u16 ioaddr, vlun->lun = lun;
int prio = bootprio_find_scsi_device(pci, target, lun); - int ret = scsi_init_drive(&vlun->drive, "virtio-scsi", prio); + int ret = scsi_drive_setup(&vlun->drive, "virtio-scsi", prio); if (ret) goto fail; return 0; diff --git a/src/xen.c b/src/xen.c index a4669d0..c9759f0 100644 --- a/src/xen.c +++ b/src/xen.c @@ -47,7 +47,7 @@ static void validate_info(struct xen_seabios_info *t) panic("Bad Xen info checksum\n"); }
-void xen_probe(void) +void xen_preinit(void) { u32 base, eax, ebx, ecx, edx; char signature[13]; @@ -86,7 +86,7 @@ static int hypercall_xen_version( int cmd, void *arg) }
/* Fill in hypercall transfer pages. */ -void xen_init_hypercalls(void) +void xen_hypercall_setup(void) { u32 eax, ebx, ecx, edx; xen_extraversion_t extraversion; @@ -111,7 +111,7 @@ void xen_init_hypercalls(void) dprintf(1, "Detected Xen v%u.%u%s\n", eax >> 16, eax & 0xffff, extraversion); }
-void xen_copy_biostables(void) +void xen_biostable_setup(void) { struct xen_seabios_info *info = (void *)INFO_PHYSICAL_ADDRESS; void **tables = (void*)info->tables; @@ -122,7 +122,7 @@ void xen_copy_biostables(void) copy_table(tables[i]); }
-void xen_setup(void) +void xen_ramsize_preinit(void) { u64 maxram = 0, maxram_over4G = 0; int i; diff --git a/src/xen.h b/src/xen.h index b664d9c..9b4178a 100644 --- a/src/xen.h +++ b/src/xen.h @@ -6,10 +6,10 @@
extern u32 xen_cpuid_base;
-void xen_probe(void); -void xen_setup(void); -void xen_init_hypercalls(void); -void xen_copy_biostables(void); +void xen_preinit(void); +void xen_ramsize_preinit(void); +void xen_hypercall_setup(void); +void xen_biostable_setup(void);
static inline int usingXen(void) { if (!CONFIG_XEN) diff --git a/vgasrc/bochsvga.c b/vgasrc/bochsvga.c index 938dba0..bb5a64d 100644 --- a/vgasrc/bochsvga.c +++ b/vgasrc/bochsvga.c @@ -329,9 +329,9 @@ bochsvga_set_mode(struct vgamode_s *vmode_g, int flags) ****************************************************************/
int -bochsvga_init(void) +bochsvga_setup(void) { - int ret = stdvga_init(); + int ret = stdvga_setup(); if (ret) return ret;
diff --git a/vgasrc/bochsvga.h b/vgasrc/bochsvga.h index 1c98203..87fb6ea 100644 --- a/vgasrc/bochsvga.h +++ b/vgasrc/bochsvga.h @@ -66,6 +66,6 @@ int bochsvga_size_state(int states); int bochsvga_save_state(u16 seg, void *data, int states); int bochsvga_restore_state(u16 seg, void *data, int states); int bochsvga_set_mode(struct vgamode_s *vmode_g, int flags); -int bochsvga_init(void); +int bochsvga_setup(void);
#endif // bochsvga.h diff --git a/vgasrc/clext.c b/vgasrc/clext.c index fc5459a..dd45df3 100644 --- a/vgasrc/clext.c +++ b/vgasrc/clext.c @@ -5,7 +5,7 @@ // // This file may be distributed under the terms of the GNU LGPLv3 license.
-#include "clext.h" // clext_init +#include "clext.h" // clext_setup #include "vgabios.h" // VBE_VENDOR_STRING #include "biosvar.h" // GET_GLOBAL #include "util.h" // dprintf @@ -603,9 +603,9 @@ cirrus_get_memsize(void) }
int -clext_init(void) +clext_setup(void) { - int ret = stdvga_init(); + int ret = stdvga_setup(); if (ret) return ret;
diff --git a/vgasrc/clext.h b/vgasrc/clext.h index 78dba01..efc98b9 100644 --- a/vgasrc/clext.h +++ b/vgasrc/clext.h @@ -17,6 +17,6 @@ int clext_restore_state(u16 seg, void *data, int states); int clext_set_mode(struct vgamode_s *vmode_g, int flags); struct bregs; void clext_1012(struct bregs *regs); -int clext_init(void); +int clext_setup(void);
#endif // clext.h diff --git a/vgasrc/geodevga.c b/vgasrc/geodevga.c index 5b42e00..c2dabf5 100644 --- a/vgasrc/geodevga.c +++ b/vgasrc/geodevga.c @@ -6,7 +6,7 @@ // // This file may be distributed under the terms of the GNU LGPLv3 license.
-#include "geodevga.h" // geodevga_init +#include "geodevga.h" // geodevga_setup #include "farptr.h" // SET_FARVAR #include "biosvar.h" // GET_BDA #include "vgabios.h" // VGAREG_* @@ -369,16 +369,16 @@ static u8 geode_crtc_13[] VAR16 = { 0x9b, 0x8d, 0x8f, 0x28, 0x40, 0x98, 0xb9, 0xa3, 0xff };
-int geodevga_init(void) +int geodevga_setup(void) { - int ret = stdvga_init(); + int ret = stdvga_setup(); if (ret) return ret;
- dprintf(1,"GEODEVGA_INIT\n"); + dprintf(1,"GEODEVGA_SETUP\n");
if ((ret=legacyio_check())) { - dprintf(1,"GEODEVGA_INIT legacyio_check=0x%x\n",ret); + dprintf(1,"GEODEVGA_SETUP legacyio_check=0x%x\n",ret); }
// Updated timings from geode datasheets, table 6-53 in particular diff --git a/vgasrc/geodevga.h b/vgasrc/geodevga.h index 5993b23..180bd05 100644 --- a/vgasrc/geodevga.h +++ b/vgasrc/geodevga.h @@ -84,6 +84,6 @@ /* Mask */ #define DC_CFG_MSK 0xf000a6
-int geodevga_init(); +int geodevga_setup();
#endif diff --git a/vgasrc/stdvga.c b/vgasrc/stdvga.c index ae6c0be..a29d6d4 100644 --- a/vgasrc/stdvga.c +++ b/vgasrc/stdvga.c @@ -6,7 +6,7 @@ // This file may be distributed under the terms of the GNU LGPLv3 license.
#include "vgabios.h" // struct vgamode_s -#include "stdvga.h" // stdvga_init +#include "stdvga.h" // stdvga_setup #include "ioport.h" // outb #include "farptr.h" // SET_FARVAR #include "biosvar.h" // GET_GLOBAL @@ -490,7 +490,7 @@ stdvga_enable_video_addressing(u8 disable) }
int -stdvga_init(void) +stdvga_setup(void) { // switch to color mode and enable CPU access 480 lines stdvga_misc_write(0xc3); diff --git a/vgasrc/stdvga.h b/vgasrc/stdvga.h index c9a9ba1..d712a32 100644 --- a/vgasrc/stdvga.h +++ b/vgasrc/stdvga.h @@ -107,6 +107,6 @@ int stdvga_size_state(int states); int stdvga_save_state(u16 seg, void *data, int states); int stdvga_restore_state(u16 seg, void *data, int states); void stdvga_enable_video_addressing(u8 disable); -int stdvga_init(void); +int stdvga_setup(void);
#endif // stdvga.h diff --git a/vgasrc/vgabios.c b/vgasrc/vgabios.c index afaf018..3e26e32 100644 --- a/vgasrc/vgabios.c +++ b/vgasrc/vgabios.c @@ -1281,7 +1281,7 @@ int HaveRunInit VAR16; void VISIBLE16 vga_post(struct bregs *regs) { - debug_serial_setup(); + debug_serial_preinit(); dprintf(1, "Start SeaVGABIOS (version %s)\n", VERSION); debug_enter(regs, DEBUG_VGA_POST);
@@ -1294,7 +1294,7 @@ vga_post(struct bregs *regs) SET_VGA(VgaBDF, bdf); }
- int ret = vgahw_init(); + int ret = vgahw_setup(); if (ret) { dprintf(1, "Failed to initialize VGA hardware. Exiting.\n"); return; diff --git a/vgasrc/vgahw.h b/vgasrc/vgahw.h index 044cd32..f69a5ac 100644 --- a/vgasrc/vgahw.h +++ b/vgasrc/vgahw.h @@ -7,7 +7,7 @@ #include "clext.h" // clext_set_mode #include "bochsvga.h" // bochsvga_set_mode #include "stdvga.h" // stdvga_set_mode -#include "geodevga.h" // geodevga_init +#include "geodevga.h" // geodevga_setup
static inline struct vgamode_s *vgahw_find_mode(int mode) { if (CONFIG_VGA_CIRRUS) @@ -34,14 +34,14 @@ static inline void vgahw_list_modes(u16 seg, u16 *dest, u16 *last) { stdvga_list_modes(seg, dest, last); }
-static inline int vgahw_init(void) { +static inline int vgahw_setup(void) { if (CONFIG_VGA_CIRRUS) - return clext_init(); + return clext_setup(); if (CONFIG_VGA_BOCHS) - return bochsvga_init(); + return bochsvga_setup(); if (CONFIG_VGA_GEODEGX2 || CONFIG_VGA_GEODELX) - return geodevga_init(); - return stdvga_init(); + return geodevga_setup(); + return stdvga_setup(); }
static inline int vgahw_get_window(struct vgamode_s *vmode_g, int window) {
From: Kevin O'Connor kevin@koconnor.net
Place the "interface initialization" functions together, "platform hardware initialization" functions together, and "prepare to boot" functions together. This may also be useful for using SeaBIOS as a CSM.
This slightly changes the order of some function invocations, but should otherwise not change code behavior at all.
Signed-off-by: Kevin O'Connor kevin@koconnor.net --- src/boot.c | 16 ++-- src/boot.h | 3 +- src/bootsplash.c | 2 + src/post.c | 255 ++++++++++++++++++++++++++++++------------------------- 4 files changed, 148 insertions(+), 128 deletions(-)
diff --git a/src/boot.c b/src/boot.c index 2cb3b86..3bafa5a 100644 --- a/src/boot.c +++ b/src/boot.c @@ -392,9 +392,11 @@ boot_add_cbfs(void *data, const char *desc, int prio) #define DEFAULT_BOOTMENU_WAIT 2500
// Show IPL option menu. -static void +void interactive_bootmenu(void) { + // XXX - show available drives? + if (! CONFIG_BOOTMENU || ! qemu_cfg_show_boot_menu()) return;
@@ -476,18 +478,10 @@ add_bev(int type, u32 vector)
// Prepare for boot - show menu and run bcvs. void -boot_prepboot(void) +bcv_prepboot(void) { - if (! CONFIG_BOOT) { - wait_threads(); + if (! CONFIG_BOOT) return; - } - - // XXX - show available drives? - - // Allow user to modify BCV/IPL order. - interactive_bootmenu(); - wait_threads();
int haltprio = find_prio("HALT"); if (haltprio >= 0) diff --git a/src/boot.h b/src/boot.h index 4a93d0f..4d4943b 100644 --- a/src/boot.h +++ b/src/boot.h @@ -11,7 +11,8 @@ void boot_add_floppy(struct drive_s *drive_g, const char *desc, int prio); void boot_add_hd(struct drive_s *drive_g, const char *desc, int prio); void boot_add_cd(struct drive_s *drive_g, const char *desc, int prio); void boot_add_cbfs(void *data, const char *desc, int prio); -void boot_prepboot(void); +void interactive_bootmenu(void); +void bcv_prepboot(void); struct pci_device; int bootprio_find_pci_device(struct pci_device *pci); int bootprio_find_scsi_device(struct pci_device *pci, int target, int lun); diff --git a/src/bootsplash.c b/src/bootsplash.c index 3aac459..84fca7f 100644 --- a/src/bootsplash.c +++ b/src/bootsplash.c @@ -12,6 +12,7 @@ #include "jpeg.h" // splash #include "vbe.h" // struct vbe_info #include "bmp.h" // bmp_alloc +#include "smbios.h" // display_uuid
/**************************************************************** @@ -46,6 +47,7 @@ enable_vga_console(void)
// Write to screen. printf("SeaBIOS (version %s)\n", VERSION); + display_uuid(); }
static int diff --git a/src/post.c b/src/post.c index 6f5dfef..dbf4944 100644 --- a/src/post.c +++ b/src/post.c @@ -31,11 +31,69 @@ #include "esp-scsi.h" // esp_scsi_setup #include "megasas.h" // megasas_setup
+ /**************************************************************** * BIOS init ****************************************************************/
static void +ramsize_preinit(void) +{ + dprintf(3, "Find memory size\n"); + if (CONFIG_COREBOOT) { + coreboot_preinit(); + } else if (usingXen()) { + xen_ramsize_preinit(); + } else { + // On emulators, get memory size from nvram. + u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16) + | (inb_cmos(CMOS_MEM_EXTMEM2_HIGH) << 24)); + if (rs) + rs += 16 * 1024 * 1024; + else + rs = (((inb_cmos(CMOS_MEM_EXTMEM_LOW) << 10) + | (inb_cmos(CMOS_MEM_EXTMEM_HIGH) << 18)) + + 1 * 1024 * 1024); + RamSize = rs; + add_e820(0, rs, E820_RAM); + + // Check for memory over 4Gig + u64 high = ((inb_cmos(CMOS_MEM_HIGHMEM_LOW) << 16) + | ((u32)inb_cmos(CMOS_MEM_HIGHMEM_MID) << 24) + | ((u64)inb_cmos(CMOS_MEM_HIGHMEM_HIGH) << 32)); + RamSizeOver4G = high; + add_e820(0x100000000ull, high, E820_RAM); + + /* reserve 256KB BIOS area at the end of 4 GB */ + add_e820(0xfffc0000, 256*1024, E820_RESERVED); + } + + // Don't declare any memory between 0xa0000 and 0x100000 + add_e820(BUILD_LOWRAM_END, BUILD_BIOS_ADDR-BUILD_LOWRAM_END, E820_HOLE); + + // Mark known areas as reserved. + add_e820(BUILD_BIOS_ADDR, BUILD_BIOS_SIZE, E820_RESERVED); + + u32 count = qemu_cfg_e820_entries(); + if (count) { + struct e820_reservation entry; + int i; + + for (i = 0; i < count; i++) { + qemu_cfg_e820_load_next(&entry); + add_e820(entry.address, entry.length, entry.type); + } + } else if (kvm_para_available()) { + // Backwards compatibility - provide hard coded range. + // 4 pages before the bios, 3 pages for vmx tss pages, the + // other page for EPT real mode pagetable + add_e820(0xfffbc000, 4*4096, E820_RESERVED); + } + + dprintf(1, "Ram Size=0x%08x (0x%016llx high)\n", RamSize, RamSizeOver4G); +} + +static void ivt_init(void) { dprintf(3, "init ivt\n"); @@ -101,81 +159,27 @@ bda_init(void) }
static void -ramsize_preinit(void) +interface_init(void) { - dprintf(3, "Find memory size\n"); - if (CONFIG_COREBOOT) { - coreboot_preinit(); - } else if (usingXen()) { - xen_ramsize_preinit(); - } else { - // On emulators, get memory size from nvram. - u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16) - | (inb_cmos(CMOS_MEM_EXTMEM2_HIGH) << 24)); - if (rs) - rs += 16 * 1024 * 1024; - else - rs = (((inb_cmos(CMOS_MEM_EXTMEM_LOW) << 10) - | (inb_cmos(CMOS_MEM_EXTMEM_HIGH) << 18)) - + 1 * 1024 * 1024); - RamSize = rs; - add_e820(0, rs, E820_RAM); - - // Check for memory over 4Gig - u64 high = ((inb_cmos(CMOS_MEM_HIGHMEM_LOW) << 16) - | ((u32)inb_cmos(CMOS_MEM_HIGHMEM_MID) << 24) - | ((u64)inb_cmos(CMOS_MEM_HIGHMEM_HIGH) << 32)); - RamSizeOver4G = high; - add_e820(0x100000000ull, high, E820_RAM); - - /* reserve 256KB BIOS area at the end of 4 GB */ - add_e820(0xfffc0000, 256*1024, E820_RESERVED); - } - - // Don't declare any memory between 0xa0000 and 0x100000 - add_e820(BUILD_LOWRAM_END, BUILD_BIOS_ADDR-BUILD_LOWRAM_END, E820_HOLE); - - // Mark known areas as reserved. - add_e820(BUILD_BIOS_ADDR, BUILD_BIOS_SIZE, E820_RESERVED); - - u32 count = qemu_cfg_e820_entries(); - if (count) { - struct e820_reservation entry; - int i; - - for (i = 0; i < count; i++) { - qemu_cfg_e820_load_next(&entry); - add_e820(entry.address, entry.length, entry.type); - } - } else if (kvm_para_available()) { - // Backwards compatibility - provide hard coded range. - // 4 pages before the bios, 3 pages for vmx tss pages, the - // other page for EPT real mode pagetable - add_e820(0xfffbc000, 4*4096, E820_RESERVED); - } - - dprintf(1, "Ram Size=0x%08x (0x%016llx high)\n", RamSize, RamSizeOver4G); -} - -static void -biostable_setup(void) -{ - if (CONFIG_COREBOOT) { - coreboot_biostable_setup(); - return; - } - if (usingXen()) { - xen_biostable_setup(); - return; - } - - pirtable_setup(); + // Running at new code address - do code relocation fixups + malloc_fixupreloc_init();
- mptable_setup(); + // Setup romfile items. + qemu_romfile_init(); + coreboot_cbfs_init();
- smbios_setup(); + // Setup ivt/bda/ebda + ivt_init(); + bda_init();
- acpi_setup(); + // Other interfaces + mathcp_init(); + boot_init(); + bios32_init(); + pmm_init(); + pnp_init(); + kbd_init(); + mouse_init(); }
// Initialize hardware devices @@ -199,39 +203,33 @@ device_hardware_setup(void) megasas_setup(); }
-// Begin the boot process by invoking an int0x19 in 16bit mode. static void -startBoot(void) +biostable_setup(void) { - // Clear low-memory allocations (required by PMM spec). - memset((void*)BUILD_STACK_ADDR, 0, BUILD_EBDA_MINIMUM - BUILD_STACK_ADDR); + if (CONFIG_COREBOOT) { + coreboot_biostable_setup(); + return; + } + if (usingXen()) { + xen_biostable_setup(); + return; + }
- dprintf(3, "Jump to int19\n"); - struct bregs br; - memset(&br, 0, sizeof(br)); - br.flags = F_IF; - call16_int(0x19, &br); -} + pirtable_setup();
-// Main setup code. -void VISIBLE32INIT -maininit(void) -{ - // Running at new code address - do code relocation fixups - malloc_fixupreloc_init(); + mptable_setup();
- // Setup romfile items. - qemu_romfile_init(); - coreboot_cbfs_init(); + smbios_setup();
- // Setup ivt/bda/ebda - ivt_init(); - bda_init(); + acpi_setup(); +}
+static void +platform_hardware_setup(void) +{ // Init base pc hardware. pic_setup(); timer_setup(); - mathcp_init();
// Initialize pci pci_setup(); @@ -243,9 +241,6 @@ maininit(void) // Setup Xen hypercalls xen_hypercall_setup();
- // Initialize internal tables - boot_init(); - // Start hardware initialization (if optionrom threading) if (CONFIG_THREADS && CONFIG_THREAD_OPTIONROMS) device_hardware_setup(); @@ -253,20 +248,39 @@ maininit(void) // Find and initialize other cpus smp_setup();
- // Setup interfaces that option roms may need - bios32_init(); - pmm_init(); - pnp_init(); - kbd_init(); - mouse_init(); + // Setup external BIOS interface tables biostable_setup(); +} + +static void +prepareboot(void) +{ + // Run BCVs + bcv_prepboot(); + + // Finalize data structures before boot + cdrom_prepboot(); + pmm_prepboot(); + malloc_prepboot(); + memmap_prepboot(); + + // Setup bios checksum. + BiosChecksum -= checksum((u8*)BUILD_BIOS_ADDR, BUILD_BIOS_SIZE); +} + +// Main setup code. +void VISIBLE32INIT +maininit(void) +{ + // Initialize internal interfaces. + interface_init(); + + // Setup platform devices. + platform_hardware_setup();
// Run vga option rom vgarom_setup();
- // SMBIOS tables and VGA console are ready, print UUID - display_uuid(); - // Do hardware initialization (if running synchronously) if (!CONFIG_THREADS || !CONFIG_THREAD_OPTIONROMS) { device_hardware_setup(); @@ -276,22 +290,31 @@ maininit(void) // Run option roms optionrom_setup();
- // Run BCVs and show optional boot menu - boot_prepboot(); + // Allow user to modify overall boot order. + interactive_bootmenu(); + wait_threads();
- // Finalize data structures before boot - cdrom_prepboot(); - pmm_prepboot(); - malloc_prepboot(); - memmap_prepboot(); - - // Setup bios checksum. - BiosChecksum -= checksum((u8*)BUILD_BIOS_ADDR, BUILD_BIOS_SIZE); + // Prepare for boot. + prepareboot();
// Write protect bios memory. make_bios_readonly(); }
+// Begin the boot process by invoking an int0x19 in 16bit mode. +static void +startBoot(void) +{ + // Clear low-memory allocations (required by PMM spec). + memset((void*)BUILD_STACK_ADDR, 0, BUILD_EBDA_MINIMUM - BUILD_STACK_ADDR); + + dprintf(3, "Jump to int19\n"); + struct bregs br; + memset(&br, 0, sizeof(br)); + br.flags = F_IF; + call16_int(0x19, &br); +} +
/**************************************************************** * POST entry and code relocation
From: David Woodhouse David.Woodhouse@intel.com
Not-yet-signed-off-by: David Woodhouse David.Woodhouse@intel.com --- src/post.c | 10 +++++----- src/post.h | 11 +++++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 src/post.h
diff --git a/src/post.c b/src/post.c index dbf4944..b53f1eb 100644 --- a/src/post.c +++ b/src/post.c @@ -158,7 +158,7 @@ bda_init(void) StackPos = (void*)(&ExtraStack[BUILD_EXTRA_STACK_SIZE] - datalow_base); }
-static void +void VISIBLE32INIT interface_init(void) { // Running at new code address - do code relocation fixups @@ -183,7 +183,7 @@ interface_init(void) }
// Initialize hardware devices -static void +void VISIBLE32INIT device_hardware_setup(void) { usb_setup(); @@ -252,7 +252,7 @@ platform_hardware_setup(void) biostable_setup(); }
-static void +void VISIBLE32INIT prepareboot(void) { // Run BCVs @@ -302,7 +302,7 @@ maininit(void) }
// Begin the boot process by invoking an int0x19 in 16bit mode. -static void +void startBoot(void) { // Clear low-memory allocations (required by PMM spec). @@ -330,7 +330,7 @@ updateRelocs(void *dest, u32 *rstart, u32 *rend, u32 delta) }
// Relocate init code and then call maininit() at new address. -static void +void VISIBLE32INIT reloc_preinit(void) { if (!CONFIG_RELOCATE_INIT) diff --git a/src/post.h b/src/post.h new file mode 100644 index 0000000..29304aa --- /dev/null +++ b/src/post.h @@ -0,0 +1,11 @@ +// Functions used during POST +// +// Copyright © 2012 Intel Corporation +// +// This file may be distributed under the terms of the GNU LGPLv3 license. + +void interface_init(void); +void device_hardware_setup(void); +void prepareboot(void); +void startBoot(void); +void reloc_preinit(void);
On Mon, Jan 28, 2013 at 04:23:37PM +0000, David Woodhouse wrote:
From: David Woodhouse David.Woodhouse@intel.com
Not-yet-signed-off-by: David Woodhouse David.Woodhouse@intel.com
src/post.c | 10 +++++----- src/post.h | 11 +++++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 src/post.h
diff --git a/src/post.c b/src/post.c index dbf4944..b53f1eb 100644 --- a/src/post.c +++ b/src/post.c @@ -158,7 +158,7 @@ bda_init(void) StackPos = (void*)(&ExtraStack[BUILD_EXTRA_STACK_SIZE] - datalow_base); }
-static void +void VISIBLE32INIT
The sprinkling of VISIBLE32INIT is non-optimal and pretty ugly. Ideally, only handle_elf_post(), handle_post(), and handle_csm32() would have this flag. Then the build would automatically propagate the flag to all functions and data only reachable via one of these entry points.
Unfortunately, the CSM has to return back to UEFI from the init code and that complicates the implementation. The init code is running at one address prior to relocation and at another address after relocation - when unwinding the call stack to return to UEFI the code pointers on the stack could have a mix of old and new init code locations. That's going to be complex and error prone. Patch 1 of this series avoids that by making sure that reloc_preinit() and maininit() are only called from non-init code - thus ensuring a sane return path. However, it leads to the sprinkling of VISIBLE32INIT definitions.
I'm not sure how to best address this. One way is to go forward and sprinkle VISIBLE32INIT. Another way would be to revert patch 1, pass a function pointer to reloc_preinit() instead of hard-coding maininit, and teach the CSM code how to "longjmp" back to UEFI after relocation so it doesn't have to unwind the stack. I'm not sure that would be any less "ugly" though.
Any other ideas?
-Kevin
On Sat, 2013-02-02 at 19:32 -0500, Kevin O'Connor wrote:
I'm not sure how to best address this. One way is to go forward and sprinkle VISIBLE32INIT. Another way would be to revert patch 1, pass a function pointer to reloc_preinit() instead of hard-coding maininit, and teach the CSM code how to "longjmp" back to UEFI after relocation so it doesn't have to unwind the stack. I'm not sure that would be any less "ugly" though.
Any other ideas?
If we special-case handle_csm32() in layoutrom.py, so that it doesn't mark any of the functions it links to as also being runtime, then perhaps that might suffice?
On Sat, Feb 02, 2013 at 07:32:42PM -0500, Kevin O'Connor wrote:
I'm not sure how to best address this. One way is to go forward and sprinkle VISIBLE32INIT. Another way would be to revert patch 1, pass a function pointer to reloc_preinit() instead of hard-coding maininit, and teach the CSM code how to "longjmp" back to UEFI after relocation so it doesn't have to unwind the stack. I'm not sure that would be any less "ugly" though.
FYI, below is one way to "longjmp" back to UEFI without unwinding the stack (based on your latest git tree and totally untested). This assumes it is okay to clobber %fs, %gs and the gdt.
-Kevin
diff --git a/src/csm.c b/src/csm.c index a773f0d..ee14486 100644 --- a/src/csm.c +++ b/src/csm.c @@ -67,6 +67,14 @@ void handle_csm_0000(struct bregs *regs) csm_compat_table.PnPInstallationCheckOffset = get_pnp_offset();
regs->ax = 0; + + // Return directly to UEFI instead of unwinding stack. + extern void csm_return(); + asm volatile( + " jmp transition16" + : : "d"((u32)csm_return - BUILD_BIOS_ADDR), "S"(regs->code.seg) + , "b"((u32)regs - (regs->code.seg << 4)) + : "memory"); }
/* Legacy16UpdateBbs */ diff --git a/src/romlayout.S b/src/romlayout.S index 420bf4e..98f2b11 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -470,37 +470,48 @@ irqentryarg:
EXPORTFUNC entry_csm16 entry_csm16: + // Backup register state + pushfw + cli + cld + pushl %eax // dummy PUSHBREGS
- // Reset stack and store EFI's old SS:SP on it - movl %esp, %edx - movw %ss, %cx + // Backup stack location + movl %ss, %esi + movl %esp, %ebx + movl %esi, BREGS_code+2(%esp) // Also store %ss in bregs->code.seg
+ // Change to BUILD_STACK_ADDR stack xorl %eax, %eax - movw %ax, %ss movw %ax, %ds + movw %ax, %ss movl $BUILD_STACK_ADDR, %esp
- pushl %ecx // EFI's SS - pushl %edx // EFI's SP + // Turn %eax into a flat pointer of struct bregs + movl %esi, %eax + shll $4, %eax + addl %ebx, %eax
- // Turn %edx into a flat pointer (including segment base) - shll $4, %ecx - addl %ecx, %edx - - // call32(handle_csm32, bregs, -1) - movl $_cfunc32flat_handle_csm32, %eax - movl $-1, %ecx - calll call32 + // Jump to 32bit mode and call handle_csm32(bregs) + movl $(1f + BUILD_BIOS_ADDR), %edx + jmp transition32 + .code32 +1: calll _cfunc32flat_handle_csm32 + movl $csm_return, %edx + jmp transition16 + .code16gcc
- // Switch back to EFI's stack and return - popl %edx - popl %ecx - movw %cx, %ss - movw %cx, %ds - movl %edx, %esp + .global csm_return +csm_return: + // Switch back to original stack + movl %esi, %ss + movl %ebx, %esp
+ // Restore register state and return. POPBREGS + addw $4, %sp // pop dummy + popfw lretw
// int 18/19 are special - they reset stack and call into 32bit mode.
On Tue, Feb 05, 2013 at 12:52:50AM -0500, Kevin O'Connor wrote:
On Sat, Feb 02, 2013 at 07:32:42PM -0500, Kevin O'Connor wrote:
I'm not sure how to best address this. One way is to go forward and sprinkle VISIBLE32INIT. Another way would be to revert patch 1, pass a function pointer to reloc_preinit() instead of hard-coding maininit, and teach the CSM code how to "longjmp" back to UEFI after relocation so it doesn't have to unwind the stack. I'm not sure that would be any less "ugly" though.
FYI, below is one way to "longjmp" back to UEFI without unwinding the stack (based on your latest git tree and totally untested). This assumes it is okay to clobber %fs, %gs and the gdt.
This may be slightly nicer (still totally untested).
-Kevin
diff --git a/src/csm.c b/src/csm.c index a773f0d..d5ed8ad 100644 --- a/src/csm.c +++ b/src/csm.c @@ -36,6 +36,8 @@ EFI_COMPATIBILITY16_TABLE csm_compat_table VAR32FLATVISIBLE __aligned(16) = { EFI_TO_COMPATIBILITY16_INIT_TABLE *csm_init_table; EFI_TO_COMPATIBILITY16_BOOT_TABLE *csm_boot_table;
+extern void csm_return(struct bregs *regs) __noreturn; + /* Legacy16InitializeYourself */ void handle_csm_0000(struct bregs *regs) { @@ -67,6 +69,9 @@ void handle_csm_0000(struct bregs *regs) csm_compat_table.PnPInstallationCheckOffset = get_pnp_offset();
regs->ax = 0; + + // Return directly to UEFI instead of unwinding stack. + csm_return(regs); }
/* Legacy16UpdateBbs */ diff --git a/src/romlayout.S b/src/romlayout.S index 420bf4e..42aeaff 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -469,38 +469,53 @@ irqentryarg: DECL_IRQ_ENTRY hwpic2
EXPORTFUNC entry_csm16 + .global csm_return entry_csm16: + // Backup register state + pushfw + cli + cld + pushl %eax // dummy PUSHBREGS
- // Reset stack and store EFI's old SS:SP on it - movl %esp, %edx - movw %ss, %cx + // Backup stack location and convert to a "flat pointer" + movl %ss, %ebx + movw %bx, BREGS_code+2(%esp) // Store %ss in bregs->code.seg + shll $4, %ebx + addl %esp, %ebx
+ // Change to BUILD_STACK_ADDR stack xorl %eax, %eax movw %ax, %ss - movw %ax, %ds movl $BUILD_STACK_ADDR, %esp
- pushl %ecx // EFI's SS - pushl %edx // EFI's SP - - // Turn %edx into a flat pointer (including segment base) - shll $4, %ecx - addl %ecx, %edx + // Jump to 32bit mode and call handle_csm32(bregs) + movl $(1f + BUILD_BIOS_ADDR), %edx + jmp transition32 + .code32 +1: movl %ebx, %eax + calll _cfunc32flat_handle_csm32 + movl $2f, %edx + jmp transition16big
- // call32(handle_csm32, bregs, -1) - movl $_cfunc32flat_handle_csm32, %eax - movl $-1, %ecx - calll call32 +csm_return: + movl %eax, %ebx + movl $2f, %edx + jmp transition16big + .code16gcc
- // Switch back to EFI's stack and return - popl %edx - popl %ecx - movw %cx, %ss - movw %cx, %ds - movl %edx, %esp + // Switch back to original stack +2: movzwl BREGS_code+2(%ebx), %eax + movl %eax, %ecx + shll $4, %ecx + subl %ecx, %ebx + movl %eax, %ss + movl %ebx, %esp
+ // Restore register state and return. POPBREGS + addw $4, %sp // pop dummy + popfw lretw
// int 18/19 are special - they reset stack and call into 32bit mode.
From: David Woodhouse David.Woodhouse@intel.com
I want to do this too, and can't bring myself to introduce yet another copy.
Not-yet-signed-off-by: David Woodhouse David.Woodhouse@intel.com --- src/entryfuncs.S | 74 ++++++++++++++++++++++---------------------------------- 1 file changed, 29 insertions(+), 45 deletions(-)
diff --git a/src/entryfuncs.S b/src/entryfuncs.S index afc5e61..ea6f990 100644 --- a/src/entryfuncs.S +++ b/src/entryfuncs.S @@ -9,6 +9,30 @@ * Entry macros ****************************************************************/
+ .macro PUSHBREGS + pushl %eax // Save registers (matches struct bregs) + pushl %ecx + pushl %edx + pushl %ebx + pushl %ebp + pushl %esi + pushl %edi + pushw %es + pushw %ds + .endm + + .macro POPBREGS + popw %ds // Restore registers (from struct bregs) + popw %es + popl %edi + popl %esi + popl %ebp + popl %ebx + popl %edx + popl %ecx + popl %eax + .endm + // Call a C function - this does the minimal work necessary to // call into C. It sets up %ds, backs up %es, and backs up // those registers that are call clobbered by the C compiler. @@ -63,15 +87,7 @@ .macro ENTRY_ARG cfunc cli cld - pushl %eax // Save registers (matches struct bregs) - pushl %ecx - pushl %edx - pushl %ebx - pushl %ebp - pushl %esi - pushl %edi - pushw %es - pushw %ds + PUSHBREGS movw %ss, %ax // Move %ss to %ds movw %ax, %ds movl %esp, %ebx // Backup %esp, then zero high bits @@ -79,15 +95,7 @@ movl %esp, %eax // First arg is pointer to struct bregs calll \cfunc movl %ebx, %esp // Restore %esp (including high bits) - popw %ds // Restore registers (from struct bregs) - popw %es - popl %edi - popl %esi - popl %ebp - popl %ebx - popl %edx - popl %ecx - popl %eax + POPBREGS .endm
// As above, but get calling function from stack. @@ -111,43 +119,19 @@ movl %esp, %eax // First arg is pointer to struct bregs calll *%ecx movl %ebx, %esp // Restore %esp (including high bits) - popw %ds // Restore registers (from struct bregs) - popw %es - popl %edi - popl %esi - popl %ebp - popl %ebx - popl %edx - popl %ecx - popl %eax + POPBREGS .endm
// Same as ENTRY_ARG, but don't mangle %esp .macro ENTRY_ARG_ESP cfunc cli cld - pushl %eax // Save registers (matches struct bregs) - pushl %ecx - pushl %edx - pushl %ebx - pushl %ebp - pushl %esi - pushl %edi - pushw %es - pushw %ds + PUSHBREGS movw %ss, %ax // Move %ss to %ds movw %ax, %ds movl %esp, %eax // First arg is pointer to struct bregs calll \cfunc - popw %ds // Restore registers (from struct bregs) - popw %es - popl %edi - popl %esi - popl %ebp - popl %ebx - popl %edx - popl %ecx - popl %eax + POPBREGS .endm
// Reset stack, transition to 32bit mode, and call a C function.
On Mon, Jan 28, 2013 at 9:23 AM, David Woodhouse dwmw2@infradead.org wrote:
From: David Woodhouse David.Woodhouse@intel.com
I want to do this too, and can't bring myself to introduce yet another copy.
Not-yet-signed-off-by: David Woodhouse David.Woodhouse@intel.com
would-be-acked-by: Marc Jones marc.jones@se-eng.com
src/entryfuncs.S | 74 ++++++++++++++++++++++---------------------------------- 1 file changed, 29 insertions(+), 45 deletions(-)
diff --git a/src/entryfuncs.S b/src/entryfuncs.S index afc5e61..ea6f990 100644 --- a/src/entryfuncs.S +++ b/src/entryfuncs.S @@ -9,6 +9,30 @@
- Entry macros
****************************************************************/
.macro PUSHBREGS
pushl %eax // Save registers (matches struct bregs)
pushl %ecx
pushl %edx
pushl %ebx
pushl %ebp
pushl %esi
pushl %edi
pushw %es
pushw %ds
.endm
.macro POPBREGS
popw %ds // Restore registers (from struct bregs)
popw %es
popl %edi
popl %esi
popl %ebp
popl %ebx
popl %edx
popl %ecx
popl %eax
.endm
// Call a C function - this does the minimal work necessary to // call into C. It sets up %ds, backs up %es, and backs up // those registers that are call clobbered by the C compiler.
@@ -63,15 +87,7 @@ .macro ENTRY_ARG cfunc cli cld
pushl %eax // Save registers (matches struct bregs)
pushl %ecx
pushl %edx
pushl %ebx
pushl %ebp
pushl %esi
pushl %edi
pushw %es
pushw %ds
PUSHBREGS movw %ss, %ax // Move %ss to %ds movw %ax, %ds movl %esp, %ebx // Backup %esp, then zero high bits
@@ -79,15 +95,7 @@ movl %esp, %eax // First arg is pointer to struct bregs calll \cfunc movl %ebx, %esp // Restore %esp (including high bits)
popw %ds // Restore registers (from struct bregs)
popw %es
popl %edi
popl %esi
popl %ebp
popl %ebx
popl %edx
popl %ecx
popl %eax
POPBREGS .endm // As above, but get calling function from stack.
@@ -111,43 +119,19 @@ movl %esp, %eax // First arg is pointer to struct bregs calll *%ecx movl %ebx, %esp // Restore %esp (including high bits)
popw %ds // Restore registers (from struct bregs)
popw %es
popl %edi
popl %esi
popl %ebp
popl %ebx
popl %edx
popl %ecx
popl %eax
POPBREGS .endm // Same as ENTRY_ARG, but don't mangle %esp .macro ENTRY_ARG_ESP cfunc cli cld
pushl %eax // Save registers (matches struct bregs)
pushl %ecx
pushl %edx
pushl %ebx
pushl %ebp
pushl %esi
pushl %edi
pushw %es
pushw %ds
PUSHBREGS movw %ss, %ax // Move %ss to %ds movw %ax, %ds movl %esp, %eax // First arg is pointer to struct bregs calll \cfunc
popw %ds // Restore registers (from struct bregs)
popw %es
popl %edi
popl %esi
popl %ebp
popl %ebx
popl %edx
popl %ecx
popl %eax
POPBREGS .endm // Reset stack, transition to 32bit mode, and call a C function.
-- 1.8.0.2
SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
From: David Woodhouse David.Woodhouse@intel.com
Not-yet-signed-off-by: David Woodhouse David.Woodhouse@intel.com --- src/optionroms.c | 2 +- src/optionroms.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/optionroms.c b/src/optionroms.c index c79a706..c9e7d7b 100644 --- a/src/optionroms.c +++ b/src/optionroms.c @@ -44,7 +44,7 @@ __callrom(struct rom_header *rom, u16 offset, u16 bdf) }
// Execute a given option rom at the standard entry vector. -static void +void callrom(struct rom_header *rom, u16 bdf) { __callrom(rom, OPTION_ROM_INITVECTOR, bdf); diff --git a/src/optionroms.h b/src/optionroms.h index 94ca4ae..c5ea4ba 100644 --- a/src/optionroms.h +++ b/src/optionroms.h @@ -56,4 +56,7 @@ struct pnp_data { #define OPTION_ROM_INITVECTOR offsetof(struct rom_header, initVector[0]) #define PCIROM_CODETYPE_X86 0
+void +callrom(struct rom_header *rom, u16 bdf); + #endif
From: David Woodhouse David.Woodhouse@intel.com
Yes, copy_table() would invoke it, but CSM will *only* use it for SMBIOS tables and however much we trick the compiler by gratuitously checking the table signature right before calling copy_table(), it still doesn't seem to notice that fact. And emits code for all the other three cases we don't care about.
Not-yet-signed-off-by: David Woodhouse David.Woodhouse@intel.com --- src/biostables.c | 2 +- src/util.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/biostables.c b/src/biostables.c index 81cc79b..7b860e1 100644 --- a/src/biostables.c +++ b/src/biostables.c @@ -83,7 +83,7 @@ copy_acpi_rsdp(void *pos) RsdpAddr = newpos; }
-static void +void copy_smbios(void *pos) { if (SMBiosAddr) diff --git a/src/util.h b/src/util.h index eb35d02..84915ed 100644 --- a/src/util.h +++ b/src/util.h @@ -333,6 +333,7 @@ void coreboot_preinit(void); void coreboot_cbfs_init(void);
// biostable.c +void copy_smbios(void *pos); void copy_table(void *pos);
// vgahooks.c
From: David Woodhouse David.Woodhouse@intel.com
This is under a BSD licence so it's fine to import directly.
Not-yet-signed-off-by: David Woodhouse David.Woodhouse@intel.com --- src/LegacyBios.h | 965 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 965 insertions(+) create mode 100644 src/LegacyBios.h
diff --git a/src/LegacyBios.h b/src/LegacyBios.h new file mode 100644 index 0000000..65ace3b --- /dev/null +++ b/src/LegacyBios.h @@ -0,0 +1,965 @@ +/** @file + The EFI Legacy BIOS Protocol is used to abstract legacy Option ROM usage + under EFI and Legacy OS boot. This file also includes all the related + COMPATIBILIY16 structures and defintions. + + Note: The names for EFI_IA32_REGISTER_SET elements were picked to follow + well known naming conventions. + + Thunk is the code that switches from 32-bit protected environment into the 16-bit real-mode + environment. Reverse thunk is the code that does the opposite. + +Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR> +This program and the accompanying materials are licensed and made available under +the terms and conditions of the BSD License that accompanies this distribution. +The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php. + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + + @par Revision Reference: + This protocol is defined in Framework for EFI Compatibility Support Module spec + Version 0.97. + +**/ + +#ifndef _EFI_LEGACY_BIOS_H_ +#define _EFI_LEGACY_BIOS_H_ + +/// +/// +/// +#pragma pack(1) + +typedef UINT8 SERIAL_MODE; +typedef UINT8 PARALLEL_MODE; + +#define EFI_COMPATIBILITY16_TABLE_SIGNATURE SIGNATURE_32 ('I', 'F', 'E', '$') + +/// +/// There is a table located within the traditional BIOS in either the 0xF000:xxxx or 0xE000:xxxx +/// physical address range. It is located on a 16-byte boundary and provides the physical address of the +/// entry point for the Compatibility16 functions. These functions provide the platform-specific +/// information that is required by the generic EfiCompatibility code. The functions are invoked via +/// thunking by using EFI_LEGACY_BIOS_PROTOCOL.FarCall86() with the 32-bit physical +/// entry point. +/// +typedef struct { + /// + /// The string "$EFI" denotes the start of the EfiCompatibility table. Byte 0 is "I," byte + /// 1 is "F," byte 2 is "E," and byte 3 is "$" and is normally accessed as a DWORD or UINT32. + /// + UINT32 Signature; + + /// + /// The value required such that byte checksum of TableLength equals zero. + /// + UINT8 TableChecksum; + + /// + /// The length of this table. + /// + UINT8 TableLength; + + /// + /// The major EFI revision for which this table was generated. + /// + UINT8 EfiMajorRevision; + + /// + /// The minor EFI revision for which this table was generated. + /// + UINT8 EfiMinorRevision; + + /// + /// The major revision of this table. + /// + UINT8 TableMajorRevision; + + /// + /// The minor revision of this table. + /// + UINT8 TableMinorRevision; + + /// + /// Reserved for future usage. + /// + UINT16 Reserved; + + /// + /// The segment of the entry point within the traditional BIOS for Compatibility16 functions. + /// + UINT16 Compatibility16CallSegment; + + /// + /// The offset of the entry point within the traditional BIOS for Compatibility16 functions. + /// + UINT16 Compatibility16CallOffset; + + /// + /// The segment of the entry point within the traditional BIOS for EfiCompatibility + /// to invoke the PnP installation check. + /// + UINT16 PnPInstallationCheckSegment; + + /// + /// The Offset of the entry point within the traditional BIOS for EfiCompatibility + /// to invoke the PnP installation check. + /// + UINT16 PnPInstallationCheckOffset; + + /// + /// EFI system resources table. Type EFI_SYSTEM_TABLE is defined in the IntelPlatform + ///Innovation Framework for EFI Driver Execution Environment Core Interface Specification (DXE CIS). + /// + UINT32 EfiSystemTable; + + /// + /// The address of an OEM-provided identifier string. The string is null terminated. + /// + UINT32 OemIdStringPointer; + + /// + /// The 32-bit physical address where ACPI RSD PTR is stored within the traditional + /// BIOS. The remained of the ACPI tables are located at their EFI addresses. The size + /// reserved is the maximum for ACPI 2.0. The EfiCompatibility will fill in the ACPI + /// RSD PTR with either the ACPI 1.0b or 2.0 values. + /// + UINT32 AcpiRsdPtrPointer; + + /// + /// The OEM revision number. Usage is undefined but provided for OEM module usage. + /// + UINT16 OemRevision; + + /// + /// The 32-bit physical address where INT15 E820 data is stored within the traditional + /// BIOS. The EfiCompatibility code will fill in the E820Pointer value and copy the + /// data to the indicated area. + /// + UINT32 E820Pointer; + + /// + /// The length of the E820 data and is filled in by the EfiCompatibility code. + /// + UINT32 E820Length; + + /// + /// The 32-bit physical address where the $PIR table is stored in the traditional BIOS. + /// The EfiCompatibility code will fill in the IrqRoutingTablePointer value and + /// copy the data to the indicated area. + /// + UINT32 IrqRoutingTablePointer; + + /// + /// The length of the $PIR table and is filled in by the EfiCompatibility code. + /// + UINT32 IrqRoutingTableLength; + + /// + /// The 32-bit physical address where the MP table is stored in the traditional BIOS. + /// The EfiCompatibility code will fill in the MpTablePtr value and copy the data + /// to the indicated area. + /// + UINT32 MpTablePtr; + + /// + /// The length of the MP table and is filled in by the EfiCompatibility code. + /// + UINT32 MpTableLength; + + /// + /// The segment of the OEM-specific INT table/code. + /// + UINT16 OemIntSegment; + + /// + /// The offset of the OEM-specific INT table/code. + /// + UINT16 OemIntOffset; + + /// + /// The segment of the OEM-specific 32-bit table/code. + /// + UINT16 Oem32Segment; + + /// + /// The offset of the OEM-specific 32-bit table/code. + /// + UINT16 Oem32Offset; + + /// + /// The segment of the OEM-specific 16-bit table/code. + /// + UINT16 Oem16Segment; + + /// + /// The offset of the OEM-specific 16-bit table/code. + /// + UINT16 Oem16Offset; + + /// + /// The segment of the TPM binary passed to 16-bit CSM. + /// + UINT16 TpmSegment; + + /// + /// The offset of the TPM binary passed to 16-bit CSM. + /// + UINT16 TpmOffset; + + /// + /// A pointer to a string identifying the independent BIOS vendor. + /// + UINT32 IbvPointer; + + /// + /// This field is NULL for all systems not supporting PCI Express. This field is the base + /// value of the start of the PCI Express memory-mapped configuration registers and + /// must be filled in prior to EfiCompatibility code issuing the Compatibility16 function + /// Compatibility16InitializeYourself(). + /// Compatibility16InitializeYourself() is defined in Compatability16 + /// Functions. + /// + UINT32 PciExpressBase; + + /// + /// Maximum PCI bus number assigned. + /// + UINT8 LastPciBus; +} EFI_COMPATIBILITY16_TABLE; + +/// +/// Functions provided by the CSM binary which communicate between the EfiCompatibility +/// and Compatability16 code. +/// +/// Inconsistent with the specification here: +/// The member's name started with "Compatibility16" [defined in Intel Framework +/// Compatibility Support Module Specification / 0.97 version] +/// has been changed to "Legacy16" since keeping backward compatible. +/// +typedef enum { + /// + /// Causes the Compatibility16 code to do any internal initialization required. + /// Input: + /// AX = Compatibility16InitializeYourself + /// ES:BX = Pointer to EFI_TO_COMPATIBILITY16_INIT_TABLE + /// Return: + /// AX = Return Status codes + /// + Legacy16InitializeYourself = 0x0000, + + /// + /// Causes the Compatibility16 BIOS to perform any drive number translations to match the boot sequence. + /// Input: + /// AX = Compatibility16UpdateBbs + /// ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE + /// Return: + /// AX = Returned status codes + /// + Legacy16UpdateBbs = 0x0001, + + /// + /// Allows the Compatibility16 code to perform any final actions before booting. The Compatibility16 + /// code is read/write. + /// Input: + /// AX = Compatibility16PrepareToBoot + /// ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE structure + /// Return: + /// AX = Returned status codes + /// + Legacy16PrepareToBoot = 0x0002, + + /// + /// Causes the Compatibility16 BIOS to boot. The Compatibility16 code is Read/Only. + /// Input: + /// AX = Compatibility16Boot + /// Output: + /// AX = Returned status codes + /// + Legacy16Boot = 0x0003, + + /// + /// Allows the Compatibility16 code to get the last device from which a boot was attempted. This is + /// stored in CMOS and is the priority number of the last attempted boot device. + /// Input: + /// AX = Compatibility16RetrieveLastBootDevice + /// Output: + /// AX = Returned status codes + /// BX = Priority number of the boot device. + /// + Legacy16RetrieveLastBootDevice = 0x0004, + + /// + /// Allows the Compatibility16 code rehook INT13, INT18, and/or INT19 after dispatching a legacy OpROM. + /// Input: + /// AX = Compatibility16DispatchOprom + /// ES:BX = Pointer to EFI_DISPATCH_OPROM_TABLE + /// Output: + /// AX = Returned status codes + /// BX = Number of non-BBS-compliant devices found. Equals 0 if BBS compliant. + /// + Legacy16DispatchOprom = 0x0005, + + /// + /// Finds a free area in the 0xFxxxx or 0xExxxx region of the specified length and returns the address + /// of that region. + /// Input: + /// AX = Compatibility16GetTableAddress + /// BX = Allocation region + /// 00 = Allocate from either 0xE0000 or 0xF0000 64 KB blocks. + /// Bit 0 = 1 Allocate from 0xF0000 64 KB block + /// Bit 1 = 1 Allocate from 0xE0000 64 KB block + /// CX = Requested length in bytes. + /// DX = Required address alignment. Bit mapped. First non-zero bit from the right is the alignment. + /// Output: + /// AX = Returned status codes + /// DS:BX = Address of the region + /// + Legacy16GetTableAddress = 0x0006, + + /// + /// Enables the EfiCompatibility module to do any nonstandard processing of keyboard LEDs or state. + /// Input: + /// AX = Compatibility16SetKeyboardLeds + /// CL = LED status. + /// Bit 0 Scroll Lock 0 = Off + /// Bit 1 NumLock + /// Bit 2 Caps Lock + /// Output: + /// AX = Returned status codes + /// + Legacy16SetKeyboardLeds = 0x0007, + + /// + /// Enables the EfiCompatibility module to install an interrupt handler for PCI mass media devices that + /// do not have an OpROM associated with them. An example is SATA. + /// Input: + /// AX = Compatibility16InstallPciHandler + /// ES:BX = Pointer to EFI_LEGACY_INSTALL_PCI_HANDLER structure + /// Output: + /// AX = Returned status codes + /// + Legacy16InstallPciHandler = 0x0008 +} EFI_COMPATIBILITY_FUNCTIONS; + + +/// +/// EFI_DISPATCH_OPROM_TABLE +/// +typedef struct { + UINT16 PnPInstallationCheckSegment; ///< A pointer to the PnpInstallationCheck data structure. + UINT16 PnPInstallationCheckOffset; ///< A pointer to the PnpInstallationCheck data structure. + UINT16 OpromSegment; ///< The segment where the OpROM was placed. Offset is assumed to be 3. + UINT8 PciBus; ///< The PCI bus. + UINT8 PciDeviceFunction; ///< The PCI device * 0x08 | PCI function. + UINT8 NumberBbsEntries; ///< The number of valid BBS table entries upon entry and exit. The IBV code may + ///< increase this number, if BBS-compliant devices also hook INTs in order to force the + ///< OpROM BIOS Setup to be executed. + UINT32 BbsTablePointer; ///< A pointer to the BBS table. + UINT16 RuntimeSegment; ///< The segment where the OpROM can be relocated to. If this value is 0x0000, this + ///< means that the relocation of this run time code is not supported. + ///< Inconsistent with specification here: + ///< The member's name "OpromDestinationSegment" [defined in Intel Framework Compatibility Support Module Specification / 0.97 version] + ///< has been changed to "RuntimeSegment" since keeping backward compatible. + +} EFI_DISPATCH_OPROM_TABLE; + +/// +/// EFI_TO_COMPATIBILITY16_INIT_TABLE +/// +typedef struct { + /// + /// Starting address of memory under 1 MB. The ending address is assumed to be 640 KB or 0x9FFFF. + /// + UINT32 BiosLessThan1MB; + + /// + /// The starting address of the high memory block. + /// + UINT32 HiPmmMemory; + + /// + /// The length of high memory block. + /// + UINT32 HiPmmMemorySizeInBytes; + + /// + /// The segment of the reverse thunk call code. + /// + UINT16 ReverseThunkCallSegment; + + /// + /// The offset of the reverse thunk call code. + /// + UINT16 ReverseThunkCallOffset; + + /// + /// The number of E820 entries copied to the Compatibility16 BIOS. + /// + UINT32 NumberE820Entries; + + /// + /// The amount of usable memory above 1 MB, e.g., E820 type 1 memory. + /// + UINT32 OsMemoryAbove1Mb; + + /// + /// The start of thunk code in main memory. Memory cannot be used by BIOS or PMM. + /// + UINT32 ThunkStart; + + /// + /// The size of the thunk code. + /// + UINT32 ThunkSizeInBytes; + + /// + /// Starting address of memory under 1 MB. + /// + UINT32 LowPmmMemory; + + /// + /// The length of low Memory block. + /// + UINT32 LowPmmMemorySizeInBytes; +} EFI_TO_COMPATIBILITY16_INIT_TABLE; + +/// +/// DEVICE_PRODUCER_SERIAL. +/// +typedef struct { + UINT16 Address; ///< I/O address assigned to the serial port. + UINT8 Irq; ///< IRQ assigned to the serial port. + SERIAL_MODE Mode; ///< Mode of serial port. Values are defined below. +} DEVICE_PRODUCER_SERIAL; + +/// +/// DEVICE_PRODUCER_SERIAL's modes. +///@{ +#define DEVICE_SERIAL_MODE_NORMAL 0x00 +#define DEVICE_SERIAL_MODE_IRDA 0x01 +#define DEVICE_SERIAL_MODE_ASK_IR 0x02 +#define DEVICE_SERIAL_MODE_DUPLEX_HALF 0x00 +#define DEVICE_SERIAL_MODE_DUPLEX_FULL 0x10 +///@) + +/// +/// DEVICE_PRODUCER_PARALLEL. +/// +typedef struct { + UINT16 Address; ///< I/O address assigned to the parallel port. + UINT8 Irq; ///< IRQ assigned to the parallel port. + UINT8 Dma; ///< DMA assigned to the parallel port. + PARALLEL_MODE Mode; ///< Mode of the parallel port. Values are defined below. +} DEVICE_PRODUCER_PARALLEL; + +/// +/// DEVICE_PRODUCER_PARALLEL's modes. +///@{ +#define DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY 0x00 +#define DEVICE_PARALLEL_MODE_MODE_BIDIRECTIONAL 0x01 +#define DEVICE_PARALLEL_MODE_MODE_EPP 0x02 +#define DEVICE_PARALLEL_MODE_MODE_ECP 0x03 +///@} + +/// +/// DEVICE_PRODUCER_FLOPPY +/// +typedef struct { + UINT16 Address; ///< I/O address assigned to the floppy. + UINT8 Irq; ///< IRQ assigned to the floppy. + UINT8 Dma; ///< DMA assigned to the floppy. + UINT8 NumberOfFloppy; ///< Number of floppies in the system. +} DEVICE_PRODUCER_FLOPPY; + +/// +/// LEGACY_DEVICE_FLAGS +/// +typedef struct { + UINT32 A20Kybd : 1; ///< A20 controller by keyboard controller. + UINT32 A20Port90 : 1; ///< A20 controlled by port 0x92. + UINT32 Reserved : 30; ///< Reserved for future usage. +} LEGACY_DEVICE_FLAGS; + +/// +/// DEVICE_PRODUCER_DATA_HEADER +/// +typedef struct { + DEVICE_PRODUCER_SERIAL Serial[4]; ///< Data for serial port x. Type DEVICE_PRODUCER_SERIAL is defined below. + DEVICE_PRODUCER_PARALLEL Parallel[3]; ///< Data for parallel port x. Type DEVICE_PRODUCER_PARALLEL is defined below. + DEVICE_PRODUCER_FLOPPY Floppy; ///< Data for floppy. Type DEVICE_PRODUCER_FLOPPY is defined below. + UINT8 MousePresent; ///< Flag to indicate if mouse is present. + LEGACY_DEVICE_FLAGS Flags; ///< Miscellaneous Boolean state information passed to CSM. +} DEVICE_PRODUCER_DATA_HEADER; + +/// +/// ATAPI_IDENTIFY +/// +typedef struct { + UINT16 Raw[256]; ///< Raw data from the IDE IdentifyDrive command. +} ATAPI_IDENTIFY; + +/// +/// HDD_INFO +/// +typedef struct { + /// + /// Status of IDE device. Values are defined below. There is one HDD_INFO structure + /// per IDE controller. The IdentifyDrive is per drive. Index 0 is master and index + /// 1 is slave. + /// + UINT16 Status; + + /// + /// PCI bus of IDE controller. + /// + UINT32 Bus; + + /// + /// PCI device of IDE controller. + /// + UINT32 Device; + + /// + /// PCI function of IDE controller. + /// + UINT32 Function; + + /// + /// Command ports base address. + /// + UINT16 CommandBaseAddress; + + /// + /// Control ports base address. + /// + UINT16 ControlBaseAddress; + + /// + /// Bus master address. + /// + UINT16 BusMasterAddress; + + UINT8 HddIrq; + + /// + /// Data that identifies the drive data; one per possible attached drive. + /// + ATAPI_IDENTIFY IdentifyDrive[2]; +} HDD_INFO; + +/// +/// HDD_INFO status bits +/// +#define HDD_PRIMARY 0x01 +#define HDD_SECONDARY 0x02 +#define HDD_MASTER_ATAPI_CDROM 0x04 +#define HDD_SLAVE_ATAPI_CDROM 0x08 +#define HDD_MASTER_IDE 0x20 +#define HDD_SLAVE_IDE 0x40 +#define HDD_MASTER_ATAPI_ZIPDISK 0x10 +#define HDD_SLAVE_ATAPI_ZIPDISK 0x80 + +/// +/// BBS_STATUS_FLAGS;. +/// +typedef struct { + UINT16 OldPosition : 4; ///< Prior priority. + UINT16 Reserved1 : 4; ///< Reserved for future use. + UINT16 Enabled : 1; ///< If 0, ignore this entry. + UINT16 Failed : 1; ///< 0 = Not known if boot failure occurred. + ///< 1 = Boot attempted failed. + + /// + /// State of media present. + /// 00 = No bootable media is present in the device. + /// 01 = Unknown if a bootable media present. + /// 10 = Media is present and appears bootable. + /// 11 = Reserved. + /// + UINT16 MediaPresent : 2; + UINT16 Reserved2 : 4; ///< Reserved for future use. +} BBS_STATUS_FLAGS; + +/// +/// BBS_TABLE, device type values & boot priority values. +/// +typedef struct { + /// + /// The boot priority for this boot device. Values are defined below. + /// + UINT16 BootPriority; + + /// + /// The PCI bus for this boot device. + /// + UINT32 Bus; + + /// + /// The PCI device for this boot device. + /// + UINT32 Device; + + /// + /// The PCI function for the boot device. + /// + UINT32 Function; + + /// + /// The PCI class for this boot device. + /// + UINT8 Class; + + /// + /// The PCI Subclass for this boot device. + /// + UINT8 SubClass; + + /// + /// Segment:offset address of an ASCIIZ description string describing the manufacturer. + /// + UINT16 MfgStringOffset; + + /// + /// Segment:offset address of an ASCIIZ description string describing the manufacturer. + /// + UINT16 MfgStringSegment; + + /// + /// BBS device type. BBS device types are defined below. + /// + UINT16 DeviceType; + + /// + /// Status of this boot device. Type BBS_STATUS_FLAGS is defined below. + /// + BBS_STATUS_FLAGS StatusFlags; + + /// + /// Segment:Offset address of boot loader for IPL devices or install INT13 handler for + /// BCV devices. + /// + UINT16 BootHandlerOffset; + + /// + /// Segment:Offset address of boot loader for IPL devices or install INT13 handler for + /// BCV devices. + /// + UINT16 BootHandlerSegment; + + /// + /// Segment:offset address of an ASCIIZ description string describing this device. + /// + UINT16 DescStringOffset; + + /// + /// Segment:offset address of an ASCIIZ description string describing this device. + /// + UINT16 DescStringSegment; + + /// + /// Reserved. + /// + UINT32 InitPerReserved; + + /// + /// The use of these fields is IBV dependent. They can be used to flag that an OpROM + /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI + /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup + /// + UINT32 AdditionalIrq13Handler; + + /// + /// The use of these fields is IBV dependent. They can be used to flag that an OpROM + /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI + /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup + /// + UINT32 AdditionalIrq18Handler; + + /// + /// The use of these fields is IBV dependent. They can be used to flag that an OpROM + /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI + /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup + /// + UINT32 AdditionalIrq19Handler; + + /// + /// The use of these fields is IBV dependent. They can be used to flag that an OpROM + /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI + /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup + /// + UINT32 AdditionalIrq40Handler; + UINT8 AssignedDriveNumber; + UINT32 AdditionalIrq41Handler; + UINT32 AdditionalIrq46Handler; + UINT32 IBV1; + UINT32 IBV2; +} BBS_TABLE; + +/// +/// BBS device type values +///@{ +#define BBS_FLOPPY 0x01 +#define BBS_HARDDISK 0x02 +#define BBS_CDROM 0x03 +#define BBS_PCMCIA 0x04 +#define BBS_USB 0x05 +#define BBS_EMBED_NETWORK 0x06 +#define BBS_BEV_DEVICE 0x80 +#define BBS_UNKNOWN 0xff +///@} + +/// +/// BBS boot priority values +///@{ +#define BBS_DO_NOT_BOOT_FROM 0xFFFC +#define BBS_LOWEST_PRIORITY 0xFFFD +#define BBS_UNPRIORITIZED_ENTRY 0xFFFE +#define BBS_IGNORE_ENTRY 0xFFFF +///@} + +/// +/// SMM_ATTRIBUTES +/// +typedef struct { + /// + /// Access mechanism used to generate the soft SMI. Defined types are below. The other + /// values are reserved for future usage. + /// + UINT16 Type : 3; + + /// + /// The size of "port" in bits. Defined values are below. + /// + UINT16 PortGranularity : 3; + + /// + /// The size of data in bits. Defined values are below. + /// + UINT16 DataGranularity : 3; + + /// + /// Reserved for future use. + /// + UINT16 Reserved : 7; +} SMM_ATTRIBUTES; + +/// +/// SMM_ATTRIBUTES type values. +///@{ +#define STANDARD_IO 0x00 +#define STANDARD_MEMORY 0x01 +///@} + +/// +/// SMM_ATTRIBUTES port size constants. +///@{ +#define PORT_SIZE_8 0x00 +#define PORT_SIZE_16 0x01 +#define PORT_SIZE_32 0x02 +#define PORT_SIZE_64 0x03 +///@} + +/// +/// SMM_ATTRIBUTES data size constants. +///@{ +#define DATA_SIZE_8 0x00 +#define DATA_SIZE_16 0x01 +#define DATA_SIZE_32 0x02 +#define DATA_SIZE_64 0x03 +///@} + +/// +/// SMM_FUNCTION & relating constants. +/// +typedef struct { + UINT16 Function : 15; + UINT16 Owner : 1; +} SMM_FUNCTION; + +/// +/// SMM_FUNCTION Function constants. +///@{ +#define INT15_D042 0x0000 +#define GET_USB_BOOT_INFO 0x0001 +#define DMI_PNP_50_57 0x0002 +///@} + +/// +/// SMM_FUNCTION Owner constants. +///@{ +#define STANDARD_OWNER 0x0 +#define OEM_OWNER 0x1 +///@} + +/// +/// This structure assumes both port and data sizes are 1. SmmAttribute must be +/// properly to reflect that assumption. +/// +typedef struct { + /// + /// Describes the access mechanism, SmmPort, and SmmData sizes. Type + /// SMM_ATTRIBUTES is defined below. + /// + SMM_ATTRIBUTES SmmAttributes; + + /// + /// Function Soft SMI is to perform. Type SMM_FUNCTION is defined below. + /// + SMM_FUNCTION SmmFunction; + + /// + /// SmmPort size depends upon SmmAttributes and ranges from2 bytes to 16 bytes. + /// + UINT8 SmmPort; + + /// + /// SmmData size depends upon SmmAttributes and ranges from2 bytes to 16 bytes. + /// + UINT8 SmmData; +} SMM_ENTRY; + +/// +/// SMM_TABLE +/// +typedef struct { + UINT16 NumSmmEntries; ///< Number of entries represented by SmmEntry. + SMM_ENTRY SmmEntry; ///< One entry per function. Type SMM_ENTRY is defined below. +} SMM_TABLE; + +/// +/// UDC_ATTRIBUTES +/// +typedef struct { + /// + /// This bit set indicates that the ServiceAreaData is valid. + /// + UINT8 DirectoryServiceValidity : 1; + + /// + /// This bit set indicates to use the Reserve Area Boot Code Address (RACBA) only if + /// DirectoryServiceValidity is 0. + /// + UINT8 RabcaUsedFlag : 1; + + /// + /// This bit set indicates to execute hard disk diagnostics. + /// + UINT8 ExecuteHddDiagnosticsFlag : 1; + + /// + /// Reserved for future use. Set to 0. + /// + UINT8 Reserved : 5; +} UDC_ATTRIBUTES; + +/// +/// UD_TABLE +/// +typedef struct { + /// + /// This field contains the bit-mapped attributes of the PARTIES information. Type + /// UDC_ATTRIBUTES is defined below. + /// + UDC_ATTRIBUTES Attributes; + + /// + /// This field contains the zero-based device on which the selected + /// ServiceDataArea is present. It is 0 for master and 1 for the slave device. + /// + UINT8 DeviceNumber; + + /// + /// This field contains the zero-based index into the BbsTable for the parent device. + /// This index allows the user to reference the parent device information such as PCI + /// bus, device function. + /// + UINT8 BbsTableEntryNumberForParentDevice; + + /// + /// This field contains the zero-based index into the BbsTable for the boot entry. + /// + UINT8 BbsTableEntryNumberForBoot; + + /// + /// This field contains the zero-based index into the BbsTable for the HDD diagnostics entry. + /// + UINT8 BbsTableEntryNumberForHddDiag; + + /// + /// The raw Beer data. + /// + UINT8 BeerData[128]; + + /// + /// The raw data of selected service area. + /// + UINT8 ServiceAreaData[64]; +} UD_TABLE; + +#define EFI_TO_LEGACY_MAJOR_VERSION 0x02 +#define EFI_TO_LEGACY_MINOR_VERSION 0x00 +#define MAX_IDE_CONTROLLER 8 + +/// +/// EFI_TO_COMPATIBILITY16_BOOT_TABLE +/// +typedef struct { + UINT16 MajorVersion; ///< The EfiCompatibility major version number. + UINT16 MinorVersion; ///< The EfiCompatibility minor version number. + UINT32 AcpiTable; ///< The location of the RSDT ACPI table. < 4G range. + UINT32 SmbiosTable; ///< The location of the SMBIOS table in EFI memory. < 4G range. + UINT32 SmbiosTableLength; + // + // Legacy SIO state + // + DEVICE_PRODUCER_DATA_HEADER SioData; ///< Standard traditional device information. + UINT16 DevicePathType; ///< The default boot type. + UINT16 PciIrqMask; ///< Mask of which IRQs have been assigned to PCI. + UINT32 NumberE820Entries; ///< Number of E820 entries. The number can change from the + ///< Compatibility16InitializeYourself() function. + // + // Controller & Drive Identify[2] per controller information + // + HDD_INFO HddInfo[MAX_IDE_CONTROLLER]; ///< Hard disk drive information, including raw Identify Drive data. + UINT32 NumberBbsEntries; ///< Number of entries in the BBS table + UINT32 BbsTable; ///< A pointer to the BBS table. Type BBS_TABLE is defined below. + UINT32 SmmTable; ///< A pointer to the SMM table. Type SMM_TABLE is defined below. + UINT32 OsMemoryAbove1Mb; ///< The amount of usable memory above 1 MB, i.e. E820 type 1 memory. This value can + ///< differ from the value in EFI_TO_COMPATIBILITY16_INIT_TABLE as more + ///< memory may have been discovered. + UINT32 UnconventionalDeviceTable; ///< Information to boot off an unconventional device like a PARTIES partition. Type + ///< UD_TABLE is defined below. +} EFI_TO_COMPATIBILITY16_BOOT_TABLE; + +/// +/// EFI_LEGACY_INSTALL_PCI_HANDLER +/// +typedef struct { + UINT8 PciBus; ///< The PCI bus of the device. + UINT8 PciDeviceFun; ///< The PCI device in bits 7:3 and function in bits 2:0. + UINT8 PciSegment; ///< The PCI segment of the device. + UINT8 PciClass; ///< The PCI class code of the device. + UINT8 PciSubclass; ///< The PCI subclass code of the device. + UINT8 PciInterface; ///< The PCI interface code of the device. + // + // Primary section + // + UINT8 PrimaryIrq; ///< The primary device IRQ. + UINT8 PrimaryReserved; ///< Reserved. + UINT16 PrimaryControl; ///< The primary device control I/O base. + UINT16 PrimaryBase; ///< The primary device I/O base. + UINT16 PrimaryBusMaster; ///< The primary device bus master I/O base. + // + // Secondary Section + // + UINT8 SecondaryIrq; ///< The secondary device IRQ. + UINT8 SecondaryReserved; ///< Reserved. + UINT16 SecondaryControl; ///< The secondary device control I/O base. + UINT16 SecondaryBase; ///< The secondary device I/O base. + UINT16 SecondaryBusMaster; ///< The secondary device bus master I/O base. +} EFI_LEGACY_INSTALL_PCI_HANDLER; + +#endif
From: David Woodhouse David.Woodhouse@intel.com
We need this proposed addition to the CSM spec, or OVMF will make the whole region from 0xC0000 to 0xFFFFF read-only before invoking our Legacy16Boot method. Read-only stack considered harmful.
http://www.sourceforge.net/mailarchive/forum.php?thread_name=50FD7290.906000...
Not-yet-signed-off-by: David Woodhouse David.Woodhouse@intel.com --- src/LegacyBios.h | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/src/LegacyBios.h b/src/LegacyBios.h index 65ace3b..69eabd1 100644 --- a/src/LegacyBios.h +++ b/src/LegacyBios.h @@ -228,6 +228,17 @@ typedef struct { /// Maximum PCI bus number assigned. /// UINT8 LastPciBus; + + /// + /// Start address of UMB RAM (>> 12) + /// + UINT8 UmbStart; + + /// + /// End address of UMB RAM (>> 12) + /// + UINT8 UmbEnd; + } EFI_COMPATIBILITY16_TABLE;
///
From: David Woodhouse David.Woodhouse@intel.com
I'm about to introduce some post-processing in checkrom.py which will want access to public symbols. So let's make sure they're defined in the final link even if they're *not* cross-referenced from a different code section.
Not-yet-signed-off-by: David Woodhouse David.Woodhouse@intel.com --- tools/layoutrom.py | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/tools/layoutrom.py b/tools/layoutrom.py index 816ff9b..75c49be 100755 --- a/tools/layoutrom.py +++ b/tools/layoutrom.py @@ -248,7 +248,7 @@ def doLayout(sections, genreloc): ######################################################################
# Write LD script includes for the given cross references -def outXRefs(sections, useseg=0): +def outXRefs(sections, useseg=0, exportsyms=[]): xrefs = {} out = "" for section in sections: @@ -264,6 +264,16 @@ def outXRefs(sections, useseg=0): if useseg: loc = symbol.section.finalsegloc out += "%s = 0x%x ;\n" % (reloc.symbolname, loc + symbol.offset) + + for symbol in exportsyms: + if symbol.name in xrefs: + continue + xrefs[symbol.name] = 1 + loc = symbol.section.finalloc + if useseg: + loc = symbol.section.finalsegloc + out += "%s = 0x%x ;\n" % (symbol.name, loc + symbol.offset) + return out
# Write LD script includes for the given sections using relative offsets @@ -310,7 +320,7 @@ def getSectionsStart(sections, defaddr=0): if section.finalloc is not None] or [defaddr])
# Output the linker scripts for all required sections. -def writeLinkerScripts(li, entrysym, genreloc, out16, out32seg, out32flat): +def writeLinkerScripts(li, entrysym, genreloc, exportsyms, out16, out32seg, out32flat): # Write 16bit linker script out = outXRefs(li.sections16, useseg=1) + """ datalow_base = 0x%x ; @@ -361,7 +371,7 @@ def writeLinkerScripts(li, entrysym, genreloc, out16, out32seg, out32flat): + strRelocs("_reloc_datalow", "code32flat_start", lowrelocs)) numrelocs = len(absrelocs + relrelocs + initrelocs + lowrelocs) sec32all_start -= numrelocs * 4 - out = outXRefs(sections32all) + """ + out = outXRefs(sections32all, exportsyms=exportsyms) + """ %s = 0x%x ; _reloc_min_align = 0x%x ; datalow_base = 0x%x ; @@ -518,6 +528,7 @@ def parseObjDump(file, fileid): sectionmap = {} # symbols[symbolname] = symbol symbols = {} + exportsyms = {}
state = None for line in file.readlines(): @@ -569,6 +580,9 @@ def parseObjDump(file, fileid): symbol.name = name symbol.section = sectionmap.get(sectionname) symbols[name] = symbol + if ".export." in sectionname and sectionname != name: + exportsyms[symbol] = symbol + except ValueError: pass continue @@ -592,7 +606,7 @@ def parseObjDump(file, fileid): relocsection.relocs.append(reloc) except ValueError: pass - return sections, symbols + return sections, symbols, exportsyms
def main(): # Get output name @@ -613,6 +627,7 @@ def main():
# Separate 32bit flat into runtime and init parts findInit(sections) + exportsyms = dict(info16[2].items() + info32seg[2].items() + info32flat[2].items())
# Note "low memory" parts for section in getSectionsPrefix(sections, '.datalow.'): @@ -624,7 +639,7 @@ def main():
# Write out linker script files. entrysym = info16[1]['entry_elf'] - writeLinkerScripts(li, entrysym, genreloc, out16, out32seg, out32flat) + writeLinkerScripts(li, entrysym, genreloc, exportsyms, out16, out32seg, out32flat)
if __name__ == '__main__': main()
From: David Woodhouse David.Woodhouse@intel.com
GCC, for reasons unknown, will refuse to compile code such as extern int bar; uint16_t foo = &bar;
The assembler would happily emit a R_386_16 relocation for this if asked nicely, and all would be well. But instead, GCC complains about the initialiser not being constant.
So we tend to fill in 16-bit offsets at run-time, which is only moderately inefficient. But for the CSM table used by EFI, it doesn't work. We need the offset to be present in the *image*, before a line of our own code has been run. Likewise the checksum.
This special-cases the table and entry point in checkrom.py rather than attempting to do something generic. I did have a functional generic implementation which could be invoked from csm.c along the lines of CHECKSUM(csm_compat_table, TableChecksum) ... and which would emit the required offsetof(typeof(\1), \2) into a special data section which was elided from the final build but parsed by 'objdump -s' and the location of the table to be checksummed was inferred from the name of the *variable* that got put into that special section... seriously, it's better just to special-case it.
It was baroque enough just for the checksums, and filling in the entry point which required access to *two* symbols was probably going to involve emitting a *string* into that special build-data section. It had to die.
So yes, we have hard-coded symbol names, and even magic numbers in the python script for table offsets etc., but that's because this is an ABI. It doesn't change, and neither do any of the other tables that we might now consider filling at build time just to avoid having to spend time on doing so at runtime.
Not-yet-signed-off-by: David Woodhouse David.Woodhouse@intel.com --- tools/checkrom.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+)
diff --git a/tools/checkrom.py b/tools/checkrom.py index 69d65e8..00a652a 100755 --- a/tools/checkrom.py +++ b/tools/checkrom.py @@ -8,6 +8,17 @@ import sys import layoutrom
+def subst(data, offset, new): + return data[:offset] + new + data[offset + len(new):] + +def checksum(data, start, size, csum): + sumbyte = 0 + while size: + sumbyte = sumbyte + ord(data[start + size - 1]) + size = size - 1 + sumbyte = (0x100 - sumbyte) & 0xff + return subst(data, start+csum, chr(sumbyte)) + def main(): # Get args objinfo, rawfile, outfile = sys.argv[1:] @@ -45,6 +56,22 @@ def main(): datasize, expdatasize) sys.exit(1)
+ # Fix up CSM Compatibility16 table + if 'csm_compat_table' in symbols and 'entry_csm16' in symbols: + # Field offsets within EFI_COMPATIBILITY16_TABLE + ENTRY_FIELD_OFS = 14 # Compatibility16CallOffset (UINT16) + SIZE_FIELD_OFS = 5 # TableLength (UINT8) + CSUM_FIELD_OFS = 4 # TableChecksum (UINT8) + + tableofs = symbols['csm_compat_table'].offset - symbols['code32flat_start'].offset + entry_addr = symbols['entry_csm16'].offset - layoutrom.BUILD_BIOS_ADDR + byte1 = chr(entry_addr & 0xff) + byte2 = chr(entry_addr >> 8) + rawdata = subst(rawdata, tableofs+ENTRY_FIELD_OFS, byte1+byte2) + + tablesize = ord(rawdata[tableofs+SIZE_FIELD_OFS]) + rawdata = checksum(rawdata, tableofs, tablesize, CSUM_FIELD_OFS) + # Print statistics runtimesize = datasize if '_reloc_abs_start' in symbols:
From: David Woodhouse David.Woodhouse@intel.com
Not-yet-signed-off-by: David Woodhouse David.Woodhouse@intel.com --- Makefile | 2 +- README.CSM | 20 ++++ src/Kconfig | 7 ++ src/boot.c | 6 ++ src/boot.h | 5 + src/csm.c | 313 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/csm.h | 13 +++ src/pirtable.c | 6 +- src/pmm.c | 19 ++++ src/romlayout.S | 37 +++++++ src/util.h | 1 + 11 files changed, 425 insertions(+), 4 deletions(-) create mode 100644 README.CSM create mode 100644 src/csm.c create mode 100644 src/csm.h
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/README.CSM b/README.CSM new file mode 100644 index 0000000..fb4973c --- /dev/null +++ b/README.CSM @@ -0,0 +1,20 @@ +Enabling CONFIG_CSM allows SeaBIOS to be built as a Compatibility Support +Module for use with the OMVF/EDK-II UEFI firmware. + +It will provide "legacy" BIOS services for booting non-EFI operating +systems and will also allow OVMF to display on otherwise unsupported +video hardware by using the traditional VGA BIOS. + +Windows 2008r2 is known to use INT 10h BIOS calls even when booted via +EFI, and the presence of a CSM makes this work as expected too. + +Having built SeaBIOS with CONFIG_CSM, you should be able to drop the +result into your OVMF build tree at OvmfPkg/Csm/Csm16/Csm16.bin and +then build OVMF with 'build -D CSM_ENABLE'. The SeaBIOS binary will be +included as a discrete file within the 'Flash Volume' which is +created, and there are tools which will extract it and allow it to be +replaced; satisfying the requirements of the LGPL licence. + +A patch to OVMF is required; see +http://www.sourceforge.net/mailarchive/forum.php?thread_name=50FD7290.906000... + 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/boot.c b/src/boot.c index 3bafa5a..8899c0b 100644 --- a/src/boot.c +++ b/src/boot.c @@ -120,6 +120,8 @@ build_pci_path(char *buf, int max, const char *devname, struct pci_device *pci)
int bootprio_find_pci_device(struct pci_device *pci) { + if (CONFIG_CSM) + return csm_bootprio_pci(pci); if (!CONFIG_BOOTORDER) return -1; // Find pci device - for example: /pci@i0cf8/ethernet@5 @@ -144,6 +146,8 @@ int bootprio_find_scsi_device(struct pci_device *pci, int target, int lun)
int bootprio_find_ata_device(struct pci_device *pci, int chanid, int slave) { + if (CONFIG_CSM) + return csm_bootprio_ata(pci, chanid, slave); if (!CONFIG_BOOTORDER) return -1; if (!pci) @@ -158,6 +162,8 @@ int bootprio_find_ata_device(struct pci_device *pci, int chanid, int slave)
int bootprio_find_fdc_device(struct pci_device *pci, int port, int fdid) { + if (CONFIG_CSM) + return csm_bootprio_fdc(pci, port, fdid); if (!CONFIG_BOOTORDER) return -1; if (!pci) diff --git a/src/boot.h b/src/boot.h index 4d4943b..9c532df 100644 --- a/src/boot.h +++ b/src/boot.h @@ -23,4 +23,9 @@ int bootprio_find_named_rom(const char *name, int instance); struct usbdevice_s; int bootprio_find_usb(struct usbdevice_s *usbdev, int lun);
+// csm.c +int csm_bootprio_fdc(struct pci_device *pci, int port, int fdid); +int csm_bootprio_ata(struct pci_device *pci, int chanid, int slave); +int csm_bootprio_pci(struct pci_device *pci); + #endif // __BOOT_H diff --git a/src/csm.c b/src/csm.c new file mode 100644 index 0000000..92b2e84 --- /dev/null +++ b/src/csm.c @@ -0,0 +1,313 @@ +// Compatibility Support Module (CSM) for UEFI / EDK-II +// +// Copyright © 2013 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" +#include "optionroms.h" +#include "pci.h" +#include "memmap.h" +#include "biosvar.h" +#include "post.h" +#include "acpi.h" +#include "boot.h" +#include "smbios.h" +#include "pic.h" + +#if CONFIG_CSM +#define MAX_ACPI2_RSDP_SIZE 36 + +struct rsdp_descriptor VAR32FLATVISIBLE __aligned(16) csm_rsdp; + +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", + .AcpiRsdPtrPointer = (u32)&csm_rsdp, + .UmbStart = 0xe0, + .UmbEnd = 0xf0, +}; + + +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); + + csm_malloc_setup(csm_init_table->LowPmmMemory, csm_init_table->LowPmmMemorySizeInBytes, + csm_init_table->HiPmmMemory, csm_init_table->HiPmmMemorySizeInBytes); + reloc_preinit(); + interface_init(); + timer_setup(); + pci_probe_devices(); + + csm_compat_table.PnPInstallationCheckSegment = SEG_BIOS; + csm_compat_table.PnPInstallationCheckOffset = get_pnp_offset(); + + 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; +} + +/* PrepareToBoot */ +void handle_csm_0002(struct bregs *regs) +{ + dprintf(3, "PrepareToBoot table %04x:%04x\n", regs->es, regs->bx); + + /* La la la */ + dprintf(3, "%d e820 entries (%d bytes)`n", csm_compat_table.E820Length / sizeof(struct e820entry), csm_compat_table.E820Length); + memcpy(e820_list, (void *)csm_compat_table.E820Pointer, csm_compat_table.E820Length); + e820_count = csm_compat_table.E820Length / sizeof(struct e820entry); + + if (csm_init_table->HiPmmMemorySizeInBytes > CONFIG_MAX_HIGHTABLE) { + u32 hi_pmm_end = csm_init_table->HiPmmMemory + csm_init_table->HiPmmMemorySizeInBytes; + add_e820(hi_pmm_end - CONFIG_MAX_HIGHTABLE, CONFIG_MAX_HIGHTABLE, E820_RESERVED); + } + + // For PCIBIOS 1ab10e + if (csm_compat_table.IrqRoutingTablePointer && + csm_compat_table.IrqRoutingTableLength) { + PirAddr = (void *)csm_compat_table.IrqRoutingTablePointer; + dprintf(3, "CSM PIRQ table at %p\n", PirAddr); + } + + // For find_resume_vector() + if (csm_rsdp.signature == RSDP_SIGNATURE) { + RsdpAddr = &csm_rsdp; + dprintf(3, "CSM ACPI RSDP at %p\n", PirAddr); + + // Find PM timer from ACPI tables provided by UEFI + // XXX: Theoretically, we should use XSDT and X_PM_TMR_BLK. + if (csm_rsdp.rsdt_physical_address) { + u32 *rsdt = (u32 *)csm_rsdp.rsdt_physical_address; + int i; + + for (i = 9; i < rsdt[1] / 4; i++) { + struct fadt_descriptor_rev1 *fadt = (void *)rsdt[i]; + u32 pm_tmr; + + if (fadt->signature != FACP_SIGNATURE) + continue; + + pm_tmr = fadt->pm_tmr_blk; + if (!pm_tmr) + break; + + pmtimer_setup(PORT_ACPI_PM_BASE + 0x08, 3579); + } + } + } + + // SMBIOS table needs to be copied into the f-seg + // XX: OVMF doesn't seem to set SmbiosTableLength so don't check it + if (csm_boot_table->SmbiosTable && !SMBiosAddr) + copy_smbios((void *)csm_boot_table->SmbiosTable); + + // MPTABLE is just there; we don't care where. + + // EFI may have reinitialised the video using its *own* driver. + enable_vga_console(); + + // EFI fills this in for us. Zero it for now... + struct bios_data_area_s *bda = MAKE_FLATPTR(SEG_BDA, 0); + bda->hdcount = 0; + + device_hardware_setup(); + wait_threads(); + + interactive_bootmenu(); + wait_threads(); + + prepareboot(); + + regs->ax = 0; +} + +/* Boot */ +void handle_csm_0003(struct bregs *regs) +{ + dprintf(3, "Boot\n"); + + startBoot(); + + regs->ax = 1; +} + +/* Legacy16DispatchOprom */ +void handle_csm_0005(struct bregs *regs) +{ + EFI_DISPATCH_OPROM_TABLE *table = MAKE_FLATPTR(regs->es, regs->bx); + struct rom_header *rom; + u16 bdf; + + dprintf(3, "Legacy16DispatchOprom rom %p\n", table); + + dprintf(3, "OpromSegment %04x\n", table->OpromSegment); + dprintf(3, "RuntimeSegment %04x\n", table->RuntimeSegment); + dprintf(3, "PnPInstallationCheck %04x:%04x\n", + table->PnPInstallationCheckSegment, + table->PnPInstallationCheckOffset); + dprintf(3, "RuntimeSegment %04x\n", table->RuntimeSegment); + + rom = MAKE_FLATPTR(table->OpromSegment, 0); + bdf = pci_bus_devfn_to_bdf(table->PciBus, table->PciDeviceFunction); + + rom_confirm(rom->size * 512); + + // XX PnP seg/ofs should never be other than default + callrom(rom, bdf); + + regs->bx = 0; // FIXME + 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 = NULL; + + if (!region) + region = 3; + + dprintf(3, "Legacy16GetTableAddress size %x align %x region %d\n", + size, align, region); + + if (region & 2) + chunk = pmm_malloc(&ZoneLow, PMM_DEFAULT_HANDLE, size, align); + if (!chunk && (region & 1)) + 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; + } +} + +static u8 pic_mask[2] = { ~PIC1_IRQ2, ~0 }; + +void VISIBLE32FLAT +handle_csm32(struct bregs *regs) +{ + ASSERT32FLAT(); + + dprintf(3, "handle_csm16 regs %p AX=%04x (PIC %02x%02x)\n", regs, regs->ax, + pic_mask[0], pic_mask[1]); + + outb(pic_mask[0], PORT_PIC1_DATA); + outb(pic_mask[1], PORT_PIC2_DATA); + + 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; + } + wait_threads(); + + pic_mask[0] = inb(PORT_PIC1_DATA); + pic_mask[1] = inb(PORT_PIC2_DATA); + + dprintf(3, "handle_csm16 returning AX=%04x (PIC %02x%02x)\n", regs->ax, + pic_mask[0], pic_mask[1]); +} + +int csm_bootprio_ata(struct pci_device *pci, int chanid, int slave) +{ + if (!csm_boot_table) + return -1; + BBS_TABLE *bbs = (void *)csm_boot_table->BbsTable; + int index = 1 + (chanid * 2) + slave; + dprintf(3, "CSM bootprio for ATA%d,%d (index %d) is %d\n", chanid, slave, + index, bbs[index].BootPriority); + return bbs[index].BootPriority; +} + +int csm_bootprio_fdc(struct pci_device *pci, int port, int fdid) +{ + if (!csm_boot_table) + return -1; + BBS_TABLE *bbs = (void *)csm_boot_table->BbsTable; + dprintf(3, "CSM bootprio for FDC is %d\n", bbs[0].BootPriority); + return bbs[0].BootPriority; +} + +int csm_bootprio_pci(struct pci_device *pci) +{ + if (!csm_boot_table) + return -1; + BBS_TABLE *bbs = (void *)csm_boot_table->BbsTable; + int i; + + for (i = 5; i < csm_boot_table->NumberBbsEntries; i++) { + if (pci->bdf == pci_to_bdf(bbs[i].Bus, bbs[i].Device, bbs[i].Function)) { + dprintf(3, "CSM bootprio for PCI(%d,%d,%d) is %d\n", bbs[i].Bus, + bbs[i].Device, bbs[i].Function, bbs[i].BootPriority); + return bbs[i].BootPriority; + } + } + return -1; +} +#endif /* CONFIG_CSM */ diff --git a/src/csm.h b/src/csm.h new file mode 100644 index 0000000..31504fd --- /dev/null +++ b/src/csm.h @@ -0,0 +1,13 @@ +// Compatibility Support Module (CSM) for UEFI / EDK-II +// +// Copyright © 2013 Intel Corporation +// +// This file may be distributed under the terms of the GNU LGPLv3 license. + +#include "types.h" + +#define UINT8 u8 +#define UINT16 u16 +#define UINT32 u32 + +#include "LegacyBios.h" diff --git a/src/pirtable.c b/src/pirtable.c index 62b62b8..2ba70ee 100644 --- a/src/pirtable.c +++ b/src/pirtable.c @@ -17,7 +17,7 @@ struct pir_table { } PACKED;
extern struct pir_table PIR_TABLE; -#if CONFIG_PIRTABLE && !CONFIG_COREBOOT +#if CONFIG_PIRTABLE && !CONFIG_COREBOOT && !CONFIG_CSM struct pir_table PIR_TABLE __aligned(16) VAR16EXPORT = { .pir = { .version = 0x0100, @@ -89,12 +89,12 @@ struct pir_table PIR_TABLE __aligned(16) VAR16EXPORT = { }, } }; -#endif // CONFIG_PIRTABLE && !CONFIG_COREBOOT +#endif // CONFIG_PIRTABLE && !CONFIG_COREBOOT && !CONFIG_CSM
void pirtable_setup(void) { - if (! CONFIG_PIRTABLE) + if (! CONFIG_PIRTABLE || CONFIG_CSM) return;
dprintf(3, "init PIR table\n"); diff --git a/src/pmm.c b/src/pmm.c index 0dbc86e..f36b7c8 100644 --- a/src/pmm.c +++ b/src/pmm.c @@ -256,6 +256,25 @@ malloc_preinit(void) } }
+void +csm_malloc_setup(u32 low_pmm, u32 low_pmm_size, u32 hi_pmm, u32 hi_pmm_size) +{ + ASSERT32FLAT(); + + if (hi_pmm_size > CONFIG_MAX_HIGHTABLE) { + void *hi_pmm_end = (void *)hi_pmm + hi_pmm_size; + addSpace(&ZoneTmpHigh, (void *)hi_pmm, hi_pmm_end - CONFIG_MAX_HIGHTABLE); + addSpace(&ZoneHigh, hi_pmm_end - CONFIG_MAX_HIGHTABLE, hi_pmm_end); + } else { + addSpace(&ZoneTmpHigh, (void *)hi_pmm, (void *)hi_pmm + hi_pmm_size); + } + addSpace(&ZoneTmpLow, (void *)low_pmm, (void *)low_pmm + low_pmm_size); + addSpace(&ZoneFSeg, BiosTableSpace, &BiosTableSpace[CONFIG_MAX_BIOSTABLE]); + extern u8 final_datalow_start[]; + addSpace(&ZoneLow, datalow_base + OPROM_HEADER_RESERVE, final_datalow_start); + RomBase = findLast(&ZoneLow); +} + // Update pointers after code relocation. void malloc_fixupreloc_init(void) diff --git a/src/romlayout.S b/src/romlayout.S index 8125277..0c1cfb4 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -468,6 +468,43 @@ irqentryarg: DECL_IRQ_ENTRY hwpic1 DECL_IRQ_ENTRY hwpic2
+#if CONFIG_CSM + EXPORTFUNC entry_csm16 +entry_csm16: + PUSHBREGS + + // Reset stack and store EFI's old SS:SP on it + movl %esp, %edx + movw %ss, %cx + + xorl %eax, %eax + movw %ax, %ss + movw %ax, %ds + movl $BUILD_STACK_ADDR, %esp + + pushl %ecx // EFI's SS + pushl %edx // EFI's SP + + // Turn %edx into a flat pointer (including segment base) + shll $4, %ecx + addl %ecx, %edx + + // call32(handle_csm32, bregs, -1) + movl $_cfunc32flat_handle_csm32, %eax + movl $-1, %ecx + calll call32 + + // Switch back to EFI's stack and return + popl %edx + popl %ecx + movw %cx, %ss + movw %cx, %ds + movl %edx, %esp + + POPBREGS + iretw +#endif + // int 18/19 are special - they reset stack and call into 32bit mode. DECLFUNC entry_19 entry_19: diff --git a/src/util.h b/src/util.h index 84915ed..6846bb9 100644 --- a/src/util.h +++ b/src/util.h @@ -368,6 +368,7 @@ u32 rom_get_top(void); u32 rom_get_last(void); struct rom_header *rom_reserve(u32 size); int rom_confirm(u32 size); +void csm_malloc_setup(u32 low_pmm, u32 low_pmm_size, u32 hi_pmm, u32 hi_pmm_size); void malloc_preinit(void); void malloc_fixupreloc_init(void); void malloc_prepboot(void);
On Mon, Jan 28, 2013 at 04:23:45PM +0000, David Woodhouse wrote:
From: David Woodhouse David.Woodhouse@intel.com
Thanks. I have a few minor comments.
[...]
--- /dev/null +++ b/README.CSM @@ -0,0 +1,20 @@ +Enabling CONFIG_CSM allows SeaBIOS to be built as a Compatibility Support +Module for use with the OMVF/EDK-II UEFI firmware.
Ideally this would be added to the existing README instead of adding a new file.
[...]
--- a/src/boot.h +++ b/src/boot.h @@ -23,4 +23,9 @@ int bootprio_find_named_rom(const char *name, int instance); struct usbdevice_s; int bootprio_find_usb(struct usbdevice_s *usbdev, int lun);
+// csm.c +int csm_bootprio_fdc(struct pci_device *pci, int port, int fdid); +int csm_bootprio_ata(struct pci_device *pci, int chanid, int slave); +int csm_bootprio_pci(struct pci_device *pci);
Ideally this would be added to util.h or csm.h instead of boot.h.
[...]
--- /dev/null +++ b/src/csm.c @@ -0,0 +1,313 @@ +// Compatibility Support Module (CSM) for UEFI / EDK-II +// +// Copyright © 2013 Intel Corporation
I think the copyright notice should be in ASCII unless there is a compelling reason not to.
+// +// 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" +#include "optionroms.h" +#include "pci.h" +#include "memmap.h" +#include "biosvar.h" +#include "post.h" +#include "acpi.h" +#include "boot.h" +#include "smbios.h" +#include "pic.h"
+#if CONFIG_CSM
I'd prefer to avoid #if statements. Instead, just add "if (!CONFIG_CSM) return" to handle_csm32() and let gcc and the build weed out the unused code.
+#define MAX_ACPI2_RSDP_SIZE 36
+struct rsdp_descriptor VAR32FLATVISIBLE __aligned(16) csm_rsdp;
+extern void entry_csm16(void);
This extern is dead code.
+EFI_COMPATIBILITY16_TABLE csm_compat_table VAR16EXPORT __aligned(16) = {
Instead of declaring this VAR16EXPORT I think this can be declared as VAR32FLATVISIBLE. (Technically it should be a new definition as VAR32FLATEXPORT, but it wont matter in practice.) Once this is done csm.c can be moved from SRCBOTH to SRC32FLAT in the Makefile and patch 10 is no longer needed.
[...]
+/* 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);
- csm_malloc_setup(csm_init_table->LowPmmMemory, csm_init_table->LowPmmMemorySizeInBytes,
csm_init_table->HiPmmMemory, csm_init_table->HiPmmMemorySizeInBytes);
- reloc_preinit();
- interface_init();
- timer_setup();
- pci_probe_devices();
- csm_compat_table.PnPInstallationCheckSegment = SEG_BIOS;
- csm_compat_table.PnPInstallationCheckOffset = get_pnp_offset();
- regs->ax = 0;
+}
[...]
+/* PrepareToBoot */ +void handle_csm_0002(struct bregs *regs) +{
- dprintf(3, "PrepareToBoot table %04x:%04x\n", regs->es, regs->bx);
Out of curiosity, does the e820 map, pirtable init, and pmtimer init need to happen here instead of in handle_csm_0000()? Normally these types of things would be done earlier. (I can also envision optionroms trying to access some of this info.)
- /* La la la */
- dprintf(3, "%d e820 entries (%d bytes)`n", csm_compat_table.E820Length / sizeof(struct e820entry), csm_compat_table.E820Length);
- memcpy(e820_list, (void *)csm_compat_table.E820Pointer, csm_compat_table.E820Length);
- e820_count = csm_compat_table.E820Length / sizeof(struct e820entry);
I think it would be better to loop through the table and call add_e820() - this will ensure the seabios invariants (sort order, overlap checks, CONFIG_MAX_E820 checks, etc) are still run.
Also, I don't understand the comment.
[...]
- // For find_resume_vector()
- if (csm_rsdp.signature == RSDP_SIGNATURE) {
RsdpAddr = &csm_rsdp;
dprintf(3, "CSM ACPI RSDP at %p\n", PirAddr);
// Find PM timer from ACPI tables provided by UEFI
// XXX: Theoretically, we should use XSDT and X_PM_TMR_BLK.
if (csm_rsdp.rsdt_physical_address) {
u32 *rsdt = (u32 *)csm_rsdp.rsdt_physical_address;
int i;
for (i = 9; i < rsdt[1] / 4; i++) {
struct fadt_descriptor_rev1 *fadt = (void *)rsdt[i];
u32 pm_tmr;
if (fadt->signature != FACP_SIGNATURE)
continue;
pm_tmr = fadt->pm_tmr_blk;
if (!pm_tmr)
break;
pmtimer_setup(PORT_ACPI_PM_BASE + 0x08, 3579);
}
- }
- }
Ideally this would be put in a function as I think Xen and Coreboot could make use of this as well.
Also, SeaBIOS uses space indentation and no tabs.
- // SMBIOS table needs to be copied into the f-seg
- // XX: OVMF doesn't seem to set SmbiosTableLength so don't check it
- if (csm_boot_table->SmbiosTable && !SMBiosAddr)
copy_smbios((void *)csm_boot_table->SmbiosTable);
Out of curiosity, why does the smbios table need to be copied when the pir and mptables do not?
- // EFI may have reinitialised the video using its *own* driver.
- enable_vga_console();
- // EFI fills this in for us. Zero it for now...
- struct bios_data_area_s *bda = MAKE_FLATPTR(SEG_BDA, 0);
- bda->hdcount = 0;
- device_hardware_setup();
- wait_threads();
- interactive_bootmenu();
- wait_threads();
Minor, but there's no need for the additional wait_threads() call. It's only in the maininit() code path because of the possibility that CONFIG_THREAD_OPTIONROMS is set.
[...]
+static u8 pic_mask[2] = { ~PIC1_IRQ2, ~0 };
+void VISIBLE32FLAT +handle_csm32(struct bregs *regs) +{
- ASSERT32FLAT();
- dprintf(3, "handle_csm16 regs %p AX=%04x (PIC %02x%02x)\n", regs, regs->ax,
pic_mask[0], pic_mask[1]);
- outb(pic_mask[0], PORT_PIC1_DATA);
- outb(pic_mask[1], PORT_PIC2_DATA);
Wow, that's ugly. Ideally OVMF would do that. But, I understand why it's needed. I think it would be better to make a pic_save() and pic_restore() which lived in pic.c/h though.
- 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;
Is there a plan to implement the 4/7/8 calls?
- 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;
- }
- wait_threads();
Unless I'm missing something, the wait_threads() call shouldn't be needed.
[...]
+int csm_bootprio_ata(struct pci_device *pci, int chanid, int slave) +{
- if (!csm_boot_table)
return -1;
- BBS_TABLE *bbs = (void *)csm_boot_table->BbsTable;
- int index = 1 + (chanid * 2) + slave;
- dprintf(3, "CSM bootprio for ATA%d,%d (index %d) is %d\n", chanid, slave,
index, bbs[index].BootPriority);
- return bbs[index].BootPriority;
Does UEFI really guarantee the order of the entries in the table (floppy, then ata, then pci)? Otherwise, the code could loop through the table (as csm_bootprio_pci does) and inspect DeviceType.
[...]
--- /dev/null +++ b/src/csm.h @@ -0,0 +1,13 @@ +// Compatibility Support Module (CSM) for UEFI / EDK-II +// +// Copyright © 2013 Intel Corporation +// +// This file may be distributed under the terms of the GNU LGPLv3 license.
+#include "types.h"
Due to quirks in the SeaBIOS build (it textually includes files together at build) all headers really should have an include guard.
Also, I'd prefer not to put copyright notices on header files that just contain boilerplate definitions.
[...]
--- a/src/pirtable.c +++ b/src/pirtable.c @@ -17,7 +17,7 @@ struct pir_table { } PACKED;
extern struct pir_table PIR_TABLE; -#if CONFIG_PIRTABLE && !CONFIG_COREBOOT +#if CONFIG_PIRTABLE && !CONFIG_COREBOOT && !CONFIG_CSM
Ideally these constraints would be set in Kconfig.
[...]
--- a/src/romlayout.S +++ b/src/romlayout.S @@ -468,6 +468,43 @@ irqentryarg: DECL_IRQ_ENTRY hwpic1 DECL_IRQ_ENTRY hwpic2
+#if CONFIG_CSM
I'd avoid the #if and waste the few bytes of assembler - just make sure handle_csm32() has a "if (!CONFIG_CSM) return" test.
-Kevin
On Sat, 2013-02-02 at 20:21 -0500, Kevin O'Connor wrote:
On Mon, Jan 28, 2013 at 04:23:45PM +0000, David Woodhouse wrote:
+++ b/README.CSM
Ideally this would be added to the existing README instead of adding a new file.
OK, will fix.
+// csm.c +int csm_bootprio_fdc(struct pci_device *pci, int port, int fdid); +int csm_bootprio_ata(struct pci_device *pci, int chanid, int slave); +int csm_bootprio_pci(struct pci_device *pci);
Ideally this would be added to util.h or csm.h instead of boot.h.
OK.
+// Copyright © 2013 Intel Corporation
I think the copyright notice should be in ASCII unless there is a compelling reason not to.
Really? This far into the 21st century? When the only "failure mode" for the Luddites who *are* stuck in the 20th century is cosmetic? I'd really rather not ☺
I'd prefer to avoid #if statements. Instead, just add "if (!CONFIG_CSM) return" to handle_csm32() and let gcc and the build weed out the unused code.
OK.
+#define MAX_ACPI2_RSDP_SIZE 36 +struct rsdp_descriptor VAR32FLATVISIBLE __aligned(16) csm_rsdp; +extern void entry_csm16(void);
This extern is dead code.
As is MAX_ACPI2_RSDP_SIZE. Will fix.
+EFI_COMPATIBILITY16_TABLE csm_compat_table VAR16EXPORT __aligned(16) = {
Instead of declaring this VAR16EXPORT I think this can be declared as VAR32FLATVISIBLE. (Technically it should be a new definition as VAR32FLATEXPORT, but it wont matter in practice.) Once this is done csm.c can be moved from SRCBOTH to SRC32FLAT in the Makefile and patch 10 is no longer needed.
I thought I'd experimented with that and it hadn't been sufficient. Will re-test, and make it work if it doesn't. I have a little more clue about the linking process now.
[...]
+/* 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);
- csm_malloc_setup(csm_init_table->LowPmmMemory, csm_init_table->LowPmmMemorySizeInBytes,
csm_init_table->HiPmmMemory, csm_init_table->HiPmmMemorySizeInBytes);
- reloc_preinit();
- interface_init();
- timer_setup();
- pci_probe_devices();
- csm_compat_table.PnPInstallationCheckSegment = SEG_BIOS;
- csm_compat_table.PnPInstallationCheckOffset = get_pnp_offset();
- regs->ax = 0;
+}
[...]
+/* PrepareToBoot */ +void handle_csm_0002(struct bregs *regs) +{
- dprintf(3, "PrepareToBoot table %04x:%04x\n", regs->es, regs->bx);
Out of curiosity, does the e820 map, pirtable init, and pmtimer init need to happen here instead of in handle_csm_0000()? Normally these types of things would be done earlier. (I can also envision optionroms trying to access some of this info.)
The E820 map and PIR table are allocated by calls to our GetTableAddress() function, so they're not present when the InitializeYourself() function is first called. The ACPI table is different, since it's copied into a static buffer that we provide, but still it's not done until later.
In general, the CSM design seems to be assuming very well-behaved option ROMs that don't do *anything* out of the ordinary. I'm receiving reports that even doing timer_init() in the first call is causing problems, and we shouldn't be touching real hardware until we are actually booting. If an option ROM requires us to have functional timers, or even keyboard, then I think it's just not expected to work.
I don't really know a lot more than you about it though, except what I can glean from the specification PDF (not a lot), and from reading through the code paths on the OVMF side (only a little bit more).
There might be *some* scope for making things a little saner, but I don't think there's a massive appetite for it.
- /* La la la */
- dprintf(3, "%d e820 entries (%d bytes)`n", csm_compat_table.E820Length / sizeof(struct e820entry), csm_compat_table.E820Length);
- memcpy(e820_list, (void *)csm_compat_table.E820Pointer, csm_compat_table.E820Length);
- e820_count = csm_compat_table.E820Length / sizeof(struct e820entry);
I think it would be better to loop through the table and call add_e820() - this will ensure the seabios invariants (sort order, overlap checks, CONFIG_MAX_E820 checks, etc) are still run.
OK, I'll have a go at that.
Also, I don't understand the comment.
Oh, that's a hangover from when the function just said /* la la la */ and returned success without doing anything. I'll remove it.
[...]
- // For find_resume_vector()
- if (csm_rsdp.signature == RSDP_SIGNATURE) {
RsdpAddr = &csm_rsdp;
dprintf(3, "CSM ACPI RSDP at %p\n", PirAddr);
// Find PM timer from ACPI tables provided by UEFI
// XXX: Theoretically, we should use XSDT and X_PM_TMR_BLK.
if (csm_rsdp.rsdt_physical_address) {
u32 *rsdt = (u32 *)csm_rsdp.rsdt_physical_address;
int i;
for (i = 9; i < rsdt[1] / 4; i++) {
struct fadt_descriptor_rev1 *fadt = (void *)rsdt[i];
u32 pm_tmr;
if (fadt->signature != FACP_SIGNATURE)
continue;
pm_tmr = fadt->pm_tmr_blk;
if (!pm_tmr)
break;
pmtimer_setup(PORT_ACPI_PM_BASE + 0x08, 3579);
}
- }
- }
Ideally this would be put in a function as I think Xen and Coreboot could make use of this as well.
OK.
Also, SeaBIOS uses space indentation and no tabs.
Oops. I'd fixed that once (but not taught emacs about it), and then remembered that I had to go back and fix this instead of just pulling the numbers out of my posterior for calling pmtimer_init(). Will fix.
- // SMBIOS table needs to be copied into the f-seg
- // XX: OVMF doesn't seem to set SmbiosTableLength so don't check it
- if (csm_boot_table->SmbiosTable && !SMBiosAddr)
copy_smbios((void *)csm_boot_table->SmbiosTable);
Out of curiosity, why does the smbios table need to be copied when the pir and mptables do not?
$DEITY knows.
- wait_threads();
Minor, but there's no need for the additional wait_threads() call. It's only in the maininit() code path because of the possibility that CONFIG_THREAD_OPTIONROMS is set.
OK, will kill it.
[...]
+static u8 pic_mask[2] = { ~PIC1_IRQ2, ~0 };
+void VISIBLE32FLAT +handle_csm32(struct bregs *regs) +{
- ASSERT32FLAT();
- dprintf(3, "handle_csm16 regs %p AX=%04x (PIC %02x%02x)\n", regs, regs->ax,
pic_mask[0], pic_mask[1]);
- outb(pic_mask[0], PORT_PIC1_DATA);
- outb(pic_mask[1], PORT_PIC2_DATA);
Wow, that's ugly. Ideally OVMF would do that. But, I understand why it's needed. I think it would be better to make a pic_save() and pic_restore() which lived in pic.c/h though.
Yeah, this is horrid. I wonder if we could declare it to be a bug on the OVMF side that it *doesn't* save and restore the mask. At least between PrepareToBoot() and Boot() calls. Or maybe we're not *supposed* to have enabled interrupts until we finally get the Boot() call?
- 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;
Is there a plan to implement the 4/7/8 calls?
Eventually, once we work out what they're actually for and when they get called. So far I've just gone through and implemented the functions as and when I've seen OVMF actually call them...
- wait_threads();
Unless I'm missing something, the wait_threads() call shouldn't be needed.
Right. I'll kill it.
+int csm_bootprio_ata(struct pci_device *pci, int chanid, int slave)
Does UEFI really guarantee the order of the entries in the table (floppy, then ata, then pci)? Otherwise, the code could loop through the table (as csm_bootprio_pci does) and inspect DeviceType.
The BBS_TABLE has no 'lun' or equivalent field. You can't tell the difference between the various devices that might be attached to a given PCI bus/dev/func. This is insane and I'm trying to get it fixed. For now, the *only* way we can infer which IDE device they're talking about, is from its position in the array. This is not supported by the spec, but it's all we have for now.
+++ b/src/csm.h
Due to quirks in the SeaBIOS build (it textually includes files together at build) all headers really should have an include guard.
Also, I'd prefer not to put copyright notices on header files that just contain boilerplate definitions.
OK.
-#if CONFIG_PIRTABLE && !CONFIG_COREBOOT +#if CONFIG_PIRTABLE && !CONFIG_COREBOOT && !CONFIG_CSM
Ideally these constraints would be set in Kconfig.
OK. I think that just making PIRTABLE depend on !CSM should suffice, although I have no idea about the COREBOOT case.
[...]
--- a/src/romlayout.S +++ b/src/romlayout.S @@ -468,6 +468,43 @@ irqentryarg: DECL_IRQ_ENTRY hwpic1 DECL_IRQ_ENTRY hwpic2
+#if CONFIG_CSM
I'd avoid the #if and waste the few bytes of assembler - just make sure handle_csm32() has a "if (!CONFIG_CSM) return" test.
I think we also mentioned that this entry point didn't really need to be in the F-segment?
Will put together a new patch with most of the above fixed; thanks for the detailed review.
On Sat, 2013-02-02 at 20:21 -0500, Kevin O'Connor wrote:
Ideally this would be added to the existing README instead of adding a new file.
I couldn't see a clean way to merge the files together. Other than that, various fixes are now in my git tree at http://git.infradead.org/users/dwmw2/seabios.git
The VISIBLE32INIT cleanup for post.c wants some more thought, but it's late now. I'll work on that some more tomorrow, along with anything else I haven't yet fixed.
I've done it as incremental commits for now, but it probably makes sense for me to to back and rewrite history to incorporate these fixes in the original version?
From: David Woodhouse David.Woodhouse@intel.com
This removes 25KiB of unused cruft from the image, crucially making the difference between a 128KiB image (which works with OVMF) and a 256KiB image (which doesn't).
Not-yet-signed-off-by: David Woodhouse David.Woodhouse@intel.com --- src/pirtable.c | 2 +- src/romlayout.S | 6 ++++++ tools/layoutrom.py | 20 ++++++++++++-------- 3 files changed, 19 insertions(+), 9 deletions(-)
diff --git a/src/pirtable.c b/src/pirtable.c index 2ba70ee..3c06db1 100644 --- a/src/pirtable.c +++ b/src/pirtable.c @@ -94,7 +94,7 @@ struct pir_table PIR_TABLE __aligned(16) VAR16EXPORT = { void pirtable_setup(void) { - if (! CONFIG_PIRTABLE || CONFIG_CSM) + if (! CONFIG_PIRTABLE) return;
dprintf(3, "init PIR table\n"); diff --git a/src/romlayout.S b/src/romlayout.S index 0c1cfb4..3176067 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -366,6 +366,7 @@ entry_bios32: 2: popfl lretl
+#if !CONFIG_CSM // 32bit elf entry point EXPORTFUNC entry_elf entry_elf: @@ -381,6 +382,7 @@ entry_elf: movw %ax, %ss movl $BUILD_STACK_ADDR, %esp ljmpl $SEG32_MODE32_CS, $_cfunc32flat_handle_post +#endif
.code16gcc
@@ -526,9 +528,13 @@ entry_18:
ORG 0xe05b entry_post: +#if CONFIG_CSM + jmp entry_resume +#else cmpl $0, %cs:HaveRunPost // Check for resume/reboot jnz entry_resume ENTRY_INTO32 _cfunc32flat_handle_post // Normal entry point +#endif
ORG 0xe2c3 IRQ_ENTRY 02 diff --git a/tools/layoutrom.py b/tools/layoutrom.py index 75c49be..eecb141 100755 --- a/tools/layoutrom.py +++ b/tools/layoutrom.py @@ -353,7 +353,6 @@ def writeLinkerScripts(li, entrysym, genreloc, exportsyms, out16, out32seg, out3 # Write 32flat linker script sections32all = li.sections32flat + li.sections32init + li.sections32low sec32all_start = li.sec32low_start - entrysympos = entrysym.section.finalloc + entrysym.offset relocstr = "" if genreloc: # Generate relocations @@ -371,8 +370,10 @@ def writeLinkerScripts(li, entrysym, genreloc, exportsyms, out16, out32seg, out3 + strRelocs("_reloc_datalow", "code32flat_start", lowrelocs)) numrelocs = len(absrelocs + relrelocs + initrelocs + lowrelocs) sec32all_start -= numrelocs * 4 - out = outXRefs(sections32all, exportsyms=exportsyms) + """ - %s = 0x%x ; + out = outXRefs(sections32all, exportsyms=exportsyms) + if entrysym is not None: + out = out + "%s = 0x%x ;\n" % ( entrysym.name, entrysym.section.finalloc + entrysym.offset ) + out = out + """ _reloc_min_align = 0x%x ; datalow_base = 0x%x ; final_datalow_start = 0x%x ; @@ -393,8 +394,7 @@ def writeLinkerScripts(li, entrysym, genreloc, exportsyms, out16, out32seg, out3 *(.text16) code32flat_end = ABSOLUTE(.) ; } :text -""" % (entrysym.name, entrysympos, - li.sec32init_align, +""" % (li.sec32init_align, li.datalow_base, li.final_sec32low_start, sec32all_start, @@ -405,12 +405,13 @@ def writeLinkerScripts(li, entrysym, genreloc, exportsyms, out16, out32seg, out3 li.sec32seg_start, li.sec16_start) out = COMMONHEADER + out + COMMONTRAILER + """ -ENTRY(%s) PHDRS { text PT_LOAD AT ( code32flat_start ) ; } -""" % (entrysym.name,) +""" + if entrysym is not None: + out = out + "\nENTRY(%s)\n" % entrysym.name outfile = open(out32flat, 'wb') outfile.write(out) outfile.close() @@ -638,7 +639,10 @@ def main(): li = doLayout(sections, genreloc)
# Write out linker script files. - entrysym = info16[1]['entry_elf'] + if 'entry_elf' in info16[1]: + entrysym = info16[1]['entry_elf'] + else: + entrysym = None writeLinkerScripts(li, entrysym, genreloc, exportsyms, out16, out32seg, out32flat)
if __name__ == '__main__':
On Mon, Jan 28, 2013 at 04:23:46PM +0000, David Woodhouse wrote:
From: David Woodhouse David.Woodhouse@intel.com
This removes 25KiB of unused cruft from the image, crucially making the difference between a 128KiB image (which works with OVMF) and a 256KiB image (which doesn't).
[...]
+#if !CONFIG_CSM // 32bit elf entry point EXPORTFUNC entry_elf entry_elf:
Instead of adding #if statements to the assembler one can add a "if (CONFIG_CSM) return" to handle_post(). (Or, even better would be to add "if (!CONFIG_QEMU) return" to handle_post).
-Kevin
On Mon, 2013-01-28 at 16:23 +0000, David Woodhouse wrote:
I haven't quite finished going through the corporate bureaucracy for releasing this, so it's for review only.
Now done.
s/Not-yet-signed-off-by/Signed-off-by/