Author Topic: 7448 mysteries?  (Read 2953 times)

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
7448 mysteries?
« on: February 13, 2021, 09:59:58 AM »
First can anyone decode what the Power Logix NVRam script does, E.I. Can we make this human readable so we can understand how to apply it:

Code: [Select]
sudo nvram nvramrc=" "(F1084C2A00000103120A6465766963652D656E64CDA5CA065F2E6C2E72310800B8A5CA065F2E6C2E72320801B812192F6F70656E70726F6D2F636C69656E742D7365727669636573120B66696E642D646576696365CD120B5B275D2071756965736365CDC30800CA07717569657363650802B708001D08011DC2120A6465766963652D656E64CDCA055F2E6C2E720803B7120C00000024FFFF0000800300001000004000B14A4AA74EA74EA74E7AA53C1400205210000000041E4710FFF80000497310800000004910000000041E7333B24A10000000041E471003FFFFF83C14FFC54652C2120470767240CD10FFFF00002310800400003C140009110803C30801B200)" dup -rot alloc-mem dup 2swap -rot move 1 byte-load \ PLX-OSX-PATCH
Also, any OF gurus, can we create some colon definitions in OF to set the DFS modes of the 7448, we already have words for the 7447a to would apply to the 7448, setting HID1 bit 9 to one or zero. ( set-dfs-high and set-dfs-low).

Code: [Select]
0 > see set-dfs-low
:
set-dfs-low               
  pvr@ 10 rshift 8003 <> if
    exit
    else
    hid1@ 1 1f 9 - lshift or hid1! 1 ms 4 1 gpio!
    then
  ; ok

So a patch for the 7448 would be something like:

Code: [Select]
:
set-dfs-7448-low               
  pvr@ 10 rshift 8004 <> if // we do this small change to check we are running on a 7448 PVR
    exit
    else
    hid1@ 1 1f 9 - lshift or hid1! 1 ms 4 1 gpio!
    then
  ; ok

And setting HID1 DFS4 ( bit 8 ) to 1 should get us 1/4 speed:

Code: [Select]
0 > : set-dfs-real-low pvr@ 10 rshift 8004 <> if exit else hid1@ 1 1f 8 - lshift or hid1! 1 ms 4 1 gpio! then ;  ok
0 > see set-dfs-real-low
:
set-dfs-real-low         
  pvr@ 10 rshift 8004 <> if   // We check for a 7448 PVR
    exit
    else
    hid1@ 1 1f 8 - lshift or hid1! 1 ms 4 1 gpio! // Not sure this is correct?
    then
  ; ok


I don't understand what HID1@ and HID1! do, surely I understand it's accessing HID1 I just don't understand @ and !.

Next 1 1f 8, I don't understand what the 1f does?

Then we have the 1 ms 4 1 gpio!, we are waiting on ms, but what does the 4 1 gpio! do?


Offline Daniel

  • Gold Member
  • *****
  • Posts: 300
  • Programmer, Hacker, Thinker
Re: 7448 mysteries?
« Reply #1 on: February 13, 2021, 02:41:39 PM »
Open Firmware syntax lets you encode arbitrary bytes as hex pairs in a string literal. It's used when the literal is a binary blob rather than text, and you don't want to be limited to just printable characters in your string.
Code: [Select]
" "(xxxx)"

Here's a breakdown of the code, annotated with what the stack looks like at the end of each line.

Code: [Select]
" "(xxxx)" ( str-base str-len)
dup -rot ( str-len str-base str-len)
alloc-mem ( str-len str-base mem-base)
dup 2swap ( mem-base mem-base str-len str-base)
-rot ( mem-base str-len str-base mem-base str-len)
move ( mem-base)
1 byte-load ( )

So the NVRAM script takes a hex string, copies it into memory, and then uses byte-load to run it as a FCode script. The memory isn't freed afterwards, which isn't that big a deal for OF.

