9 #include <generated/mem.h>
10 #include <generated/csr.h>
12 #include <net/microudp.h>
17 extern void boot_helper(unsigned int r1
, unsigned int r2
, unsigned int r3
, unsigned int addr
);
19 static void __attribute__((noreturn
)) boot(unsigned int r1
, unsigned int r2
, unsigned int r3
, unsigned int addr
)
21 printf("Executing booted program.\n");
26 boot_helper(r1
, r2
, r3
, addr
);
30 static int check_ack(void)
33 static const char str
[SFL_MAGIC_LEN
] = SFL_MAGIC_ACK
;
36 timer0_reload_write(0);
37 timer0_load_write(identifier_frequency_read()/4);
39 timer0_update_value_write(1);
41 while(timer0_value_read()) {
42 if(uart_read_nonblock()) {
45 if(c
== str
[recognized
]) {
47 if(recognized
== SFL_MAGIC_LEN
)
56 timer0_update_value_write(1);
65 struct sfl_frame frame
;
67 unsigned int cmdline_adr
, initrdstart_adr
, initrdend_adr
;
68 static const char str
[SFL_MAGIC_LEN
+1] = SFL_MAGIC_REQ
;
71 printf("Booting from serial...\n");
84 cmdline_adr
= initrdstart_adr
= initrdend_adr
= 0;
91 frame
.length
= uart_read();
92 frame
.crc
[0] = uart_read();
93 frame
.crc
[1] = uart_read();
94 frame
.cmd
= uart_read();
95 for(i
=0;i
<frame
.length
;i
++)
96 frame
.payload
[i
] = uart_read();
99 actualcrc
= ((int)frame
.crc
[0] << 8)|(int)frame
.crc
[1];
100 goodcrc
= crc16(&frame
.cmd
, frame
.length
+1);
101 if(actualcrc
!= goodcrc
) {
103 if(failed
== MAX_FAILED
) {
104 printf("Too many consecutive errors, aborting");
107 uart_write(SFL_ACK_CRCERROR
);
115 uart_write(SFL_ACK_SUCCESS
);
121 writepointer
= (char *)(
122 ((unsigned int)frame
.payload
[0] << 24)
123 |((unsigned int)frame
.payload
[1] << 16)
124 |((unsigned int)frame
.payload
[2] << 8)
125 |((unsigned int)frame
.payload
[3] << 0));
126 for(i
=4;i
<frame
.length
;i
++)
127 *(writepointer
++) = frame
.payload
[i
];
128 uart_write(SFL_ACK_SUCCESS
);
135 addr
= ((unsigned int)frame
.payload
[0] << 24)
136 |((unsigned int)frame
.payload
[1] << 16)
137 |((unsigned int)frame
.payload
[2] << 8)
138 |((unsigned int)frame
.payload
[3] << 0);
139 uart_write(SFL_ACK_SUCCESS
);
140 boot(cmdline_adr
, initrdstart_adr
, initrdend_adr
, addr
);
143 case SFL_CMD_CMDLINE
:
145 cmdline_adr
= ((unsigned int)frame
.payload
[0] << 24)
146 |((unsigned int)frame
.payload
[1] << 16)
147 |((unsigned int)frame
.payload
[2] << 8)
148 |((unsigned int)frame
.payload
[3] << 0);
149 uart_write(SFL_ACK_SUCCESS
);
151 case SFL_CMD_INITRDSTART
:
153 initrdstart_adr
= ((unsigned int)frame
.payload
[0] << 24)
154 |((unsigned int)frame
.payload
[1] << 16)
155 |((unsigned int)frame
.payload
[2] << 8)
156 |((unsigned int)frame
.payload
[3] << 0);
157 uart_write(SFL_ACK_SUCCESS
);
159 case SFL_CMD_INITRDEND
:
161 initrdend_adr
= ((unsigned int)frame
.payload
[0] << 24)
162 |((unsigned int)frame
.payload
[1] << 16)
163 |((unsigned int)frame
.payload
[2] << 8)
164 |((unsigned int)frame
.payload
[3] << 0);
165 uart_write(SFL_ACK_SUCCESS
);
169 if(failed
== MAX_FAILED
) {
170 printf("Too many consecutive errors, aborting");
173 uart_write(SFL_ACK_UNKNOWN
);
179 #ifdef CSR_ETHMAC_BASE
185 #define REMOTEIP1 192
186 #define REMOTEIP2 168
190 static int tftp_get_v(unsigned int ip
, const char *filename
, char *buffer
)
194 r
= tftp_get(ip
, filename
, buffer
);
196 printf("Successfully downloaded %d bytes from %s over TFTP\n", r
, filename
);
198 printf("Unable to download %s over TFTP\n", filename
);
202 static const unsigned char macadr
[6] = {0x10, 0xe2, 0xd5, 0x00, 0x00, 0x00};
207 unsigned int cmdline_adr
, initrdstart_adr
, initrdend_adr
;
210 printf("Booting from network...\n");
211 printf("Local IP : %d.%d.%d.%d\n", LOCALIP1
, LOCALIP2
, LOCALIP3
, LOCALIP4
);
212 printf("Remote IP: %d.%d.%d.%d\n", REMOTEIP1
, REMOTEIP2
, REMOTEIP3
, REMOTEIP4
);
214 ip
= IPTOINT(REMOTEIP1
, REMOTEIP2
, REMOTEIP3
, REMOTEIP4
);
216 microudp_start(macadr
, IPTOINT(LOCALIP1
, LOCALIP2
, LOCALIP3
, LOCALIP4
));
218 if(tftp_get_v(ip
, "boot.bin", (void *)MAIN_RAM_BASE
) <= 0) {
219 printf("Network boot failed\n");
223 cmdline_adr
= MAIN_RAM_BASE
+0x1000000;
224 size
= tftp_get_v(ip
, "cmdline.txt", (void *)cmdline_adr
);
226 printf("No command line parameters found\n");
229 *((char *)(cmdline_adr
+size
)) = 0x00;
231 initrdstart_adr
= MAIN_RAM_BASE
+0x1002000;
232 size
= tftp_get_v(ip
, "initrd.bin", (void *)initrdstart_adr
);
234 printf("No initial ramdisk found\n");
238 initrdend_adr
= initrdstart_adr
+ size
;
240 boot(cmdline_adr
, initrdstart_adr
, initrdend_adr
, MAIN_RAM_BASE
);
245 #ifdef FLASH_BOOT_ADDRESS
248 unsigned int *flashbase
;
251 unsigned int got_crc
;
253 printf("Booting from flash...\n");
254 flashbase
= (unsigned int *)FLASH_BOOT_ADDRESS
;
255 length
= *flashbase
++;
257 if((length
< 32) || (length
> 4*1024*1024)) {
258 printf("Error: Invalid flash boot image length 0x%08x\n", length
);
262 printf("Loading %d bytes from flash...\n", length
);
263 memcpy((void *)MAIN_RAM_BASE
, flashbase
, length
);
264 got_crc
= crc32((unsigned char *)MAIN_RAM_BASE
, length
);
266 printf("CRC failed (expected %08x, got %08x)\n", crc
, got_crc
);
269 boot(0, 0, 0, MAIN_RAM_BASE
);
273 #ifdef ROM_BOOT_ADDRESS
274 /* When firmware is small enough, it can be interesting to run code from an
275 embedded blockram memory (faster and not impacted by memory controller
276 activity). Define ROM_BOOT_ADDRESS for that and initialize the blockram
277 with the firmware data. */
280 boot(0, 0, 0, ROM_BOOT_ADDRESS
);