diff --git a/corev_apu/fpga/src/bootrom/src/main.c b/corev_apu/fpga/src/bootrom/src/main.c index b05f12ebb..f62485ba2 100644 --- a/corev_apu/fpga/src/bootrom/src/main.c +++ b/corev_apu/fpga/src/bootrom/src/main.c @@ -7,12 +7,71 @@ #include "sd.h" #include "gpt.h" +// 1 second at 50MHz +#define SECOND_CYCLES (50 * 1000 * 1000) +#define WAIT_SECONDS (5) + +static inline uintptr_t get_cycle_count() { + uintptr_t cycle; + __asm__ volatile ("csrr %0, cycle" : "=r" (cycle)); + return cycle; +} + +int update(uint8_t *dest) +{ + int i; + uint32_t size = 0; + + print_uart("receiving boot image\r\nsize: "); + for(i = 0; i < sizeof(uint32_t); i++) { + while(!read_serial(&((uint8_t *) &size)[i])); + } + + print_uart_int(size); + print_uart("\r\nreceiving "); + + for(i = 0; i < size; i++) { + while(!read_serial(&dest[i])); + + if(i % (size >> 4) == 0) { + print_uart("."); + } + } + + print_uart(" done!\r\n"); + return 0; +} + int main() { + int i, ret = 0; + uint8_t uart_res = 0; + uintptr_t start; + init_uart(CLOCK_FREQUENCY, UART_BITRATE); print_uart("Hello World!\r\n"); - int res = gpt_find_boot_partition((uint8_t *)0x80000000UL, 2 * 16384); + // See if we should enter update mode + print_uart("Hit any key to enter update mode "); + for(i = 0; i < WAIT_SECONDS && !ret; i++) { + print_uart("."); + start = get_cycle_count(); + while(get_cycle_count() - start < SECOND_CYCLES) { + ret = read_serial(&uart_res); + if(ret) { + break; + } + } + } + + int res; + if(ret) { + print_uart(" updating!\r\n"); + res = update((uint8_t *)0x80000000UL); + } else { + print_uart(" booting!\r\n"); + res = gpt_find_boot_partition((uint8_t *)0x80000000UL, 2 * 16384); + } if (res == 0) { diff --git a/corev_apu/fpga/src/bootrom/src/uart.c b/corev_apu/fpga/src/bootrom/src/uart.c index dac70f6b8..a400b87ac 100644 --- a/corev_apu/fpga/src/bootrom/src/uart.c +++ b/corev_apu/fpga/src/bootrom/src/uart.c @@ -20,6 +20,11 @@ int is_transmit_empty() return read_reg_u8(UART_LINE_STATUS) & 0x20; } +int is_receive_empty() +{ + return !(read_reg_u8(UART_LINE_STATUS) & 0x1); +} + void write_serial(char a) { while (is_transmit_empty() == 0) {}; @@ -27,6 +32,16 @@ void write_serial(char a) write_reg_u8(UART_THR, a); } +int read_serial(uint8_t *res) +{ + if(is_receive_empty()) { + return 0; + } + + *res = read_reg_u8(UART_RBR); + return 1; +} + void init_uart(uint32_t freq, uint32_t baud) { uint32_t divisor = freq / (baud << 4); diff --git a/corev_apu/fpga/src/bootrom/src/uart.h b/corev_apu/fpga/src/bootrom/src/uart.h index b25ac7df6..38c7e44a4 100644 --- a/corev_apu/fpga/src/bootrom/src/uart.h +++ b/corev_apu/fpga/src/bootrom/src/uart.h @@ -22,6 +22,8 @@ void init_uart(); +int read_serial(uint8_t *res); + void print_uart(const char* str); void print_uart_int(uint32_t addr);