[OpenBIOS] SOLVED: the mystery of Solaris on SPARC32 and the missing Forth arguments
blauwirbel at gmail.com
Sat Oct 23 12:41:51 CEST 2010
On Sat, Oct 23, 2010 at 8:51 AM, Mark Cave-Ayland
<mark.cave-ayland at siriusit.co.uk> wrote:
> Blue Swirl wrote:
>>> The only thing I can think of is that this simple example fails because
>>> something related to the return address, but I'm not 100% sure.
>> 'call' instruction writes the return address to %o7, clobbering
>> previous %o7 from the OS. That's why 'save' and 'restore' are needed.
>> In this case, alternatively changing just 'call' to 'jmp' and deleting
>> the rest should also work.
>>> Also what
>>> are the rules about how much information you can push onto the stack of
>>> previous frame, i.e. the frame pointer? My current thoughts are that I
>>> either i) push arguments onto the %fp and not save into a new window or
>>> push arguments onto the %sp after a save (in which case I need additional
>>> code to copy the i registers into the o registers before calling the C
>>> function). Does this sound correct?
>> I'd go for ii) or 'jmp'.
> Okay. I tried using jmp but I got an "out of range" error on compilation so
> I started working on something based on disassembling the output of a GCC
> wrapper function. The attached patch works well my Solaris 8 ISO, although
> now after some twirly batons we appear to be sat in an infinite loop:
The address of jmp target needs be in a register. Alternatively 'b' should work.
The offsets to %sp are too low, the area you are using is used by
window trap handlers. They should be %sp+0x60 etc, but usually the
addressing is %fp-0x20 etc which should yield the same address. Maybe
this was the problem?
This document describes the usual stack frame layout:
Other nitpicks: The usual practice is to use 'ret' followed by
'restore' in the delay slot (which can also perform 'mov %o0, %i0').
'extern' is not needed with function declarations.
obp_fortheval_v2_handler2() is not used AFAICT. init_openprom()
declaration should be moved to romvec.h so all romvec stuff is in one
> build at zeno:~/src/openbios/openbios-devel$ sparc64-linux-gdb
> GNU gdb 6.8
> Copyright (C) 2008 Free Software Foundation, Inc.
> License GPLv3+: GNU GPL version 3 or later
> This is free software: you are free to change and redistribute it.
> There is NO WARRANTY, to the extent permitted by law. Type "show copying"
> and "show warranty" for details.
> This GDB was configured as "--host=x86_64-unknown-linux-gnu
> (gdb) file obj-sparc32/openbios-builtin.elf.nostrip
> Reading symbols from
> (gdb) target remote :1234
> Remote debugging using :1234
> [New Thread 1]
> 0x00000000 in ?? ()
> (gdb) cont
> Program received signal SIGINT, Interrupt.
> 0x00106190 in ?? ()
> (gdb) stepi
> 0x00106194 in ?? ()
> 0x00106190 in ?? ()
> (gdb) disas 0x106190 0x106194
> Dump of assembler code from 0x106190 to 0x106194:
> 0x00106190: call 0x106190
> End of assembler dump.
> From the addresses and the twirly baton beforehand, I'd say we're actually
> now in the Solaris kernel. The interesting part of this is the fact that we
> get stuck in an infinite loop as shown above - I wonder if this is just the
> Solaris way of handling errors? Or perhaps maybe OpenBIOS doesn't have a
> romvec entry to enable diagnostic messages to be output to the console?
We don't implement pv_putstr (not used by Linux) and pv_printf calls
printk directly without your wrappers.
> While there is no notable regression when building with -Os, my NetBSD and
> Debian test ISO images crash out when compiled with -O0 (as set in this
> patch) - anyone have any ideas on this one?
Probably related to low %sp offset: unoptimized functions always use
save/restore and they are not inlined, so the call chain is longer and
window spills more likely to happen.
More information about the OpenBIOS