Tuesday, May 20, 2008

Why Open Firmware is pretty neat

I've just been impressed by the power of Open Firmware again. I'm currently tinkering with the decrementer and time base registers on a PowerPC processor and I need to find out if some of my assumptions are correct.

One way to do that is to compile my C code, load and start it over the network and see if things work the way I think they should work. While this works, it's somewhat time consuming.

Another way of doing this is to use the Open Firmware user interface - a full featured Forth system. As such, it offers very powerful features during development. In fact, everything entered at the client interface could also be compiled into a forth word, which could even be included in the firmware's dictionary.

So let's take a look at the base conversion features Forth offers.
0> decimal
0> 63 19 - dup .
44 OK
1> hex .
2c OK
The code above switches the default number base to decimal. Then the (decimal) numbers 63 and 19 are placed on the stack and a subtraction (63 - 19) is performed. What ends up on the stack is the result of the math operation. We duplicate the item (basically saving a copy for later use) and then pop and display the top value. The result is 44, i.e. the result of the subtraction when calculating with decimal numbers.
Now we're switching the number base to hexadecimal again, and display the stack's topmost value (we saved the calculation result before). The result is 2c, i.e. 44 displayed as a hexadecimal number.

Next up, logical operations. A left shift is defined as
lshift (value count -- value)
meaning you place value on the stack, place the amount of bits you want it to be shifted (count) on the stack and when the lshift word returns, the shifted value will be on the stack. So take a look at this:
o> decimal 63 19 - hex
1> 1 swap lshift
1> dup .
100000000000  OK
The first line is the subtraction explained above. Then, we push a 1 on the stack and swap the two top most items. The stack now looks like ( 1 2c ) which we'll feed the lshift operator. We duplicate the result and display one copy. And there's bitmask, where the 44th bit is set.

Going further to the more firmware specific parts. The Open Firmware implementation I'm using right now offers a word that let's me read the boot processor's HID0 register. The word is hid0@, it takes no input and places the register's value on the stack. Similarily, there's a word that let's me write the register, it's hid0!. It takes one argument from the stack and doesn't place anything on the stack.
So take the next sequence. I'm assuming it's executed right after the previously quoted sequence, so the calculated bitmask should be on the stack.
2> dup .
100080000000 OK
2> or dup .
100080000000 OK
1> First, we read the HID0's value and display it in a non-destructive manner. Then we or the bitmask and the register value and display it's result. Note that the result is the same, meaning the 44th bit was already set. Then, we write the value back to the register.

This is just an example of the power of Open Firmware. I'm going to play some other tricks right now, but I wanted this to be written down first so I can look it up again.

No comments: