Changes from v1: - Make CONFIG_CSM a top-level build target in parallel with COREBOOT/QEMU. - More Kconfig cleanup. - Add generic find_pmtimer() function to find the pmtimer from ACPI tables. - Make Xen and coreboot builds both use find_pmtimer(). - Merge E820 table one entry at a time instead of wholesale copy. - Add pic_save_mask() and pic_restore_mask() functions. - Less intrusive size reduction for handle_post(). - Various other cleanups.
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
Signed-off-by: David Woodhouse David.Woodhouse@intel.com --- src/post.c | 10 +++++----- src/post.h | 10 ++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 src/post.h
diff --git a/src/post.c b/src/post.c index dbf4944..ec014c0 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 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 device_hardware_setup(void) { usb_setup(); @@ -252,7 +252,7 @@ platform_hardware_setup(void) biostable_setup(); }
-static void +void 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 reloc_preinit(void) { if (!CONFIG_RELOCATE_INIT) diff --git a/src/post.h b/src/post.h new file mode 100644 index 0000000..5a5b10f --- /dev/null +++ b/src/post.h @@ -0,0 +1,10 @@ +#ifndef __POST_H +#define __POST_H + +void interface_init(void); +void device_hardware_setup(void); +void prepareboot(void); +void startBoot(void); +void reloc_preinit(void); + +#endif // __POST_H
From: David Woodhouse David.Woodhouse@intel.com
I want to do this too, and can't bring myself to introduce yet another copy.
Signed-off-by: David Woodhouse David.Woodhouse@intel.com 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.
From: David Woodhouse David.Woodhouse@intel.com
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.
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
With CSM (and maybe coreboot) we'll want to find the pmtimer from the ACPI tables, instead of knowing where it is and *putting* it into the ACPI tables.
Extract the first part of the existing find_resume_vector() function into a find_fadt() function, and use it from both find_resume_vector() and our new find_pmtimer().
Signed-off-by: David Woodhouse David.Woodhouse@intel.com --- src/acpi.c | 46 ++++++++++++++++++++++++++++++++++------------ src/acpi.h | 1 + 2 files changed, 35 insertions(+), 12 deletions(-)
diff --git a/src/acpi.c b/src/acpi.c index 03cda34..d4fe92e 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -889,16 +889,16 @@ acpi_setup(void) dprintf(1, "ACPI tables: RSDP=%p RSDT=%p\n", rsdp, rsdt); }
-u32 -find_resume_vector(void) +static struct fadt_descriptor_rev1 * +find_fadt(void) { dprintf(4, "rsdp=%p\n", RsdpAddr); if (!RsdpAddr || RsdpAddr->signature != RSDP_SIGNATURE) - return 0; + return NULL; struct rsdt_descriptor_rev1 *rsdt = (void*)RsdpAddr->rsdt_physical_address; dprintf(4, "rsdt=%p\n", rsdt); if (!rsdt || rsdt->signature != RSDT_SIGNATURE) - return 0; + return NULL; void *end = (void*)rsdt + rsdt->length; int i; for (i=0; (void*)&rsdt->table_offset_entry[i] < end; i++) { @@ -906,13 +906,35 @@ find_resume_vector(void) if (!fadt || fadt->signature != FACP_SIGNATURE) continue; dprintf(4, "fadt=%p\n", fadt); - struct facs_descriptor_rev1 *facs = (void*)fadt->firmware_ctrl; - dprintf(4, "facs=%p\n", facs); - if (! facs || facs->signature != FACS_SIGNATURE) - return 0; - // Found it. - dprintf(4, "resume addr=%d\n", facs->firmware_waking_vector); - return facs->firmware_waking_vector; + return fadt; } - return 0; + return NULL; +} + +u32 +find_resume_vector(void) +{ + struct fadt_descriptor_rev1 *fadt = find_fadt(); + if (!fadt) + return 0; + struct facs_descriptor_rev1 *facs = (void*)fadt->firmware_ctrl; + dprintf(4, "facs=%p\n", facs); + if (! facs || facs->signature != FACS_SIGNATURE) + return 0; + // Found it. + dprintf(4, "resume addr=%d\n", facs->firmware_waking_vector); + return facs->firmware_waking_vector; +} + +void +find_pmtimer(void) +{ + struct fadt_descriptor_rev1 *fadt = find_fadt(); + if (!fadt) + return; + u32 pm_tmr = fadt->pm_tmr_blk; + if (!pm_tmr) + return; + + pmtimer_setup(pm_tmr, 3579); } diff --git a/src/acpi.h b/src/acpi.h index 8bbf25c..e52470e 100644 --- a/src/acpi.h +++ b/src/acpi.h @@ -5,6 +5,7 @@
void acpi_setup(void); u32 find_resume_vector(void); +void find_pmtimer(void);
#define RSDP_SIGNATURE 0x2052545020445352LL // "RSD PTR "
From: David Woodhouse David.Woodhouse@intel.com
Signed-off-by: David Woodhouse David.Woodhouse@intel.com --- src/xen.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/src/xen.c b/src/xen.c index c9759f0..2e6849c 100644 --- a/src/xen.c +++ b/src/xen.c @@ -10,6 +10,7 @@ #include "memmap.h" // add_e820 #include "types.h" // ASM32FLAT #include "util.h" // copy_acpi_rsdp +#include "acpi.h" // find_pmtimer
#define INFO_PHYSICAL_ADDRESS 0x00001000
@@ -120,6 +121,8 @@ void xen_biostable_setup(void) dprintf(1, "xen: copy BIOS tables...\n"); for (i=0; i<info->tables_nr; i++) copy_table(tables[i]); + + find_pmtimer(); }
void xen_ramsize_preinit(void)
From: David Woodhouse David.Woodhouse@intel.com
Signed-off-by: David Woodhouse David.Woodhouse@intel.com --- src/Kconfig | 1 - src/coreboot.c | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/Kconfig b/src/Kconfig index 0b112ed..43046c5 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -239,7 +239,6 @@ menu "Hardware support" help Initialize the Memory Type Range Registers (on emulators). config PMTIMER - depends on QEMU bool "Use ACPI timer" default y help diff --git a/src/coreboot.c b/src/coreboot.c index 5d013cf..7855703 100644 --- a/src/coreboot.c +++ b/src/coreboot.c @@ -12,7 +12,7 @@ #include "boot.h" // boot_add_cbfs #include "disk.h" // MAXDESCSIZE #include "config.h" // CONFIG_* - +#include "acpi.h" // find_pmtimer
/**************************************************************** * Memory map @@ -219,6 +219,8 @@ coreboot_biostable_setup(void) if (m->type == CB_MEM_TABLE) scan_tables(m->start, m->size); } + + find_pmtimer(); }
From: David Woodhouse David.Woodhouse@intel.com
CONFIG_PIRTABLE, along with various other BIOS tables, is only selectable if CONFIG_QEMU is selected. QEMU/COREBOOT/CSM is a choice, so you can't enable CONFIG_PIRTABLE if you've selected COREBOOT or CSM. So kill the excessive #if check for COREBOOT.
Signed-off-by: David Woodhouse David.Woodhouse@intel.com --- src/pirtable.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/pirtable.c b/src/pirtable.c index 62b62b8..8b79791 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 struct pir_table PIR_TABLE __aligned(16) VAR16EXPORT = { .pir = { .version = 0x0100, @@ -89,7 +89,7 @@ struct pir_table PIR_TABLE __aligned(16) VAR16EXPORT = { }, } }; -#endif // CONFIG_PIRTABLE && !CONFIG_COREBOOT +#endif // CONFIG_PIRTABLE
void pirtable_setup(void)
From: David Woodhouse David.Woodhouse@intel.com
cf. http://lists.gnu.org/archive/html/qemu-devel/2013-01/msg03650.html
Signed-off-by: David Woodhouse David.Woodhouse@intel.com --- src/Kconfig | 7 +++++++ src/optionroms.c | 2 ++ 2 files changed, 9 insertions(+)
diff --git a/src/Kconfig b/src/Kconfig index 43046c5..b9206e5 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -285,6 +285,13 @@ menu "BIOS interfaces" default y help Support finding and running option roms during POST. + config PERMIT_UNALIGNED_PCIROM + bool "Allow broken PCI option ROMs with unaligned PCIR table" + default n + help + Support initialising PCI ROMs which violate the spec by having + their PCI information at an unaligned offset, and which may not + be accepted by other firmwares. config OPTIONROMS_DEPLOYED depends on OPTIONROMS bool "Option roms are already at 0xc0000-0xf0000" diff --git a/src/optionroms.c b/src/optionroms.c index c9e7d7b..99c4135 100644 --- a/src/optionroms.c +++ b/src/optionroms.c @@ -107,6 +107,8 @@ static struct pci_data * get_pci_rom(struct rom_header *rom) { struct pci_data *pd = (void*)((u32)rom + rom->pcioffset); + if ((rom->pcioffset & 3) && !CONFIG_PERMIT_UNALIGNED_PCIROM) + return NULL; if (pd->signature != PCI_ROM_SIGNATURE) return NULL; return pd;
From: David Woodhouse David.Woodhouse@intel.com
This is under a BSD licence so it's fine to import directly.
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
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.
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.
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..f141f8b 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_csm' 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_csm'].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
CSM will (unfortunately) need to use these.
Signed-off-by: David Woodhouse David.Woodhouse@intel.com --- src/pic.c | 16 ++++++++++++++++ src/pic.h | 2 ++ 2 files changed, 18 insertions(+)
diff --git a/src/pic.c b/src/pic.c index 8992a8b..669d670 100644 --- a/src/pic.c +++ b/src/pic.c @@ -50,3 +50,19 @@ handle_hwpic2(struct bregs *regs) dprintf(DEBUG_ISR_hwpic2, "handle_hwpic2 irq=%x\n", get_pic2_isr()); eoi_pic2(); } + +u8 saved_pic_mask[2] = { ~PIC1_IRQ2, ~0 }; + +void +pic_save_mask(void) +{ + saved_pic_mask[0] = inb(PORT_PIC1_DATA); + saved_pic_mask[1] = inb(PORT_PIC2_DATA); +} + +void +pic_restore_mask(void) +{ + outb(saved_pic_mask[0], PORT_PIC1_DATA); + outb(saved_pic_mask[1], PORT_PIC2_DATA); +} diff --git a/src/pic.h b/src/pic.h index c75af3e..0ea5622 100644 --- a/src/pic.h +++ b/src/pic.h @@ -93,5 +93,7 @@ enable_hwirq(int hwirq, struct segoff_s func)
void set_pics(u8 irq0, u8 irq8); void pic_setup(void); +void pic_save_mask(void); +void pic_restore_mask(void);
#endif // pic.h
From: David Woodhouse David.Woodhouse@intel.com
Signed-off-by: David Woodhouse David.Woodhouse@intel.com --- Makefile | 2 +- README.CSM | 21 ++++ src/Kconfig | 19 ++-- src/boot.c | 7 ++ src/csm.c | 289 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/csm.h | 18 ++++ src/pmm.c | 19 ++++ src/romlayout.S | 35 +++++++ src/util.h | 2 + 9 files changed, 405 insertions(+), 7 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..ea71846 --- /dev/null +++ b/README.CSM @@ -0,0 +1,21 @@ +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, to prevent it from marking the region from +0xC0000-0xFFFFF as read-only before invoking our Legacy16Boot method. See +http://www.sourceforge.net/mailarchive/forum.php?thread_name=50FD7290.906000... + diff --git a/src/Kconfig b/src/Kconfig index b9206e5..f07cd71 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -18,6 +18,12 @@ choice help Configure as QEMU bios.
+ config CSM + bool "Build as Compatibilty Support Module for EFI BIOS" + help + Configure to be used by EFI firmware as Compatibility Support + module (CSM) to provide legacy BIOS services. + endchoice
config XEN @@ -118,25 +124,25 @@ menu "Hardware support" help Support for AHCI disk code. config VIRTIO_BLK - depends on DRIVES && QEMU + depends on DRIVES && !COREBOOT bool "virtio-blk controllers" default y help Support boot from virtio-blk storage. config VIRTIO_SCSI - depends on DRIVES && QEMU + depends on DRIVES && !COREBOOT bool "virtio-scsi controllers" default y help Support boot from virtio-scsi storage. config ESP_SCSI - depends on DRIVES && QEMU + depends on DRIVES && !COREBOOT bool "AMD PCscsi controllers" default y help Support boot from AMD PCscsi storage. config LSI_SCSI - depends on DRIVES && QEMU + depends on DRIVES && !COREBOOT bool "lsi53c895a scsi controllers" default y help @@ -281,6 +287,7 @@ menu "BIOS interfaces" help Support PnP BIOS entry point. config OPTIONROMS + depends on !CSM bool "Option ROMS" default y help @@ -302,12 +309,12 @@ menu "BIOS interfaces" Bochs or QEMU versions older than 0.12. config PMM depends on OPTIONROMS - bool "PMM interface" + bool "PMM interface" if !CSM default y help Support Post Memory Manager (PMM) entry point. config BOOT - bool "Boot interface" + bool "Boot interface" if !CSM default y help Support int 19/18 system bootup support. diff --git a/src/boot.c b/src/boot.c index 3bafa5a..85d5051 100644 --- a/src/boot.c +++ b/src/boot.c @@ -14,6 +14,7 @@ #include "paravirt.h" // qemu_cfg_show_boot_menu #include "pci.h" // pci_bdf_to_* #include "usb.h" // struct usbdevice_s +#include "csm.h" // csm_bootprio_*
/**************************************************************** @@ -120,6 +121,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 +147,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 +163,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/csm.c b/src/csm.c new file mode 100644 index 0000000..c453ebd --- /dev/null +++ b/src/csm.c @@ -0,0 +1,289 @@ +// 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" + +struct rsdp_descriptor VAR32FLATVISIBLE __aligned(16) csm_rsdp; + +EFI_COMPATIBILITY16_TABLE csm_compat_table VAR32FLATVISIBLE __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, +}; + + +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_preinit(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 VISIBLE32INIT +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 VISIBLE32INIT +handle_csm_0002(struct bregs *regs) +{ + dprintf(3, "PrepareToBoot table %04x:%04x\n", regs->es, regs->bx); + + struct e820entry *p = (void *)csm_compat_table.E820Pointer; + int i; + for (i=0; i < csm_compat_table.E820Length / sizeof(struct e820entry); i++) + add_e820(p[i].start, p[i].size, p[i].type); + + 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()... and find_pmtimer() + if (csm_rsdp.signature == RSDP_SIGNATURE) { + RsdpAddr = &csm_rsdp; + dprintf(3, "CSM ACPI RSDP at %p\n", RsdpAddr); + + find_pmtimer(); + } + + // 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(); + + interactive_bootmenu(); + + prepareboot(); + + regs->ax = 0; +} + +/* Boot */ +void VISIBLE32INIT +handle_csm_0003(struct bregs *regs) +{ + dprintf(3, "Boot\n"); + + startBoot(); + + regs->ax = 1; +} + +/* Legacy16DispatchOprom */ +void VISIBLE32INIT +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 VISIBLE32INIT +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; + } +} + +void VISIBLE32FLAT +handle_csm(struct bregs *regs) +{ + ASSERT32FLAT(); + + if (!CONFIG_CSM) + return; + + dprintf(3, "handle_csm16 regs %p AX=%04x\n", regs, regs->ax); + + pic_restore_mask(); + + 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; + } + + pic_save_mask(); + + dprintf(3, "handle_csm16 returning AX=%04x\n", regs->ax); +} + +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; +} diff --git a/src/csm.h b/src/csm.h new file mode 100644 index 0000000..77e5bf0 --- /dev/null +++ b/src/csm.h @@ -0,0 +1,18 @@ +#ifndef __CSM_H +#define __CSM_H + +#include "types.h" +#include "pci.h" + +#define UINT8 u8 +#define UINT16 u16 +#define UINT32 u32 + +// 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); + +#include "LegacyBios.h" + +#endif // __CSM_H diff --git a/src/pmm.c b/src/pmm.c index 0dbc86e..eb29a64 100644 --- a/src/pmm.c +++ b/src/pmm.c @@ -256,6 +256,25 @@ malloc_preinit(void) } }
+void +csm_malloc_preinit(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..aebe2df 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -384,6 +384,41 @@ entry_elf:
.code16gcc
+ EXPORTFUNC entry_csm +entry_csm: + 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_csm, %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 + lretw +
/**************************************************************** * Interrupt entry points diff --git a/src/util.h b/src/util.h index 84915ed..f486c85 100644 --- a/src/util.h +++ b/src/util.h @@ -368,6 +368,8 @@ 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_preinit(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);
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).
Signed-off-by: David Woodhouse David.Woodhouse@intel.com --- src/post.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/src/post.c b/src/post.c index ec014c0..2f3633d 100644 --- a/src/post.c +++ b/src/post.c @@ -389,6 +389,9 @@ doreloc(void) void VISIBLE32FLAT handle_post(void) { + if (CONFIG_CSM) + return; + debug_serial_preinit(); dprintf(1, "Start bios (version %s)\n", VERSION);
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...
Signed-off-by: David Woodhouse David.Woodhouse@intel.com --- src/LegacyBios.h | 11 +++++++++++ src/csm.c | 2 ++ 2 files changed, 13 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;
/// diff --git a/src/csm.c b/src/csm.c index c453ebd..352c3c2 100644 --- a/src/csm.c +++ b/src/csm.c @@ -28,6 +28,8 @@ EFI_COMPATIBILITY16_TABLE csm_compat_table VAR32FLATVISIBLE __aligned(16) = { .Compatibility16CallOffset = 0 /* Filled in by checkrom.py */, .OemIdStringPointer = (u32)"SeaBIOS", .AcpiRsdPtrPointer = (u32)&csm_rsdp, + .UmbStart = 0xe0, + .UmbEnd = 0xf0, };
On Tue, Feb 05, 2013 at 04:47:39PM +0000, David Woodhouse wrote:
Changes from v1: - Make CONFIG_CSM a top-level build target in parallel with COREBOOT/QEMU. - More Kconfig cleanup. - Add generic find_pmtimer() function to find the pmtimer from ACPI tables. - Make Xen and coreboot builds both use find_pmtimer(). - Merge E820 table one entry at a time instead of wholesale copy.
- Add pic_save_mask() and pic_restore_mask() functions.
- Less intrusive size reduction for handle_post().
- Various other cleanups.
Thanks. I pushed patches 2, 3, 5, and 11.
I think the reloc_init() change that I wrote (patch 1) may have been a mistake because of the VISIBLE32INIT proliferation that it causes. I put together an alternate approach which requires csm_return(). I still need to get an OVMF environment up to test this - I'll do that tomorrow. The main idea is in the attached patches.
I also rebased the above changes (with just the key csm parts) and pushed the series to a test location at: https://github.com/KevinOConnor/seabios/tree/csm-test-20130205 (This also has some changes to patch 14.)
-Kevin
On Tue, 2013-02-05 at 23:14 -0500, Kevin O'Connor wrote:
I still need to get an OVMF environment up to test this - I'll do that tomorrow.
Should go something like this...
git clone git://git.infradead.org/users/dwmw2/edk2.git cd edk2 make -C BaseTools . edksetup.sh ln -sf /where/your/seabios/out/bios.bin OvmfPkg/Csm/Csm16/Csm16.bin sed s/-melf_x86_64// -i Conf/tools_def.txt sed -e s%^ACTIVE_PLATFORM.*%ACTIVE_PLATFORM=OvmfPkg/OvmfPkgX64.dsc% \ -e s/^TARGET_ARCH.*/TARGET_ARCH=X64/ \ -e s/^TOOL_CHAIN_TAG.*/TOOL_CHAIN_TAG=GCC46/ \ -i Conf/target.txt build -D CSM_ENABLE -DDEBUG_ON_SERIAL_PORT qemu -bios Build/OvmfX64/DEBUG_GCC46/FV/OVMF.fd ...
I'll take a look at merging your csm_return() with the rest of my tree. Thanks.
On 02/06/13 12:06, David Woodhouse wrote:
On Tue, 2013-02-05 at 23:14 -0500, Kevin O'Connor wrote:
I still need to get an OVMF environment up to test this - I'll do that tomorrow.
(Sorry for not having yet begun the review, working on other stuff... But certainly don't wait for my review; I skimmed the series last night, and whatever I managed to understand at first glance didn't set off any alarms for me.)
Should go something like this...
git clone git://git.infradead.org/users/dwmw2/edk2.git cd edk2 make -C BaseTools . edksetup.sh ln -sf /where/your/seabios/out/bios.bin OvmfPkg/Csm/Csm16/Csm16.bin sed s/-melf_x86_64// -i Conf/tools_def.txt
If you're doing this for gcc-4.7, then please see http://sourceforge.net/mailarchive/forum.php?thread_name=1341995918-22888-1-git-send-email-pbonzini%40redhat.com&forum_name=edk2-buildtools-devel. The patch should be applied before running (sourcing) edksetup.sh, and then the sed command should not be necessary.
The patch has already been picked up by the edk2-buildtools project, which is expected to be synced into edk2 in 2013q1; http://sourceforge.net/mailarchive/forum.php?thread_name=CAFe8ug_bLMvKiUaSqU4g7_LCW-rxz5RyvVFPhKwmt-7ean_riQ@mail.gmail.com&forum_name=edk2-devel.
sed -e s%^ACTIVE_PLATFORM.*%ACTIVE_PLATFORM=OvmfPkg/OvmfPkgX64.dsc% \ -e s/^TARGET_ARCH.*/TARGET_ARCH=X64/ \ -e s/^TOOL_CHAIN_TAG.*/TOOL_CHAIN_TAG=GCC46/ \ -i Conf/target.txt
These can all be passed to the "build" utility (see build -h):
-p OvmfPkg/OvmfPkgX64.dsc \ -a X64 \ -t GCC47
(assuming you have the gcc47 patch from above).
I'd also recommend the following option, for a parallel build, 50% oversubscription:
-n $(( $(getconf _NPROCESSORS_ONLN) * 3 / 2 ))
build -D CSM_ENABLE -DDEBUG_ON_SERIAL_PORT
Finally, there's a wrapper script in "OvmfPkg/build.sh"; it accepts "-n", and sets up / detects the rest of the above for you. Using that (with the gcc47 patch), it should be only
git clone git://git.infradead.org/users/dwmw2/edk2.git cd edk2 # apply gcc47 patch if not yet in David's tree ln -sf /where/your/seabios/out/bios.bin OvmfPkg/Csm/Csm16/Csm16.bin OvmfPkg/build.sh \ -D CSM_ENABLE -D DEBUG_ON_SERIAL_PORT \ -n $(( $(getconf _NPROCESSORS_ONLN) * 3 / 2 ))
Thanks Laszlo
On Tue, 2013-02-05 at 23:14 -0500, Kevin O'Connor wrote:
I think the reloc_init() change that I wrote (patch 1) may have been a mistake because of the VISIBLE32INIT proliferation that it causes. I put together an alternate approach which requires csm_return().
Hm, there is strangeness here.
I disabled CONFIG_RELOCATE_INIT, and I made the Lock call in OVMF's LegacyRegion code a no-op so it's never actually locking it; just to eliminate certain classes of problem.
I also fixed your code as follows:
commit debcd72c34a6b8eba91c9157b15422d418fe8868 Author: David Woodhouse David.Woodhouse@intel.com Date: Wed Feb 6 13:25:34 2013 +0000
Fix handle_csm invocation to compensate for BUILD_BIOS_ADDR
Signed-off-by: David Woodhouse David.Woodhouse@intel.com
diff --git a/src/csm.c b/src/csm.c index 473d322..91a1a57 100644 --- a/src/csm.c +++ b/src/csm.c @@ -49,7 +49,8 @@ csm_maininit(struct bregs *regs) regs->ax = 0;
// Return directly to UEFI instead of unwinding stack. - csm_return(regs); + if (CONFIG_RELOCATE_INIT) + csm_return(regs); }
/* Legacy16InitializeYourself */ diff --git a/src/romlayout.S b/src/romlayout.S index 07d1645..cbe6b1c 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -385,7 +385,6 @@ entry_elf: .code16gcc
EXPORTFUNC entry_csm - .global csm_return entry_csm: // Backup register state pushfw @@ -405,15 +404,16 @@ entry_csm: movw %ax, %ss movl $BUILD_STACK_ADDR, %esp
- // Jump to 32bit mode and call handle_csm32(bregs) + // Jump to 32bit mode and call handle_csm(bregs) movl $(1f + BUILD_BIOS_ADDR), %edx jmp transition32 .code32 1: movl %ebx, %eax - calll _cfunc32flat_handle_csm + calll _cfunc32flat_handle_csm - BUILD_BIOS_ADDR movl $2f, %edx jmp transition16big
+ .global csm_return csm_return: movl %eax, %ebx movl $2f, %edx
It kind of works. Sometimes. But other times it just locks up in OVMF code at...
handle_csm16 regs 0x0004ffd4 AX=0001 Legacy16UpdateBbs table 480a:0008 MajorVersion 0000 MinorVersion 0000 AcpiTable 00000000 SmbiosTable 00000000 SmbiosTableLength 00000000 DevicePathType 0000 PciIrqMask 0000 NumberE820Entries 0000000c NumberBbsEntries 00000100 BBsTable 0004a1ea SmmTable 00000000 OsMemoryAbove1Mb 07a15000 UnconventionalDeviceTable 00000000 handle_csm16 returning AX=0000 enter handle_15: a=00002401 b=00000008 c=00000000 d=00000003 ds=0000 es=480a ss=4000 si=00000000 di=00000000 bp=00000000 sp=0000ffc6 cs=4f00 ip=0030 f=3002 Buffer: EFI DVD/CDROM Select Item: 0x19
This is most easily reproduced by pressing a key to enter the boot menu. And if I add '-d in_asm' or '-enable-kvm' to the qemu command line it's a lot *less* likely to trigger. I don't think I've *ever* seen it with KVM enabled in fact... but remember, the whole region should be *unlocked* so I don't know why.
If I then revert romlayout.S to the version I had in my tree (which obviously won't work with CONFIG_RELOCATE_INIT but as I said, I turned that off), everything works fine.
I'm using qemu-system-x86_64 v1.3.0 (the Fedora package).
On Wed, Feb 06, 2013 at 04:53:29PM +0000, David Woodhouse wrote:
On Tue, 2013-02-05 at 23:14 -0500, Kevin O'Connor wrote:
I think the reloc_init() change that I wrote (patch 1) may have been a mistake because of the VISIBLE32INIT proliferation that it causes. I put together an alternate approach which requires csm_return().
Hm, there is strangeness here.
I disabled CONFIG_RELOCATE_INIT, and I made the Lock call in OVMF's LegacyRegion code a no-op so it's never actually locking it; just to eliminate certain classes of problem.
I also fixed your code as follows:
[...]
It kind of works. Sometimes. But other times it just locks up in OVMF code at...
[...]
Buffer: EFI DVD/CDROM Select Item: 0x19
This is most easily reproduced by pressing a key to enter the boot menu. And if I add '-d in_asm' or '-enable-kvm' to the qemu command line it's a lot *less* likely to trigger. I don't think I've *ever* seen it with KVM enabled in fact... but remember, the whole region should be *unlocked* so I don't know why.
If I then revert romlayout.S to the version I had in my tree (which obviously won't work with CONFIG_RELOCATE_INIT but as I said, I turned that off), everything works fine.
Hi David,
I'm pretty sure I tracked this down. I had three bad errors in the patches I made (one you spotted, one was a rebase error, one was a missed consequence of csm_return). These can be fixed with the patch below.
With those fixes in place (and OVMF set to not write-protect ram), I can reliably reproduce your sporadic "Select Item: 0x19" failure. This failure looks to be the result of my changes to entry_csm to have it restore flags on exit. This has the effect of enabling irqs briefly before returning to OVMF. When I run QEMU with "-d in_asm,int,pcall" I see this pattern on failed boots:
0x00000000000fc303: pop %eax 0x00000000000fc305: add $0x4,%sp 0x00000000000fc308: popf
Servicing hardware INT=0x68 ---------------- IN: 0x00000000000fff53: iret
---------------- IN: 0x00000000000fc309: lret
I don't see the "INT=0x68" on successful boots. It looks like enabling the timer allows IRQs to fire that OVMF is expecting to see in its irq handler.
Restoring flags on exit is assuredly more correct, and if I move timer_setup() to the prepare-to-boot phase this problem goes away for me. So, I think this is more evidence that the timer can not be enabled in the init-yourself phase.
-Kevin
--- a/src/csm.c +++ b/src/csm.c @@ -49,6 +49,8 @@ csm_maininit(struct bregs *regs) regs->ax = 0;
// Return directly to UEFI instead of unwinding stack. + pic_save_mask(); + dprintf(3, "csm_maininit fast returning AX=%04x\n", regs->ax); csm_return(regs); }
diff --git a/src/pmm.c b/src/pmm.c index e432395..b3aa527 100644 --- a/src/pmm.c +++ b/src/pmm.c @@ -291,6 +291,10 @@ malloc_fixupreloc_init(void) zone->info->pprev = &zone->info; }
+ // 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); + // Add space free'd during relocation in f-segment to ZoneFSeg extern u8 code32init_end[]; if ((u32)code32init_end > BUILD_BIOS_ADDR) { diff --git a/src/romlayout.S b/src/romlayout.S index 07d1645..a9232a8 100644 --- a/src/romlayout.S +++ b/src/romlayout.S @@ -410,7 +410,7 @@ entry_csm: jmp transition32 .code32 1: movl %ebx, %eax - calll _cfunc32flat_handle_csm + calll _cfunc32flat_handle_csm - BUILD_BIOS_ADDR movl $2f, %edx jmp transition16big
On Wed, 2013-02-06 at 23:13 -0500, Kevin O'Connor wrote:
Restoring flags on exit is assuredly more correct, and if I move timer_setup() to the prepare-to-boot phase this problem goes away for me. So, I think this is more evidence that the timer can not be enabled in the init-yourself phase.
Yeah, I'll change that. Thanks.
On Thu, 2013-02-07 at 08:40 +0000, David Woodhouse wrote:
On Wed, 2013-02-06 at 23:13 -0500, Kevin O'Connor wrote:
Restoring flags on exit is assuredly more correct, and if I move timer_setup() to the prepare-to-boot phase this problem goes away for me. So, I think this is more evidence that the timer can not be enabled in the init-yourself phase.
Yeah, I'll change that. Thanks.
Ah, I see you already did. It breaks the pmtimer support though; we end up calling timer_setup() and thus setting cpu_khz *after* pmtimer_setup() has set it. Was that why you disabled CONFIG_PMTIMER for the CSM build in your tree? I've fixed that up in my tree now, as well as reinstating the pmtimer support for Xen and Coreboot builds.
With the ps2 init taking forever due to that bug, I also discovered that we really do need to call wait_threads() during the PrepareToBoot phase; I've put that back in too.
http://git.infradead.org/users/dwmw2/seabios.git as before.
On Thu, Feb 07, 2013 at 03:01:50PM +0000, David Woodhouse wrote:
On Thu, 2013-02-07 at 08:40 +0000, David Woodhouse wrote:
On Wed, 2013-02-06 at 23:13 -0500, Kevin O'Connor wrote:
Restoring flags on exit is assuredly more correct, and if I move timer_setup() to the prepare-to-boot phase this problem goes away for me. So, I think this is more evidence that the timer can not be enabled in the init-yourself phase.
Yeah, I'll change that. Thanks.
Ah, I see you already did. It breaks the pmtimer support though; we end up calling timer_setup() and thus setting cpu_khz *after* pmtimer_setup() has set it. Was that why you disabled CONFIG_PMTIMER for the CSM build in your tree? I've fixed that up in my tree now, as well as reinstating the pmtimer support for Xen and Coreboot builds.
Thanks. I rolled up your changes and my changes into a new patch 17 and pushed it out along with your patches 4, 6, 7, 13, 14 (modified) 15, and 16. In addition to the reloc changes and fixes we discussed, I modified the core csm patch (patch 17) to not depend on pmtimer and to remove some Kconfig changes. I wanted to merge the core CSM code and then add those on top.
So, at this point, I think still pending is: Kconfig changes, pmtimer, UmbStart/UmbEnd, and unaligned PCIR.
On these:
Kconfig - I'm not sure we should have a qemu vs coreboot vs csm selection as it's possible we can have qemu+csm (or even qemu+coreboot+csm) and I think Kconfig should reflect that reality. I'll put together a patch to demonstrate what I'm thinking.
pmtimer - the patches are fine - the coreboot/xen parts just need to be tested before merging. I may be able to test the coreboot part on my e350m1.
UmbStart/UmbEnd - I'd like to hear back from the OVMF team before merging this.
unaligned PCIR - I'm not sure we can merge this as it would break QEMU users with a current "lgpl vgabios".
-Kevin
On Thu, 2013-02-07 at 20:48 -0500, Kevin O'Connor wrote:
Kconfig - I'm not sure we should have a qemu vs coreboot vs csm selection as it's possible we can have qemu+csm (or even qemu+coreboot+csm) and I think Kconfig should reflect that reality. I'll put together a patch to demonstrate what I'm thinking.
CSM is theoretically supposed to be hardware-agnostic, so I was happy with it being orthogonal to QEMU. Wasn't that fairly much the idea with COREBOOT vs. QEMU too? It's more about "direct/native boot on QEMU" rather than "running on QEMU at all". Which is why the virtio drivers shouldn't depend on QEMU alone.
You could perhaps introduce a separate config option for 'running on QEMU at all', and *that* one wouldn't in part of the choice.
pmtimer - the patches are fine - the coreboot/xen parts just need to be tested before merging. I may be able to test the coreboot part on my e350m1.
Cool, thanks.
UmbStart/UmbEnd - I'd like to hear back from the OVMF team before merging this.
Yes, that makes sense. I've chased them up. Not really the OVMF team but the people who own the *spec* within Intel. Once the spec is fixed, OVMF can happily implement it.
unaligned PCIR - I'm not sure we can merge this as it would break QEMU users with a current "lgpl vgabios".
That's why I made it optional ;)
On Thu, 2013-02-07 at 20:48 -0500, Kevin O'Connor wrote:
So, at this point, I think still pending is: Kconfig changes, pmtimer, UmbStart/UmbEnd, and unaligned PCIR.
I've pushed these remaining changes, rebased and slightly retested, to my git tree. The pmtimer support still needs testing for Xen and Coreboot. And it wouldn't hurt to test find_resume_vector() either.
The pmtimer thing is just an optimisation, as is the pedantry about PCIR tables — when they don't work, I don't want it to be just *my* fault ;)
UmbStart/UmbEnd can wait until OVMF catches up, I agree — although in that case we ought to point people at a simple patch for OVMF that just disables the LegacyRegion->Lock completely. Like the one I sent you the other night. I note we aren't giving *any* build instructions at the moment; you dropped my README.CSM without merging it into README?
The real problem with the current tree is the Kconfig changes. What you've committed still doesn't let me enable the virtio-blk driver when I've configured it to build as CSM. And in fact I don't understand why you force those to be disabled for the coreboot case either, if you can be booted from coreboot under qemu.
See the final two patches in my git tree... I wouldn't mind getting these merged so that they're part of the *base* for your subsequent Kconfig changes.
commit 1c78b74a62a178050c1e9763b0943725a32ec060 Author: David Woodhouse David.Woodhouse@intel.com Date: Fri Feb 8 08:52:32 2013 +0000
Clean up Kconfig options for CSM
It makes no sense to turn CONFIG_OPTIONROMS on or off because we call directly into callrom() anyway. Likewise CONFIG_OPTIONROMS_DEPLOYED is never going to make any difference.
Also force CONFIG_BOOT to be enabled; we definitely need that to work.
Signed-off-by: David Woodhouse David.Woodhouse@intel.com
commit 3a98c83e12c719dfb5e2f6fd195068b23ac3b78a Author: David Woodhouse David.Woodhouse@intel.com Date: Fri Feb 8 08:11:18 2013 +0000
Enable virtio devices for CSM build
These shouldn't depend purely on CONFIG_QEMU, as CSM can be used under Qemu too. In fact, can't we boot via Coreboot under Qemu also? Why restrict these hardware drivers at all?
Signed-off-by: David Woodhouse David.Woodhouse@intel.com
diff --git a/src/Kconfig b/src/Kconfig index aa0e49e..459708c 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -124,25 +124,25 @@ menu "Hardware support" help Support for AHCI disk code. config VIRTIO_BLK - depends on DRIVES && QEMU + depends on DRIVES && !COREBOOT bool "virtio-blk controllers" default y help Support boot from virtio-blk storage. config VIRTIO_SCSI - depends on DRIVES && QEMU + depends on DRIVES && !COREBOOT bool "virtio-scsi controllers" default y help Support boot from virtio-scsi storage. config ESP_SCSI - depends on DRIVES && QEMU + depends on DRIVES && !COREBOOT bool "AMD PCscsi controllers" default y help Support boot from AMD PCscsi storage. config LSI_SCSI - depends on DRIVES && QEMU + depends on DRIVES && !COREBOOT bool "lsi53c895a scsi controllers" default y help @@ -287,7 +287,7 @@ menu "BIOS interfaces" help Support PnP BIOS entry point. config OPTIONROMS - bool "Option ROMS" + bool "Option ROMS" if !CSM default y help Support finding and running option roms during POST. @@ -300,7 +300,7 @@ menu "BIOS interfaces" be accepted by other firmwares. config OPTIONROMS_DEPLOYED depends on OPTIONROMS - bool "Option roms are already at 0xc0000-0xf0000" + bool "Option roms are already at 0xc0000-0xf0000" if !CSM default n help Select this if option ROMs are already copied to @@ -313,7 +313,7 @@ menu "BIOS interfaces" help Support Post Memory Manager (PMM) entry point. config BOOT - bool "Boot interface" + bool "Boot interface" if !CSM default y help Support int 19/18 system bootup support.
On Fri, 2013-02-08 at 09:06 +0000, David Woodhouse wrote:
my git tree. The pmtimer support still needs testing for Xen and
I've not been following this thread all that closely, what specifically should I be testing on Xen? Just starting a guest which uses pmtimer under latest SeaBIOS git and checking it works OK?
Ian.
On Fri, 2013-02-08 at 09:51 +0000, Ian Campbell wrote:
I've not been following this thread all that closely, what specifically should I be testing on Xen? Just starting a guest which uses pmtimer under latest SeaBIOS git and checking it works OK?
It's not merged yet; it's at http:// and git://git.infradead.org/users/dwmw2/seabios.git
Specifically commit 5ba80fac ("Add find_pmtimer() function") and 56014611 ("Use find_pmtimer() after copying Xen ACPI tables").
Previously, SeaBIOS wouldn't use the pmtimer for its own timing purposes unless it actually set it up for itself and created its *own* ACPI tables.
I've made it look through the ACPI tables which are provided to it by Coreboot/Xen/CSM and *find* the pmtimer there, and use it.
So with debug enabled you should see a line something like 'Using pmtimer, ioport 0xb008, freq 3579 kHz' and then lots of 'pmtimer: 0:16408743' as it actually gets read, and the debug statement in pmtimer_get() gets invoked.
And clock stuff should work correctly.
Thanks.
On Fri, 2013-02-08 at 10:33 +0000, David Woodhouse wrote:
On Fri, 2013-02-08 at 09:51 +0000, Ian Campbell wrote:
I've not been following this thread all that closely, what specifically should I be testing on Xen? Just starting a guest which uses pmtimer under latest SeaBIOS git and checking it works OK?
It's not merged yet; it's at http:// and git://git.infradead.org/users/dwmw2/seabios.git
Thanks I ran a build with this and I had to select between "Coreboot", "Qemu" or "CSM". Xen depends on !Coreboot so I probably ought to select the Qemu option but it seems like the Qemu option is misnamed, unless there are other things under the Qemu umbrella perhaps "Virtualised (Qemu or Xen)"?
Specifically commit 5ba80fac ("Add find_pmtimer() function") and 56014611 ("Use find_pmtimer() after copying Xen ACPI tables").
Previously, SeaBIOS wouldn't use the pmtimer for its own timing purposes unless it actually set it up for itself and created its *own* ACPI tables.
I've made it look through the ACPI tables which are provided to it by Coreboot/Xen/CSM and *find* the pmtimer there, and use it.
So with debug enabled you should see a line something like 'Using pmtimer, ioport 0xb008, freq 3579 kHz' and then lots of 'pmtimer: 0:16408743' as it actually gets read, and the debug statement in pmtimer_get() gets invoked.
Running with your HEAD (1c78b74) I get: XEN) HVM51: Invoking SeaBIOS ... (XEN) io.c:201:d51 MMIO emulation failed @ 0008:ffff1474: 00 80 2d c0 c4 82 ff ff 18 7a (XEN) hvm.c:1237:d51 Triple fault on VCPU0 - invoking HVM system reset.
I don't see this with rel-1.7.2. Bisecting fingers commit 6ca0460fbb8ecfa5d42c8928b7ee71f20d0cffdb Author: Kevin O'Connor kevin@koconnor.net Date: Mon Jan 21 11:38:49 2013 -0500
POST: Reorganize post entry and "preinit" functions.
But it doesn't look like this changes the order of anything,
I'm not quite sure what address ffff1474 is, if it corresponds to address f1474 in SeaBIOS then it corresponds to: 000f1474 <__make_bios_writable_intel>: f1474: 55 push %ebp f1475: 57 push %edi f1476: 56 push %esi f1477: 53 push %ebx f1478: 83 ec 0c sub $0xc,%esp f147b: 89 d3 mov %edx,%ebx f147d: 0f b7 e8 movzwl %ax,%ebp f1480: c1 e5 08 shl $0x8,%ebp
but that doesn't correspond to the instruction stream bytes in the emu failed message, I also wouldn't expect a stack push to result in MMIO but stranger things have happened ;-). Lastly that call seems to be after the SeaBIOS banner should have been printed.
But, I can't find those bytes anywhere else in the objdump. 00 80 2d seems to be an add of ax and [bx] + 0x2d
And clock stuff should work correctly.
Clock stuff in SeaBIOS or in the eventual kernel?
Ian.
Logs, SeaBIOS starts after "Invoking SeaBIOS ..."
On Fri, 2013-02-08 at 14:45 +0000, Ian Campbell wrote:
I don't see this with rel-1.7.2. Bisecting fingers commit 6ca0460fbb8ecfa5d42c8928b7ee71f20d0cffdb Author: Kevin O'Connor kevin@koconnor.net Date: Mon Jan 21 11:38:49 2013 -0500
POST: Reorganize post entry and "preinit" functions.
But it doesn't look like this changes the order of anything,
Except Xen is entering via handle_post not handle_elf, so it does change something, specifically xen_preinit() isn't called before make_bios_writable so the usingXen in there doesn't trigger. Xen (actually hvmloader) launches SeaBIOS with "ljmp $0xf000,$0xfff0" so I think handle_post is the expected landing point.
The patch below fixes this issue for me, however even with that and CONFIG_DEBUG_LEVEL=2 I still don't see the expected "Using pmtimer" message. Full messages are below, SeaBIOS starts at "Invoking SeaBIOS ..."
Linux does see the PM-Timer: ACPI: PM-Timer IO Port: 0xb008 Although it doesn't use it because it prefers the Xen virtual timers.
The patch:
diff --git a/src/post.c b/src/post.c index ae5e923..78ef4b1 100644 --- a/src/post.c +++ b/src/post.c @@ -315,9 +315,6 @@ dopost(void) // Make sure legacy DMA isn't running. dma_preinit();
- // Check if we are running under Xen. - xen_preinit(); - // Detect ram and setup internal malloc. qemu_cfg_preinit(); if (CONFIG_COREBOOT) @@ -357,6 +354,9 @@ handle_post(void) { debug_splash();
+ // Check if we are running under Xen. + xen_preinit(); + // Allow writes to modify bios area (0xf0000) make_bios_writable();
Logs:
(XEN) HVM164: HVM Loader (XEN) HVM164: Detected Xen v4.3-unstable (XEN) HVM164: Xenbus rings @0xfeffc000, event channel 4 (XEN) HVM164: System requested SeaBIOS (XEN) HVM164: CPU speed is 2400 MHz (XEN) HVM164: PCI-ISA link 0 routed to IRQ5 (XEN) HVM164: PCI-ISA link 1 routed to IRQ10 (XEN) HVM164: PCI-ISA link 2 routed to IRQ11 (XEN) HVM164: PCI-ISA link 3 routed to IRQ5 (XEN) HVM164: pci dev 01:3 INTA->IRQ10 (XEN) HVM164: pci dev 03:0 INTA->IRQ5 (XEN) HVM164: pci dev 04:0 INTA->IRQ5 (XEN) HVM164: pci dev 02:0 bar 10 size lx: 02000000 (XEN) HVM164: pci dev 03:0 bar 14 size lx: 01000000 (XEN) HVM164: pci dev 04:0 bar 10 size lx: 00020000 (XEN) HVM164: pci dev 04:0 bar 30 size lx: 00020000 (XEN) HVM164: pci dev 02:0 bar 30 size lx: 00010000 (XEN) HVM164: pci dev 02:0 bar 14 size lx: 00001000 (XEN) HVM164: pci dev 03:0 bar 10 size lx: 00000100 (XEN) HVM164: pci dev 04:0 bar 14 size lx: 00000040 (XEN) HVM164: pci dev 01:1 bar 20 size lx: 00000010 (XEN) HVM164: Multiprocessor initialisation: (XEN) HVM164: - CPU0 ... 36-bit phys ... fixed MTRRs ... var MTRRs [2/8] ... done. (XEN) HVM164: - CPU1 ... 36-bit phys ... fixed MTRRs ... var MTRRs [2/8] ... done. (XEN) HVM164: Testing HVM environment: (XEN) HVM164: - REP INSB across page boundaries ... passed (XEN) HVM164: - GS base MSRs and SWAPGS ... passed (XEN) HVM164: Passed 2 of 2 tests (XEN) HVM164: Writing SMBIOS tables ... (XEN) HVM164: Loading SeaBIOS ... (XEN) HVM164: Creating MP tables ... (XEN) HVM164: Loading ACPI ... (XEN) HVM164: vm86 TSS at fc00a080 (XEN) HVM164: BIOS map: (XEN) HVM164: 10000-100d3: Scratch space (XEN) HVM164: e0000-fffff: Main BIOS (XEN) HVM164: E820 table: (XEN) HVM164: [00]: 00000000:00000000 - 00000000:000a0000: RAM (XEN) HVM164: HOLE: 00000000:000a0000 - 00000000:000e0000 (XEN) HVM164: [01]: 00000000:000e0000 - 00000000:00100000: RESERVED (XEN) HVM164: [02]: 00000000:00100000 - 00000000:07800000: RAM (XEN) HVM164: HOLE: 00000000:07800000 - 00000000:fc000000 (XEN) HVM164: [03]: 00000000:fc000000 - 00000001:00000000: RESERVED (XEN) HVM164: Invoking SeaBIOS ... (XEN) HVM164: SeaBIOS (version rel-1.7.2-18-g6ca0460-dirty-20130208_144531-cosworth) (XEN) HVM164: (XEN) HVM164: Found Xen hypervisor signature at 40000000 (XEN) HVM164: xen: copy e820... (XEN) HVM164: Ram Size=0x07800000 (0x0000000000000000 high) (XEN) HVM164: Relocating low data from 0x000e1b60 to 0x000ef740 (size 2164) (XEN) HVM164: Relocating init from 0x000e23d4 to 0x077e22f0 (size 56296) (XEN) HVM164: CPU Mhz=2402 (XEN) HVM164: Found 7 PCI devices (max PCI bus is 00) (XEN) HVM164: Allocated Xen hypercall page at 77ff000 (XEN) HVM164: Detected Xen v4.3-unstable (XEN) HVM164: Found 2 cpu(s) max supported 2 cpu(s) (XEN) HVM164: xen: copy BIOS tables... (XEN) HVM164: Copying SMBIOS entry point from 0x00010010 to 0x000fdb10 (XEN) HVM164: Copying MPTABLE from 0xfc001170/fc001180 to 0x000fda10 (XEN) HVM164: Copying PIR from 0x00010030 to 0x000fd990 (XEN) HVM164: Copying ACPI RSDP from 0x000100b0 to 0x000fd960 (XEN) HVM164: Scan for VGA option rom (XEN) HVM164: Running option rom at c000:0003 (XEN) HVM164: Turning on vga text mode console (XEN) HVM164: SeaBIOS (version rel-1.7.2-18-g6ca0460-dirty-20130208_144531-cosworth) (XEN) HVM164: Machine UUID 5f1a6b33-97ac-4503-b38a-5ee17030e4fd (XEN) HVM164: /077e0000\ Start thread (XEN) HVM164: Found 1 lpt ports (XEN) HVM164: Found 1 serial ports (XEN) HVM164: Searching bootorder for: /pci@i0cf8/isa@1/fdc@03f0/floppy@0 (XEN) HVM164: ATA controller 1 at 1f0/3f4/c140 (irq 14 dev 9) (XEN) HVM164: /077df000\ Start thread (XEN) HVM164: ATA controller 2 at 170/374/c148 (irq 15 dev 9) (XEN) HVM164: /077de000\ Start thread (XEN) HVM164: |077df000| ata0-0: QEMU HARDDISK ATA-7 Hard-Disk (8192 MiBytes) (XEN) HVM164: |077df000| Searching bootorder for: /pci@i0cf8/*@1,1/drive@0/disk@0 (XEN) HVM164: \077df000/ End thread (XEN) HVM164: |077de000| DVD/CD [ata1-0: QEMU DVD-ROM ATAPI-4 DVD/CD] (XEN) HVM164: |077de000| Searching bootorder for: /pci@i0cf8/*@1,1/drive@1/disk@0 (XEN) HVM164: \077de000/ End thread (XEN) HVM164: |077e0000| PS2 keyboard initialized (XEN) HVM164: \077e0000/ End thread (XEN) HVM164: All threads complete. (XEN) HVM164: Scan for option roms (XEN) HVM164: Running option rom at c900:0003 (XEN) HVM164: pmm call arg1=1 (XEN) HVM164: pmm call arg1=0 (XEN) HVM164: pmm call arg1=1 (XEN) HVM164: pmm call arg1=0 (XEN) HVM164: Searching bootorder for: /pci@i0cf8/*@4 (XEN) HVM164: (XEN) HVM164: Press F12 for boot menu. (XEN) HVM164: (XEN) HVM164: Searching bootorder for: HALT (XEN) HVM164: drive 0x000fd8e0: PCHS=16383/16/63 translation=lba LCHS=1024/255/63 s=16777216 (XEN) HVM164: (XEN) HVM164: Space available for UMB: 000ca000-000ee800 (XEN) HVM164: Returned 61440 bytes of ZoneHigh (XEN) HVM164: e820 map has 6 items: (XEN) HVM164: 0: 0000000000000000 - 000000000009fc00 = 1 RAM (XEN) HVM164: 1: 000000000009fc00 - 00000000000a0000 = 2 RESERVED (XEN) HVM164: 2: 00000000000f0000 - 0000000000100000 = 2 RESERVED (XEN) HVM164: 3: 0000000000100000 - 00000000077ff000 = 1 RAM (XEN) HVM164: 4: 00000000077ff000 - 0000000007800000 = 2 RESERVED (XEN) HVM164: 5: 00000000fc000000 - 0000000100000000 = 2 RESERVED (XEN) HVM164: enter handle_19: (XEN) HVM164: NULL (XEN) HVM164: Booting from ROM... (XEN) HVM164: Booting from c900:0372 (XEN) HVM164: enter handle_12: (XEN) HVM164: a=dced0200 b=00000030 c=00030000 d=00090027 ds=0000 es=0000 ss=9cf2 (XEN) HVM164: si=00002e10 di=0000b7b6 bp=00032ca2 sp=00002ca2 cs=0000 ip=7eef f=0246 (XEN) HVM164: unimplemented handle_16XX:231: (XEN) HVM164: a=00000305 b=00000000 c=00000000 d=00000000 ds=3000 es=3000 ss=3000 (XEN) HVM164: si=00000000 di=00000000 bp=00000000 sp=0000f70c cs=3000 ip=05f0 f=0003 (XEN) HVM164: unimplemented handle_15XX:338: (XEN) HVM164: a=0000e980 b=00000000 c=00000000 d=47534943 ds=3000 es=3000 ss=3000 (XEN) HVM164: si=00000000 di=00000000 bp=00000000 sp=0000f70c cs=3000 ip=05f0 f=0003
On Fri, 2013-02-08 at 14:50 +0000, Ian Campbell wrote:
even with that and CONFIG_DEBUG_LEVEL=2 I still don't see the expected "Using pmtimer" message.
pci_setup() doesn't run on coreboot or Xen (because they do PCI setup themselves first), and AFAICT this is the path which leads to the call to pmtimer_setup(), so I don't think pmtimer will be initialised on either Xen or coreboot.
Ian.
On Fri, 2013-02-08 at 15:27 +0000, Ian Campbell wrote:
On Fri, 2013-02-08 at 14:50 +0000, Ian Campbell wrote:
even with that and CONFIG_DEBUG_LEVEL=2 I still don't see the expected "Using pmtimer" message.
pci_setup() doesn't run on coreboot or Xen (because they do PCI setup themselves first), and AFAICT this is the path which leads to the call to pmtimer_setup(), so I don't think pmtimer will be initialised on either Xen or coreboot.
Except that my patch at http://git.infradead.org/users/dwmw2/seabios.git/commitdiff/56014611 adds a call to find_pmtimer() right after copying the Xen tables.
So the find_pmtimer() function which was added by my other patch at http://git.infradead.org/users/dwmw2/seabios.git/commitdiff/5ba80fac ought to go grubbing around in the Xen-provided ACPI table, find the pmtimer, and set SeaBIOS up to use it.
From then on, everything timer-related in the BIOS ought to use the pmtimer instead of the TSC (with lots of corresponding debug output).
No, it doesn't affect the kernel; just the BIOS and bootloaders.
On Fri, 2013-02-08 at 15:33 +0000, David Woodhouse wrote:
On Fri, 2013-02-08 at 15:27 +0000, Ian Campbell wrote:
On Fri, 2013-02-08 at 14:50 +0000, Ian Campbell wrote:
even with that and CONFIG_DEBUG_LEVEL=2 I still don't see the expected "Using pmtimer" message.
pci_setup() doesn't run on coreboot or Xen (because they do PCI setup themselves first), and AFAICT this is the path which leads to the call to pmtimer_setup(), so I don't think pmtimer will be initialised on either Xen or coreboot.
Except that my patch at http://git.infradead.org/users/dwmw2/seabios.git/commitdiff/56014611 adds a call to find_pmtimer() right after copying the Xen tables.
So the find_pmtimer() function which was added by my other patch at http://git.infradead.org/users/dwmw2/seabios.git/commitdiff/5ba80fac ought to go grubbing around in the Xen-provided ACPI table, find the pmtimer, and set SeaBIOS up to use it.
From then on, everything timer-related in the BIOS ought to use the pmtimer instead of the TSC (with lots of corresponding debug output).
Setting debug level 4 would show some output from find_fadt() and find_pmtimer() when it's trawling the ACPI tables and looking for the pmtimer. You *do* put a pm_tmr_blk field into your FADT table, don't you? If not, then I suppose it's not surprising that SeaBIOS doesn't find it :)
On Fri, 2013-02-08 at 15:46 +0000, David Woodhouse wrote:
Setting debug level 4 would show some output from find_fadt() and find_pmtimer() when it's trawling the ACPI tables and looking for the pmtimer. You *do* put a pm_tmr_blk field into your FADT table, don't you? If not, then I suppose it's not surprising that SeaBIOS doesn't find it :)
Yep, here is the DEBUG=4 stuff, FWIW:
(XEN) HVM167: HVM Loader (XEN) HVM167: Detected Xen v4.3-unstable (XEN) HVM167: Xenbus rings @0xfeffc000, event channel 4 (XEN) HVM167: System requested SeaBIOS (XEN) HVM167: CPU speed is 2400 MHz (XEN) HVM167: PCI-ISA link 0 routed to IRQ5 (XEN) HVM167: PCI-ISA link 1 routed to IRQ10 (XEN) HVM167: PCI-ISA link 2 routed to IRQ11 (XEN) HVM167: PCI-ISA link 3 routed to IRQ5 (XEN) HVM167: pci dev 01:3 INTA->IRQ10 (XEN) HVM167: pci dev 03:0 INTA->IRQ5 (XEN) HVM167: pci dev 04:0 INTA->IRQ5 (XEN) HVM167: pci dev 02:0 bar 10 size lx: 02000000 (XEN) HVM167: pci dev 03:0 bar 14 size lx: 01000000 (XEN) HVM167: pci dev 04:0 bar 10 size lx: 00020000 (XEN) HVM167: pci dev 04:0 bar 30 size lx: 00020000 (XEN) HVM167: pci dev 02:0 bar 30 size lx: 00010000 (XEN) HVM167: pci dev 02:0 bar 14 size lx: 00001000 (XEN) HVM167: pci dev 03:0 bar 10 size lx: 00000100 (XEN) HVM167: pci dev 04:0 bar 14 size lx: 00000040 (XEN) HVM167: pci dev 01:1 bar 20 size lx: 00000010 (XEN) HVM167: Multiprocessor initialisation: (XEN) HVM167: - CPU0 ... 36-bit phys ... fixed MTRRs ... var MTRRs [2/8] ... done. (XEN) HVM167: - CPU1 ... 36-bit phys ... fixed MTRRs ... var MTRRs [2/8] ... done. (XEN) HVM167: Testing HVM environment: (XEN) HVM167: - REP INSB across page boundaries ... passed (XEN) HVM167: - GS base MSRs and SWAPGS ... passed (XEN) HVM167: Passed 2 of 2 tests (XEN) HVM167: Writing SMBIOS tables ... (XEN) HVM167: Loading SeaBIOS ... (XEN) HVM167: Creating MP tables ... (XEN) HVM167: Loading ACPI ... (XEN) HVM167: vm86 TSS at fc00a080 (XEN) HVM167: BIOS map: (XEN) HVM167: 10000-100d3: Scratch space (XEN) HVM167: e0000-fffff: Main BIOS (XEN) HVM167: E820 table: (XEN) HVM167: [00]: 00000000:00000000 - 00000000:000a0000: RAM (XEN) HVM167: HOLE: 00000000:000a0000 - 00000000:000e0000 (XEN) HVM167: [01]: 00000000:000e0000 - 00000000:00100000: RESERVED (XEN) HVM167: [02]: 00000000:00100000 - 00000000:07800000: RAM (XEN) HVM167: HOLE: 00000000:07800000 - 00000000:fc000000 (XEN) HVM167: [03]: 00000000:fc000000 - 00000001:00000000: RESERVED (XEN) HVM167: Invoking SeaBIOS ... (XEN) HVM167: SeaBIOS (version rel-1.7.2-29-gf9614ba-dirty-20130208_160952-cosworth) (XEN) HVM167: (XEN) HVM167: Found Xen hypervisor signature at 40000000 (XEN) HVM167: qemu_cfg_present=0 (XEN) HVM167: xen: copy e820... (XEN) HVM167: malloc setup (XEN) HVM167: Ram Size=0x07800000 (0x0000000000000000 high) (XEN) HVM167: Relocating low data from 0x000e0f20 to 0x000eeeb0 (size 2164) (XEN) HVM167: Relocating init from 0x000e1794 to 0x077e1f50 (size 57232) (XEN) HVM167: malloc fixup reloc (XEN) HVM167: init ivt (XEN) HVM167: init bda (XEN) HVM167: math cp init (XEN) HVM167: init bios32 (XEN) HVM167: init PMM (XEN) HVM167: init PNPBIOS table (XEN) HVM167: init keyboard (XEN) HVM167: init mouse (XEN) HVM167: init pic (XEN) HVM167: init timer (XEN) HVM167: CPU Mhz=2402 (XEN) HVM167: PCI probe (XEN) HVM167: PCI device 00:00.0 (vd=8086:1237 c=0600) (XEN) HVM167: PCI device 00:01.0 (vd=8086:7000 c=0601) (XEN) HVM167: PCI device 00:01.1 (vd=8086:7010 c=0101) (XEN) HVM167: PCI device 00:01.3 (vd=8086:7113 c=0680) (XEN) HVM167: PCI device 00:02.0 (vd=1013:00b8 c=0300) (XEN) HVM167: PCI device 00:03.0 (vd=5853:0001 c=ff80) (XEN) HVM167: PCI device 00:04.0 (vd=8086:100e c=0200) (XEN) HVM167: Found 7 PCI devices (max PCI bus is 00) (XEN) HVM167: Allocated Xen hypercall page at 77ff000 (XEN) HVM167: Detected Xen v4.3-unstable (XEN) HVM167: Found 2 cpu(s) max supported 2 cpu(s) (XEN) HVM167: xen: copy BIOS tables... (XEN) HVM167: Copying SMBIOS entry point from 0x00010010 to 0x000fdb10 (XEN) HVM167: Copying MPTABLE from 0xfc001170/fc001180 to 0x000fda10 (XEN) HVM167: Copying PIR from 0x00010030 to 0x000fd990 (XEN) HVM167: Copying ACPI RSDP from 0x000100b0 to 0x000fd960 (XEN) HVM167: rsdp=0x000fd960 (XEN) HVM167: rsdt=0xfc009fc0 (XEN) HVM167: fadt=0xfc009810 (XEN) HVM167: pm_tmr_blk=b008 (XEN) HVM167: Using pmtimer, ioport 0xb008, freq 3579 kHz (XEN) HVM167: Scan for VGA option rom (XEN) HVM167: Attempting to init PCI bdf 00:02.0 (vd 1013:00b8) (XEN) HVM167: init usb (XEN) HVM167: init ps2port (XEN) HVM167: /077e0000\ Start thread (XEN) HVM167: init lpt (XEN) HVM167: Found 1 lpt ports (XEN) HVM167: init serial (XEN) HVM167: Found 1 serial ports (XEN) HVM167: init floppy drives (XEN) HVM167: Searching bootorder for: /pci@i0cf8/isa@1/fdc@03f0/floppy@0 (XEN) HVM167: Registering bootable: Floppy [drive A] (type:1 prio:9999 data:fd930) (XEN) HVM167: init hard drives (XEN) HVM167: ATA controller 1 at 1f0/3f4/c140 (irq 14 dev 9) (XEN) HVM167: /077df000\ Start thread (XEN) HVM167: ATA controller 2 at 170/374/c148 (irq 15 dev 9) (XEN) HVM167: /077de000\ Start thread (XEN) HVM167: init ahci (XEN) HVM167: init virtio-blk (XEN) HVM167: init virtio-scsi (XEN) HVM167: init lsi53c895a (XEN) HVM167: init esp (XEN) HVM167: init megasas (XEN) HVM167: |077df000| ata0-0: QEMU HARDDISK ATA-7 Hard-Disk (8192 MiBytes) (XEN) HVM167: |077df000| Searching bootorder for: /pci@i0cf8/*@1,1/drive@0/disk@0 (XEN) HVM167: |077df000| Registering bootable: ata0-0: QEMU HARDDISK ATA-7 Hard-Disk (8192 M (XEN) HVM167: iBytes) (type:2 prio:102 data:fd8e0) (XEN) HVM167: \077df000/ End thread (XEN) HVM167: |077de000| DVD/CD [ata1-0: QEMU DVD-ROM ATAPI-4 DVD/CD] (XEN) HVM167: |077de000| Searching bootorder for: /pci@i0cf8/*@1,1/drive@1/disk@0 (XEN) HVM167: |077de000| Registering bootable: DVD/CD [ata1-0: QEMU DVD-ROM ATAPI-4 DVD/CD] (XEN) HVM167: (type:3 prio:9999 data:fd8b0) (XEN) HVM167: \077de000/ End thread (XEN) HVM167: |077e0000| PS2 keyboard initialized (XEN) HVM167: \077e0000/ End thread (XEN) HVM167: All threads complete. (XEN) HVM167: Scan for option roms (XEN) HVM167: Attempting to init PCI bdf 00:00.0 (vd 8086:1237) (XEN) HVM167: Attempting to init PCI bdf 00:01.0 (vd 8086:7000) (XEN) HVM167: Attempting to init PCI bdf 00:01.3 (vd 8086:7113) (XEN) HVM167: Attempting to init PCI bdf 00:03.0 (vd 5853:0001) (XEN) HVM167: Attempting to init PCI bdf 00:04.0 (vd 8086:100e) (XEN) HVM167: Copying option rom (size 67072) from 0xf3020000 to 0x000c0000 (XEN) HVM167: Running option rom at c000:0003 (XEN) HVM167: pmm call arg1=1 (XEN) HVM167: pmm01: handle=18ae1000 (XEN) HVM167: pmm call arg1=0 (XEN) HVM167: pmm00: length=1060 handle=18ae1000 flags=2 (XEN) HVM167: pmm call arg1=1 (XEN) HVM167: pmm01: handle=18ae2004 (XEN) HVM167: pmm call arg1=0 (XEN) HVM167: pmm00: length=4000 handle=18ae2004 flags=2 (XEN) HVM167: Searching bootorder for: /pci@i0cf8/*@4 (XEN) HVM167: Registering bootable: iPXE (PCI 00:04.0) (type:128 prio:101 data:c0000372) (XEN) HVM167: (XEN) HVM167: Press F12 for boot menu. (XEN) HVM167: (XEN) HVM167: Searching bootorder for: HALT (XEN) HVM167: Mapping hd drive 0x000fd8e0 to 0 (XEN) HVM167: drive 0x000fd8e0: PCHS=16383/16/63 translation=lba LCHS=1024/255/63 s=16777216 (XEN) HVM167: (XEN) HVM167: Mapping floppy drive 0x000fd930 (XEN) HVM167: Mapping cd drive 0x000fd8b0 (XEN) HVM167: finalize PMM (XEN) HVM167: malloc finalize (XEN) HVM167: Space available for UMB: 000c1000-000ee000 (XEN) HVM167: Returned 61440 bytes of ZoneHigh (XEN) HVM167: e820 map has 6 items: (XEN) HVM167: 0: 0000000000000000 - 000000000009fc00 = 1 RAM (XEN) HVM167: 1: 000000000009fc00 - 00000000000a0000 = 2 RESERVED (XEN) HVM167: 2: 00000000000f0000 - 0000000000100000 = 2 RESERVED (XEN) HVM167: 3: 0000000000100000 - 00000000077ff000 = 1 RAM (XEN) HVM167: 4: 00000000077ff000 - 0000000007800000 = 2 RESERVED (XEN) HVM167: 5: 00000000fc000000 - 0000000100000000 = 2 RESERVED (XEN) HVM167: Jump to int19 (XEN) HVM167: enter handle_19: (XEN) HVM167: NULL (XEN) HVM167: Booting from ROM... (XEN) HVM167: Booting from c000:0372 (XEN) HVM167: enter handle_12: (XEN) HVM167: a=dced0200 b=00000030 c=00030000 d=00090027 ds=0000 es=0000 ss=9cf2 (XEN) HVM167: si=00002e10 di=0000b7b6 bp=00032ca2 sp=00002ca2 cs=0000 ip=7eef f=0246 (XEN) HVM167: unimplemented handle_16XX:231: (XEN) HVM167: a=00000305 b=00000000 c=00000000 d=00000000 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f70c cs=3000 ip=05f0 f=0003 (XEN) HVM167: unimplemented handle_15XX:338: (XEN) HVM167: a=0000e980 b=00000000 c=00000000 d=47534943 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f70c cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00004100 b=000055aa c=00000000 d=00000081 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00000201 b=00004c00 c=00000001 d=00000081 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00004100 b=000055aa c=00000000 d=00000082 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00000201 b=00004c00 c=00000001 d=00000082 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00004100 b=000055aa c=00000000 d=00000083 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00000201 b=00004c00 c=00000001 d=00000083 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00004100 b=000055aa c=00000000 d=00000084 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00000201 b=00004c00 c=00000001 d=00000084 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00004100 b=000055aa c=00000000 d=00000085 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00000201 b=00004c00 c=00000001 d=00000085 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00004100 b=000055aa c=00000000 d=00000086 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00000201 b=00004c00 c=00000001 d=00000086 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00004100 b=000055aa c=00000000 d=00000087 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00000201 b=00004c00 c=00000001 d=00000087 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00004100 b=000055aa c=00000000 d=00000088 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00000201 b=00004c00 c=00000001 d=00000088 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00004100 b=000055aa c=00000000 d=00000089 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00000201 b=00004c00 c=00000001 d=00000089 ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00004100 b=000055aa c=00000000 d=0000008a ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00000201 b=00004c00 c=00000001 d=0000008a ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00004100 b=000055aa c=00000000 d=0000008b ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00000201 b=00004c00 c=00000001 d=0000008b ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00004100 b=000055aa c=00000000 d=0000008c ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00000201 b=00004c00 c=00000001 d=0000008c ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00004100 b=000055aa c=00000000 d=0000008d ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00000201 b=00004c00 c=00000001 d=0000008d ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00004100 b=000055aa c=00000000 d=0000008e ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00000201 b=00004c00 c=00000001 d=0000008e ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00004100 b=000055aa c=00000000 d=0000008f ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003 (XEN) HVM167: invalid handle_legacy_disk:842: (XEN) HVM167: a=00000201 b=00004c00 c=00000001 d=0000008f ds=3000 es=3000 ss=3000 (XEN) HVM167: si=00000000 di=00000000 bp=00000000 sp=0000f5cc cs=3000 ip=05f0 f=0003
On Fri, 2013-02-08 at 16:11 +0000, Ian Campbell wrote:
(XEN) HVM167: xen: copy BIOS tables... (XEN) HVM167: Copying SMBIOS entry point from 0x00010010 to 0x000fdb10 (XEN) HVM167: Copying MPTABLE from 0xfc001170/fc001180 to 0x000fda10 (XEN) HVM167: Copying PIR from 0x00010030 to 0x000fd990 (XEN) HVM167: Copying ACPI RSDP from 0x000100b0 to 0x000fd960 (XEN) HVM167: rsdp=0x000fd960 (XEN) HVM167: rsdt=0xfc009fc0 (XEN) HVM167: fadt=0xfc009810 (XEN) HVM167: pm_tmr_blk=b008 (XEN) HVM167: Using pmtimer, ioport 0xb008, freq 3579 kHz
Looks good to me; thanks for testing.
On Fri, 2013-02-08 at 15:33 +0000, David Woodhouse wrote:
On Fri, 2013-02-08 at 15:27 +0000, Ian Campbell wrote:
On Fri, 2013-02-08 at 14:50 +0000, Ian Campbell wrote:
even with that and CONFIG_DEBUG_LEVEL=2 I still don't see the expected "Using pmtimer" message.
pci_setup() doesn't run on coreboot or Xen (because they do PCI setup themselves first), and AFAICT this is the path which leads to the call to pmtimer_setup(), so I don't think pmtimer will be initialised on either Xen or coreboot.
Except that my patch at http://git.infradead.org/users/dwmw2/seabios.git/commitdiff/56014611 adds a call to find_pmtimer() right after copying the Xen tables.
Right, it might help if I did "git bisect reset"and went back to the head of your branch!
With that I see the following, which looks good to me.
Ian.
(XEN) HVM166: HVM Loader (XEN) HVM166: Detected Xen v4.3-unstable (XEN) HVM166: Xenbus rings @0xfeffc000, event channel 4 (XEN) HVM166: System requested SeaBIOS (XEN) HVM166: CPU speed is 2400 MHz (XEN) HVM166: PCI-ISA link 0 routed to IRQ5 (XEN) HVM166: PCI-ISA link 1 routed to IRQ10 (XEN) HVM166: PCI-ISA link 2 routed to IRQ11 (XEN) HVM166: PCI-ISA link 3 routed to IRQ5 (XEN) HVM166: pci dev 01:3 INTA->IRQ10 (XEN) HVM166: pci dev 03:0 INTA->IRQ5 (XEN) HVM166: pci dev 04:0 INTA->IRQ5 (XEN) HVM166: pci dev 02:0 bar 10 size lx: 02000000 (XEN) HVM166: pci dev 03:0 bar 14 size lx: 01000000 (XEN) HVM166: pci dev 04:0 bar 10 size lx: 00020000 (XEN) HVM166: pci dev 04:0 bar 30 size lx: 00020000 (XEN) HVM166: pci dev 02:0 bar 30 size lx: 00010000 (XEN) HVM166: pci dev 02:0 bar 14 size lx: 00001000 (XEN) HVM166: pci dev 03:0 bar 10 size lx: 00000100 (XEN) HVM166: pci dev 04:0 bar 14 size lx: 00000040 (XEN) HVM166: pci dev 01:1 bar 20 size lx: 00000010 (XEN) HVM166: Multiprocessor initialisation: (XEN) HVM166: - CPU0 ... 36-bit phys ... fixed MTRRs ... var MTRRs [2/8] ... done. (XEN) HVM166: - CPU1 ... 36-bit phys ... fixed MTRRs ... var MTRRs [2/8] ... done. (XEN) HVM166: Testing HVM environment: (XEN) HVM166: - REP INSB across page boundaries ... passed (XEN) HVM166: - GS base MSRs and SWAPGS ... passed (XEN) HVM166: Passed 2 of 2 tests (XEN) HVM166: Writing SMBIOS tables ... (XEN) HVM166: Loading SeaBIOS ... (XEN) HVM166: Creating MP tables ... (XEN) HVM166: Loading ACPI ... (XEN) HVM166: vm86 TSS at fc00a080 (XEN) HVM166: BIOS map: (XEN) HVM166: 10000-100d3: Scratch space (XEN) HVM166: e0000-fffff: Main BIOS (XEN) HVM166: E820 table: (XEN) HVM166: [00]: 00000000:00000000 - 00000000:000a0000: RAM (XEN) HVM166: HOLE: 00000000:000a0000 - 00000000:000e0000 (XEN) HVM166: [01]: 00000000:000e0000 - 00000000:00100000: RESERVED (XEN) HVM166: [02]: 00000000:00100000 - 00000000:07800000: RAM (XEN) HVM166: HOLE: 00000000:07800000 - 00000000:fc000000 (XEN) HVM166: [03]: 00000000:fc000000 - 00000001:00000000: RESERVED (XEN) HVM166: Invoking SeaBIOS ... (XEN) HVM166: SeaBIOS (version rel-1.7.2-29-gf9614ba-dirty-20130208_160742-cosworth) (XEN) HVM166: (XEN) HVM166: Found Xen hypervisor signature at 40000000 (XEN) HVM166: xen: copy e820... (XEN) HVM166: Ram Size=0x07800000 (0x0000000000000000 high) (XEN) HVM166: Relocating low data from 0x000e2900 to 0x000ef780 (size 2164) (XEN) HVM166: Relocating init from 0x000e3174 to 0x077e2300 (size 56280) (XEN) HVM166: CPU Mhz=2403 (XEN) HVM166: Found 7 PCI devices (max PCI bus is 00) (XEN) HVM166: Allocated Xen hypercall page at 77ff000 (XEN) HVM166: Detected Xen v4.3-unstable (XEN) HVM166: Found 2 cpu(s) max supported 2 cpu(s) (XEN) HVM166: xen: copy BIOS tables... (XEN) HVM166: Copying SMBIOS entry point from 0x00010010 to 0x000fdb10 (XEN) HVM166: Copying MPTABLE from 0xfc001170/fc001180 to 0x000fda10 (XEN) HVM166: Copying PIR from 0x00010030 to 0x000fd990 (XEN) HVM166: Copying ACPI RSDP from 0x000100b0 to 0x000fd960 (XEN) HVM166: Using pmtimer, ioport 0xb008, freq 3579 kHz (XEN) HVM166: Scan for VGA option rom (XEN) HVM166: Found 1 lpt ports (XEN) HVM166: Found 1 serial ports (XEN) HVM166: Searching bootorder for: /pci@i0cf8/isa@1/fdc@03f0/floppy@0 (XEN) HVM166: ATA controller 1 at 1f0/3f4/c140 (irq 14 dev 9) (XEN) HVM166: ATA controller 2 at 170/374/c148 (irq 15 dev 9) (XEN) HVM166: ata0-0: QEMU HARDDISK ATA-7 Hard-Disk (8192 MiBytes) (XEN) HVM166: Searching bootorder for: /pci@i0cf8/*@1,1/drive@0/disk@0 (XEN) HVM166: DVD/CD [ata1-0: QEMU DVD-ROM ATAPI-4 DVD/CD] (XEN) HVM166: Searching bootorder for: /pci@i0cf8/*@1,1/drive@1/disk@0 (XEN) HVM166: PS2 keyboard initialized (XEN) HVM166: All threads complete. (XEN) HVM166: Scan for option roms (XEN) HVM166: Running option rom at c000:0003 (XEN) HVM166: pmm call arg1=1 (XEN) HVM166: pmm call arg1=0 (XEN) HVM166: pmm call arg1=1 (XEN) HVM166: pmm call arg1=0 (XEN) HVM166: Searching bootorder for: /pci@i0cf8/*@4 (XEN) HVM166: (XEN) HVM166: Press F12 for boot menu. (XEN) HVM166: (XEN) HVM166: Searching bootorder for: HALT (XEN) HVM166: drive 0x000fd8e0: PCHS=16383/16/63 translation=lba LCHS=1024/255/63 s=16777216 (XEN) HVM166: (XEN) HVM166: Space available for UMB: 000c1000-000ee800 (XEN) HVM166: Returned 61440 bytes of ZoneHigh (XEN) HVM166: e820 map has 6 items: (XEN) HVM166: 0: 0000000000000000 - 000000000009fc00 = 1 RAM (XEN) HVM166: 1: 000000000009fc00 - 00000000000a0000 = 2 RESERVED (XEN) HVM166: 2: 00000000000f0000 - 0000000000100000 = 2 RESERVED (XEN) HVM166: 3: 0000000000100000 - 00000000077ff000 = 1 RAM (XEN) HVM166: 4: 00000000077ff000 - 0000000007800000 = 2 RESERVED (XEN) HVM166: 5: 00000000fc000000 - 0000000100000000 = 2 RESERVED (XEN) HVM166: enter handle_19: (XEN) HVM166: NULL (XEN) HVM166: Booting from ROM... (XEN) HVM166: Booting from c000:0372
On Fri, Feb 08, 2013 at 02:50:35PM +0000, Ian Campbell wrote:
On Fri, 2013-02-08 at 14:45 +0000, Ian Campbell wrote:
I don't see this with rel-1.7.2. Bisecting fingers commit 6ca0460fbb8ecfa5d42c8928b7ee71f20d0cffdb Author: Kevin O'Connor kevin@koconnor.net Date: Mon Jan 21 11:38:49 2013 -0500
POST: Reorganize post entry and "preinit" functions.
But it doesn't look like this changes the order of anything,
Except Xen is entering via handle_post not handle_elf, so it does change something, specifically xen_preinit() isn't called before make_bios_writable so the usingXen in there doesn't trigger. Xen (actually hvmloader) launches SeaBIOS with "ljmp $0xf000,$0xfff0" so I think handle_post is the expected landing point.
Thanks. Sorry about that. I was under the impression that Xen used the elf entry point from our discussions long ago - but I guess that was prior to the decision to use hvmloader. I'll revert the recent change that broke Xen.
Would you have a short description of how one can pull down the Xen code and run a custom compiled SeaBIOS image on it?
-Kevin
On Fri, 2013-02-08 at 17:14 -0500, Kevin O'Connor wrote:
On Fri, Feb 08, 2013 at 02:50:35PM +0000, Ian Campbell wrote:
On Fri, 2013-02-08 at 14:45 +0000, Ian Campbell wrote:
I don't see this with rel-1.7.2. Bisecting fingers commit 6ca0460fbb8ecfa5d42c8928b7ee71f20d0cffdb Author: Kevin O'Connor kevin@koconnor.net Date: Mon Jan 21 11:38:49 2013 -0500
POST: Reorganize post entry and "preinit" functions.
But it doesn't look like this changes the order of anything,
Except Xen is entering via handle_post not handle_elf, so it does change something, specifically xen_preinit() isn't called before make_bios_writable so the usingXen in there doesn't trigger. Xen (actually hvmloader) launches SeaBIOS with "ljmp $0xf000,$0xfff0" so I think handle_post is the expected landing point.
Thanks. Sorry about that. I was under the impression that Xen used the elf entry point from our discussions long ago - but I guess that was prior to the decision to use hvmloader.
I think that was the case, yes.
I'll revert the recent change that broke Xen.
Thanks.
Would you have a short description of how one can pull down the Xen code and run a custom compiled SeaBIOS image on it?
The "short" version would feature "download, build, install and configure Xen" I'm afraid :-/ I'd be more than happy to help you do that if you want though and if you can keep a suitably configured system around (it needn't be dedicated to Xen other than when testing Xen specifically) you won't need to do the majority of the setup again.
Ian.
On Mon, 2013-02-11 at 12:31 +0000, Ian Campbell wrote:
On Fri, 2013-02-08 at 17:14 -0500, Kevin O'Connor wrote:
Would you have a short description of how one can pull down the Xen code and run a custom compiled SeaBIOS image on it?
The "short" version would feature "download, build, install and configure Xen" I'm afraid :-/ I'd be more than happy to help you do that if you want though and if you can keep a suitably configured system around (it needn't be dedicated to Xen other than when testing Xen specifically) you won't need to do the majority of the setup again.
You've probably already seen my reply to David in the "Improved multi-platform support", if you are a Fedora user then that should be enough to get going with, I think. If you aren't a Fedora user let me know and I'll see what I can come up with.
Ian.
Hi,
unaligned PCIR - I'm not sure we can merge this as it would break QEMU users with a current "lgpl vgabios".
As long as this is a config switch so we can easily turn this on for the builds shipped with qemu everything is fine.
cheers, Gerd
On Fri, 2013-02-08 at 11:27 +0100, Gerd Hoffmann wrote:
unaligned PCIR - I'm not sure we can merge this as it would break QEMU users with a current "lgpl vgabios".
As long as this is a config switch so we can easily turn this on for the builds shipped with qemu everything is fine.
It is, but I'd like to also *fix* the ROMs which are shipped with qemu. They are currently broken when I try to use them with OVMF.
David Woodhouse <dwmw2 <at> infradead.org> writes:
[ SeaBIOS as CSM ]
Great, that’s a first step towards making SeaBIOS an EFI application (in the end, I envision having a signed seabios.efi file that can be used on systems that run Restricted Boot to run “proper” BIOS OSes).
Thanks!
bye, //mirabilos