1 /* bootROM, a very small bootloader for $NAME
4 * abbrv: H = Host, CPU = C
6 * value/cmd | direction | comment
7 * ------------------------------------------------------------
8 * 'H' | H -> C | enter bootROM ("HI")
9 * 'O' | C -> H | ack bootROM entry ("OH HAI")
11 * 'W'0xZZZZZZZZ0xYYYYYYYY| H -> C | write instr (0xYY...Y) to
12 * | address (0xZZ...Z)
13 * 'D' | C -> H | instr write done
15 * 'R'0xZZZZZZZZ | H -> C | read instr from address (0xZZ..Z)
16 * 'F'0xYYYYYYYY | C -> H | instr read done and return instr
18 * 'Q'0xZZZZZZZZ0xYYYYYYYY| H -> C | write data (0xYY...Y) to
19 * | address (0xZZ...Z)
20 * 'A' | C -> H | data write done
22 * 'T'0xZZZZZZZZ | H -> C | read data from address (0xZZ..Z)
23 * 'G'0xYYYYYYYY | C -> H | read done and return data
25 * 'J'0xZZZZZZZZ | H -> C | jump to address (0xZZ...Z)
28 #define UART_BASE 0x1000
29 #define UART_STATUS (UART_BASE+0x4)
30 #define UART_RECV (UART_BASE+0x8)
31 #define UART_TRANS (UART_BASE+0xC)
32 #define UART_BAUD (UART_BAUD+0x10)
34 #define UART_TRANS_EMPTY 0
35 #define UART_RECV_NEW 1
38 * - uart: clear new_receive bit after the byte is copied?
39 * (implementation issue...)
42 /* {d,i}{read,write}{8,32}:
44 * i ... instruction space
47 typedef unsigned char u8;
48 typedef unsigned int u32;
52 while(!(dread32(UART_STATUS) & (1 << UART_TRANS_EMPTY)));
53 dwrite8(UART_TRANS, x);
58 send_byte((x >> 0) & 0xff);
59 send_byte((x >> 8) & 0xff);
60 send_byte((x >> 16) & 0xff);
61 send_byte((x >> 24) & 0xff);
67 while(!(dread32(UART_STATUS) & (1 << UART_RECV_NEW)));
68 ret = dread8(UART_RECV);
74 ret |= recv_byte() << 0;
75 ret |= recv_byte() << 8;
76 ret |= recv_byte() << 16;
77 ret |= recv_byte() << 24;
90 /* write to programm space */
91 iwrite32(addr, instr);
96 instr = iread32(addr);
103 /* write to data space */
104 dwrite32(addr, instr);
109 instr = dread32(addr);
115 jump_to_instr_mem(addr);
116 /* this should never return ;) */
127 #define TIMEOUT_START 0x13371337
128 #define DEFAULT_PROG_START 0x200
132 /* wait for timeout */
133 u32 to = TIMEOUT_START;
136 /* until to is zeros */
139 if(dread32(UART_STATUS) & (1 << UART_RECV_NEW)) {
140 rec = read8(UART_RECV);
148 /* after timeout jump to instr. mem plz */
149 jump_to_instr_mem(DEFAULT_PROG_START);