| | #include <stdint.h> |
---|
| | uint32_t volatile * const rccApb2 = (uint32_t *) 0x40021018u; |
---|
| | uint32_t volatile * const ioAModerH = (uint32_t *) 0x40010804u; |
---|
| | uint32_t volatile * const uart1Ctrl = (uint32_t *) 0x40013800u; |
---|
| | |
---|
| | void readChar( uint8_t const chr ); |
---|
| | void writeByte( uint8_t b ); |
---|
| | void writeStr( uint8_t const * const str ); |
---|
| | void writeChar( uint8_t const chr ); |
---|
| | void writeWordLe( uint32_t const word ); |
---|
| | void writeWordBe( uint32_t const word ); |
---|
| | void readCmd( uint8_t const * const cmd); |
---|
| | uint32_t hexToInt(uint8_t const * const hex); |
---|
| | void readMem(uint32_t const addr, uint32_t const len); |
---|
| | void writeMem(uint32_t const addr, uint32_t const data); |
---|
| | |
---|
| | uint8_t const strHelp[] = "Help\r\n-----------\r\n" |
---|
| | "ADDR, VAL, LEN: 32-bit Hex encoded:\r\n e.g., 0A1337FF\r\n" |
---|
| | "-----------\r\n" |
---|
| | "R ADDR LEN - Read 32-bit word\r\n" |
---|
| | "W ADDR VAL - Write 32-bit word\r\n" |
---|
| | "D - Dump all flash memory\r\n" |
---|
| | "P - Jump into chall4 function\r\n" |
---|
| | "S - Reboot\r\n" |
---|
| | "E - Exit\r\n" |
---|
| | "H - Show help \r\n" |
---|
| | "---------------\r\n"; |
---|
| | |
---|
| | int main(void) |
---|
| | { |
---|
| | /* IOA + USART1 clock enable */ |
---|
| | *rccApb2 = (uint32_t) 0x4004u; |
---|
| | |
---|
| | /* USART1 TX+RX (PA9, PX10) on */ |
---|
| | *ioAModerH = (uint32_t) 0x444444B4u; |
---|
| | |
---|
| | /* config and enable uart */ |
---|
| | uart1Ctrl[2] = 0x00000341u; |
---|
| | uart1Ctrl[3] = 0x0000200Cu; |
---|
| | |
---|
| | writeStr("\r\n##############################\r\n" |
---|
| | "# Low-Level Shell v.0xRoM #\r\n" |
---|
| | "# CPU-ID: 0x"); |
---|
| | uint32_t cpuid = *((uint32_t *) 0xe000ed00); |
---|
| | writeWordBe(cpuid); |
---|
| | writeStr( " #\r\n"); |
---|
| | writeStr("##############################\r\n\r\n"); |
---|
| | writeStr("> "); |
---|
| | |
---|
| | while (1) |
---|
| | { |
---|
| | if ((uart1Ctrl[0] & 0x80u) && (0)) |
---|
| | { |
---|
| | uart1Ctrl[1] = 0x33u; |
---|
| | } |
---|
| | |
---|
| | if (uart1Ctrl[0] & 0x20u) |
---|
| | { |
---|
| | uint32_t data = uart1Ctrl[1]; |
---|
| | readChar((uint8_t) data); |
---|
| | } |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | /* hex must have length 8 */ |
---|
| | uint32_t hexToInt(uint8_t const * const hex) |
---|
| | { |
---|
| | uint32_t ind = 0u; |
---|
| | uint32_t res = 0u; |
---|
| | |
---|
| | for (ind = 0; ind < 8; ++ind) |
---|
| | { |
---|
| | uint8_t chr = hex[ind]; |
---|
| | uint32_t val = 0u; |
---|
| | |
---|
| | res <<= 4u; |
---|
| | |
---|
| | if ((chr >= '0') && (chr <= '9')) |
---|
| | { |
---|
| | val = chr - '0'; |
---|
| | } |
---|
| | else if ((chr >= 'a') && (chr <= 'f')) |
---|
| | { |
---|
| | val = chr - 'a' + 0x0a; |
---|
| | } |
---|
| | else if ((chr >= 'A') && (chr <= 'F')) |
---|
| | { |
---|
| | val = chr - 'A' + 0x0a; |
---|
| | } |
---|
| | else |
---|
| | { |
---|
| | val = 0u; |
---|
| | } |
---|
| | res |= val; |
---|
| | } |
---|
| | |
---|
| | return res; |
---|
| | } |
---|
| | |
---|
| | void readChar( uint8_t const chr ) |
---|
| | { |
---|
| | #define CMDBUF_LEN (64u) |
---|
| | static uint8_t cmdbuf[CMDBUF_LEN] = {0u}; |
---|
| | static uint32_t cmdInd = 0u; |
---|
| | |
---|
| | switch (chr) |
---|
| | { |
---|
| | case '\n': |
---|
| | case '\r': |
---|
| | cmdbuf[cmdInd] = 0u; |
---|
| | if (cmdInd != 0) |
---|
| | { |
---|
| | writeStr("\r\n"); |
---|
| | } |
---|
| | readCmd(cmdbuf); |
---|
| | cmdInd = 0u; |
---|
| | writeStr("\r\n> "); |
---|
| | { |
---|
| | uint32_t ind = 0u; |
---|
| | for (ind = 0; ind<CMDBUF_LEN; ++ind) |
---|
| | { |
---|
| | cmdbuf[ind]=0x00u; |
---|
| | } |
---|
| | } |
---|
| | break; |
---|
| | |
---|
| | case 8: |
---|
| | case 255: |
---|
| | case 127: /* TODO backspace */ |
---|
| | if (cmdInd > 0u) |
---|
| | --cmdInd; |
---|
| | writeChar(chr); |
---|
| | break; |
---|
| | |
---|
| | default: |
---|
| | if (cmdInd < (CMDBUF_LEN - 1)) |
---|
| | { |
---|
| | cmdbuf[cmdInd] = chr; |
---|
| | ++cmdInd; |
---|
| | writeChar(chr); |
---|
| | } |
---|
| | break; |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | void readCmd( uint8_t const * const cmd ) |
---|
| | { |
---|
| | void (*chall4)(void) = (void (*)(void))0x08000ba9; |
---|
| | switch (cmd[0]) |
---|
| | { |
---|
| | case 0: |
---|
| | return; |
---|
| | break; |
---|
| | |
---|
| | /* chall4 function */ |
---|
| | case 'p': |
---|
| | case 'P': |
---|
| | writeStr("time to change baudrate to 115200\r\n"); |
---|
| | for (volatile uint32_t i = 0; i < 5000000; i++); // Crude delay |
---|
| | chall4(); |
---|
| | break; |
---|
| | |
---|
| | /* read 32-bit command */ |
---|
| | case 'r': |
---|
| | case 'R': |
---|
| | /* r 08000000 00000100 */ |
---|
| | readMem(hexToInt(&cmd[2]), hexToInt(&cmd[11])); |
---|
| | break; |
---|
| | |
---|
| | /* write 32-bit command */ |
---|
| | case 'w': |
---|
| | case 'W': |
---|
| | /* w 20000000 12345678 */ |
---|
| | writeMem(hexToInt(&cmd[2]), hexToInt(&cmd[11])); |
---|
| | break; |
---|
| | |
---|
| | /* Dump all flash */ |
---|
| | case 'd': |
---|
| | case 'D': |
---|
| | writeStr("\r\n\r\n"); |
---|
| | { |
---|
| | uint32_t const * addr = (uint32_t*) 0x08000000; |
---|
| | uint32_t br = 8u; |
---|
| | while (((uintptr_t) addr) < (0x08000000 + 64u * 1024u)) |
---|
| | { |
---|
| | if (br == 8u) |
---|
| | { |
---|
| | writeStr("\r\n["); |
---|
| | writeWordBe((uint32_t) addr); |
---|
| | writeStr("]: "); |
---|
| | br = 0u; |
---|
| | } |
---|
| | |
---|
| | writeWordBe(*addr); |
---|
| | writeChar(' '); |
---|
| | ++addr; |
---|
| | ++br; |
---|
| | } |
---|
| | } |
---|
| | writeStr("\r\n\r\n"); |
---|
| | break; |
---|
| | |
---|
| | /* Help command */ |
---|
| | case 'h': |
---|
| | case 'H': |
---|
| | writeStr(strHelp); |
---|
| | break; |
---|
| | |
---|
| | /* Reboot */ |
---|
| | case 's': |
---|
| | case 'S': |
---|
| | writeStr("Rebooting...\r\n\r\n"); |
---|
| | *((uint32_t *) 0xE000ED0C) = 0x05FA0004u; |
---|
| | break; |
---|
| | |
---|
| | /* exit */ |
---|
| | case 'e': |
---|
| | case 'E': |
---|
| | writeStr("Bye.\r\n"); |
---|
| | while (1) |
---|
| | { |
---|
| | __asm__ volatile("wfi"); |
---|
| | } |
---|
| | break; |
---|
| | |
---|
| | |
---|
| | default: |
---|
| | writeStr("Unknown command: "); |
---|
| | writeStr(cmd); |
---|
| | writeStr("\r\n"); |
---|
| | break; |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | const uint8_t txtMap[] = "0123456789ABCDEF"; |
---|
| | |
---|
| | void writeByte( uint8_t b ) |
---|
| | { |
---|
| | writeChar(txtMap[b >> 4]); |
---|
| | writeChar(txtMap[b & 0x0F]); |
---|
| | } |
---|
| | |
---|
| | |
---|
| | void writeStr( uint8_t const * const str ) |
---|
| | { |
---|
| | uint32_t ind = 0u; |
---|
| | |
---|
| | while (str[ind]) |
---|
| | { |
---|
| | writeChar(str[ind]); |
---|
| | ++ind; |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | void writeChar( uint8_t const chr ) |
---|
| | { |
---|
| | while (!(uart1Ctrl[0] & 0x80u)) |
---|
| | { |
---|
| | /* wait */ |
---|
| | } |
---|
| | |
---|
| | uart1Ctrl[1] = chr; |
---|
| | } |
---|
| | |
---|
| | void writeWordLe( uint32_t const word ) |
---|
| | { |
---|
| | writeByte((word & 0x000000FF)); |
---|
| | writeByte((word & 0x0000FF00) >> 8); |
---|
| | writeByte((word & 0x00FF0000) >> 16); |
---|
| | writeByte((word & 0xFF000000) >> 24); |
---|
| | } |
---|
| | |
---|
| | void writeWordBe( uint32_t const word ) |
---|
| | { |
---|
| | writeByte((word & 0xFF000000) >> 24); |
---|
| | writeByte((word & 0x00FF0000) >> 16); |
---|
| | writeByte((word & 0x0000FF00) >> 8); |
---|
| | writeByte((word & 0x000000FF)); |
---|
| | |
---|
| | } |
---|
| | |
---|
| | void alertCrash( uint32_t crashId ) |
---|
| | { |
---|
| | writeStr("!!! EXCEPTION !!!\r\nID: "); |
---|
| | writeByte(crashId); |
---|
| | writeStr("\r\nRestart required!\r\n\r\n"); |
---|
| | *((uint32_t *) 0xE000ED0C) = 0x05FA0004u; |
---|
| | while (1); |
---|
| | } |
---|
| | |
---|
| | void readMem(uint32_t const addr, uint32_t const len) |
---|
| | { |
---|
| | uint32_t it = 0u; |
---|
| | uint32_t addrx = 0u; |
---|
| | uint32_t lenx = 0u; |
---|
| | |
---|
| | lenx = len; |
---|
| | if (lenx == 0u) |
---|
| | { |
---|
| | lenx = 4u; |
---|
| | } |
---|
| | |
---|
| | for (it = 0u; it < (lenx / 4u); ++it) |
---|
| | { |
---|
| | addrx = addr + it*4u; |
---|
| | writeStr("Read ["); |
---|
| | writeWordBe(addrx); |
---|
| | writeStr("]: "); |
---|
| | writeWordBe(*((uint32_t*)addrx)); |
---|
| | writeStr("\r\n"); |
---|
| | } |
---|
| | } |
---|
| | |
---|
| | void writeMem(uint32_t const addr, uint32_t const data) |
---|
| | { |
---|
| | writeStr("Write ["); |
---|
| | writeWordBe(addr); |
---|
| | writeStr("]: "); |
---|
| | writeWordBe(data); |
---|
| | *((uint32_t*) addr) = data; |
---|
| | writeStr("\r\n"); |
---|
| | } |
---|
| | |
---|
| | |
---|
| | |