[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