Home | History | Annotate | Download | only in DwUsbDxe
      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
     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 
     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 
    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 
    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
    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
    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 
    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
    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
    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
    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
    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 
    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
    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
    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