901b27445818f1f59a469d93edcb1827f966d639
9 #include <generated/mem.h>
10 #include <generated/csr.h>
12 #ifdef CSR_ETHMAC_BASE
13 #include <net/microudp.h>
20 extern void boot_helper(unsigned long r1
, unsigned long r2
, unsigned long r3
, unsigned long addr
);
22 static void __attribute__((noreturn
)) boot(unsigned long r1
, unsigned long r2
, unsigned long r3
, unsigned long addr
)
24 printf("Executing booted program at 0x%08x\n", addr
);
28 /* FIXME: understand why flushing icache on Vexriscv make boot fail */
36 boot_helper(r1
, r2
, r3
, addr
);
46 static int check_ack(void)
49 static const char str
[SFL_MAGIC_LEN
] = SFL_MAGIC_ACK
;
52 timer0_reload_write(0);
53 timer0_load_write(SYSTEM_CLOCK_FREQUENCY
/4);
55 timer0_update_value_write(1);
57 while(timer0_value_read()) {
58 if(uart_read_nonblock()) {
61 if((c
== 'Q') || (c
== '\e'))
63 if(c
== str
[recognized
]) {
65 if(recognized
== SFL_MAGIC_LEN
)
74 timer0_update_value_write(1);
81 /* Returns 1 if other boot methods should be tried */
84 struct sfl_frame frame
;
86 unsigned long cmdline_adr
, initrdstart_adr
, initrdend_adr
;
87 static const char str
[SFL_MAGIC_LEN
+1] = SFL_MAGIC_REQ
;
91 printf("Booting from serial...\n");
92 printf("Press Q or ESC to abort boot completely.\n");
99 ack_status
= check_ack();
100 if(ack_status
== ACK_TIMEOUT
) {
104 if(ack_status
== ACK_CANCELLED
) {
105 printf("Cancelled\n");
111 cmdline_adr
= initrdstart_adr
= initrdend_adr
= 0;
118 frame
.length
= uart_read();
119 frame
.crc
[0] = uart_read();
120 frame
.crc
[1] = uart_read();
121 frame
.cmd
= uart_read();
122 for(i
=0;i
<frame
.length
;i
++)
123 frame
.payload
[i
] = uart_read();
126 actualcrc
= ((int)frame
.crc
[0] << 8)|(int)frame
.crc
[1];
127 goodcrc
= crc16(&frame
.cmd
, frame
.length
+1);
128 if(actualcrc
!= goodcrc
) {
130 if(failed
== MAX_FAILED
) {
131 printf("Too many consecutive errors, aborting");
134 uart_write(SFL_ACK_CRCERROR
);
142 uart_write(SFL_ACK_SUCCESS
);
148 writepointer
= (char *)(
149 ((unsigned long)frame
.payload
[0] << 24)
150 |((unsigned long)frame
.payload
[1] << 16)
151 |((unsigned long)frame
.payload
[2] << 8)
152 |((unsigned long)frame
.payload
[3] << 0));
153 for(i
=4;i
<frame
.length
;i
++)
154 *(writepointer
++) = frame
.payload
[i
];
155 uart_write(SFL_ACK_SUCCESS
);
162 addr
= ((unsigned long)frame
.payload
[0] << 24)
163 |((unsigned long)frame
.payload
[1] << 16)
164 |((unsigned long)frame
.payload
[2] << 8)
165 |((unsigned long)frame
.payload
[3] << 0);
166 uart_write(SFL_ACK_SUCCESS
);
167 boot(cmdline_adr
, initrdstart_adr
, initrdend_adr
, addr
);
170 case SFL_CMD_CMDLINE
:
172 cmdline_adr
= ((unsigned long)frame
.payload
[0] << 24)
173 |((unsigned long)frame
.payload
[1] << 16)
174 |((unsigned long)frame
.payload
[2] << 8)
175 |((unsigned long)frame
.payload
[3] << 0);
176 uart_write(SFL_ACK_SUCCESS
);
178 case SFL_CMD_INITRDSTART
:
180 initrdstart_adr
= ((unsigned long)frame
.payload
[0] << 24)
181 |((unsigned long)frame
.payload
[1] << 16)
182 |((unsigned long)frame
.payload
[2] << 8)
183 |((unsigned long)frame
.payload
[3] << 0);
184 uart_write(SFL_ACK_SUCCESS
);
186 case SFL_CMD_INITRDEND
:
188 initrdend_adr
= ((unsigned long)frame
.payload
[0] << 24)
189 |((unsigned long)frame
.payload
[1] << 16)
190 |((unsigned long)frame
.payload
[2] << 8)
191 |((unsigned long)frame
.payload
[3] << 0);
192 uart_write(SFL_ACK_SUCCESS
);
196 if(failed
== MAX_FAILED
) {
197 printf("Too many consecutive errors, aborting");
200 uart_write(SFL_ACK_UNKNOWN
);
207 #ifdef CSR_ETHMAC_BASE
217 #define REMOTEIP1 192
218 #define REMOTEIP2 168
220 #define REMOTEIP4 100
223 #define DEFAULT_TFTP_SERVER_PORT 69 /* IANA well known port: UDP/69 */
224 #ifndef TFTP_SERVER_PORT
225 #define TFTP_SERVER_PORT DEFAULT_TFTP_SERVER_PORT
228 static int tftp_get_v(unsigned int ip
, unsigned short server_port
,
229 const char *filename
, char *buffer
)
233 r
= tftp_get(ip
, server_port
, filename
, buffer
);
235 printf("Successfully downloaded %d bytes from %s over TFTP\n", r
, filename
);
237 printf("Unable to download %s over TFTP\n", filename
);
241 static const unsigned char macadr
[6] = {0x10, 0xe2, 0xd5, 0x00, 0x00, 0x00};
246 unsigned long cmdline_adr
, initrdstart_adr
, initrdend_adr
;
248 unsigned short tftp_port
;
250 printf("Booting from network...\n");
251 printf("Local IP : %d.%d.%d.%d\n", LOCALIP1
, LOCALIP2
, LOCALIP3
, LOCALIP4
);
252 printf("Remote IP: %d.%d.%d.%d\n", REMOTEIP1
, REMOTEIP2
, REMOTEIP3
, REMOTEIP4
);
254 ip
= IPTOINT(REMOTEIP1
, REMOTEIP2
, REMOTEIP3
, REMOTEIP4
);
256 microudp_start(macadr
, IPTOINT(LOCALIP1
, LOCALIP2
, LOCALIP3
, LOCALIP4
));
258 tftp_port
= TFTP_SERVER_PORT
;
259 printf("Fetching from: UDP/%d\n", tftp_port
);
261 size
= tftp_get_v(ip
, tftp_port
, "boot.bin", (void *)MAIN_RAM_BASE
);
263 if ((size
<= 0) && (tftp_port
!= DEFAULT_TFTP_SERVER_PORT
)) {
264 /* Try default TFTP port if timed out on non-standard port */
265 tftp_port
= DEFAULT_TFTP_SERVER_PORT
;
266 printf("Fetching from: UDP/%d\n", tftp_port
);
268 size
= tftp_get_v(ip
, tftp_port
, "boot.bin",
269 (void *)MAIN_RAM_BASE
);
273 printf("Network boot failed\n");
277 cmdline_adr
= MAIN_RAM_BASE
+0x1000000;
278 size
= tftp_get_v(ip
, tftp_port
, "cmdline.txt", (void *)cmdline_adr
);
280 printf("No command line parameters found\n");
283 *((char *)(cmdline_adr
+size
)) = 0x00;
285 initrdstart_adr
= MAIN_RAM_BASE
+0x1002000;
286 size
= tftp_get_v(ip
, tftp_port
, "initrd.bin", (void *)initrdstart_adr
);
288 printf("No initial ramdisk found\n");
292 initrdend_adr
= initrdstart_adr
+ size
;
294 boot(cmdline_adr
, initrdstart_adr
, initrdend_adr
, MAIN_RAM_BASE
);
299 #ifdef FLASH_BOOT_ADDRESS
301 /* On systems with exernal SDRAM we copy out of the SPI flash into the SDRAM
302 before running, as it is faster. If we have no SDRAM then we have to
303 execute directly out of the SPI flash. */
305 #define FIRMWARE_BASE_ADDRESS MAIN_RAM_BASE
307 /* Firmware code starts after (a) length and (b) CRC -- both unsigned ints */
308 #define FIRMWARE_BASE_ADDRESS (FLASH_BOOT_ADDRESS + 2 * sizeof(unsigned int))
313 unsigned int *flashbase
;
316 unsigned int got_crc
;
318 printf("Booting from flash...\n");
319 flashbase
= (unsigned int *)FLASH_BOOT_ADDRESS
;
320 length
= *flashbase
++;
322 if((length
< 32) || (length
> 4*1024*1024)) {
323 printf("Error: Invalid flash boot image length 0x%08x\n", length
);
328 printf("Loading %d bytes from flash...\n", length
);
329 memcpy((void *)MAIN_RAM_BASE
, flashbase
, length
);
332 got_crc
= crc32((unsigned char *)FIRMWARE_BASE_ADDRESS
, length
);
334 printf("CRC failed (expected %08x, got %08x)\n", crc
, got_crc
);
337 boot(0, 0, 0, FIRMWARE_BASE_ADDRESS
);
341 #ifdef ROM_BOOT_ADDRESS
342 /* When firmware is small enough, it can be interesting to run code from an
343 embedded blockram memory (faster and not impacted by memory controller
344 activity). Define ROM_BOOT_ADDRESS for that and initialize the blockram
345 with the firmware data. */
348 boot(0, 0, 0, ROM_BOOT_ADDRESS
);