greystash
greystash

Reputation: 337

Using Open Firmware to set hardware defaults

I know this is a long shot asking for advice on Open Firmware and old hardware..

I've managed to install and boot Mac OS 9 (unsupported) on a PowerBook G4. The machine gets rather hot after ~1hrs use due to OS9 not being able to manage cooling on unsupported hardware.

I have managed to turn the fans on from boot using Open Firmware and the following code:

" fan" open-dev constant fan-ih

" fans-on" fan-ih $call-method

This runs the fans at full speed but I only want them running at either 50%, or to change the hardware temp limits for when they kick in.

However, I can't figure out how to work with any of the routines. There's a lot of options that look like they can be modified but it's a matter of figuring out the correct syntax to overwrite the default values. For example 'set-speed' and '.set-speed' give very different output when using the 'see' method and don't give much indication on what can be edited:

> see .speed
1 read-speed cr " TACH1 = " type .d 2 read-speed cr " TACH2 = " type .d 3 read-speed cr " TACH3 = " type .d 4 read-speed cr " TACH4 = type .d ; ok
> see set-speed
>r 40 dup read-reg 8 andc write-reg case
    1 of
      5c dup read-reg e0 or write-reg 30 r> write-reg
      endof
    2 of
      5d dup read-reg e0 or write-reg 31 r> write-reg
      endof
    3 of
      5e dup read-reg e0 or write-reg 32 r> write-reg
      endof
    dup of
      5e dup read-reg e0 or write-reg 32 r> write-reg
      endof
  endcase
; ok
> see set-speeds
1 over set-speed 2 over set-speed 3 swap set-speed

Any help would be greatly appreciated!

Upvotes: 0

Views: 618

Answers (4)

Mitch Bradley
Mitch Bradley

Reputation: 56

That looks good. The dev fan and subsequent device-end lines are unnecessary but harmless, as open-dev and $call-method do not need to be inside a device node context to work. The first dev /cpus/PowerPC,G4@0 and its closing device-end are necessary, as property does have to be done from inside a device node. Enjoy!

Upvotes: 2

greystash
greystash

Reputation: 337

Thanks so much Mitch and Randy! I couldn't format this properly in a comment so I've posted it as an answer. I've managed to get it working using the following script:

\ comment
cr
dev /cpus/PowerPC,G4@0
80010201 encode-int " cpu-version" property
device-end
dev fan
" fan" open-dev constant fan-ih
1 3B6 " set-speed" fan-ih $call-method
2 3B6 " set-speed" fan-ih $call-method
device-end
boot hd:,\\:tbxi

I then changed the boot device to the following so it loads automatically on boot: setenv boot-device hd:\bootscript

Thanks so much I really appreciate it! I'm so glad to have this PowerBook running Mac OS 9, it's so fast! Will keep working on this.

Upvotes: 0

Mitch Bradley
Mitch Bradley

Reputation: 56

I largely agree with Randy, but it appears to me that set-speed takes two arguments. The top of the stack is some value that relates to the desired speed, and underneath that is the fan number (1, 2 or 3).

in Forth stack diagram notation, those words would be described as:

.speed  ( -- )  \ Display the speeds of all the fans
set-speed  ( fan# speed -- )  \ Set the speed of one fan
set-speeds  ( speed -- )  \ Set  the speeds of all the fans

It's a fair guess that the numbers displayed by .speed are the same numbers that can be used as speed arguments to set-speed and set-speeds. If that is correct, then the following incantation could be used to halve the speeds:

" fan" open-dev constant fan-ih
" fans-on" fan-ih $call-method
TACH1 = <some number>
TACH2 = <some number>
TACH3 = <some number>

For the sake of argument, assume that

decimal 46 2 / "set-speeds" fan-ih $call-method

is very likely to halve the speed of all the fans.

There are more streamlined ways of writing this by using words like select-dev, depending on exactly which convenience words the Apple OFW implements, but the above uses only words that the standard requires so it is reliable across different implementations.

If you want to find all the words that relate to fan control, you can write:

dev fan
words

and then decompile them with see.

You might be able to automate the setting of the fan speed by putting the commands in nvramrc.

Upvotes: 2

Randy Leberknight
Randy Leberknight

Reputation: 1463

In Forth and Open Firmware, starting the name of a word with a period, (pronounced dot) is an indicator that this word will print something. For example, to print (and drop) the top number from the parameter stack, the word we call is . (yes, that is a period, and it is a forth word).

So .speed means "print the speed information. 1 read-speed reads the speed for tach1, and places the value on the parameter stack.

cr " TACH1 = " type prints a carriage return and the string TACH1 =

.d prints the value which read-speed put on the stack. The d means print the value in decimal.

set-speed looks like it takes 3 parameters (enter them at the command line before calling set-speed). (speed tach-number address?) So it looks like the last parameter you type (which will be on the top of the parameter stack when you call set-speed) is some kind of address, but I'm a little unclear on exactly what it is. So calling set-speed might be something like: 1 set-speed 2 set-speed

I am inferring this from the decompilation you showed.

I don't think this is quite enough info, (I'm quite rusty on this stuff) but it might get you a little farther along.

Perhaps you could show the output of:

see read-reg

and see write-reg

That might help a bit.

Upvotes: 2

Related Questions