summaryrefslogtreecommitdiff
path: root/utils/hwstub/stmp/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/hwstub/stmp/main.c')
-rw-r--r--utils/hwstub/stmp/main.c1105
1 files changed, 0 insertions, 1105 deletions
diff --git a/utils/hwstub/stmp/main.c b/utils/hwstub/stmp/main.c
deleted file mode 100644
index 845f3842ea..0000000000
--- a/utils/hwstub/stmp/main.c
+++ /dev/null
@@ -1,1105 +0,0 @@
1#include "stddef.h"
2#include "protocol.h"
3#include "logf.h"
4#include "usb_ch9.h"
5
6extern unsigned char oc_codestart[];
7extern unsigned char oc_codeend[];
8extern unsigned char oc_stackstart[];
9extern unsigned char oc_stackend[];
10extern unsigned char oc_bufferstart[];
11extern unsigned char oc_bufferend[];
12
13#define oc_codesize ((size_t)(oc_codeend - oc_codestart))
14#define oc_stacksize ((size_t)(oc_stackend - oc_stackstart))
15#define oc_buffersize ((size_t)(oc_bufferend - oc_bufferstart))
16
17/**
18 *
19 * Common
20 *
21 */
22#define MIN(a,b) ((a) < (b) ? (a) : (b))
23
24#define __REG_SET(reg) (*((volatile uint32_t *)(&reg + 1)))
25#define __REG_CLR(reg) (*((volatile uint32_t *)(&reg + 2)))
26#define __REG_TOG(reg) (*((volatile uint32_t *)(&reg + 3)))
27
28#define __BLOCK_SFTRST (1 << 31)
29#define __BLOCK_CLKGATE (1 << 30)
30
31#define __XTRACT(reg, field) ((reg & reg##__##field##_BM) >> reg##__##field##_BP)
32#define __XTRACT_EX(val, field) (((val) & field##_BM) >> field##_BP)
33#define __FIELD_SET(reg, field, val) reg = (reg & ~reg##__##field##_BM) | (val << reg##__##field##_BP)
34
35/**
36 *
37 * Global
38 *
39 */
40
41enum stmp_family_t
42{
43 UNKNOWN,
44 STMP3600,
45 STMP3700,
46 STMP3770,
47 STMP3780
48};
49
50enum stmp_family_t g_stmp_family = UNKNOWN;
51
52/**
53 *
54 * USB subsystem
55 *
56 */
57
58#define USB_BASE 0x80080000
59#define USB_NUM_ENDPOINTS 2
60#define MAX_PKT_SIZE 1024
61#define MAX_PKT_SIZE_EP0 64
62
63/* USB device mode registers (Little Endian) */
64#define REG_USBCMD (*(volatile unsigned int *)(USB_BASE+0x140))
65#define REG_DEVICEADDR (*(volatile unsigned int *)(USB_BASE+0x154))
66#define REG_ENDPOINTLISTADDR (*(volatile unsigned int *)(USB_BASE+0x158))
67#define REG_PORTSC1 (*(volatile unsigned int *)(USB_BASE+0x184))
68#define REG_USBMODE (*(volatile unsigned int *)(USB_BASE+0x1a8))
69#define REG_ENDPTSETUPSTAT (*(volatile unsigned int *)(USB_BASE+0x1ac))
70#define REG_ENDPTPRIME (*(volatile unsigned int *)(USB_BASE+0x1b0))
71#define REG_ENDPTSTATUS (*(volatile unsigned int *)(USB_BASE+0x1b8))
72#define REG_ENDPTCOMPLETE (*(volatile unsigned int *)(USB_BASE+0x1bc))
73#define REG_ENDPTCTRL0 (*(volatile unsigned int *)(USB_BASE+0x1c0))
74#define REG_ENDPTCTRL1 (*(volatile unsigned int *)(USB_BASE+0x1c4))
75#define REG_ENDPTCTRL2 (*(volatile unsigned int *)(USB_BASE+0x1c8))
76#define REG_ENDPTCTRL(_x_) (*(volatile unsigned int *)(USB_BASE+0x1c0+4*(_x_)))
77
78/* USB CMD Register Bit Masks */
79#define USBCMD_RUN (0x00000001)
80#define USBCMD_CTRL_RESET (0x00000002)
81#define USBCMD_PERIODIC_SCHEDULE_EN (0x00000010)
82#define USBCMD_ASYNC_SCHEDULE_EN (0x00000020)
83#define USBCMD_INT_AA_DOORBELL (0x00000040)
84#define USBCMD_ASP (0x00000300)
85#define USBCMD_ASYNC_SCH_PARK_EN (0x00000800)
86#define USBCMD_SUTW (0x00002000)
87#define USBCMD_ATDTW (0x00004000)
88#define USBCMD_ITC (0x00FF0000)
89
90/* Device Address bit masks */
91#define USBDEVICEADDRESS_MASK (0xFE000000)
92#define USBDEVICEADDRESS_BIT_POS (25)
93
94/* Endpoint Setup Status bit masks */
95#define EPSETUP_STATUS_EP0 (0x00000001)
96
97/* PORTSCX Register Bit Masks */
98#define PORTSCX_CURRENT_CONNECT_STATUS (0x00000001)
99#define PORTSCX_CONNECT_STATUS_CHANGE (0x00000002)
100#define PORTSCX_PORT_ENABLE (0x00000004)
101#define PORTSCX_PORT_EN_DIS_CHANGE (0x00000008)
102#define PORTSCX_OVER_CURRENT_ACT (0x00000010)
103#define PORTSCX_OVER_CURRENT_CHG (0x00000020)
104#define PORTSCX_PORT_FORCE_RESUME (0x00000040)
105#define PORTSCX_PORT_SUSPEND (0x00000080)
106#define PORTSCX_PORT_RESET (0x00000100)
107#define PORTSCX_LINE_STATUS_BITS (0x00000C00)
108#define PORTSCX_PORT_POWER (0x00001000)
109#define PORTSCX_PORT_INDICTOR_CTRL (0x0000C000)
110#define PORTSCX_PORT_TEST_CTRL (0x000F0000)
111#define PORTSCX_WAKE_ON_CONNECT_EN (0x00100000)
112#define PORTSCX_WAKE_ON_CONNECT_DIS (0x00200000)
113#define PORTSCX_WAKE_ON_OVER_CURRENT (0x00400000)
114#define PORTSCX_PHY_LOW_POWER_SPD (0x00800000)
115#define PORTSCX_PORT_FORCE_FULL_SPEED (0x01000000)
116#define PORTSCX_PORT_SPEED_MASK (0x0C000000)
117#define PORTSCX_PORT_WIDTH (0x10000000)
118#define PORTSCX_PHY_TYPE_SEL (0xC0000000)
119
120/* bit 11-10 are line status */
121#define PORTSCX_LINE_STATUS_SE0 (0x00000000)
122#define PORTSCX_LINE_STATUS_JSTATE (0x00000400)
123#define PORTSCX_LINE_STATUS_KSTATE (0x00000800)
124#define PORTSCX_LINE_STATUS_UNDEF (0x00000C00)
125#define PORTSCX_LINE_STATUS_BIT_POS (10)
126
127/* bit 15-14 are port indicator control */
128#define PORTSCX_PIC_OFF (0x00000000)
129#define PORTSCX_PIC_AMBER (0x00004000)
130#define PORTSCX_PIC_GREEN (0x00008000)
131#define PORTSCX_PIC_UNDEF (0x0000C000)
132#define PORTSCX_PIC_BIT_POS (14)
133
134/* bit 19-16 are port test control */
135#define PORTSCX_PTC_DISABLE (0x00000000)
136#define PORTSCX_PTC_JSTATE (0x00010000)
137#define PORTSCX_PTC_KSTATE (0x00020000)
138#define PORTSCX_PTC_SE0NAK (0x00030000)
139#define PORTSCX_PTC_PACKET (0x00040000)
140#define PORTSCX_PTC_FORCE_EN (0x00050000)
141#define PORTSCX_PTC_BIT_POS (16)
142
143/* bit 27-26 are port speed */
144#define PORTSCX_PORT_SPEED_FULL (0x00000000)
145#define PORTSCX_PORT_SPEED_LOW (0x04000000)
146#define PORTSCX_PORT_SPEED_HIGH (0x08000000)
147#define PORTSCX_PORT_SPEED_UNDEF (0x0C000000)
148#define PORTSCX_SPEED_BIT_POS (26)
149
150/* bit 28 is parallel transceiver width for UTMI interface */
151#define PORTSCX_PTW (0x10000000)
152#define PORTSCX_PTW_8BIT (0x00000000)
153#define PORTSCX_PTW_16BIT (0x10000000)
154
155/* bit 31-30 are port transceiver select */
156#define PORTSCX_PTS_UTMI (0x00000000)
157#define PORTSCX_PTS_CLASSIC (0x40000000)
158#define PORTSCX_PTS_ULPI (0x80000000)
159#define PORTSCX_PTS_FSLS (0xC0000000)
160#define PORTSCX_PTS_BIT_POS (30)
161
162/* USB MODE Register Bit Masks */
163#define USBMODE_CTRL_MODE_IDLE (0x00000000)
164#define USBMODE_CTRL_MODE_DEVICE (0x00000002)
165#define USBMODE_CTRL_MODE_HOST (0x00000003)
166#define USBMODE_CTRL_MODE_RSV (0x00000001)
167#define USBMODE_SETUP_LOCK_OFF (0x00000008)
168#define USBMODE_STREAM_DISABLE (0x00000010)
169
170/* ENDPOINTCTRLx Register Bit Masks */
171#define EPCTRL_TX_ENABLE (0x00800000)
172#define EPCTRL_TX_DATA_TOGGLE_RST (0x00400000) /* Not EP0 */
173#define EPCTRL_TX_DATA_TOGGLE_INH (0x00200000) /* Not EP0 */
174#define EPCTRL_TX_TYPE (0x000C0000)
175#define EPCTRL_TX_DATA_SOURCE (0x00020000) /* Not EP0 */
176#define EPCTRL_TX_EP_STALL (0x00010000)
177#define EPCTRL_RX_ENABLE (0x00000080)
178#define EPCTRL_RX_DATA_TOGGLE_RST (0x00000040) /* Not EP0 */
179#define EPCTRL_RX_DATA_TOGGLE_INH (0x00000020) /* Not EP0 */
180#define EPCTRL_RX_TYPE (0x0000000C)
181#define EPCTRL_RX_DATA_SINK (0x00000002) /* Not EP0 */
182#define EPCTRL_RX_EP_STALL (0x00000001)
183
184/* bit 19-18 and 3-2 are endpoint type */
185#define EPCTRL_TX_EP_TYPE_SHIFT (18)
186#define EPCTRL_RX_EP_TYPE_SHIFT (2)
187
188#define QH_MULT_POS (30)
189#define QH_ZLT_SEL (0x20000000)
190#define QH_MAX_PKT_LEN_POS (16)
191#define QH_IOS (0x00008000)
192#define QH_NEXT_TERMINATE (0x00000001)
193#define QH_IOC (0x00008000)
194#define QH_MULTO (0x00000C00)
195#define QH_STATUS_HALT (0x00000040)
196#define QH_STATUS_ACTIVE (0x00000080)
197#define EP_QUEUE_CURRENT_OFFSET_MASK (0x00000FFF)
198#define EP_QUEUE_HEAD_NEXT_POINTER_MASK (0xFFFFFFE0)
199#define EP_QUEUE_FRINDEX_MASK (0x000007FF)
200#define EP_MAX_LENGTH_TRANSFER (0x4000)
201
202#define DTD_NEXT_TERMINATE (0x00000001)
203#define DTD_IOC (0x00008000)
204#define DTD_STATUS_ACTIVE (0x00000080)
205#define DTD_STATUS_HALTED (0x00000040)
206#define DTD_STATUS_DATA_BUFF_ERR (0x00000020)
207#define DTD_STATUS_TRANSACTION_ERR (0x00000008)
208#define DTD_RESERVED_FIELDS (0x80007300)
209#define DTD_ADDR_MASK (0xFFFFFFE0)
210#define DTD_PACKET_SIZE (0x7FFF0000)
211#define DTD_LENGTH_BIT_POS (16)
212#define DTD_ERROR_MASK (DTD_STATUS_HALTED | \
213 DTD_STATUS_DATA_BUFF_ERR | \
214 DTD_STATUS_TRANSACTION_ERR)
215/*-------------------------------------------------------------------------*/
216/* manual: 32.13.2 Endpoint Transfer Descriptor (dTD) */
217struct transfer_descriptor {
218 unsigned int next_td_ptr; /* Next TD pointer(31-5), T(0) set
219 indicate invalid */
220 unsigned int size_ioc_sts; /* Total bytes (30-16), IOC (15),
221 MultO(11-10), STS (7-0) */
222 unsigned int buff_ptr0; /* Buffer pointer Page 0 */
223 unsigned int buff_ptr1; /* Buffer pointer Page 1 */
224 unsigned int buff_ptr2; /* Buffer pointer Page 2 */
225 unsigned int buff_ptr3; /* Buffer pointer Page 3 */
226 unsigned int buff_ptr4; /* Buffer pointer Page 4 */
227 unsigned int reserved;
228} __attribute__ ((packed));
229
230static struct transfer_descriptor td_array[USB_NUM_ENDPOINTS*2]
231 __attribute__((aligned(32)));
232
233/* manual: 32.13.1 Endpoint Queue Head (dQH) */
234struct queue_head {
235 unsigned int max_pkt_length; /* Mult(31-30) , Zlt(29) , Max Pkt len
236 and IOS(15) */
237 unsigned int curr_dtd_ptr; /* Current dTD Pointer(31-5) */
238 struct transfer_descriptor dtd; /* dTD overlay */
239 unsigned int setup_buffer[2]; /* Setup data 8 bytes */
240 unsigned int reserved; /* for software use, pointer to the first TD */
241 unsigned int status; /* for software use, status of chain in progress */
242 unsigned int length; /* for software use, transfered bytes of chain in progress */
243 unsigned int wait; /* for softwate use, indicates if the transfer is blocking */
244} __attribute__((packed));
245
246static struct queue_head qh_array[USB_NUM_ENDPOINTS*2] __attribute__((aligned(2048)));
247
248static const unsigned int pipe2mask[] = {
249 0x01, 0x010000,
250 0x02, 0x020000,
251 0x04, 0x040000,
252 0x08, 0x080000,
253 0x10, 0x100000,
254};
255
256/* return transfered size if wait=true */
257static int prime_transfer(int ep_num, void *ptr, int len, bool send, bool wait)
258{
259 int pipe = ep_num * 2 + (send ? 1 : 0);
260 unsigned mask = pipe2mask[pipe];
261 struct transfer_descriptor *td = &td_array[pipe];
262 struct queue_head* qh = &qh_array[pipe];
263
264 /* prepare TD */
265 td->next_td_ptr = DTD_NEXT_TERMINATE;
266 td->size_ioc_sts = (len<< DTD_LENGTH_BIT_POS) | DTD_STATUS_ACTIVE;
267 td->buff_ptr0 = (unsigned int)ptr;
268 td->buff_ptr1 = ((unsigned int)ptr & 0xfffff000) + 0x1000;
269 td->buff_ptr2 = ((unsigned int)ptr & 0xfffff000) + 0x2000;
270 td->buff_ptr3 = ((unsigned int)ptr & 0xfffff000) + 0x3000;
271 td->buff_ptr4 = ((unsigned int)ptr & 0xfffff000) + 0x4000;
272 td->reserved = 0;
273 /* prime */
274 qh->dtd.next_td_ptr = (unsigned int)td;
275 qh->dtd.size_ioc_sts &= ~(QH_STATUS_HALT | QH_STATUS_ACTIVE);
276 REG_ENDPTPRIME |= mask;
277 /* wait for priming to be taken into account */
278 while(!(REG_ENDPTSTATUS & mask));
279 /* wait for completion */
280 if(wait)
281 {
282 while(!(REG_ENDPTCOMPLETE & mask));
283 REG_ENDPTCOMPLETE = mask;
284 /* memory barrier */
285 asm volatile("":::"memory");
286 /* return transfered size */
287 return len - (td->size_ioc_sts >> DTD_LENGTH_BIT_POS);
288 }
289 else
290 return 0;
291}
292
293void usb_drv_set_address(int address)
294{
295 REG_DEVICEADDR = address << USBDEVICEADDRESS_BIT_POS;
296}
297
298/* endpoints */
299#define EP_CONTROL 0
300
301#define DIR_OUT 0
302#define DIR_IN 1
303
304#define EP_DIR(ep) (((ep) & USB_ENDPOINT_DIR_MASK) ? DIR_IN : DIR_OUT)
305#define EP_NUM(ep) ((ep) & USB_ENDPOINT_NUMBER_MASK)
306
307static int usb_drv_send_nonblocking(int endpoint, void* ptr, int length)
308{
309 return prime_transfer(EP_NUM(endpoint), ptr, length, true, false);
310}
311
312static int usb_drv_send(int endpoint, void* ptr, int length)
313{
314 return prime_transfer(EP_NUM(endpoint), ptr, length, true, true);
315}
316
317static int usb_drv_recv(int endpoint, void* ptr, int length)
318{
319 return prime_transfer(EP_NUM(endpoint), ptr, length, false, true);
320}
321
322static int usb_drv_recv_nonblocking(int endpoint, void* ptr, int length)
323{
324 return prime_transfer(EP_NUM(endpoint), ptr, length, false, false);
325}
326
327static int usb_drv_port_speed(void)
328{
329 return (REG_PORTSC1 & 0x08000000) ? 1 : 0;
330}
331
332static void usb_drv_stall(int endpoint, bool stall, bool in)
333{
334 int ep_num = EP_NUM(endpoint);
335
336 if(in)
337 {
338 if(stall)
339 REG_ENDPTCTRL(ep_num) |= EPCTRL_TX_EP_STALL;
340 else
341 REG_ENDPTCTRL(ep_num) &= ~EPCTRL_TX_EP_STALL;
342 }
343 else
344 {
345 if (stall)
346 REG_ENDPTCTRL(ep_num) |= EPCTRL_RX_EP_STALL;
347 else
348 REG_ENDPTCTRL(ep_num) &= ~EPCTRL_RX_EP_STALL;
349 }
350}
351
352static void usb_drv_configure_endpoint(int ep_num, int type)
353{
354 REG_ENDPTCTRL(ep_num) =
355 EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE |
356 EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE |
357 (type << EPCTRL_RX_EP_TYPE_SHIFT) |
358 (type << EPCTRL_TX_EP_TYPE_SHIFT);
359}
360
361/**
362 *
363 * Clkctrl
364 *
365 */
366
367#define HW_CLKCTRL_BASE 0x80040000
368
369#define HW_CLKCTRL_PLLCTRL0 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x0))
370#define HW_CLKCTRL_PLLCTRL0__BYPASS (1 << 17) /* STMP3600 only */
371#define HW_CLKCTRL_PLLCTRL0__POWER (1 << 16)
372#define HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS (1 << 18)
373
374#define HW_CLKCTRL_PLLCTRL1 (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x10))
375#define HW_CLKCTRL_PLLCTRL1__LOCK (1 << 31)
376
377/* STMP3600 only */
378#define HW_CLKCTRL_CPUCLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x20))
379#define HW_CLKCTRL_CPUCLKCTRL__DIV_BP 0
380#define HW_CLKCTRL_CPUCLKCTRL__DIV_BM 0x3ff
381#define HW_CLKCTRL_CPUCLKCTRL__WAIT_PLL_LOCK (1 << 30)
382
383/* STMP3600 */
384#define HW_CLKCTRL_HBUSCLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x30))
385
386/* STMP3600 only */
387#define HW_CLKCTRL_XBUSCLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x40))
388#define HW_CLKCTRL_XBUSCLKCTRL__DIV_BP 0
389#define HW_CLKCTRL_XBUSCLKCTRL__DIV_BM 0x3ff
390
391/* STMP3600 only */
392#define HW_CLKCTRL_UTMICLKCTRL (*(volatile uint32_t *)(HW_CLKCTRL_BASE + 0x70))
393#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE (1 << 30)
394#define HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE (1 << 31)
395
396/**
397 *
398 * Digctl
399 *
400 */
401
402/* Digital control */
403#define HW_DIGCTL_BASE 0x8001C000
404#define HW_DIGCTL_CTRL (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0))
405#define HW_DIGCTL_CTRL__USB_CLKGATE (1 << 2)
406
407#define HW_DIGCTL_MICROSECONDS (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0xC0))
408
409#define HW_DIGCTL_CHIPID (*(volatile uint32_t *)(HW_DIGCTL_BASE + 0x310))
410#define HW_DIGCTL_CHIPID__PRODUCT_CODE_BP 16
411#define HW_DIGCTL_CHIPID__PRODUCT_CODE_BM 0xffff0000
412#define HW_DIGCTL_CHIPID__REVISION_BP 0
413#define HW_DIGCTL_CHIPID__REVISION_BM 0xff
414
415static bool imx233_us_elapsed(uint32_t ref, unsigned us_delay)
416{
417 uint32_t cur = HW_DIGCTL_MICROSECONDS;
418 if(ref + us_delay <= ref)
419 return !(cur > ref) && !(cur < (ref + us_delay));
420 else
421 return (cur < ref) || cur >= (ref + us_delay);
422}
423
424static void udelay(unsigned us)
425{
426 uint32_t ref = HW_DIGCTL_MICROSECONDS;
427 while(!imx233_us_elapsed(ref, us));
428}
429
430#define HZ 1000000
431
432/**
433 *
434 * USB PHY
435 *
436 */
437/* USB Phy */
438#define HW_USBPHY_BASE 0x8007C000
439#define HW_USBPHY_PWD (*(volatile uint32_t *)(HW_USBPHY_BASE + 0))
440
441#define HW_USBPHY_CTRL (*(volatile uint32_t *)(HW_USBPHY_BASE + 0x30))
442
443/**
444 *
445 * DCP
446 *
447 */
448#define HW_DCP_BASE 0x80028000
449
450#define HW_DCP_CTRL (*(volatile unsigned long *)(HW_DCP_BASE + 0x0))
451
452#define HW_DCP_STAT (*(volatile unsigned long *)(HW_DCP_BASE + 0x10))
453#define HW_DCP_STAT__IRQ(x) (1 << (x))
454
455#define HW_DCP_CHANNELCTRL (*(volatile unsigned long *)(HW_DCP_BASE + 0x20))
456#define HW_DCP_CHANNELCTRL__ENABLE_CHANNEL(x) (1 << (x))
457
458#define HW_DCP_CH0CMDPTR (*(volatile unsigned long *)(HW_DCP_BASE + 0x100))
459
460#define HW_DCP_CH0SEMA (*(volatile unsigned long *)(HW_DCP_BASE + 0x110))
461#define HW_DCP_CH0SEMA__INCREMENT(x) (x)
462#define HW_DCP_CH0SEMA__VALUE_BP 16
463#define HW_DCP_CH0SEMA__VALUE_BM (0xff << 16)
464#define HW_DCP_CH0STAT (*(volatile unsigned long *)(HW_DCP_BASE + 0x120))
465
466#define HW_DCP_CTRL0__INTERRUPT_ENABLE (1 << 0)
467#define HW_DCP_CTRL0__DECR_SEMAPHORE (1 << 1)
468#define HW_DCP_CTRL0__ENABLE_MEMCOPY (1 << 4)
469#define HW_DCP_CTRL0__ENABLE_CIPHER (1 << 5)
470#define HW_DCP_CTRL0__ENABLE_HASH (1 << 6)
471#define HW_DCP_CTRL0__CIPHER_ENCRYPT (1 << 8)
472#define HW_DCP_CTRL0__CIPHER_INIT (1 << 9)
473#define HW_DCP_CTRL0__OTP_KEY (1 << 10)
474#define HW_DCP_CTRL0__HASH_INIT (1 << 12)
475#define HW_DCP_CTRL0__HASH_TERM (1 << 13)
476#define HW_DCP_CTRL0__HASH_OUTPUT (1 << 15)
477
478#define HW_DCP_CTRL1__CIPHER_SELECT_BP 0
479#define HW_DCP_CTRL1__CIPHER_SELECT_BM 0xf
480#define HW_DCP_CTRL1__CIPHER_SELECT__AES128 0
481#define HW_DCP_CTRL1__CIPHER_MODE_BP 4
482#define HW_DCP_CTRL1__CIPHER_MODE_BM 0xf0
483#define HW_DCP_CTRL1__CIPHER_MODE__CBC (1 << 4)
484#define HW_DCP_CTRL1__HASH_SELECT_BP 4
485#define HW_DCP_CTRL1__HASH_SELECT_BM 0xf00
486
487struct dcp_packet_t
488{
489 unsigned long next;
490 unsigned long ctrl0;
491 unsigned long ctrl1;
492 unsigned long src_buf;
493 unsigned long dst_buf;
494 unsigned long buf_sz;
495 unsigned long payload_ptr;
496 unsigned long status;
497} __attribute__((packed));
498
499/**
500 *
501 * Misc
502 *
503 */
504
505void memcpy(void *dest, const void *src, size_t n);
506void memmove(void *dest, const void *src, size_t n);
507void memset(void *dst, int value, size_t n);
508
509/**
510 *
511 * USB stack
512 *
513 */
514
515static struct usb_device_descriptor __attribute__((aligned(2)))
516 device_descriptor=
517{
518 .bLength = sizeof(struct usb_device_descriptor),
519 .bDescriptorType = USB_DT_DEVICE,
520 .bcdUSB = 0x0200,
521 .bDeviceClass = USB_CLASS_PER_INTERFACE,
522 .bDeviceSubClass = 0,
523 .bDeviceProtocol = 0,
524 .bMaxPacketSize0 = 64,
525 .idVendor = HWSTUB_USB_VID,
526 .idProduct = HWSTUB_USB_PID,
527 .bcdDevice = HWSTUB_VERSION_MAJOR << 8 | HWSTUB_VERSION_MINOR,
528 .iManufacturer = 1,
529 .iProduct = 2,
530 .iSerialNumber = 3,
531 .bNumConfigurations = 1
532};
533
534#define USB_MAX_CURRENT 200
535
536static struct usb_config_descriptor __attribute__((aligned(2)))
537 config_descriptor =
538{
539 .bLength = sizeof(struct usb_config_descriptor),
540 .bDescriptorType = USB_DT_CONFIG,
541 .wTotalLength = 0, /* will be filled in later */
542 .bNumInterfaces = 1,
543 .bConfigurationValue = 1,
544 .iConfiguration = 0,
545 .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
546 .bMaxPower = (USB_MAX_CURRENT + 1) / 2, /* In 2mA units */
547};
548
549/* main interface */
550static struct usb_interface_descriptor __attribute__((aligned(2)))
551 interface_descriptor =
552{
553 .bLength = sizeof(struct usb_interface_descriptor),
554 .bDescriptorType = USB_DT_INTERFACE,
555 .bInterfaceNumber = 0,
556 .bAlternateSetting = 0,
557 .bNumEndpoints = 3,
558 .bInterfaceClass = HWSTUB_CLASS,
559 .bInterfaceSubClass = HWSTUB_SUBCLASS,
560 .bInterfaceProtocol = HWSTUB_PROTOCOL,
561 .iInterface = 4
562};
563
564
565static struct usb_endpoint_descriptor __attribute__((aligned(2)))
566 endpoint_descriptor =
567{
568 .bLength = sizeof(struct usb_endpoint_descriptor),
569 .bDescriptorType = USB_DT_ENDPOINT,
570 .bEndpointAddress = 0,
571 .bmAttributes = USB_ENDPOINT_XFER_BULK,
572 .wMaxPacketSize = 0,
573 .bInterval = 0
574};
575
576static const struct usb_string_descriptor __attribute__((aligned(2)))
577 usb_string_iManufacturer =
578{
579 24,
580 USB_DT_STRING,
581 {'R', 'o', 'c', 'k', 'b', 'o', 'x', '.', 'o', 'r', 'g'}
582};
583
584static const struct usb_string_descriptor __attribute__((aligned(2)))
585 usb_string_iProduct =
586{
587 52,
588 USB_DT_STRING,
589 {'R', 'o', 'c', 'k', 'b', 'o', 'x', ' ',
590 'h', 'a', 'r', 'd', 'w', 'a', 'r', 'e', ' ',
591 'e', 'm', 'u', 'l', 'a', 't', 'e', 'r'}
592};
593
594static struct usb_string_descriptor __attribute__((aligned(2)))
595 usb_string_iSerial =
596{
597 84,
598 USB_DT_STRING,
599 {'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
600 '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
601 '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
602 '0', '0', '0', '0', '0', '0', '0', '0'}
603};
604
605static struct usb_string_descriptor __attribute__((aligned(2)))
606 usb_string_iInterface =
607{
608 28,
609 USB_DT_STRING,
610 {'A', 'c', 'i', 'd', ' ',
611 '0' + (HWSTUB_VERSION_MAJOR >> 4), '0' + (HWSTUB_VERSION_MAJOR & 0xf), '.',
612 '0' + (HWSTUB_VERSION_MINOR >> 4), '0' + (HWSTUB_VERSION_MINOR & 0xf), '.',
613 '0' + (HWSTUB_VERSION_REV >> 4), '0' + (HWSTUB_VERSION_REV & 0xf) }
614};
615
616/* this is stringid #0: languages supported */
617static const struct usb_string_descriptor __attribute__((aligned(2)))
618 lang_descriptor =
619{
620 4,
621 USB_DT_STRING,
622 {0x0409} /* LANGID US English */
623};
624
625#define USB_NUM_STRINGS 5
626
627static const struct usb_string_descriptor* const usb_strings[USB_NUM_STRINGS] =
628{
629 &lang_descriptor,
630 &usb_string_iManufacturer,
631 &usb_string_iProduct,
632 &usb_string_iSerial,
633 &usb_string_iInterface
634};
635
636uint8_t *usb_buffer = oc_bufferstart;
637uint32_t usb_buffer_size = 0;
638
639#define EP_BULK 1
640#define EP_INT 2
641
642static void set_config(void)
643{
644 usb_drv_configure_endpoint(EP_BULK, USB_ENDPOINT_XFER_BULK);
645 usb_drv_configure_endpoint(EP_INT, USB_ENDPOINT_XFER_INT);
646}
647
648static void handle_std_dev_desc(struct usb_ctrlrequest *req)
649{
650 int size;
651 const void* ptr = NULL;
652 unsigned index = req->wValue & 0xff;
653
654 switch(req->wValue >> 8)
655 {
656 case USB_DT_DEVICE:
657 ptr = &device_descriptor;
658 size = sizeof(struct usb_device_descriptor);
659 break;
660 case USB_DT_OTHER_SPEED_CONFIG:
661 case USB_DT_CONFIG:
662 {
663 int max_packet_size;
664
665 /* config desc */
666 if((req->wValue >> 8) ==USB_DT_CONFIG)
667 {
668 max_packet_size = (usb_drv_port_speed() ? 512 : 64);
669 config_descriptor.bDescriptorType = USB_DT_CONFIG;
670 }
671 else
672 {
673 max_packet_size=(usb_drv_port_speed() ? 64 : 512);
674 config_descriptor.bDescriptorType = USB_DT_OTHER_SPEED_CONFIG;
675 }
676 size = sizeof(struct usb_config_descriptor);
677
678 /* interface */
679 memcpy(usb_buffer + size, (void *)&interface_descriptor,
680 sizeof(interface_descriptor));
681 size += sizeof(interface_descriptor);
682 /* endpoint 1: bulk out */
683 endpoint_descriptor.bEndpointAddress = EP_BULK | USB_DIR_OUT;
684 endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_BULK;
685 endpoint_descriptor.wMaxPacketSize = 512;
686 memcpy(usb_buffer + size, (void *)&endpoint_descriptor,
687 sizeof(endpoint_descriptor));
688 size += sizeof(endpoint_descriptor);
689 /* endpoint 2: bulk in */
690 endpoint_descriptor.bEndpointAddress = EP_BULK | USB_DIR_IN;
691 endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_BULK;
692 endpoint_descriptor.wMaxPacketSize = 512;
693 memcpy(usb_buffer + size, (void *)&endpoint_descriptor,
694 sizeof(endpoint_descriptor));
695 size += sizeof(endpoint_descriptor);
696 /* endpoint 3: int in */
697 endpoint_descriptor.bEndpointAddress = EP_INT | USB_DIR_IN;
698 endpoint_descriptor.bmAttributes = USB_ENDPOINT_XFER_INT;
699 endpoint_descriptor.wMaxPacketSize = 1024;
700 memcpy(usb_buffer + size, (void *)&endpoint_descriptor,
701 sizeof(endpoint_descriptor));
702 size += sizeof(endpoint_descriptor);
703
704 /* fix config descriptor */
705 config_descriptor.bNumInterfaces = 1;
706 config_descriptor.wTotalLength = size;
707 memcpy(usb_buffer, (void *)&config_descriptor, sizeof(config_descriptor));
708
709 ptr = usb_buffer;
710 break;
711 }
712 case USB_DT_STRING:
713 if(index < USB_NUM_STRINGS)
714 {
715 size = usb_strings[index]->bLength;
716 ptr = usb_strings[index];
717 }
718 else
719 usb_drv_stall(EP_CONTROL, true, true);
720 break;
721 default:
722 break;
723 }
724
725 if(ptr)
726 {
727 int length = MIN(size, req->wLength);
728
729 if(ptr != usb_buffer)
730 memcpy(usb_buffer, ptr, length);
731
732 usb_drv_send(EP_CONTROL, usb_buffer, length);
733 usb_drv_recv(EP_CONTROL, NULL, 0);
734 }
735 else
736 usb_drv_stall(EP_CONTROL, true, true);
737}
738
739static void handle_std_dev_req(struct usb_ctrlrequest *req)
740{
741 switch(req->bRequest)
742 {
743 case USB_REQ_GET_CONFIGURATION:
744 usb_buffer[0] = 1;
745 usb_drv_send(EP_CONTROL, usb_buffer, 1);
746 usb_drv_recv(EP_CONTROL, NULL, 0);
747 break;
748 case USB_REQ_SET_CONFIGURATION:
749 usb_drv_send(EP_CONTROL, NULL, 0);
750 set_config();
751 break;
752 case USB_REQ_GET_DESCRIPTOR:
753 handle_std_dev_desc(req);
754 break;
755 case USB_REQ_SET_ADDRESS:
756 usb_drv_send(EP_CONTROL, NULL, 0);
757 usb_drv_set_address(req->wValue);
758 break;
759 case USB_REQ_GET_STATUS:
760 usb_buffer[0] = 0;
761 usb_buffer[1] = 0;
762 usb_drv_send(EP_CONTROL, usb_buffer, 2);
763 usb_drv_recv(EP_CONTROL, NULL, 0);
764 break;
765 default:
766 usb_drv_stall(EP_CONTROL, true, true);
767 }
768}
769
770static void handle_std_req(struct usb_ctrlrequest *req)
771{
772 switch(req->bRequestType & USB_RECIP_MASK)
773 {
774 case USB_RECIP_DEVICE:
775 return handle_std_dev_req(req);
776 default:
777 usb_drv_stall(EP_CONTROL, true, true);
778 }
779}
780
781struct usb_resp_info_version_t g_version =
782{
783 .major = HWSTUB_VERSION_MAJOR,
784 .minor = HWSTUB_VERSION_MINOR,
785 .revision = HWSTUB_VERSION_REV
786};
787
788struct usb_resp_info_layout_t g_layout;
789
790struct usb_resp_info_stmp_t g_stmp;
791
792struct usb_resp_info_features_t g_features =
793{
794 .feature_mask = HWSTUB_FEATURE_LOG | HWSTUB_FEATURE_MEM |
795 HWSTUB_FEATURE_CALL | HWSTUB_FEATURE_JUMP | HWSTUB_FEATURE_AES_OTP
796};
797
798static void fill_layout_info(void)
799{
800 g_layout.oc_code_start = (uint32_t)oc_codestart;
801 g_layout.oc_code_size = oc_codesize;
802 g_layout.oc_stack_start = (uint32_t)oc_stackstart;
803 g_layout.oc_stack_size = oc_stacksize;
804 g_layout.oc_buffer_start = (uint32_t)oc_bufferstart;
805 g_layout.oc_buffer_size = oc_buffersize;
806}
807
808static void fill_stmp_info(void)
809{
810 g_stmp.chipid = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE);
811 g_stmp.rev = __XTRACT(HW_DIGCTL_CHIPID, REVISION);
812 g_stmp.is_supported = g_stmp.chipid == 0x3780 || g_stmp.chipid == 0x3700 ||
813 g_stmp.chipid == 0x3b00;
814}
815
816static void handle_get_info(struct usb_ctrlrequest *req)
817{
818 void *ptr = NULL;
819 int size = 0;
820 switch(req->wIndex)
821 {
822 case HWSTUB_INFO_VERSION:
823 ptr = &g_version;
824 size = sizeof(g_version);
825 break;
826 case HWSTUB_INFO_LAYOUT:
827 fill_layout_info();
828 ptr = &g_layout;
829 size = sizeof(g_layout);
830 break;
831 case HWSTUB_INFO_STMP:
832 fill_stmp_info();
833 ptr = &g_stmp;
834 size = sizeof(g_stmp);
835 break;
836 case HWSTUB_INFO_FEATURES:
837 ptr = &g_features;
838 size = sizeof(g_features);
839 break;
840 default:
841 usb_drv_stall(EP_CONTROL, true, true);
842 }
843
844 if(ptr)
845 {
846 int length = MIN(size, req->wLength);
847
848 if(ptr != usb_buffer)
849 memcpy(usb_buffer, ptr, length);
850 usb_drv_send(EP_CONTROL, usb_buffer, length);
851 usb_drv_recv(EP_CONTROL, NULL, 0);
852 }
853}
854
855static void handle_get_log(struct usb_ctrlrequest *req)
856{
857 enable_logf(false);
858 int length = logf_readback(usb_buffer, MIN(req->wLength, usb_buffer_size));
859 usb_drv_send(EP_CONTROL, usb_buffer, length);
860 usb_drv_recv(EP_CONTROL, NULL, 0);
861 enable_logf(true);
862}
863
864static void handle_rw_mem(struct usb_ctrlrequest *req)
865{
866 uint32_t addr = req->wValue | req->wIndex << 16;
867 uint16_t length = req->wLength;
868
869 if(req->bRequestType & USB_DIR_IN)
870 {
871 memcpy(usb_buffer, (void *)addr, length);
872 asm volatile("nop" : : : "memory");
873 usb_drv_send(EP_CONTROL, usb_buffer, length);
874 usb_drv_recv(EP_CONTROL, NULL, 0);
875 }
876 else
877 {
878 int size = usb_drv_recv(EP_CONTROL, usb_buffer, length);
879 asm volatile("nop" : : : "memory");
880 if(size != length)
881 usb_drv_stall(EP_CONTROL, true, true);
882 else
883 {
884 memcpy((void *)addr, usb_buffer, length);
885 usb_drv_send(EP_CONTROL, NULL, 0);
886 }
887 }
888}
889
890static void handle_call_jump(struct usb_ctrlrequest *req)
891{
892 uint32_t addr = req->wValue | req->wIndex << 16;
893
894 if(req->bRequest == HWSTUB_CALL)
895 ((void (*)(void))addr)();
896 else
897 {
898 /* disconnect to make sure usb/dma won't interfere */
899 REG_USBCMD &= ~USBCMD_RUN;
900 REG_USBCMD |= USBCMD_CTRL_RESET;
901 asm volatile("bx %0\n" : : "r" (addr) : "memory");
902 }
903}
904
905static void do_aes_otp(void *buffer, unsigned length, unsigned params)
906{
907 static struct dcp_packet_t dcp_packet;
908
909 bool encrypt = !!(params & HWSTUB_AES_OTP_ENCRYPT);
910 /* reset DCP */
911 __REG_SET(HW_DCP_CTRL) = 0x80000000;
912 /* clear clock gate */
913 __REG_CLR(HW_DCP_CTRL) = 0xc0000000;
914 /* enable dma for channel 0 */
915 __REG_SET(HW_DCP_CHANNELCTRL) = HW_DCP_CHANNELCTRL__ENABLE_CHANNEL(0);
916 /* prepare packet */
917 dcp_packet.next = 0;
918
919 dcp_packet.ctrl0 = HW_DCP_CTRL0__INTERRUPT_ENABLE |
920 HW_DCP_CTRL0__DECR_SEMAPHORE | HW_DCP_CTRL0__CIPHER_INIT |
921 HW_DCP_CTRL0__ENABLE_CIPHER | HW_DCP_CTRL0__OTP_KEY |
922 (encrypt ? HW_DCP_CTRL0__CIPHER_ENCRYPT : 0);
923 dcp_packet.ctrl1 = HW_DCP_CTRL1__CIPHER_SELECT__AES128 |
924 HW_DCP_CTRL1__CIPHER_MODE__CBC;
925 dcp_packet.src_buf = (unsigned long)buffer + 16;
926 dcp_packet.dst_buf = (unsigned long)buffer + 16;
927 dcp_packet.buf_sz = length - 16;
928 dcp_packet.payload_ptr = (unsigned long)buffer;
929 dcp_packet.status = 0;
930
931 asm volatile("":::"memory");
932 /* kick */
933 HW_DCP_CH0CMDPTR = (unsigned long)&dcp_packet;
934 HW_DCP_CH0SEMA = HW_DCP_CH0SEMA__INCREMENT(1);
935 /* wait */
936 while(!(HW_DCP_STAT & HW_DCP_STAT__IRQ(0)));
937
938 usb_drv_send_nonblocking(EP_INT, buffer, length);
939}
940
941static void handle_aes_otp(struct usb_ctrlrequest *req)
942{
943 uint16_t length = req->wLength;
944
945 int size = usb_drv_recv(EP_CONTROL, usb_buffer, length);
946 if(size != length)
947 usb_drv_stall(EP_CONTROL, true, true);
948 else
949 usb_drv_send(EP_CONTROL, NULL, 0);
950 do_aes_otp(usb_buffer, length, req->wValue);
951}
952
953static void handle_class_dev_req(struct usb_ctrlrequest *req)
954{
955 switch(req->bRequest)
956 {
957 case HWSTUB_GET_INFO:
958 handle_get_info(req);
959 break;
960 case HWSTUB_GET_LOG:
961 handle_get_log(req);
962 break;
963 case HWSTUB_RW_MEM:
964 handle_rw_mem(req);
965 break;
966 case HWSTUB_CALL:
967 case HWSTUB_JUMP:
968 handle_call_jump(req);
969 break;
970 case HWSTUB_AES_OTP:
971 handle_aes_otp(req);
972 break;
973 default:
974 usb_drv_stall(EP_CONTROL, true, true);
975 }
976}
977
978static void handle_class_req(struct usb_ctrlrequest *req)
979{
980 switch(req->bRequestType & USB_RECIP_MASK)
981 {
982 case USB_RECIP_DEVICE:
983 return handle_class_dev_req(req);
984 default:
985 usb_drv_stall(EP_CONTROL, true, true);
986 }
987}
988
989/**
990 *
991 * Main
992 *
993 */
994
995void main(uint32_t arg)
996{
997 usb_buffer_size = oc_buffersize;
998
999 logf("hwstub %d.%d.%d\n", HWSTUB_VERSION_MAJOR, HWSTUB_VERSION_MINOR,
1000 HWSTUB_VERSION_REV);
1001 logf("argument: 0x%08x\n", arg);
1002
1003 /* detect family */
1004 uint16_t product_code = __XTRACT(HW_DIGCTL_CHIPID, PRODUCT_CODE);
1005 if(product_code >= 0x3600 && product_code < 0x3700)
1006 {
1007 logf("identified STMP3600 family\n");
1008 g_stmp_family = STMP3600;
1009 }
1010 else if(product_code == 0x3700)
1011 {
1012 logf("identified STMP3700 family\n");
1013 g_stmp_family = STMP3700;
1014 }
1015 else if(product_code == 0x37b0)
1016 {
1017 logf("identified STMP3770 family\n");
1018 g_stmp_family = STMP3770;
1019 }
1020 else if(product_code == 0x3780)
1021 {
1022 logf("identified STMP3780 family\n");
1023 g_stmp_family = STMP3780;
1024 }
1025 else
1026 logf("cannot identify family: 0x%x\n", product_code);
1027
1028 /* we don't know if USB was connected or not. In USB recovery mode it will
1029 * but in other cases it might not be. In doubt, disconnect */
1030 REG_USBCMD &= ~USBCMD_RUN;
1031 if(g_stmp_family == STMP3600)
1032 {
1033 /* CPU clock is always derived from PLL, if we switch to PLL, cpu will
1034 * run at 480 MHz unprepared ! That's bad so prepare to run at slow sleed
1035 * (1.2MHz) for a safe transition */
1036 HW_CLKCTRL_CPUCLKCTRL = HW_CLKCTRL_CPUCLKCTRL__WAIT_PLL_LOCK | 400;
1037 /* We need to ensure that XBUS < HBUS but HBUS will be 1.2 MHz after the
1038 * switch so lower XBUS too */
1039 HW_CLKCTRL_XBUSCLKCTRL = 20;
1040 /* Power PLL */
1041 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER;
1042 HW_CLKCTRL_PLLCTRL0 = (HW_CLKCTRL_PLLCTRL0 & ~0x3ff) | 480;
1043 /* Wait lock */
1044 while(!(HW_CLKCTRL_PLLCTRL1 & HW_CLKCTRL_PLLCTRL1__LOCK));
1045 /* Switch to PLL source */
1046 __REG_CLR(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__BYPASS;
1047 /* Get back XBUS = 24 MHz and CPU = HBUS = 64MHz */
1048 HW_CLKCTRL_CPUCLKCTRL = 7;
1049 HW_CLKCTRL_HBUSCLKCTRL = 7;
1050 HW_CLKCTRL_XBUSCLKCTRL = 1;
1051 __REG_CLR(HW_CLKCTRL_UTMICLKCTRL) = HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK120M_GATE;
1052 __REG_CLR(HW_CLKCTRL_UTMICLKCTRL) = HW_CLKCTRL_UTMICLKCTRL__UTMI_CLK30M_GATE;
1053 }
1054 else
1055 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__POWER;
1056 /* enable USB PHY PLL */
1057 __REG_SET(HW_CLKCTRL_PLLCTRL0) = HW_CLKCTRL_PLLCTRL0__EN_USB_CLKS;
1058 /* power up USB PHY */
1059 __REG_CLR(HW_USBPHY_CTRL) = __BLOCK_CLKGATE | __BLOCK_SFTRST;
1060 HW_USBPHY_PWD = 0;
1061 /* enable USB controller */
1062 __REG_CLR(HW_DIGCTL_CTRL) = HW_DIGCTL_CTRL__USB_CLKGATE;
1063 /* reset the controller */
1064 REG_USBCMD |= USBCMD_CTRL_RESET;
1065 while (REG_USBCMD & USBCMD_CTRL_RESET);
1066 /* put it in device mode */
1067 REG_USBMODE = USBMODE_CTRL_MODE_DEVICE;
1068 /* reset address */
1069 REG_DEVICEADDR = 0;
1070 /* prepare qh array */
1071 qh_array[0].max_pkt_length = 1 << 29 | MAX_PKT_SIZE_EP0 << 16;
1072 qh_array[1].max_pkt_length = 1 << 29 | MAX_PKT_SIZE_EP0 << 16;
1073 qh_array[2].max_pkt_length = 1 << 29 | MAX_PKT_SIZE << 16;
1074 qh_array[3].max_pkt_length = 1 << 29 | MAX_PKT_SIZE << 16;
1075 /* setup qh */
1076 REG_ENDPOINTLISTADDR = (unsigned int)qh_array;
1077 /* clear setup status */
1078 REG_ENDPTSETUPSTAT = EPSETUP_STATUS_EP0;
1079 /* run! */
1080 REG_USBCMD |= USBCMD_RUN;
1081
1082 while(1)
1083 {
1084 /* wait for setup */
1085 while(!(REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0))
1086 ;
1087 /* clear setup status */
1088 REG_ENDPTSETUPSTAT = EPSETUP_STATUS_EP0;
1089 /* check request */
1090 asm volatile("":::"memory");
1091 struct usb_ctrlrequest *req = (void *)&qh_array[0].setup_buffer[0];
1092
1093 switch(req->bRequestType & USB_TYPE_MASK)
1094 {
1095 case USB_TYPE_STANDARD:
1096 handle_std_req(req);
1097 break;
1098 case USB_TYPE_CLASS:
1099 handle_class_req(req);
1100 break;
1101 default:
1102 usb_drv_stall(EP_CONTROL, true, true);
1103 }
1104 }
1105}