mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-22 21:27:10 -04:00
Implement simple uart-based updater for the bootrom (#2267)
This commit is contained in:
parent
9df64701bd
commit
c92245b20b
3 changed files with 77 additions and 1 deletions
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue