[SeaBIOS] [PATCH v2 00/19] SeaBIOS as Compatibility Support Module for UEFI/OVMF

Kevin O'Connor kevin at koconnor.net
Thu Feb 7 05:13:20 CET 2013


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
 



More information about the SeaBIOS mailing list