From 8a0a972f12037b8b4c4bf355bfdc6401afbca1c4 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Mon, 21 Jan 2013 01:53:31 -0500 Subject: [PATCH] POST: Reorganize post init functions for better grouping and reusability. 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 --- src/boot.c | 16 +-- src/boot.h | 3 +- src/bootsplash.c | 2 + src/post.c | 273 ++++++++++++++++++++++++----------------------- 4 files changed, 151 insertions(+), 143 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 fb7372b..4b04740 100644 --- a/src/post.c +++ b/src/post.c @@ -1,6 +1,6 @@ // 32bit code to Power On Self Test (POST) a machine. // -// Copyright (C) 2008-2010 Kevin O'Connor +// Copyright (C) 2008-2013 Kevin O'Connor // Copyright (C) 2002 MandrakeSoft S.A. // // This file may be distributed under the terms of the GNU LGPLv3 license. @@ -30,10 +30,68 @@ #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) { @@ -100,81 +158,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 @@ -198,36 +202,33 @@ device_hardware_setup(void) megasas_setup(); } -// Begin the boot process by invoking an int0x19 in 16bit mode. -void VISIBLE32FLAT -startBoot(void) +static 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(); + + mptable_setup(); + + smbios_setup(); + + acpi_setup(); } -// Main setup code. static void -maininit(void) +platform_hardware_setup(void) { - // Setup romfile items. - qemu_romfile_init(); - coreboot_cbfs_init(); - - // Setup ivt/bda/ebda - ivt_init(); - bda_init(); - // Init base pc hardware. pic_setup(); timer_setup(); - mathcp_init(); // Initialize pci pci_setup(); @@ -239,9 +240,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(); @@ -249,20 +247,53 @@ 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); +} + +// Begin the boot process by invoking an int0x19 in 16bit mode. +void VISIBLE32FLAT +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); +} + +// Main setup code. +static void +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(); @@ -272,17 +303,12 @@ maininit(void) // Run option roms optionrom_setup(); - // Run BCVs and show optional boot menu - boot_prepboot(); - - // Finalize data structures before boot - cdrom_prepboot(); - pmm_prepboot(); - malloc_prepboot(); - memmap_prepboot(); + // Allow user to modify overall boot order. + interactive_bootmenu(); + wait_threads(); - // Setup bios checksum. - BiosChecksum -= checksum((u8*)BUILD_BIOS_ADDR, BUILD_BIOS_SIZE); + // Prepare for boot. + prepareboot(); // Write protect bios memory. make_bios_readonly(); @@ -296,21 +322,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_init(); - - // 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) @@ -359,7 +370,7 @@ reloc_preinit(void) updateRelocs(code32flat_start, _reloc_init_start, _reloc_init_end, delta); // Call maininit() in relocated code. - void (*func)(void) = (void*)afterReloc + delta; + void (*func)(void) = (void*)maininit + delta; barrier(); func(); } -- 2.39.5