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