Code: [Select]
F1084C2A00000103120A6465766963652D656E64CDA5CA065F2E6C2E72310800B8A5CA065F2E6C2E72320801B812192F6F70656E70726F6D2F636C69656E742D7365727669636573120B66696E642D646576696365CD120B5B275D2071756965736365CDC30800CA07717569657363650802B708001D08011DC2120A6465766963652D656E64CDCA055F2E6C2E720803B7120C00000024FFFF0000800300001000004000B14A4AA74EA74EA74E7AA53C1400205210000000041E4710FFF80000497310800000004910000000041E7333B24A10000000041E471003FFFFF83C14FFC54652C2120470767240CD10FFFF00002310800400003C140009110803C30801B200
So what does the FCode script do? I have no idea. To figure it out, we will have to detokenize it into Forth source code. While you certainly can go to section "G.2 Assigned FCode numbers" of the "IEEE Standard for Boot (Initialization Configuration) Firmware: Core Requirements and Practices" pdf and manually decode each byte, I do not recommend it. Instead, compile and run the tool at this url. https://github.com/openbios/fcode-utils/tree/master/detok. It will do most of the work for you.

You will probably have to convert the hex pairs into raw bytes in a file before the tool can use it. Google suggests the following command, though I havn't tested it myself.
Code: [Select]
xxd -r -p input.hex output.bin

Good luck, have fun.

Offline Daniel

  • Gold Member
  • *****
  • Posts: 300
  • Programmer, Hacker, Thinker
Re: 7448 mysteries?
« Reply #2 on: February 13, 2021, 02:54:11 PM »
@ means "fetch", and ! means "store". So HID1@ reads HID1, and HID1! writes HID1.

Code: [Select]
1 1f 9 - lshift

Code: [Select]
1 << (31-9)

PowerPC numbers bits starting with MSB=0. Bit 0 is 0x80000000, but 1<<0 = 1. Code to get the mask for an arbitrary bit number must convert the PowerPC convention into a format that the left-shift operator can use (they could have done it with 0x80000000 >> bit, but chose not to).

Offline darthnVader

  • Platinum Member
  • *****
  • Posts: 679
  • New Member
Re: 7448 mysteries?
« Reply #3 on: February 13, 2021, 09:00:45 PM »
Open Firmware syntax lets you encode arbitrary bytes as hex pairs in a string literal. It's used when the literal is a binary blob rather than text, and you don't want to be limited to just printable characters in your string.
Code: [Select]
" "(xxxx)"

Here's a breakdown of the code, annotated with what the stack looks like at the end of each line.

Code: [Select]
" "(xxxx)" ( str-base str-len)
dup -rot ( str-len str-base str-len)
alloc-mem ( str-len str-base mem-base)
dup 2swap ( mem-base mem-base str-len str-base)
-rot ( mem-base str-len str-base mem-base str-len)
move ( mem-base)
1 byte-load ( )

So the NVRAM script takes a hex string, copies it into memory, and then uses byte-load to run it as a FCode script. The memory isn't freed afterwards, which isn't that big a deal for OF.

Code: [Select]
F1084C2A00000103120A6465766963652D656E64CDA5CA065F2E6C2E72310800B8A5CA065F2E6C2E72320801B812192F6F70656E70726F6D2F636C69656E742D7365727669636573120B66696E642D646576696365CD120B5B275D2071756965736365CDC30800CA07717569657363650802B708001D08011DC2120A6465766963652D656E64CDCA055F2E6C2E720803B7120C00000024FFFF0000800300001000004000B14A4AA74EA74EA74E7AA53C1400205210000000041E4710FFF80000497310800000004910000000041E7333B24A10000000041E471003FFFFF83C14FFC54652C2120470767240CD10FFFF00002310800400003C140009110803C30801B200
So what does the FCode script do? I have no idea. To figure it out, we will have to detokenize it into Forth source code. While you certainly can go to section "G.2 Assigned FCode numbers" of the "IEEE Standard for Boot (Initialization Configuration) Firmware: Core Requirements and Practices" pdf and manually decode each byte, I do not recommend it. Instead, compile and run the tool at this url. https://github.com/openbios/fcode-utils/tree/master/detok. It will do most of the work for you.

You will probably have to convert the hex pairs into raw bytes in a file before the tool can use it. Google suggests the following command, though I havn't tested it myself.
Code: [Select]
xxd -r -p input.hex output.bin

Good luck, have fun.

