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