[OpenBIOS] [RFC 3/3] SPARC32/64: Mimic Sun's OBP behaviour if a divide by zero occurs.
Tarl Neustaedter
tarl-b2 at tarl.net
Mon Jan 7 20:37:44 CET 2013
On 2013-Jan-7 14:08 , Mark Cave-Ayland wrote:
>> .
>
> Ah I see. So for example if on SPARC that was in the middle of a CIF
> interpret call or similar, then you'd be dropped back to the OpenBoot
> prompt at this point too? I didn't pick up on that from Artyom's
> original email.
Yup. Either drop to the ok prompt or fully reset the machine, depending
on other settings.
> Unfortunately the sad truth is that BootX is written to rely on this
> (ahem) feature to work if booting from anything that isn't the network:
>
> 0 value screenIH
> 0 value cursorAddr
> 0 value cursorX
> 0 value cursorY
> 0 value cursorW
> 0 value cursorH
> 0 value cursorFrames
> 0 value cursorPixelSize
> 0 value cursorStage
> 0 value cursorTime
> 0 value cursorDelay
>
> ...
>
> : slw_spin_init
> dup FFFF and to cursorH 10 >> drop
> dup FFFF and to cursorW 10 >> to cursorPixelSize
> dup FFFF and to cursorY 10 >> d# 1000 swap / to cursorDelay
> dup FFFF and to cursorX 10 >> to cursorFrames
> to cursorAddr
> to screenIH
> ['] slw_spin to spin ;
>
> And slw_spin_init is invoked from DrawSplashScreen() like this:
>
> if (gBootFileType != kNetworkDeviceType) {
> SpinInit(0, 0, NULL, 0, 0, 0, 0, 0, 0, 0);
> }
The key error here (as I see it) is:
dup FFFF and to cursorY 10 >> d# 1000 swap / to cursorDelay
Where is that code? It looks like it's the third argument to
"slw_spin_init" that is being used as a divisor, and it should be
checked for zero.
I think this code (commenting to relate arguments to lines of code)
looks like:
: slw_spin_init ( arg7 arg6 arg5 arg4 arg3 arg2 arg1 -- )
dup FFFF and to cursorH 10 >> drop( arg7 arg6 arg5 arg4 arg3 arg2 )
dup FFFF and to cursorW 10 >> to cursorPixelSize ( arg7 arg6
arg5 arg4 arg3 )
dup FFFF and to cursorY 10 >> d# 1000 swap / to cursorDelay ( arg7
arg6 arg5 arg4 )
dup FFFF and to cursorX 10 >> to cursorFrames ( arg7 arg6 arg5 )
to cursorAddr ( arg7 arg6 )
to screenIH ( arg7 )
['] slw_spin to spin ; ( )
;
So it looks like this code depends on arg3 being non-zero. I assume the
arguments are coming from right-to-left, which is backwards from other
c-to-forth implementations I've seen (usually the c call is
procedure(arg1, arg2, arg3, ...) ), but that would not seem to fit here,
since arg5 appears to require a pointer. Note that not all architectures
use 0 == NULL; some use other values, so I wonder if this is a bug
originating from some such usage combined with argument order confusion.
The better fix would be to check for zero in slw_spin_init. Or are you
saying that both the call to SpinInit() /and/ the slw_spin_init( -- )
forth code are in BootX, code we aren't allowed to touch? If that's the
case, indeed, a program which deliberately sets up a divide by zero
expecting it to work has to be hacked around. To quote from that PPC
8360 article:
"I've inherited legacy code like this before & I feel your pain. You
want to shake your fist at the people who installed such bone-headed
behavior, but right now shaking your fist doesn't help you ship product.
You need a solution. Good luck."
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openbios.org/pipermail/openbios/attachments/20130107/80793042/attachment.html>
More information about the OpenBIOS
mailing list