[ Index ] [ Prev: Playing With The Hardware ] [ Next: Taming The MMU ]
So, I now could run arbitrary code on the box. But how far did it go? And how could it talk to me?
An easy way would be to have the code send characters to the serial port. But, on the ZSCC, this requires a few delays between registers programming, which can be a bit tedious. So, before I could be in a good enough situation to be able to talk over serial, I needed something simpler... and glancing at idt/cpuboard.h, I realized the front LED has 6 different states:
/* board status register */ #define iGLU_BSR (iGLU_BASE + 0x0001800) /* physical address */ # define BSR_LED 0x07 /* mask for LED control bits */ # define BSR_LED_OFF 0x00 /* LED off */ # define BSR_LED_YEL 0x02 /* LED yellow */ # define BSR_LED_BYEL 0x03 /* LED blink yellow */ # define BSR_LED_GRN 0x04 /* LED green */ # define BSR_LED_BGRN 0x05 /* LED blink green */ # define BSR_LED_BALT 0x07 /* LED blink alternating yellow/green */This would be good enough for a while...
So, I naively put something like this at the very beginning of my locore.s:
set 0x60001800, %l1 ! iGLU_BSR ld [%l1], %l2 andn %l2, 7, %l2 or %l2, 2, %l2 ! fixed amber st %l2, [%l1]Unfortunately for me, the LED did not become amber (the header file says yellow, but it lies). Yet the PROM had loaded and run my code! What could be wrong?
Nothing was wrong, really. Except that, when writing this code, I had made the following assumptions:
These are easy to check at the PROM, with some Forth code. Moreover, the PROM even defines an iglu-bsr symbol!
ok iglu-bsr . 60001800 okSo my first assumption is correct. Let's verify the second one:
ok iglu-bsr l@ . 1c019138It is correct. But something's fishy. The idt/cpuboard.h file only defines values for the low 6 bits of this register, so we should not have a value greater than 0000003f here...
Let's read it again.
ok iglu-bsr l@ . 1c3f40c2 okInteresting. It looks like the top 8 bits are our value, while the low 24 bits are simply noise from the bus latches. Let's prove it by changing the LED status! Here our value was 1c, so the LED bits were 04 (1c & 07), solid green. If we want to turn this into flashing amber, we need to do something like this:
ok iglu-bsr l@ f8000000 and 03000000 or iglu-bsr l! okand the LED indeed turned flashing amber (the Forth sequence above reads iglu-bsr, ands the value read with f8000000, thus masking the low 24 bits and the LED mask, then ors it with 03000000, thus selecting BSR_LED_BYEL shifted 24 bits, and writes it into iglu-bsr).
My code quickly became:
ENTRY(blink) ! void blink(int); save %sp, -64, %sp set 0x60001800, %l1 ! iGLU_BSR ld [%l1], %l2 srl %l2, 24, %l2 andn %l2, 7, %l2 ! BSR_LED or %l2, %i0, %l2 sll %l2, 24, %l2 st %l2, [%l1] ret restore [...] #define BLINK(how) \ call _C_LABEL(blink); \ mov how, %o0 [...] BLINK(2) ! fixed amberand I could pick my favorite LED state, and even call blink() from C code...
[ Index ] [ Prev: Playing With The Hardware ] [ Next: Taming The MMU ]