Cool, thanks.

Code: [Select]
\  Welcome to detok - FCode detokenizer v1.0.3
\  (C) Copyright 2001-2010 Stefan Reinauer
\  (C) Copyright 2006 coresystems GmbH
\  (C) Copyright 2005 IBM Corporation.  All Rights Reserved.
\  Written by Stefan Reinauer
\  This program is free software; you may redistribute it under the terms of
\  the GNU General Public License v2. This program has absolutely no warranty.

start1 ( 0x0f1 )   ( 16-bit offsets)
  format:    0x08
  checksum:  0x4c2a (Ok)
  len:       0x0103 ( 259 bytes)
b(") ( 0x012 ) ( len=0xa [10 bytes] )
" device-end"
evaluate ( 0x0cd )
0 ( 0x0a5 )
external-token ( 0x0ca ) _.l.r1 0x800
b(value) ( 0x0b8 )
0 ( 0x0a5 )
external-token ( 0x0ca ) _.l.r2 0x801
b(value) ( 0x0b8 )
b(") ( 0x012 ) ( len=0x19 [25 bytes] )
" /openprom/client-services"
b(") ( 0x012 ) ( len=0xb [11 bytes] )
" find-device"
evaluate ( 0x0cd )
b(") ( 0x012 ) ( len=0xb [11 bytes] )
" ['] quiesce"
evaluate ( 0x0cd )
b(to) ( 0x0c3 ) _.l.r1 ( 0x800 )
external-token ( 0x0ca ) quiesce 0x802
b(:) ( 0x0b7 )
    _.l.r1 ( 0x800 )
    execute ( 0x01d )
    _.l.r2 ( 0x801 )
    execute ( 0x01d )
b(;) ( 0x0c2 )
b(") ( 0x012 ) ( len=0xa [10 bytes] )
" device-end"
evaluate ( 0x0cd )
external-token ( 0x0ca ) _.l.r 0x803
b(:) ( 0x0b7 )
    b(") ( 0x012 ) ( len=0xc [12 bytes] )
    " "( 00 00 00 )$"( ff ff 00 00 80 03 00 00 )"
    b(lit) ( 0x010 ) 0x4000
    b(<mark) ( 0x0b1 )
        rot ( 0x04a )
        rot ( 0x04a )
        2 ( 0x0a7 )
        pick ( 0x04e )
        2 ( 0x0a7 )
        pick ( 0x04e )
        2 ( 0x0a7 )
        pick ( 0x04e )
        comp ( 0x07a )
        0 ( 0x0a5 )
        = ( 0x03c )
        b?branch ( 0x014 ) 0x0020 ( =dec 32)
            2drop ( 0x052 )
            b(lit) ( 0x010 ) 0x4
            + ( 0x01e )
            dup ( 0x047 )
            b(lit) ( 0x010 ) 0xfff80000
            swap ( 0x049 )
            l! ( 0x073 )
            b(lit) ( 0x010 ) 0x80000000
            swap ( 0x049 )
            b(lit) ( 0x010 ) 0x4
            + ( 0x01e )
            l! ( 0x073 )
            exit ( 0x033 )
        b(>resolve) ( 0x0b2 )
        rot ( 0x04a )
        b(lit) ( 0x010 ) 0x4
        + ( 0x01e )
        dup ( 0x047 )
        b(lit) ( 0x010 ) 0x3fffff8
        = ( 0x03c )
        b?branch ( 0x014 ) 0xffc5 ( =dec -59)
    drop ( 0x046 )
    2drop ( 0x052 )
b(;) ( 0x0c2 )
b(") ( 0x012 ) ( len=4 )
" pvr@"
evaluate ( 0x0cd )
b(lit) ( 0x010 ) 0xffff0000
and ( 0x023 )
b(lit) ( 0x010 ) 0x80040000
= ( 0x03c )
b?branch ( 0x014 ) 0x0009 ()
    b(') ( 0x011 ) _.l.r ( 0x803 )
    b(to) ( 0x0c3 ) _.l.r2 ( 0x801 )
b(>resolve) ( 0x0b2 )
end0 ( 0x000 )
\  Detokenization finished normally after 259 bytes.
End of file.