arm: working bootloader, example app

'make' will produce two outputs:
- bootloader.elf to be loaded into the bitstream
- app.bin to be loaded through the programmer

Loading app.bin is as simple as:
- reset the board
- `python3 prog.py app.bin`
This commit is contained in:
2022-05-10 11:20:02 -07:00
parent 43d245bae2
commit b8b0d94065
10 changed files with 231 additions and 46 deletions

63
arm/bootloader.cc Normal file
View File

@@ -0,0 +1,63 @@
#include <cstdint>
#include "gpio.h"
#include "uart.h"
namespace {
uint8_t UartRead() {
uint8_t c;
while (XUartLite_Recv(uart0, &c, 1) < 1) {}
return c;
}
void UartWrite(uint8_t c) {
XUartLite_Send(uart0, &c, 1);
}
uint32_t UartRead32() {
uint32_t val = 0;
// little endian
val |= (UartRead() << 0);
val |= (UartRead() << 8);
val |= (UartRead() << 16);
val |= (UartRead() << 24);
return val;
}
} // namespace
int main() {
gpio0->data = 1;
InitUarts();
while(1) {
uint8_t c = UartRead();
if (c == 'c') {
uint32_t addr = UartRead32();
uint32_t bytes = UartRead32();
uint8_t* start = reinterpret_cast<uint8_t*>(addr);
uint8_t* end = reinterpret_cast<uint8_t*>(addr + bytes);
for (uint8_t* ptr = start; ptr < end; ptr++) {
*ptr = UartRead();
}
UartWrite('a');
UartWrite(bytes);
gpio0->data = 0xf0;
} else if (c == 'j') {
uint32_t addr = UartRead32();
gpio0->data = 0x55;
addr |= 0x0001;
auto jump = reinterpret_cast<void(*)()>(addr);
jump();
}
}
}