1 /** @file
2 
3   Copyright (c) 2015-2017, Linaro. All rights reserved.
4 
5   This program and the accompanying materials
6   are licensed and made available under the terms and conditions of the BSD License
7   which accompanies this distribution.  The full text of the license may be found at
8   http://opensource.org/licenses/bsd-license.php
9 
10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 **/
14 
15 #include <IndustryStandard/Usb.h>
16 #include <Library/ArmLib.h>
17 #include <Library/TimerLib.h>
18 #include <Library/DebugLib.h>
19 #include <Library/UefiBootServicesTableLib.h>
20 #include <Library/UefiDriverEntryPoint.h>
21 #include <Library/UefiRuntimeServicesTableLib.h>
22 #include <Library/IoLib.h>
23 #include <Library/MemoryAllocationLib.h>
24 #include <Library/UncachedMemoryAllocationLib.h>
25 #include <Library/CacheMaintenanceLib.h>
26 #include <Library/BaseMemoryLib.h>
27 #include <Library/BaseLib.h>
28 #include <Protocol/DwUsb.h>
29 #include <Protocol/UsbDevice.h>
30 
31 #include "DwUsbDxe.h"
32 
33 #define USB_TYPE_LENGTH               16
34 #define USB_BLOCK_HIGH_SPEED_SIZE     512
35 #define DATA_SIZE                     32768
36 #define CMD_SIZE                      512
37 #define MATCH_CMD_LITERAL(Cmd, Buf)   !AsciiStrnCmp (Cmd, Buf, sizeof (Cmd) - 1)
38 
39 // The time between interrupt polls, in units of 100 nanoseconds
40 // 10 Microseconds
41 #define DW_INTERRUPT_POLL_PERIOD      10000
42 
43 EFI_GUID  gDwUsbProtocolGuid = DW_USB_PROTOCOL_GUID;
44 
45 STATIC dwc_otg_dev_dma_desc_t *gDmaDesc,*gDmaDescEp0,*gDmaDescIn;
46 STATIC USB_DEVICE_REQUEST *gCtrlReq;
47 STATIC VOID *RxBuf;
48 STATIC UINTN RxDescBytes = 0;
49 STATIC UINTN mNumDataBytes;
50 
51 STATIC DW_USB_PROTOCOL          *DwUsb;
52 
53 STATIC USB_DEVICE_DESCRIPTOR    *mDeviceDescriptor;
54 
55 // The config descriptor, interface descriptor, and endpoint descriptors in a
56 // buffer (in that order)
57 STATIC VOID                     *mDescriptors;
58 // Convenience pointers to those descriptors inside the buffer:
59 STATIC USB_INTERFACE_DESCRIPTOR *mInterfaceDescriptor;
60 STATIC USB_CONFIG_DESCRIPTOR    *mConfigDescriptor;
61 STATIC USB_ENDPOINT_DESCRIPTOR  *mEndpointDescriptors;
62 
63 STATIC USB_DEVICE_RX_CALLBACK   mDataReceivedCallback;
64 STATIC USB_DEVICE_TX_CALLBACK   mDataSentCallback;
65 
66 
67 /* To detect which mode was run, high speed or full speed */
68 STATIC
69 UINTN
UsbDrvPortSpeed(VOID)70 UsbDrvPortSpeed (
71   VOID
72   )
73 {
74   /*
75   * 2'b00: High speed (PHY clock is running at 30 or 60 MHz)
76   */
77   UINT32          Val = READ_REG32 (DSTS) & 2;
78   return (!Val);
79 }
80 
81 STATIC
82 VOID
ResetEndpoints(VOID)83 ResetEndpoints (
84   VOID
85   )
86 {
87   /* EP0 IN ACTIVE NEXT=1 */
88   WRITE_REG32 (DIEPCTL0, DXEPCTL_USBACTEP | BIT11);
89 
90   /* EP0 OUT ACTIVE */
91   WRITE_REG32 (DOEPCTL0, DXEPCTL_USBACTEP);
92 
93   /* Clear any pending OTG Interrupts */
94   WRITE_REG32 (GOTGINT, ~0);
95 
96   /* Clear any pending interrupts */
97   WRITE_REG32 (GINTSTS, ~0);
98   WRITE_REG32 (DIEPINT0, ~0);
99   WRITE_REG32 (DOEPINT0, ~0);
100   WRITE_REG32 (DIEPINT1, ~0);
101   WRITE_REG32 (DOEPINT1, ~0);
102 
103   /* IN EP interrupt mask */
104   WRITE_REG32 (DIEPMSK, DXEPMSK_TIMEOUTMSK | DXEPMSK_AHBERMSK | DXEPMSK_XFERCOMPLMSK);
105   /* OUT EP interrupt mask */
106   WRITE_REG32 (DOEPMSK, DXEPMSK_TIMEOUTMSK | DXEPMSK_AHBERMSK | DXEPMSK_XFERCOMPLMSK);
107   /* Enable interrupts on Ep0 */
108   WRITE_REG32 (DAINTMSK, (1 << DAINTMSK_OUTEPMSK_SHIFT) | (1 << DAINTMSK_INEPMSK_SHIFT));
109 
110   /* EP0 OUT Transfer Size:64 Bytes, 1 Packet, 3 Setup Packet, Read to receive setup packet*/
111   WRITE_REG32 (DOEPTSIZ0, DXEPTSIZ_SUPCNT(3) | DXEPTSIZ_PKTCNT(1) | DXEPTSIZ_XFERSIZE(64));
112 
113   //notes that:the compulsive conversion is expectable.
114   gDmaDescEp0->status.b.bs = 0x3;
115   gDmaDescEp0->status.b.mtrf = 0;
116   gDmaDescEp0->status.b.sr = 0;
117   gDmaDescEp0->status.b.l = 1;
118   gDmaDescEp0->status.b.ioc = 1;
119   gDmaDescEp0->status.b.sp = 0;
120   gDmaDescEp0->status.b.bytes = 64;
121   gDmaDescEp0->buf = (UINT32)(UINTN)(gCtrlReq);
122   gDmaDescEp0->status.b.sts = 0;
123   gDmaDescEp0->status.b.bs = 0x0;
124   WRITE_REG32 (DOEPDMA0, (UINT32)(UINTN)(gDmaDescEp0));
125   /* EP0 OUT ENABLE CLEARNAK */
126   WRITE_REG32 (DOEPCTL0, (READ_REG32 (DOEPCTL0) | DXEPCTL_EPENA | DXEPCTL_CNAK));
127 }
128 
129 STATIC
130 VOID
EpTx(IN UINT8 Ep,IN CONST VOID * Ptr,IN UINTN Len)131 EpTx (
132   IN UINT8          Ep,
133   IN CONST VOID    *Ptr,
134   IN UINTN          Len
135   )
136 {
137     UINT32          BlockSize;
138     UINT32          Packets;
139 
140     /* EPx OUT ACTIVE */
141     WRITE_REG32 (DIEPCTL (Ep), (READ_REG32 (DIEPCTL (Ep))) | DXEPCTL_USBACTEP);
142     if (!Ep) {
143         BlockSize = 64;
144     } else {
145         BlockSize = UsbDrvPortSpeed () ? USB_BLOCK_HIGH_SPEED_SIZE : 64;
146     }
147     Packets = (Len + BlockSize - 1) / BlockSize;
148 
149     if (!Len) {
150       /* send one empty packet */
151       gDmaDescIn->status.b.bs = 0x3;
152       gDmaDescIn->status.b.l = 1;
153       gDmaDescIn->status.b.ioc = 1;
154       gDmaDescIn->status.b.sp = 1;
155       gDmaDescIn->status.b.bytes = 0;
156       gDmaDescIn->buf = 0;
157       gDmaDescIn->status.b.sts = 0;
158       gDmaDescIn->status.b.bs = 0x0;
159 
160       WRITE_REG32 (DIEPDMA (Ep), (UINT32)(UINTN)(gDmaDescIn));             // DMA Address (DMAAddr) is zero
161     } else {
162       WRITE_REG32 (DIEPTSIZ (Ep), Len | (Packets << 19));
163 
164       //flush cache
165       WriteBackDataCacheRange ((VOID *)Ptr, Len);
166 
167       gDmaDescIn->status.b.bs = 0x3;
168       gDmaDescIn->status.b.l = 1;
169       gDmaDescIn->status.b.ioc = 1;
170       gDmaDescIn->status.b.sp = 1;
171       gDmaDescIn->status.b.bytes = Len;
172       gDmaDescIn->buf = (UINT32)((UINTN)Ptr);
173       gDmaDescIn->status.b.sts = 0;
174       gDmaDescIn->status.b.bs = 0x0;
175       WRITE_REG32 (DIEPDMA (Ep), (UINT32)(UINTN)(gDmaDescIn));         // Ptr is DMA address
176     }
177     ArmDataSynchronizationBarrier ();
178     /* epena & cnak */
179     WRITE_REG32 (DIEPCTL (Ep), READ_REG32 (DIEPCTL (Ep)) | DXEPCTL_EPENA | DXEPCTL_CNAK | BIT11);
180 }
181 
182 STATIC
183 VOID
EpRx(IN UINTN Ep,IN UINTN Len)184 EpRx (
185   IN UINTN            Ep,
186   IN UINTN            Len
187   )
188 {
189   /* EPx UNSTALL */
190   WRITE_REG32 (DOEPCTL (Ep), ((READ_REG32 (DOEPCTL (Ep))) & (~DXEPCTL_STALL)));
191   /* EPx OUT ACTIVE */
192   WRITE_REG32 (DOEPCTL (Ep), (READ_REG32 (DOEPCTL (Ep)) | DXEPCTL_USBACTEP));
193 
194   if (Len >= DATA_SIZE) {
195     RxDescBytes = DATA_SIZE;
196   } else {
197     RxDescBytes = Len;
198   }
199 
200   RxBuf = AllocateZeroPool (DATA_SIZE);
201   ASSERT (RxBuf != NULL);
202 
203   InvalidateDataCacheRange (RxBuf, Len);
204 
205   gDmaDesc->status.b.bs = 0x3;
206   gDmaDesc->status.b.mtrf = 0;
207   gDmaDesc->status.b.sr = 0;
208   gDmaDesc->status.b.l = 1;
209   gDmaDesc->status.b.ioc = 1;
210   gDmaDesc->status.b.sp = 0;
211   gDmaDesc->status.b.bytes = (UINT32)RxDescBytes;
212   gDmaDesc->buf = (UINT32)((UINTN)RxBuf);
213   gDmaDesc->status.b.sts = 0;
214   gDmaDesc->status.b.bs = 0x0;
215 
216   ArmDataSynchronizationBarrier ();
217   WRITE_REG32 (DOEPDMA (Ep), (UINT32)((UINTN)gDmaDesc));
218   /* EPx OUT ENABLE CLEARNAK */
219   WRITE_REG32 (DOEPCTL (Ep), (READ_REG32 (DOEPCTL (Ep)) | DXEPCTL_EPENA | DXEPCTL_CNAK));
220 }
221 
222 STATIC
223 EFI_STATUS
HandleGetDescriptor(IN USB_DEVICE_REQUEST * Request)224 HandleGetDescriptor (
225   IN USB_DEVICE_REQUEST  *Request
226   )
227 {
228   UINT8       DescriptorType;
229   UINTN       ResponseSize;
230   VOID       *ResponseData;
231   EFI_USB_STRING_DESCRIPTOR        *Descriptor = NULL;
232   UINTN                             DescriptorSize;
233 
234   ResponseSize = 0;
235   ResponseData = NULL;
236 
237   // Pretty confused if bmRequestType is anything but this:
238   ASSERT (Request->RequestType == USB_DEV_GET_DESCRIPTOR_REQ_TYPE);
239 
240   // Choose the response
241   DescriptorType = Request->Value >> 8;
242   switch (DescriptorType) {
243   case USB_DESC_TYPE_DEVICE:
244     DEBUG ((DEBUG_INFO, "USB: Got a request for device descriptor\n"));
245     ResponseSize = sizeof (USB_DEVICE_DESCRIPTOR);
246     ResponseData = mDeviceDescriptor;
247     break;
248   case USB_DESC_TYPE_CONFIG:
249     DEBUG ((DEBUG_INFO, "USB: Got a request for config descriptor\n"));
250     ResponseSize = mConfigDescriptor->TotalLength;
251     ResponseData = mDescriptors;
252     break;
253   case USB_DESC_TYPE_STRING:
254     DEBUG ((DEBUG_INFO, "USB: Got a request for String descriptor %d\n", Request->Value & 0xFF));
255     switch (Request->Value & 0xff) {
256     case 0:
257       DescriptorSize = sizeof (EFI_USB_STRING_DESCRIPTOR) +
258                        LANG_LENGTH * sizeof (CHAR16) + 1;
259       Descriptor = (EFI_USB_STRING_DESCRIPTOR *)AllocateZeroPool (DescriptorSize);
260       ASSERT (Descriptor != NULL);
261       Descriptor->Length = LANG_LENGTH * sizeof (CHAR16);
262       Descriptor->DescriptorType = USB_DESC_TYPE_STRING;
263       DwUsb->GetLang (Descriptor->String, &Descriptor->Length);
264       ResponseSize = Descriptor->Length;
265       ResponseData = Descriptor;
266       break;
267     case 1:
268       DescriptorSize = sizeof (EFI_USB_STRING_DESCRIPTOR) +
269                        MANU_FACTURER_STRING_LENGTH * sizeof (CHAR16) + 1;
270       Descriptor = (EFI_USB_STRING_DESCRIPTOR *)AllocateZeroPool (DescriptorSize);
271       ASSERT (Descriptor != NULL);
272       Descriptor->Length = MANU_FACTURER_STRING_LENGTH * sizeof (CHAR16);
273       Descriptor->DescriptorType = USB_DESC_TYPE_STRING;
274       DwUsb->GetManuFacturer (Descriptor->String, &Descriptor->Length);
275       ResponseSize = Descriptor->Length;
276       ResponseData = Descriptor;
277       break;
278     case 2:
279       DescriptorSize = sizeof (EFI_USB_STRING_DESCRIPTOR) +
280                        PRODUCT_STRING_LENGTH * sizeof (CHAR16) + 1;
281       Descriptor = (EFI_USB_STRING_DESCRIPTOR *)AllocateZeroPool (DescriptorSize);
282       ASSERT (Descriptor != NULL);
283       Descriptor->Length = PRODUCT_STRING_LENGTH * sizeof (CHAR16);
284       Descriptor->DescriptorType = USB_DESC_TYPE_STRING;
285       DwUsb->GetProduct (Descriptor->String, &Descriptor->Length);
286       ResponseSize = Descriptor->Length;
287       ResponseData = Descriptor;
288       break;
289     case 3:
290       DescriptorSize = sizeof (EFI_USB_STRING_DESCRIPTOR) +
291                        SERIAL_STRING_LENGTH * sizeof (CHAR16) + 1;
292       Descriptor = (EFI_USB_STRING_DESCRIPTOR *)AllocateZeroPool (DescriptorSize);
293       ASSERT (Descriptor != NULL);
294       Descriptor->Length = SERIAL_STRING_LENGTH * sizeof (CHAR16);
295       Descriptor->DescriptorType = USB_DESC_TYPE_STRING;
296       DwUsb->GetSerialNo (Descriptor->String, &Descriptor->Length);
297       ResponseSize = Descriptor->Length;
298       ResponseData = Descriptor;
299       break;
300     }
301     break;
302   default:
303     DEBUG ((DEBUG_INFO, "USB: Didn't understand request for descriptor 0x%04x\n", Request->Value));
304     break;
305   }
306 
307   // Send the response
308   if (ResponseData) {
309     ASSERT (ResponseSize != 0);
310 
311     if (Request->Length < ResponseSize) {
312       // Truncate response
313       ResponseSize = Request->Length;
314     } else if (Request->Length > ResponseSize) {
315       DEBUG ((DEBUG_INFO, "USB: Info: ResponseSize < wLength\n"));
316     }
317 
318     EpTx (0, ResponseData, ResponseSize);
319   }
320   if (Descriptor) {
321     FreePool (Descriptor);
322   }
323 
324   return EFI_SUCCESS;
325 }
326 
327 STATIC
328 EFI_STATUS
HandleSetAddress(IN USB_DEVICE_REQUEST * Request)329 HandleSetAddress (
330   IN USB_DEVICE_REQUEST  *Request
331   )
332 {
333   // Pretty confused if bmRequestType is anything but this:
334   ASSERT (Request->RequestType == USB_DEV_SET_ADDRESS_REQ_TYPE);
335   DEBUG ((DEBUG_INFO, "USB: Setting address to %d\n", Request->Value));
336   ResetEndpoints ();
337 
338   WRITE_REG32 (DCFG, (READ_REG32 (DCFG) & ~DCFG_DEVADDR_MASK) | DCFG_DEVADDR(Request->Value));
339   EpTx (0, 0, 0);
340 
341   return EFI_SUCCESS;
342 }
343 
344 STATIC
345 UINTN
UsbDrvRequestEndpoint(IN UINTN Type,IN UINTN Dir)346 UsbDrvRequestEndpoint (
347   IN UINTN           Type,
348   IN UINTN           Dir
349   )
350 {
351   UINTN              Ep = 1;
352   UINTN              Ret, NewBits;
353 
354   Ret = Ep | Dir;
355   NewBits = (Type << 18) | 0x10000000;
356 
357   /*
358    * (Type << 18):Endpoint Type (EPType)
359    * 0x10000000:Endpoint Enable (EPEna)
360    * 0x000C000:Endpoint Type (EPType);Hardcoded to 00 for control.
361    * (ep<<22):TxFIFO Number (TxFNum)
362    * 0x20000:NAK Status (NAKSts);The core is transmitting NAK handshakes on this endpoint.
363    */
364   if (Dir) {  // IN: to host
365     WRITE_REG32 (DIEPCTL (Ep), ((READ_REG32 (DIEPCTL (Ep))) & ~DXEPCTL_EPTYPE_MASK) | NewBits | (Ep << 22) | DXEPCTL_NAKSTS);
366   } else {    // OUT: to device
367     WRITE_REG32 (DOEPCTL (Ep), ((READ_REG32 (DOEPCTL (Ep))) & ~DXEPCTL_EPTYPE_MASK) | NewBits);
368   }
369 
370   return Ret;
371 }
372 
373 STATIC
374 EFI_STATUS
HandleSetConfiguration(IN USB_DEVICE_REQUEST * Request)375 HandleSetConfiguration (
376   IN USB_DEVICE_REQUEST  *Request
377   )
378 {
379   ASSERT (Request->RequestType == USB_DEV_SET_CONFIGURATION_REQ_TYPE);
380 
381   // Cancel all transfers
382   ResetEndpoints ();
383 
384   UsbDrvRequestEndpoint (2, 0);
385   UsbDrvRequestEndpoint (2, 0x80);
386 
387   WRITE_REG32 (DIEPCTL1, (READ_REG32 (DIEPCTL1)) | BIT28 | BIT19 | DXEPCTL_USBACTEP | BIT11);
388 
389   /* Enable interrupts on all endpoints */
390   WRITE_REG32 (DAINTMSK, ~0);
391 
392   EpRx (1, CMD_SIZE);
393   EpTx (0, 0, 0);
394   return EFI_SUCCESS;
395 }
396 
397 
398 STATIC
399 EFI_STATUS
HandleDeviceRequest(IN USB_DEVICE_REQUEST * Request)400 HandleDeviceRequest (
401   IN USB_DEVICE_REQUEST  *Request
402   )
403 {
404   EFI_STATUS  Status;
405 
406   switch (Request->Request) {
407   case USB_DEV_GET_DESCRIPTOR:
408     Status = HandleGetDescriptor (Request);
409     break;
410   case USB_DEV_SET_ADDRESS:
411     Status = HandleSetAddress (Request);
412     break;
413   case USB_DEV_SET_CONFIGURATION:
414     Status = HandleSetConfiguration (Request);
415     break;
416   default:
417     DEBUG ((DEBUG_ERROR,
418       "Didn't understand RequestType 0x%x Request 0x%x\n",
419       Request->RequestType, Request->Request));
420       Status = EFI_INVALID_PARAMETER;
421     break;
422   }
423 
424   return Status;
425 }
426 
427 
428 // Instead of actually registering interrupt handlers, we poll the controller's
429 //  interrupt source register in this function.
430 STATIC
431 VOID
CheckInterrupts(IN EFI_EVENT Event,IN VOID * Context)432 CheckInterrupts (
433   IN EFI_EVENT        Event,
434   IN VOID            *Context
435   )
436 {
437   UINT32              Ints, EpInts;
438 
439 
440   // interrupt register
441   Ints = READ_REG32 (GINTSTS);
442 
443   /*
444    * bus reset
445    * The core sets this bit to indicate that a reset is detected on the USB.
446    */
447   if (Ints & GINTSTS_USBRST) {
448     WRITE_REG32 (DCFG, DCFG_DESCDMA | DCFG_NZ_STS_OUT_HSHK);
449     ResetEndpoints ();
450   }
451 
452   /*
453    * enumeration done, we now know the speed
454    * The core sets this bit to indicate that speed enumeration is complete. The
455    * application must read the Device Status (DSTS) register to obtain the
456    * enumerated speed.
457    */
458   if (Ints & GINTSTS_ENUMDONE) {
459     /* Set up the maximum packet sizes accordingly */
460     UINTN MaxPacket = UsbDrvPortSpeed () ? USB_BLOCK_HIGH_SPEED_SIZE : 64;
461     //Set Maximum In Packet Size (MPS)
462     WRITE_REG32 (DIEPCTL1, ((READ_REG32 (DIEPCTL1)) & ~DXEPCTL_MPS_MASK) | MaxPacket);
463     //Set Maximum Out Packet Size (MPS)
464     WRITE_REG32 (DOEPCTL1, ((READ_REG32 (DOEPCTL1)) & ~DXEPCTL_MPS_MASK) | MaxPacket);
465   }
466 
467   /*
468    * IN EP event
469    * The core sets this bit to indicate that an interrupt is pending on one of the IN
470    * endpoInts of the core (in Device mode). The application must read the
471    * Device All EndpoInts Interrupt (DAINT) register to determine the exact
472    * number of the IN endpoint on which the interrupt occurred, and then read
473    * the corresponding Device IN Endpoint-n Interrupt (DIEPINTn) register to
474    * determine the exact cause of the interrupt. The application must clear the
475    * appropriate status bit in the corresponding DIEPINTn register to clear this bit.
476    */
477   if (Ints & GINTSTS_IEPINT) {
478     EpInts = READ_REG32 (DIEPINT0);
479     WRITE_REG32 (DIEPINT0, EpInts);
480     if (EpInts & DXEPINT_XFERCOMPL) {
481       DEBUG ((DEBUG_INFO, "INT: IN TX completed.DIEPTSIZ (0) = 0x%x.\n", READ_REG32 (DIEPTSIZ0)));
482     }
483 
484     EpInts = READ_REG32 (DIEPINT1);
485     WRITE_REG32 (DIEPINT1, EpInts);
486     if (EpInts & DXEPINT_XFERCOMPL) {
487       DEBUG ((DEBUG_INFO, "ep1: IN TX completed\n"));
488     }
489   }
490 
491   /*
492    * OUT EP event
493    * The core sets this bit to indicate that an interrupt is pending on one of the
494    * OUT endpoints of the core (in Device mode). The application must read the
495    * Device All EndpoInts Interrupt (DAINT) register to determine the exact
496    * number of the OUT endpoint on which the interrupt occurred, and then read
497    * the corresponding Device OUT Endpoint-n Interrupt (DOEPINTn) register
498    * to determine the exact cause of the interrupt. The application must clear the
499    * appropriate status bit in the corresponding DOEPINTn register to clear this bit.
500    */
501   if (Ints & GINTSTS_OEPINT) {
502     /* indicates the status of an endpoint
503      * with respect to USB- and AHB-related events. */
504     EpInts = READ_REG32 (DOEPINT0);
505     if (EpInts) {
506       WRITE_REG32 (DOEPINT0, EpInts);
507       if (EpInts & DXEPINT_XFERCOMPL) {
508         DEBUG ((DEBUG_INFO, "INT: EP0 RX completed. DOEPTSIZ(0) = 0x%x.\n", READ_REG32 (DOEPTSIZ0)));
509       }
510       /*
511        *
512        IN Token Received When TxFIFO is Empty (INTknTXFEmp)
513        * Indicates that an IN token was received when the associated TxFIFO (periodic/nonperiodic)
514        * was empty. This interrupt is asserted on the endpoint for which the IN token
515        * was received.
516        */
517       if (EpInts & BIT3) { /* SETUP phase done */
518         WRITE_REG32 (DIEPCTL0, READ_REG32 (DIEPCTL0) | DXEPCTL_SNAK);
519         WRITE_REG32 (DOEPCTL0, READ_REG32 (DOEPCTL0) | DXEPCTL_SNAK);
520         /*clear IN EP intr*/
521         WRITE_REG32 (DIEPINT0, ~0);
522         HandleDeviceRequest((USB_DEVICE_REQUEST *)gCtrlReq);
523       }
524 
525       /* Make sure EP0 OUT is set up to accept the next request */
526       WRITE_REG32 (DOEPTSIZ0, DXEPTSIZ_SUPCNT(3) | DXEPTSIZ_PKTCNT(1) | DXEPTSIZ_XFERSIZE(64));
527       /*
528        * IN Token Received When TxFIFO is Empty (INTknTXFEmp)
529        * Indicates that an IN token was received when the associated TxFIFO (periodic/nonperiodic)
530        * was empty. This interrupt is asserted on the endpoint for which the IN token
531        * was received.
532        */
533       gDmaDescEp0->status.b.bs = 0x3;
534       gDmaDescEp0->status.b.mtrf = 0;
535       gDmaDescEp0->status.b.sr = 0;
536       gDmaDescEp0->status.b.l = 1;
537       gDmaDescEp0->status.b.ioc = 1;
538       gDmaDescEp0->status.b.sp = 0;
539       gDmaDescEp0->status.b.bytes = 64;
540       gDmaDescEp0->buf = (UINT32)(UINTN)(gCtrlReq);
541       gDmaDescEp0->status.b.sts = 0;
542       gDmaDescEp0->status.b.bs = 0x0;
543       WRITE_REG32 (DOEPDMA0, (UINT32)(UINTN)(gDmaDescEp0));
544       // endpoint enable; clear NAK
545       WRITE_REG32 (DOEPCTL0, DXEPCTL_EPENA | DXEPCTL_CNAK);
546     }
547 
548     EpInts = (READ_REG32 (DOEPINT1));
549     if (EpInts) {
550       WRITE_REG32 (DOEPINT1, EpInts);
551       /* Transfer Completed Interrupt (XferCompl);Transfer completed */
552       if (EpInts & DXEPINT_XFERCOMPL) {
553 
554         UINTN Bytes = RxDescBytes - gDmaDesc->status.b.bytes;
555         UINTN Len = 0;
556 
557         ArmDataSynchronizationBarrier ();
558         if (MATCH_CMD_LITERAL ("download:", RxBuf)) {
559           mNumDataBytes = AsciiStrHexToUint64 (RxBuf + sizeof ("download:"));
560         } else {
561           if (mNumDataBytes != 0) {
562             mNumDataBytes -= Bytes;
563           }
564         }
565 
566         mDataReceivedCallback (Bytes, RxBuf);
567 
568         if (mNumDataBytes == 0) {
569           Len = CMD_SIZE;
570         } else if (mNumDataBytes > DATA_SIZE) {
571           Len = DATA_SIZE;
572         } else {
573           Len = mNumDataBytes;
574         }
575 
576         EpRx (1, Len);
577       }
578     }
579   }
580 
581   //WRITE_REG32 clear ints
582   WRITE_REG32 (GINTSTS, Ints);
583 }
584 
585 EFI_STATUS
DwUsbSend(IN UINT8 EndpointIndex,IN UINTN Size,IN CONST VOID * Buffer)586 DwUsbSend (
587   IN        UINT8  EndpointIndex,
588   IN        UINTN  Size,
589   IN  CONST VOID  *Buffer
590   )
591 {
592     EpTx (EndpointIndex, Buffer, Size);
593     return EFI_SUCCESS;
594 }
595 
596 STATIC
597 VOID
DwUsbInit(VOID)598 DwUsbInit (
599   VOID
600   )
601 {
602   VOID     *Buf;
603   UINT32   Data;
604 
605   Buf = UncachedAllocatePages (16);
606   gDmaDesc = Buf;
607   gDmaDescEp0 = gDmaDesc + sizeof (dwc_otg_dev_dma_desc_t);
608   gDmaDescIn = gDmaDescEp0 + sizeof (dwc_otg_dev_dma_desc_t);
609   gCtrlReq = (USB_DEVICE_REQUEST *)gDmaDescIn + sizeof (dwc_otg_dev_dma_desc_t);
610 
611   ZeroMem (gDmaDesc, sizeof (dwc_otg_dev_dma_desc_t));
612   ZeroMem (gDmaDescEp0, sizeof (dwc_otg_dev_dma_desc_t));
613   ZeroMem (gDmaDescIn, sizeof (dwc_otg_dev_dma_desc_t));
614 
615   /*Reset usb controller.*/
616   /* Wait for OTG AHB master idle */
617   do {
618     Data = READ_REG32 (GRSTCTL) & GRSTCTL_AHBIDLE;
619   } while (Data == 0);
620 
621   /* OTG: Assert Software Reset */
622   WRITE_REG32 (GRSTCTL, GRSTCTL_CSFTRST);
623 
624   /* Wait for OTG to ack reset */
625   while (READ_REG32 (GRSTCTL) & GRSTCTL_CSFTRST);
626 
627   /* Wait for OTG AHB master idle */
628   while ((READ_REG32 (GRSTCTL) & GRSTCTL_AHBIDLE) == 0);
629 
630   WRITE_REG32 (GDFIFOCFG, DATA_FIFO_CONFIG);
631   WRITE_REG32 (GRXFSIZ, RX_SIZE);
632   WRITE_REG32 (GNPTXFSIZ, ENDPOINT_TX_SIZE);
633   WRITE_REG32 (DIEPTXF1, DATA_IN_ENDPOINT_TX_FIFO1);
634   WRITE_REG32 (DIEPTXF2, DATA_IN_ENDPOINT_TX_FIFO2);
635   WRITE_REG32 (DIEPTXF3, DATA_IN_ENDPOINT_TX_FIFO3);
636   WRITE_REG32 (DIEPTXF4, DATA_IN_ENDPOINT_TX_FIFO4);
637   WRITE_REG32 (DIEPTXF5, DATA_IN_ENDPOINT_TX_FIFO5);
638   WRITE_REG32 (DIEPTXF6, DATA_IN_ENDPOINT_TX_FIFO6);
639   WRITE_REG32 (DIEPTXF7, DATA_IN_ENDPOINT_TX_FIFO7);
640   WRITE_REG32 (DIEPTXF8, DATA_IN_ENDPOINT_TX_FIFO8);
641   WRITE_REG32 (DIEPTXF9, DATA_IN_ENDPOINT_TX_FIFO9);
642   WRITE_REG32 (DIEPTXF10, DATA_IN_ENDPOINT_TX_FIFO10);
643   WRITE_REG32 (DIEPTXF11, DATA_IN_ENDPOINT_TX_FIFO11);
644   WRITE_REG32 (DIEPTXF12, DATA_IN_ENDPOINT_TX_FIFO12);
645   WRITE_REG32 (DIEPTXF13, DATA_IN_ENDPOINT_TX_FIFO13);
646   WRITE_REG32 (DIEPTXF14, DATA_IN_ENDPOINT_TX_FIFO14);
647   WRITE_REG32 (DIEPTXF15, DATA_IN_ENDPOINT_TX_FIFO15);
648 
649   /*
650    * set Periodic TxFIFO Empty Level,
651    * Non-Periodic TxFIFO Empty Level,
652    * Enable DMA, Unmask Global Intr
653    */
654   WRITE_REG32 (GAHBCFG, GAHBCFG_CTRL_MASK);
655 
656   /*select 8bit UTMI+, ULPI Inerface*/
657   WRITE_REG32 (GUSBCFG, 0x2400);
658 
659   /* Detect usb work mode,host or device? */
660   do {
661     Data = READ_REG32 (GINTSTS);
662   } while (Data & GINTSTS_CURMODE_HOST);
663   MicroSecondDelay (3);
664 
665   /*Init global and device mode csr register.*/
666   /*set Non-Zero-Length status out handshake */
667   Data = (0x20 << DCFG_EPMISCNT_SHIFT) | DCFG_NZ_STS_OUT_HSHK;
668   WRITE_REG32 (DCFG, Data);
669 
670   /* Interrupt unmask: IN event, OUT event, bus reset */
671   Data = GINTSTS_OEPINT | GINTSTS_IEPINT | GINTSTS_ENUMDONE | GINTSTS_USBRST;
672   WRITE_REG32 (GINTMSK, Data);
673 
674   do {
675     Data = READ_REG32 (GINTSTS) & GINTSTS_ENUMDONE;
676   } while (Data);
677 
678   /* Clear any pending OTG Interrupts */
679   WRITE_REG32 (GOTGINT, ~0);
680   /* Clear any pending interrupts */
681   WRITE_REG32 (GINTSTS, ~0);
682   WRITE_REG32 (GINTMSK, ~0);
683   Data = READ_REG32 (GOTGINT);
684   Data &= ~0x3000;
685   WRITE_REG32 (GOTGINT, Data);
686 
687   /* endpoint settings cfg */
688   ResetEndpoints ();
689   MicroSecondDelay (1);
690 
691   /* init finish. and ready to transfer data */
692 
693   /* Soft Disconnect */
694   WRITE_REG32 (DCTL, DCTL_PWRONPRGDONE | DCTL_SFTDISCON);
695   MicroSecondDelay (10000);
696 
697   /* Soft Reconnect */
698   WRITE_REG32 (DCTL, DCTL_PWRONPRGDONE);
699 }
700 
701 EFI_STATUS
702 EFIAPI
DwUsbStart(IN USB_DEVICE_DESCRIPTOR * DeviceDescriptor,IN VOID ** Descriptors,IN USB_DEVICE_RX_CALLBACK RxCallback,IN USB_DEVICE_TX_CALLBACK TxCallback)703 DwUsbStart (
704   IN USB_DEVICE_DESCRIPTOR   *DeviceDescriptor,
705   IN VOID                   **Descriptors,
706   IN USB_DEVICE_RX_CALLBACK   RxCallback,
707   IN USB_DEVICE_TX_CALLBACK   TxCallback
708   )
709 {
710   UINT8                    *Ptr;
711   EFI_STATUS                Status;
712   EFI_EVENT                 TimerEvent;
713 
714   ASSERT (DeviceDescriptor != NULL);
715   ASSERT (Descriptors[0] != NULL);
716   ASSERT (RxCallback != NULL);
717   ASSERT (TxCallback != NULL);
718 
719   DwUsbInit();
720 
721   mDeviceDescriptor = DeviceDescriptor;
722   mDescriptors = Descriptors[0];
723 
724   // Right now we just support one configuration
725   ASSERT (mDeviceDescriptor->NumConfigurations == 1);
726   mDeviceDescriptor->StrManufacturer = 1;
727   mDeviceDescriptor->StrProduct = 2;
728   mDeviceDescriptor->StrSerialNumber = 3;
729   // ... and one interface
730   mConfigDescriptor = (USB_CONFIG_DESCRIPTOR *)mDescriptors;
731   ASSERT (mConfigDescriptor->NumInterfaces == 1);
732 
733   Ptr = ((UINT8 *) mDescriptors) + sizeof (USB_CONFIG_DESCRIPTOR);
734   mInterfaceDescriptor = (USB_INTERFACE_DESCRIPTOR *) Ptr;
735   Ptr += sizeof (USB_INTERFACE_DESCRIPTOR);
736 
737   mEndpointDescriptors = (USB_ENDPOINT_DESCRIPTOR *) Ptr;
738 
739   mDataReceivedCallback = RxCallback;
740   mDataSentCallback = TxCallback;
741 
742   // Register a timer event so CheckInterupts gets called periodically
743   Status = gBS->CreateEvent (
744                   EVT_TIMER | EVT_NOTIFY_SIGNAL,
745                   TPL_CALLBACK,
746                   CheckInterrupts,
747                   NULL,
748                   &TimerEvent
749                   );
750   ASSERT_EFI_ERROR (Status);
751   if (EFI_ERROR (Status)) {
752     return Status;
753   }
754 
755   Status = gBS->SetTimer (
756                   TimerEvent,
757                   TimerPeriodic,
758                   DW_INTERRUPT_POLL_PERIOD
759                   );
760   ASSERT_EFI_ERROR (Status);
761 
762   return Status;
763 }
764 
765 USB_DEVICE_PROTOCOL mUsbDevice = {
766   DwUsbStart,
767   DwUsbSend
768 };
769 
770 
771 EFI_STATUS
772 EFIAPI
DwUsbEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)773 DwUsbEntryPoint (
774   IN EFI_HANDLE                            ImageHandle,
775   IN EFI_SYSTEM_TABLE                      *SystemTable
776   )
777 {
778   EFI_STATUS      Status;
779 
780   Status = gBS->LocateProtocol (&gDwUsbProtocolGuid, NULL, (VOID **) &DwUsb);
781   if (EFI_ERROR (Status)) {
782     return Status;
783   }
784 
785   Status = DwUsb->PhyInit(USB_DEVICE_MODE);
786   if (EFI_ERROR (Status)) {
787     return Status;
788   }
789 
790   return gBS->InstallProtocolInterface (
791                 &ImageHandle,
792                 &gUsbDeviceProtocolGuid,
793                 EFI_NATIVE_INTERFACE,
794                 &mUsbDevice
795                 );
796 }
797