On Dec 24, 2012, at 6:26 AM, Mark Cave-Ayland wrote:
On 21/12/12 14:45, Programmingkid wrote:
How to reproduce the problem:
Start QEMU for debugging: qemu-system-ppc -m 128 -bios openbios-qemu.elf.nostrip -cdrom darwin8.iso -s -S
Start up gdb to read the firmware file: powerpc-linux-gdb openbios-qemu.elf.nostrip
Connect to QEMU using this command inside gdb: target remote localhost:1234
Set a breakpoint at this place: b ofmem.c:414
Have OpenBIOS start the boot process by entering this in QEMU: boot cd:,\:tbxi
When the breakpoint in tripped, type this in gdb: print&next_grab_slot.
next_grab_slot will have an address that isn't available to QEMU. The value I see is 0xfffda060. QEMU would have to have over 4 GB of ram in order to access this address.
In short, this is actually fine. You have to remember that OpenBIOS uses the MMU (emulated by QEMU) and hence physical pages can be mapped to any virtual address within the 32-bit address space of the PPC CPU.
Once the MMU is enabled in the OpenBIOS startup code, all addresses (including those used by gdb) are virtual addresses. If you want to view the current virtual to physical mappings, use the "info tlb" command from the QEMU monitor.
Note that if you try and access an unmapped address then you will normally obtain some kind of "page fault" or "TLB miss" processor exception. So if you can read and write from the variable, then everything is working correctly.
I tried "info tlb" inside QEMU, but I don't see any information printed.
The issue is no code appears to be able to write to the next_grab_slot variable. This needs to be fixed.
This patch should fix the division by zero issue. Only on the PowerPC platform will division by zero equal zero.
signed-off-by: John Arbuckle programmingkidx@gmail.com
Index: kernel/forth.c =================================================================== --- kernel/forth.c (revision 1080) +++ kernel/forth.c (working copy) @@ -1157,6 +1157,15 @@ { const ucell b = POP(); const ducell a = DPOP(); + +#if defined (CONFIG_PPC) || defined (CONFIG_PPC64) + if (b == 0) { // division by zero equals zero on PowerPC platform + PUSH(0); + DPUSH(0); + return; + } +#endif + #ifdef NEED_FAKE_INT128_T if (a.hi != 0) { fprintf(stderr, "mudivmod called (0x%016llx %016llx / 0x%016llx)\n",