diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2013-01-21 01:53:31 -0500 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2013-02-05 20:01:08 -0500 |
commit | 8a0a972f12037b8b4c4bf355bfdc6401afbca1c4 (patch) | |
tree | 9e10305a816a8dc4e2ea33100177a6d0596d1d26 /src/post.c | |
parent | d83c87bb20a8ac5faf80ead44ff8dc793bf25a84 (diff) | |
download | seabios-8a0a972f12037b8b4c4bf355bfdc6401afbca1c4.tar.gz |
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 <kevin@koconnor.net>
Diffstat (limited to 'src/post.c')
-rw-r--r-- | src/post.c | 273 |
1 files changed, 142 insertions, 131 deletions
@@ -1,6 +1,6 @@ // 32bit code to Power On Self Test (POST) a machine. // -// Copyright (C) 2008-2010 Kevin O'Connor <kevin@koconnor.net> +// Copyright (C) 2008-2013 Kevin O'Connor <kevin@koconnor.net> // Copyright (C) 2002 MandrakeSoft S.A. // // This file may be distributed under the terms of the GNU LGPLv3 license. @@ -30,11 +30,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"); @@ -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(); } |