Newer
Older
Hardware / FaultInjection / examples / CuriousBolt / Level-1 / Chall-4-Firmware / main.c
  1. #include <stdint.h>
  2. uint32_t volatile * const rccApb2 = (uint32_t *) 0x40021018u;
  3. uint32_t volatile * const ioAModerH = (uint32_t *) 0x40010804u;
  4. uint32_t volatile * const uart1Ctrl = (uint32_t *) 0x40013800u;
  5.  
  6. void readChar( uint8_t const chr );
  7. void writeByte( uint8_t b );
  8. void writeStr( uint8_t const * const str );
  9. void writeChar( uint8_t const chr );
  10. void writeWordLe( uint32_t const word );
  11. void writeWordBe( uint32_t const word );
  12. void readCmd( uint8_t const * const cmd);
  13. uint32_t hexToInt(uint8_t const * const hex);
  14. void readMem(uint32_t const addr, uint32_t const len);
  15. void writeMem(uint32_t const addr, uint32_t const data);
  16.  
  17. uint8_t const strHelp[] = "Help\r\n-----------\r\n"
  18. "ADDR, VAL, LEN: 32-bit Hex encoded:\r\n e.g., 0A1337FF\r\n"
  19. "-----------\r\n"
  20. "R ADDR LEN - Read 32-bit word\r\n"
  21. "W ADDR VAL - Write 32-bit word\r\n"
  22. "D - Dump all flash memory\r\n"
  23. "P - Jump into chall4 function\r\n"
  24. "S - Reboot\r\n"
  25. "E - Exit\r\n"
  26. "H - Show help \r\n"
  27. "---------------\r\n";
  28.  
  29. int main(void)
  30. {
  31. /* IOA + USART1 clock enable */
  32. *rccApb2 = (uint32_t) 0x4004u;
  33.  
  34. /* USART1 TX+RX (PA9, PX10) on */
  35. *ioAModerH = (uint32_t) 0x444444B4u;
  36.  
  37. /* config and enable uart */
  38. uart1Ctrl[2] = 0x00000341u;
  39. uart1Ctrl[3] = 0x0000200Cu;
  40. writeStr("\r\n##############################\r\n"
  41. "# Low-Level Shell v.0xRoM #\r\n"
  42. "# CPU-ID: 0x");
  43. uint32_t cpuid = *((uint32_t *) 0xe000ed00);
  44. writeWordBe(cpuid);
  45. writeStr( " #\r\n");
  46. writeStr("##############################\r\n\r\n");
  47. writeStr("> ");
  48.  
  49. while (1)
  50. {
  51. if ((uart1Ctrl[0] & 0x80u) && (0))
  52. {
  53. uart1Ctrl[1] = 0x33u;
  54. }
  55.  
  56. if (uart1Ctrl[0] & 0x20u)
  57. {
  58. uint32_t data = uart1Ctrl[1];
  59. readChar((uint8_t) data);
  60. }
  61. }
  62. }
  63.  
  64. /* hex must have length 8 */
  65. uint32_t hexToInt(uint8_t const * const hex)
  66. {
  67. uint32_t ind = 0u;
  68. uint32_t res = 0u;
  69.  
  70. for (ind = 0; ind < 8; ++ind)
  71. {
  72. uint8_t chr = hex[ind];
  73. uint32_t val = 0u;
  74.  
  75. res <<= 4u;
  76.  
  77. if ((chr >= '0') && (chr <= '9'))
  78. {
  79. val = chr - '0';
  80. }
  81. else if ((chr >= 'a') && (chr <= 'f'))
  82. {
  83. val = chr - 'a' + 0x0a;
  84. }
  85. else if ((chr >= 'A') && (chr <= 'F'))
  86. {
  87. val = chr - 'A' + 0x0a;
  88. }
  89. else
  90. {
  91. val = 0u;
  92. }
  93. res |= val;
  94. }
  95.  
  96. return res;
  97. }
  98.  
  99. void readChar( uint8_t const chr )
  100. {
  101. #define CMDBUF_LEN (64u)
  102. static uint8_t cmdbuf[CMDBUF_LEN] = {0u};
  103. static uint32_t cmdInd = 0u;
  104.  
  105. switch (chr)
  106. {
  107. case '\n':
  108. case '\r':
  109. cmdbuf[cmdInd] = 0u;
  110. if (cmdInd != 0)
  111. {
  112. writeStr("\r\n");
  113. }
  114. readCmd(cmdbuf);
  115. cmdInd = 0u;
  116. writeStr("\r\n> ");
  117. {
  118. uint32_t ind = 0u;
  119. for (ind = 0; ind<CMDBUF_LEN; ++ind)
  120. {
  121. cmdbuf[ind]=0x00u;
  122. }
  123. }
  124. break;
  125.  
  126. case 8:
  127. case 255:
  128. case 127: /* TODO backspace */
  129. if (cmdInd > 0u)
  130. --cmdInd;
  131. writeChar(chr);
  132. break;
  133.  
  134. default:
  135. if (cmdInd < (CMDBUF_LEN - 1))
  136. {
  137. cmdbuf[cmdInd] = chr;
  138. ++cmdInd;
  139. writeChar(chr);
  140. }
  141. break;
  142. }
  143. }
  144.  
  145. void readCmd( uint8_t const * const cmd )
  146. {
  147. void (*chall4)(void) = (void (*)(void))0x08000ba9;
  148. switch (cmd[0])
  149. {
  150. case 0:
  151. return;
  152. break;
  153.  
  154. /* chall4 function */
  155. case 'p':
  156. case 'P':
  157. writeStr("time to change baudrate to 115200\r\n");
  158. for (volatile uint32_t i = 0; i < 5000000; i++); // Crude delay
  159. chall4();
  160. break;
  161.  
  162. /* read 32-bit command */
  163. case 'r':
  164. case 'R':
  165. /* r 08000000 00000100 */
  166. readMem(hexToInt(&cmd[2]), hexToInt(&cmd[11]));
  167. break;
  168.  
  169. /* write 32-bit command */
  170. case 'w':
  171. case 'W':
  172. /* w 20000000 12345678 */
  173. writeMem(hexToInt(&cmd[2]), hexToInt(&cmd[11]));
  174. break;
  175.  
  176. /* Dump all flash */
  177. case 'd':
  178. case 'D':
  179. writeStr("\r\n\r\n");
  180. {
  181. uint32_t const * addr = (uint32_t*) 0x08000000;
  182. uint32_t br = 8u;
  183. while (((uintptr_t) addr) < (0x08000000 + 64u * 1024u))
  184. {
  185. if (br == 8u)
  186. {
  187. writeStr("\r\n[");
  188. writeWordBe((uint32_t) addr);
  189. writeStr("]: ");
  190. br = 0u;
  191. }
  192.  
  193. writeWordBe(*addr);
  194. writeChar(' ');
  195. ++addr;
  196. ++br;
  197. }
  198. }
  199. writeStr("\r\n\r\n");
  200. break;
  201.  
  202. /* Help command */
  203. case 'h':
  204. case 'H':
  205. writeStr(strHelp);
  206. break;
  207.  
  208. /* Reboot */
  209. case 's':
  210. case 'S':
  211. writeStr("Rebooting...\r\n\r\n");
  212. *((uint32_t *) 0xE000ED0C) = 0x05FA0004u;
  213. break;
  214.  
  215. /* exit */
  216. case 'e':
  217. case 'E':
  218. writeStr("Bye.\r\n");
  219. while (1)
  220. {
  221. __asm__ volatile("wfi");
  222. }
  223. break;
  224.  
  225.  
  226. default:
  227. writeStr("Unknown command: ");
  228. writeStr(cmd);
  229. writeStr("\r\n");
  230. break;
  231. }
  232. }
  233. const uint8_t txtMap[] = "0123456789ABCDEF";
  234.  
  235. void writeByte( uint8_t b )
  236. {
  237. writeChar(txtMap[b >> 4]);
  238. writeChar(txtMap[b & 0x0F]);
  239. }
  240.  
  241.  
  242. void writeStr( uint8_t const * const str )
  243. {
  244. uint32_t ind = 0u;
  245.  
  246. while (str[ind])
  247. {
  248. writeChar(str[ind]);
  249. ++ind;
  250. }
  251. }
  252.  
  253. void writeChar( uint8_t const chr )
  254. {
  255. while (!(uart1Ctrl[0] & 0x80u))
  256. {
  257. /* wait */
  258. }
  259.  
  260. uart1Ctrl[1] = chr;
  261. }
  262.  
  263. void writeWordLe( uint32_t const word )
  264. {
  265. writeByte((word & 0x000000FF));
  266. writeByte((word & 0x0000FF00) >> 8);
  267. writeByte((word & 0x00FF0000) >> 16);
  268. writeByte((word & 0xFF000000) >> 24);
  269. }
  270.  
  271. void writeWordBe( uint32_t const word )
  272. {
  273. writeByte((word & 0xFF000000) >> 24);
  274. writeByte((word & 0x00FF0000) >> 16);
  275. writeByte((word & 0x0000FF00) >> 8);
  276. writeByte((word & 0x000000FF));
  277.  
  278. }
  279.  
  280. void alertCrash( uint32_t crashId )
  281. {
  282. writeStr("!!! EXCEPTION !!!\r\nID: ");
  283. writeByte(crashId);
  284. writeStr("\r\nRestart required!\r\n\r\n");
  285. *((uint32_t *) 0xE000ED0C) = 0x05FA0004u;
  286. while (1);
  287. }
  288.  
  289. void readMem(uint32_t const addr, uint32_t const len)
  290. {
  291. uint32_t it = 0u;
  292. uint32_t addrx = 0u;
  293. uint32_t lenx = 0u;
  294.  
  295. lenx = len;
  296. if (lenx == 0u)
  297. {
  298. lenx = 4u;
  299. }
  300.  
  301. for (it = 0u; it < (lenx / 4u); ++it)
  302. {
  303. addrx = addr + it*4u;
  304. writeStr("Read [");
  305. writeWordBe(addrx);
  306. writeStr("]: ");
  307. writeWordBe(*((uint32_t*)addrx));
  308. writeStr("\r\n");
  309. }
  310. }
  311.  
  312. void writeMem(uint32_t const addr, uint32_t const data)
  313. {
  314. writeStr("Write [");
  315. writeWordBe(addr);
  316. writeStr("]: ");
  317. writeWordBe(data);
  318. *((uint32_t*) addr) = data;
  319. writeStr("\r\n");
  320. }
  321.  
Buy Me A Coffee