firmware.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583
  1. /*
  2. * firmware.c
  3. *
  4. * Copyright (C) 2019 Sylvain Munaut
  5. * All rights reserved.
  6. *
  7. * LGPL v3+, see LICENSE.lgpl3
  8. *
  9. * This program is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation; either
  12. * version 3 of the License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public License
  20. * along with this program; if not, write to the Free Software Foundation,
  21. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  22. */
  23. #include <stdint.h>
  24. #include <stdbool.h>
  25. #include <string.h>
  26. #include "io.h"
  27. #include "usb_desc.h"
  28. /* USB specs structures / values */
  29. struct usb_ctrl_req_hdr {
  30. uint8_t bmRequestType;
  31. uint8_t bRequest;
  32. uint16_t wValue;
  33. uint16_t wIndex;
  34. uint16_t wLength;
  35. } __attribute__((packed));
  36. #define USB_REQ_IS_READ(req) ( req->bmRequestType & 0x80 )
  37. #define USB_REQ_IS_WRITE(req) (!(req->bmRequestType & 0x80))
  38. #define USB_REQ_GET_STATUS 0
  39. #define USB_REQ_CLEAR_FEATURE 1
  40. #define USB_REQ_SET_FEATURE 3
  41. #define USB_REQ_SET_ADDRESS 5
  42. #define USB_REQ_GET_DESCRIPTOR 6
  43. #define USB_REQ_SET_DESCRIPTOR 7
  44. #define USB_REQ_GET_CONFIGURATION 8
  45. #define USB_REQ_SET_CONFIGURATION 9
  46. #define USB_REQ_GET_INTERFACE 10
  47. #define USB_REQ_SET_INTERFACE 11
  48. #define USB_REQ_SYNCHFRAME 12
  49. /* Registers / Control addresses */
  50. #define usb_csr (*(volatile uint32_t*)(0x84000000))
  51. #define usb_ep_status(ep,dir) (*(volatile uint32_t*)(0x84002000 + ((ep)<<6) + ((dir) << 5)))
  52. #define usb_ep_bd(ep,dir,i,w) (*(volatile uint32_t*)(0x84002010 + ((ep)<<6) + ((dir) << 5) + ((i) << 3) + ((w) << 2)))
  53. #define usb_data(o) (*(volatile uint32_t*)(0x85000000 + ((o) << 2)))
  54. #define USB_SR_IS_SETUP (1 << 2)
  55. #define USB_SR_IRQ_PENDING (1 << 0)
  56. #define USB_CR_PU_ENA (1 << 15)
  57. #define USB_CR_CEL_ENA (1 << 14)
  58. #define USB_CR_CEL_RELEASE (1 << 1)
  59. #define USB_CR_IRQ_ACK (1 << 0)
  60. #define USB_EP_TYPE_NONE 0x0000
  61. #define USB_EP_TYPE_ISOC 0x0001
  62. #define USB_EP_TYPE_INT 0x0002
  63. #define USB_EP_TYPE_BULK 0x0004
  64. #define USB_EP_TYPE_CTRL 0x0006
  65. #define USB_EP_TYPE_HALTED 0x0001
  66. #define USB_EP_DT_BIT 0x0080
  67. #define USB_EP_BD_IDX 0x0040
  68. #define USB_EP_BD_CTRL 0x0020
  69. #define USB_EP_BD_DUAL 0x0010
  70. #define USB_BD_STATE_MSK 0xe000
  71. #define USB_BD_STATE_NONE 0x0000
  72. #define USB_BD_STATE_RDY_DATA 0x4000
  73. #define USB_BD_STATE_RDY_STALL 0x6000
  74. #define USB_BD_STATE_DONE_OK 0x8000
  75. #define USB_BD_STATE_DONE_ERR 0xa000
  76. #define USB_BD_IS_SETUP 0x1000
  77. /* Helpers to copy data to/from EP memory */
  78. static void
  79. usb_data_write(volatile uint32_t *dst_u32, const void *src, int len)
  80. {
  81. uint32_t *src_u32 = (uint32_t *)src;
  82. int i, j;
  83. for (i=0, j=0; i<len; i+=4, j++)
  84. dst_u32[j] = src_u32[j];
  85. }
  86. static void
  87. usb_data_read(void *dst, const volatile uint32_t *src_u32, int len)
  88. {
  89. uint32_t *dst_u32 = (uint32_t *)dst;
  90. uint8_t *dst_u8 = (uint8_t *)dst;
  91. uint32_t x;
  92. int i, j;
  93. for (i=0, j=0; i<(len-3); i+=4, j++)
  94. dst_u32[j] = src_u32[j];
  95. if (len & 3) {
  96. x = src_u32[j];
  97. for (;i<len; i++) {
  98. dst_u8[i] = (x & 0xff);
  99. x >>= 8;
  100. }
  101. }
  102. }
  103. /* Main USB functions */
  104. static void
  105. usb_short_debug_print(void)
  106. {
  107. printf("BD0.0 %04x\n", usb_ep_bd(0,0,0,0));
  108. printf("BD1.0 %04x\n", usb_ep_bd(0,0,1,0));
  109. }
  110. static void
  111. usb_debug_print(void)
  112. {
  113. puts("\nCSR\n");
  114. printf("SR %04x\n", usb_csr);
  115. puts("\nEP0 OUT\n");
  116. printf("S %04x\n", usb_ep_status(0,0));
  117. printf("BD0.0 %04x\n", usb_ep_bd(0,0,0,0));
  118. printf("BD0.1 %04x\n", usb_ep_bd(0,0,0,1));
  119. printf("BD1.0 %04x\n", usb_ep_bd(0,0,1,0));
  120. printf("BD1.1 %04x\n", usb_ep_bd(0,0,1,1));
  121. puts("\nEP0 IN\n");
  122. printf("S %04x\n", usb_ep_status(0,1));
  123. printf("BD0.0 %04x\n", usb_ep_bd(0,1,0,0));
  124. printf("BD0.1 %04x\n", usb_ep_bd(0,1,0,1));
  125. printf("BD1.0 %04x\n", usb_ep_bd(0,1,1,0));
  126. printf("BD1.1 %04x\n", usb_ep_bd(0,1,1,1));
  127. puts("\nEP1 OUT\n");
  128. printf("S %04x\n", usb_ep_status(1,0));
  129. printf("BD0.0 %04x\n", usb_ep_bd(1,0,0,0));
  130. printf("BD0.1 %04x\n", usb_ep_bd(1,0,0,1));
  131. printf("BD1.0 %04x\n", usb_ep_bd(1,0,1,0));
  132. printf("BD1.1 %04x\n", usb_ep_bd(1,0,1,1));
  133. puts("\nData\n");
  134. printf("%08x\n", usb_data(0));
  135. printf("%08x\n", usb_data(1));
  136. printf("%08x\n", usb_data(2));
  137. printf("%08x\n", usb_data(3));
  138. }
  139. struct {
  140. uint32_t csr;
  141. struct {
  142. enum {
  143. IDLE,
  144. DATA_IN, /* Data stage via 'IN' */
  145. DATA_OUT, /* Data stage via 'OUT' */
  146. STATUS_DONE_OUT, /* Status sent via 'OUT' EP */
  147. STATUS_DONE_IN, /* Status sent via 'IN' EP */
  148. } state;
  149. struct usb_ctrl_req_hdr req;
  150. union {
  151. const uint8_t *out;
  152. uint8_t *in;
  153. } data;
  154. int len;
  155. int ofs;
  156. } ctrl;
  157. } g_usb;
  158. static inline void
  159. usb_ep0_out_queue_bd(bool setup, int ofs, int len, bool stall)
  160. {
  161. int bdi = setup ? 1 : 0;
  162. usb_ep_bd(0,0,bdi,1) = ofs;
  163. usb_ep_bd(0,0,bdi,0) = stall ? 0x6000 : (0x4000 | len);
  164. }
  165. static inline void
  166. usb_ep0_in_queue_bd(int ofs, int len, bool stall)
  167. {
  168. usb_ep_bd(0,1,0,1) = ofs;
  169. usb_ep_bd(0,1,0,0) = stall ? 0x6000 : (0x4000 | len);
  170. }
  171. static inline uint32_t
  172. usb_ep0_out_peek_bd(bool setup)
  173. {
  174. int bdi = setup ? 1 : 0;
  175. return usb_ep_bd(0,0,bdi,0);
  176. }
  177. static inline uint32_t
  178. usb_ep0_in_peek_bd(void)
  179. {
  180. return usb_ep_bd(0,1,0,0);
  181. }
  182. static inline void
  183. usb_ep0_out_done_bd(bool setup)
  184. {
  185. int bdi = setup ? 1 : 0;
  186. usb_ep_bd(0,0,bdi,0) = 0;
  187. }
  188. static inline void
  189. usb_ep0_in_done_bd(void)
  190. {
  191. usb_ep_bd(0,1,0,0) = 0;
  192. }
  193. static void
  194. usb_init(void)
  195. {
  196. memset(&g_usb, 0x00, sizeof(g_usb));
  197. g_usb.csr = USB_CR_PU_ENA | USB_CR_CEL_ENA;
  198. /* Configure EP0 */
  199. usb_ep_status(0,0) = 0x0026; /* Type=Control, control mode buffered */
  200. usb_ep_status(0,1) = 0x0086; /* Type=Control, single buffered, DT=1 */
  201. /* Queue one buffer for SETUP */
  202. usb_ep0_out_queue_bd(true, 0, 64, false);
  203. /* Configure EP1 IN/OUT */
  204. usb_ep_status(1,0) = 0x0011; /* Type=Isochronous, dual buffered */
  205. usb_ep_status(1,1) = 0x0011; /* Type=Isochronous, dual buffered */
  206. usb_ep_bd(1,0,0,1) = 1184;
  207. usb_ep_bd(1,0,0,0) = 0x4000 | 432;
  208. usb_ep_bd(1,0,1,1) = 1616;
  209. usb_ep_bd(1,0,1,0) = 0x4000 | 432;
  210. g_usb.ctrl.state = IDLE;
  211. }
  212. static void
  213. usb_handle_control_data()
  214. {
  215. /* Handle read requests */
  216. if (g_usb.ctrl.state == DATA_IN) {
  217. /* How much left to do ? */
  218. int xflen = g_usb.ctrl.len - g_usb.ctrl.ofs;
  219. if (xflen > 64)
  220. xflen = 64;
  221. /* Setup descriptor for output */
  222. if (xflen)
  223. usb_data_write(&usb_data(0), &g_usb.ctrl.data.in[g_usb.ctrl.ofs], xflen);
  224. usb_ep0_in_queue_bd(0, xflen, false);
  225. /* Move on */
  226. g_usb.ctrl.ofs += xflen;
  227. /* If we're done, setup the OUT ack */
  228. if (xflen < 64) {
  229. usb_ep0_out_queue_bd(false, 0, 0, false);
  230. g_usb.ctrl.state = STATUS_DONE_OUT;
  231. }
  232. }
  233. /* Handle write requests */
  234. if (g_usb.ctrl.state == DATA_OUT) {
  235. if (g_usb.ctrl.ofs == g_usb.ctrl.len)
  236. {
  237. /* Done, ACK with a ZLP */
  238. usb_ep0_in_queue_bd(0, 0, false);
  239. g_usb.ctrl.state = STATUS_DONE_IN;
  240. }
  241. else
  242. {
  243. /* Fill a BD with as much as we can */
  244. }
  245. }
  246. }
  247. static void
  248. usb_handle_control_request(struct usb_ctrl_req_hdr *req)
  249. {
  250. bool handled = false;
  251. /* Defaults */
  252. g_usb.ctrl.data.in = NULL;
  253. g_usb.ctrl.data.out = NULL;
  254. g_usb.ctrl.len = req->wLength;
  255. g_usb.ctrl.ofs = 0;
  256. /* Process request */
  257. switch (req->bRequest)
  258. {
  259. case USB_REQ_GET_STATUS:
  260. case USB_REQ_CLEAR_FEATURE:
  261. case USB_REQ_SET_FEATURE:
  262. break;
  263. case USB_REQ_SET_ADDRESS:
  264. handled = true;
  265. break;
  266. case USB_REQ_GET_DESCRIPTOR:
  267. {
  268. int idx = req->wValue & 0xff;
  269. switch (req->wValue & 0xff00)
  270. {
  271. case 0x0100: /* Device */
  272. g_usb.ctrl.data.out = usb_get_device_desc(&g_usb.ctrl.len);
  273. break;
  274. case 0x0200: /* Configuration */
  275. g_usb.ctrl.data.out = usb_get_config_desc(&g_usb.ctrl.len, idx);
  276. break;
  277. case 0x0300: /* String */
  278. g_usb.ctrl.data.out = usb_get_string_desc(&g_usb.ctrl.len, idx);
  279. break;
  280. }
  281. handled = g_usb.ctrl.data.out != NULL;
  282. break;
  283. }
  284. case USB_REQ_SET_DESCRIPTOR:
  285. case USB_REQ_GET_CONFIGURATION:
  286. break;
  287. case USB_REQ_SET_CONFIGURATION:
  288. handled = true;
  289. break;
  290. case USB_REQ_GET_INTERFACE:
  291. case USB_REQ_SET_INTERFACE:
  292. case USB_REQ_SYNCHFRAME:
  293. default:
  294. break;
  295. }
  296. /* If the request isn't handled, answer wil STALL */
  297. if (!handled) {
  298. if (USB_REQ_IS_READ(req)) {
  299. /* Read request, send a STALL for the DATA IN stage */
  300. g_usb.ctrl.state = STATUS_DONE_IN;
  301. usb_ep0_in_queue_bd(0, 0, true);
  302. } else if (req->wLength) {
  303. /* Write request with some incoming data, send a STALL to next OUT */
  304. g_usb.ctrl.state = STATUS_DONE_OUT;
  305. usb_ep0_out_queue_bd(false, 0, 0, true);
  306. } else {
  307. /* Write request with no dat, send a STALL in the STATUS IN stage */
  308. g_usb.ctrl.state = STATUS_DONE_IN;
  309. usb_ep0_in_queue_bd(0, 0, true);
  310. }
  311. return;
  312. }
  313. /* Handle the 'data' stage now */
  314. g_usb.ctrl.state = USB_REQ_IS_READ(req) ? DATA_IN : DATA_OUT;
  315. if (g_usb.ctrl.len > req->wLength)
  316. g_usb.ctrl.len = req->wLength;
  317. usb_handle_control_data();
  318. }
  319. static void
  320. usb_run_control(void)
  321. {
  322. uint32_t bds_setup, bds_out, bds_in;
  323. bool acted;
  324. do {
  325. /* Not done anything yet */
  326. acted = false;
  327. /* Grab current EP status */
  328. bds_out = usb_ep0_out_peek_bd(false);
  329. bds_setup = usb_ep0_out_peek_bd(true);
  330. bds_in = usb_ep0_in_peek_bd();
  331. /* Check for status IN stage finishing */
  332. if (g_usb.ctrl.state == STATUS_DONE_IN) {
  333. if ((bds_in & USB_BD_STATE_MSK) == USB_BD_STATE_DONE_OK)
  334. {
  335. g_usb.ctrl.state = IDLE;
  336. usb_ep0_in_done_bd();
  337. acted = true;
  338. continue;
  339. }
  340. }
  341. /* Check for status OUT stage finishing */
  342. if (g_usb.ctrl.state == STATUS_DONE_OUT) {
  343. if ((bds_out & USB_BD_STATE_MSK) == USB_BD_STATE_DONE_OK)
  344. {
  345. if ((bds_out & 0x0fff) == 2) {
  346. g_usb.ctrl.state = IDLE;
  347. usb_ep0_out_done_bd(false);
  348. acted = true;
  349. continue;
  350. } else {
  351. puts("[!] Got a non ZLP as a status stage packet ?!?\n");
  352. }
  353. }
  354. }
  355. /* Retry any RX error on both setup and data buffers */
  356. if ((bds_setup & USB_BD_STATE_MSK) == USB_BD_STATE_DONE_ERR)
  357. {
  358. usb_ep0_out_queue_bd(true, 0, 64, false);
  359. acted = true;
  360. continue;
  361. }
  362. if ((bds_out & USB_BD_STATE_MSK) == USB_BD_STATE_DONE_ERR)
  363. {
  364. usb_ep0_out_queue_bd(false, 64, 64, false);
  365. acted = true;
  366. continue;
  367. }
  368. /* Check for SETUP */
  369. if ((bds_setup & USB_BD_STATE_MSK) == USB_BD_STATE_DONE_OK)
  370. {
  371. /* Really setup ? */
  372. if (!(bds_setup & USB_BD_IS_SETUP)) {
  373. puts("[!] Got non-SETUP in the SETUP BD !?!\n");
  374. }
  375. /* Were we waiting for this ? */
  376. if (g_usb.ctrl.state != IDLE) {
  377. puts("[!] Got SETUP while busy !??\n");
  378. }
  379. /* Clear descriptors */
  380. usb_ep_bd(0,0,0,0) = 0x0000;
  381. usb_ep_bd(0,1,0,0) = 0x0000;
  382. /* Make sure DT=1 for IN endpoint after a SETUP */
  383. usb_ep_status(0,1) = 0x0086; /* Type=Control, single buffered, DT=1 */
  384. /* We acked it, need to handle it */
  385. usb_data_read(&g_usb.ctrl.req, &usb_data(0), sizeof(struct usb_ctrl_req_hdr));
  386. usb_handle_control_request(&g_usb.ctrl.req);
  387. /* Release the lockout and allow new SETUP */
  388. usb_csr = g_usb.csr | USB_CR_CEL_RELEASE;
  389. usb_ep0_out_queue_bd(true, 0, 64, false);
  390. return;
  391. }
  392. /* Process data stage */
  393. if (((bds_out & USB_BD_STATE_MSK) == USB_BD_STATE_DONE_OK)) {
  394. usb_ep0_out_done_bd(false);
  395. if (g_usb.ctrl.state != DATA_OUT) {
  396. puts("[!] Got unexpected DATA !?!\n");
  397. continue;
  398. }
  399. usb_handle_control_data();
  400. acted = true;
  401. }
  402. if ((bds_in & USB_BD_STATE_MSK) == USB_BD_STATE_DONE_OK) {
  403. usb_ep0_in_done_bd();
  404. if (g_usb.ctrl.state == DATA_IN) {
  405. usb_handle_control_data();
  406. acted = true;
  407. }
  408. }
  409. } while (acted);
  410. }
  411. static void
  412. usb_run(void)
  413. {
  414. uint32_t status;
  415. int isoc_bdi = 0;
  416. /* Enable pull-up for detection */
  417. usb_csr = g_usb.csr;
  418. /* Main polling loop */
  419. while (1) {
  420. if (getchar_nowait() == 'd')
  421. usb_debug_print();
  422. /* Poll for activity */
  423. status = usb_csr;
  424. if (!(status & USB_SR_IRQ_PENDING))
  425. continue;
  426. /* Ack interrupt */
  427. usb_csr = g_usb.csr | USB_CR_IRQ_ACK;
  428. /* Check control transfers */
  429. usb_run_control();
  430. /* Check ISOC */
  431. {
  432. uint32_t bds = usb_ep_bd(1,0,isoc_bdi,0);
  433. if ((bds & USB_BD_STATE_MSK) == USB_BD_STATE_DONE_OK)
  434. {
  435. printf("%d\n", bds & 0xfff);
  436. /* Re-arm */
  437. usb_ep_bd(1,0,isoc_bdi,0) = 0x4000 | 432;
  438. isoc_bdi ^= 1;
  439. }
  440. }
  441. }
  442. }
  443. void main()
  444. {
  445. /* Init debug IO */
  446. io_init();
  447. puts("Booting..\n");
  448. /* Init USB */
  449. usb_init();
  450. while (1)
  451. {
  452. for (int rep = 10; rep > 0; rep--)
  453. {
  454. puts("Command> ");
  455. char cmd = getchar();
  456. if (cmd > 32 && cmd < 127)
  457. putchar(cmd);
  458. puts("\n");
  459. switch (cmd)
  460. {
  461. case 'd':
  462. usb_debug_print();
  463. break;
  464. case 'r':
  465. usb_run();
  466. break;
  467. default:
  468. continue;
  469. }
  470. break;
  471. }
  472. }
  473. }