[OpenBIOS] b?branch

BALATON Zoltan balaton at eik.bme.hu
Fri Dec 22 00:51:00 CET 2017

On Thu, 21 Dec 2017, Programmingkid wrote:
>> On Dec 21, 2017, at 12:56 PM, BALATON Zoltan <balaton at eik.bme.hu> wrote:
>> On Thu, 21 Dec 2017, Jd Lyons wrote:
>>>> On Dec 21, 2017, at 9:59 AM, Programmingkid <programmingkidx at gmail.com> wrote:
>>>>> On Dec 21, 2017, at 9:36 AM, Jd Lyons <lyons_dj at yahoo.com> wrote:
>>>>> I don’t know, this maybe an issue with the way we have defined “us”.
>> I'm not sure the us word is related to problems with b?branch but I don't know anything about this other than reading the conversation here. They look unrelated to me but it could well be I did not undersand this at all.
>>>>> Looking through the SLOF code it seems they call it like this in the timebase.fs:
>>>>> : tb@  ( -- tb )
>>>>>  BEGIN tbu@ tbl@ tbu@ rot over <> WHILE 2drop REPEAT
>>>>>  20 lshift swap ffffffff and or
>>>>> ;
>>>>> : milliseconds ( -- ms ) tb@ d# 1000 * tb-frequency / ;
>>>>> : microseconds ( -- us ) tb@ d# 1000000 * tb-frequency / ;
>>>>> : ms ( ms-to-wait -- ) milliseconds + BEGIN milliseconds over >= UNTIL drop ;
>>>>> : get-msecs ( -- n ) milliseconds ;
>>>>> : us  ( us-to-wait -- )  microseconds +  BEGIN microseconds over >= UNTIL  drop ;
>>>>> Not sure if I can port/hack this code over, the copier seems to have trouble with tbu@ tbl@?
>>>> The ms and get-msecs words don't appear to be implemented correctly on OpenBIOS. 10000 ms should pause OpenBIOS for 10 seconds. It does not.
>>>> I did find a function called udelay() in the drivers/timer.c file. Maybe I can implement the word us using udelay(). Then the ms word could be implemented using the us word.
>>> See what you can do about : us, but we maybe running into an issue with Qemu/mac99. Every version of the Mac OS reports a different bus and cpu speed, so we maybe having trouble with the way the timebase is calculated in Qemu.
>> I think you have two choices for this:
>> 1. Either export udelay (or _wait_ticks it's based on) to Forth and 
>> implement these words based on that. But this comment in 
>> drivers/timer.c:
> How would I do this?
>> /*
>> * TODO: pass via lb table
>> */
>> unsigned long timer_freq = 10000000 / 4;
>> suggests you may need to fix this first to take into accound the actual 
>> TB frequency from the CPU instead of some hardcoded value.
> This would make a good next step.
>> 2. Alternatively, you could either add new helpers (maybe in 
>> arch/ppc/timebase.S) to implement tbl@ and tbu@ which probably should 
>> just do mftb and mftbu respectively or export to Forth the already 
>> existing _get_ticks which returns these as a combined 64 bit value and 
>> derive the lower and upper 32 bits from Forth and then maybe you can 
>> use the above implementation from SLOF.
> It is a possibility.
> We still need a way to access any new C function from forth. The only 
> thing that I think would work is implementing the us word in a device 
> node, then make another definition of us that is available to the 
> dictionary. If anyone has a way to do this, an example would be great.

I don't know much about this but looking at the code I think _get_ticks is 
almost equivalent to tb@ above except that _get_ticks returns tbu@ in %r3 
and tbl@ in %r4 but tb@ also combines these into one value. Then you can 
see e.g. in arch/ppc/qemu/init.c that the bind_func() function is used to 
make C functions available from Forth. So you could make a C function 
which calls _get_ticks then combines %r3 and %r4 into a 64bit value (so 
implements what tb@ does in C) then bind this to tb at . Or bind _get_ticks 
and implement tb@ calling this and combining the upper and lower values 
from Forth like above (I think this is what '20 lshift swap ffffffff and 
or' does but I don't know Forth to tell).

You'll also need tb-frequency which can be found in the cpu properties 
(added in arch/ppc/qemu/init.c by reading the correct value from QEMU). 
SLOF has a function that seems to be called during init but I can't read 
Forth enough to tell for sure what it actually does:

\ Fixup timebase frequency from device-tree
: fixup-tbfreq
     " /cpus/@0" find-device
     " timebase-frequency" get-node get-package-property IF
         decode-int to tb-frequency 2drop

But I think this is what sets tb-frequency global value so you'll probably 
need something similar somewhere (maybe ppc.fs). Then you have tb@ and 
tb-frequency so the rest should work.

Now it's your turn to find out how to do this in OpenBIOS.


More information about the OpenBIOS mailing list