[SeaBIOS] [PATCH 1/3] POST: Reorganize post entry and "preinit" functions.
Kevin O'Connor
kevin at koconnor.net
Mon Jan 21 18:58:08 CET 2013
Unlocking ram in handle_post() is tricky and only needed under qemu.
Separate out that logic from the coreboot/xen paths by invoking
handle_elf_post separately. This simplifies both the qemu and
non-qemu code paths.
Also, organize all the "pre-init" functions into one section of the
file.
Signed-off-by: Kevin O'Connor <kevin at koconnor.net>
---
src/post.c | 152 +++++++++++++++++++++++++++++++++-----------------------
src/romlayout.S | 2 +-
2 files changed, 90 insertions(+), 64 deletions(-)
diff --git a/src/post.c b/src/post.c
index 33b51b7..56df90c 100644
--- a/src/post.c
+++ b/src/post.c
@@ -1,24 +1,23 @@
// 32bit code to Power On Self Test (POST) a machine.
//
-// Copyright (C) 2008-2010 Kevin O'Connor <kevin at koconnor.net>
+// Copyright (C) 2008-2013 Kevin O'Connor <kevin at koconnor.net>
// Copyright (C) 2002 MandrakeSoft S.A.
//
// This file may be distributed under the terms of the GNU LGPLv3 license.
-#include "ioport.h" // PORT_*
#include "config.h" // CONFIG_*
#include "cmos.h" // CMOS_*
#include "util.h" // memset
#include "biosvar.h" // struct bios_data_area_s
-#include "disk.h" // floppy_drive_setup
+#include "disk.h" // floppy_setup
#include "ata.h" // ata_setup
#include "ahci.h" // ahci_setup
#include "memmap.h" // add_e820
#include "pic.h" // pic_setup
#include "bregs.h" // struct bregs
-#include "boot.h" // IPL
+#include "boot.h" // boot_init
#include "usb.h" // usb_setup
-#include "paravirt.h" // qemu_cfg_port_probe
+#include "paravirt.h" // qemu_cfg_preinit
#include "xen.h" // xen_preinit
#include "ps2port.h" // ps2port_setup
#include "virtio-blk.h" // virtio_blk_setup
@@ -29,30 +28,10 @@
/****************************************************************
- * BIOS init
+ * BIOS initialization and hardware setup
****************************************************************/
static void
-ramsize_preinit(void)
-{
- dprintf(3, "Find memory size\n");
- if (CONFIG_COREBOOT)
- coreboot_preinit();
- else if (usingXen())
- xen_ramsize_preinit();
- else
- qemu_ramsize_preinit();
-
- // 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);
-
- dprintf(1, "Ram Size=0x%08x (0x%016llx high)\n", RamSize, RamSizeOver4G);
-}
-
-static void
ivt_init(void)
{
dprintf(3, "init ivt\n");
@@ -244,24 +223,30 @@ maininit(void)
make_bios_readonly();
}
-// Begin the boot process by invoking an int0x19 in 16bit mode.
+
+/****************************************************************
+ * Early initialization (preinit) and code relocation
+ ****************************************************************/
+
static void
-startBoot(void)
+ramsize_preinit(void)
{
- // Clear low-memory allocations (required by PMM spec).
- memset((void*)BUILD_STACK_ADDR, 0, BUILD_EBDA_MINIMUM - BUILD_STACK_ADDR);
+ dprintf(3, "Find memory size\n");
+ if (CONFIG_COREBOOT)
+ coreboot_preinit();
+ else if (usingXen())
+ xen_ramsize_preinit();
+ else
+ qemu_ramsize_preinit();
- dprintf(3, "Jump to int19\n");
- struct bregs br;
- memset(&br, 0, sizeof(br));
- br.flags = F_IF;
- call16_int(0x19, &br);
-}
+ // 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);
-/****************************************************************
- * POST entry and code relocation
- ****************************************************************/
+ dprintf(1, "Ram Size=0x%08x (0x%016llx high)\n", RamSize, RamSizeOver4G);
+}
// Update given relocs for the code at 'dest' with a given 'delta'
static void
@@ -272,7 +257,7 @@ updateRelocs(void *dest, u32 *rstart, u32 *rend, u32 delta)
*((u32*)(dest + *reloc)) += delta;
}
-// Relocate init code and then call maininit() at new address.
+// Relocate init code.
static void
reloc_preinit(void)
{
@@ -311,11 +296,22 @@ reloc_preinit(void)
barrier();
}
-// Setup for code relocation and then call reloc_init
+// Setup for code relocation and then relocate.
void VISIBLE32INIT
-doreloc(void)
+preinit(void)
{
+ // Set reboot flags.
HaveRunPost = 1;
+ outb_cmos(0, CMOS_RESET_CODE);
+
+ // Enable CPU caching
+ setcr0(getcr0() & ~(CR0_CD|CR0_NW));
+
+ // 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();
@@ -326,32 +322,31 @@ doreloc(void)
reloc_preinit();
}
-// Entry point for Power On Self Test (POST) - the BIOS initilization
-// phase. This function makes the memory at 0xc0000-0xfffff
-// read/writable and then calls dopost().
-void VISIBLE32FLAT
-handle_post(void)
-{
- debug_serial_preinit();
- dprintf(1, "Start bios (version %s)\n", VERSION);
-
- // Enable CPU caching
- setcr0(getcr0() & ~(CR0_CD|CR0_NW));
-
- // Clear CMOS reboot flag.
- outb_cmos(0, CMOS_RESET_CODE);
- // Make sure legacy DMA isn't running.
- dma_preinit();
+/****************************************************************
+ * POST entry
+ ****************************************************************/
- // Check if we are running under Xen.
- xen_preinit();
+// As the last part of POST, invoke int19 to start boot phase.
+static void
+startBoot(void)
+{
+ // Clear low-memory allocations (required by PMM spec).
+ memset((void*)BUILD_STACK_ADDR, 0, BUILD_EBDA_MINIMUM - BUILD_STACK_ADDR);
- // Allow writes to modify bios area (0xf0000)
- make_bios_writable();
+ dprintf(3, "Jump to int19\n");
+ struct bregs br;
+ memset(&br, 0, sizeof(br));
+ br.flags = F_IF;
+ call16_int(0x19, &br);
+}
+// Power On Self Test (POST) - the main BIOS initialization phase.
+static void
+post(void)
+{
// Do pre-relocation setup and then relocate initialization code.
- doreloc();
+ preinit();
// Run main code
maininit();
@@ -359,3 +354,34 @@ handle_post(void)
// Invoke int 19 to start boot process.
startBoot();
}
+
+// Startup debug output and display software version.
+static void
+debug_splash(void)
+{
+ debug_serial_preinit();
+ dprintf(1, "Start bios (version %s)\n", VERSION);
+}
+
+// Entry point for Power On Self Test (POST) when running under
+// xen/coreboot.
+void VISIBLE32FLAT
+handle_elf_post(void)
+{
+ debug_splash();
+ post();
+}
+
+// Entry point for Power On Self Test (POST) when running under
+// qemu/kvm/bochs. Under qemu the memory at 0xc0000-0xfffff may be
+// read-only, so unlock the ram as the first step of booting.
+void VISIBLE32FLAT
+handle_post(void)
+{
+ debug_splash();
+
+ // Allow writes to modify bios area (0xf0000)
+ make_bios_writable();
+
+ post();
+}
diff --git a/src/romlayout.S b/src/romlayout.S
index 8125277..a8e00b6 100644
--- a/src/romlayout.S
+++ b/src/romlayout.S
@@ -380,7 +380,7 @@ entry_elf:
movw %ax, %gs
movw %ax, %ss
movl $BUILD_STACK_ADDR, %esp
- ljmpl $SEG32_MODE32_CS, $_cfunc32flat_handle_post
+ ljmpl $SEG32_MODE32_CS, $_cfunc32flat_handle_elf_post
.code16gcc
--
1.7.11.7
More information about the SeaBIOS
mailing list