ehci.h

来自「EFI BIOS是Intel提出的下一代的BIOS标准。这里上传的Edk源代码是」· C头文件 代码 · 共 2,735 行 · 第 1/4 页

H
2,735
字号
/*++

Copyright (c) 2006, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

Module Name:

    Ehci.h

Abstract:


Revision History
--*/

#ifndef _EHCI_H
#define _EHCI_H

//
// Universal Host Controller Interface data structures and defines
//
#include "Tiano.h"
#include "EfiDriverLib.h"
#include "pci22.h"

//
// Driver Consumed Protocol Prototypes
//
#include EFI_PROTOCOL_DEFINITION (DriverBinding)
#include EFI_PROTOCOL_DEFINITION (PciIo)

//
// Driver Produced Protocol Prototypes
//
#include EFI_PROTOCOL_DEFINITION (UsbHostController)
#include EFI_PROTOCOL_DEFINITION (ComponentName)

#ifdef EFI_DEBUG
extern UINTN  gEHCDebugLevel;
extern UINTN  gEHCErrorLevel;
#endif

#define STALL_1_MACRO_SECOND              1
#define STALL_1_MILLI_SECOND              1000 * STALL_1_MACRO_SECOND
#define STALL_1_SECOND                    1000 * STALL_1_MILLI_SECOND

#define MEM_UNIT_SIZE                     128


#define SETUP_PACKET_PID_CODE             0x02
#define INPUT_PACKET_PID_CODE             0x01
#define OUTPUT_PACKET_PID_CODE            0x0

#define ITD_SELECT_TYPE                   0x0
#define QH_SELECT_TYPE                    0x01
#define SITD_SELECT_TYPE                  0x02
#define FSTN_SELECT_TYPE                  0x03

#define EHCI_SET_PORT_RESET_RECOVERY_TIME     50 * STALL_1_MILLI_SECOND
#define EHCI_CLEAR_PORT_RESET_RECOVERY_TIME   STALL_1_MILLI_SECOND
#define EHCI_GENERIC_TIMEOUT                  50 * STALL_1_MILLI_SECOND
#define EHCI_GENERIC_RECOVERY_TIME            50 * STALL_1_MACRO_SECOND
#define EHCI_SYNC_REQUEST_POLLING_TIME        50 * STALL_1_MACRO_SECOND
#define EHCI_ASYNC_REQUEST_POLLING_TIME       50 * STALL_1_MILLI_SECOND

#define USB_BAR_INDEX                     0 /* how many bytes away from USB_BASE to 0x10 */

#define NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES 16

#define EHCI_MIN_PACKET_SIZE              8
#define EHCI_MAX_PACKET_SIZE              1024
#define EHCI_MAX_FRAME_LIST_LENGTH        1024
#define EHCI_BLOCK_SIZE_WITH_TT           64
#define EHCI_BLOCK_SIZE                   512
#define EHCI_MAX_QTD_CAPACITY             (EFI_PAGE_SIZE * 5)

#define NAK_COUNT_RELOAD                  3
#define QTD_ERROR_COUNTER                 3
#define HIGH_BANDWIDTH_PIPE_MULTIPLIER    1

#define QTD_STATUS_ACTIVE                 0x80
#define QTD_STATUS_HALTED                 0x40
#define QTD_STATUS_BUFFER_ERR             0x20
#define QTD_STATUS_BABBLE_ERR             0x10
#define QTD_STATUS_TRANSACTION_ERR        0x08
#define QTD_STATUS_DO_STOP_SPLIT          0x02
#define QTD_STATUS_DO_START_SPLIT         0
#define QTD_STATUS_DO_PING                0x01
#define QTD_STATUS_DO_OUT                 0

#define DATA0                             0
#define DATA1                             1

#define MICRO_FRAME_0_CHANNEL             0x01
#define MICRO_FRAME_1_CHANNEL             0x02
#define MICRO_FRAME_2_CHANNEL             0x04
#define MICRO_FRAME_3_CHANNEL             0x08
#define MICRO_FRAME_4_CHANNEL             0x10
#define MICRO_FRAME_5_CHANNEL             0x20
#define MICRO_FRAME_6_CHANNEL             0x40
#define MICRO_FRAME_7_CHANNEL             0x80

#define CONTROL_TRANSFER                  0x01
#define BULK_TRANSFER                     0x02
#define SYNC_INTERRUPT_TRANSFER           0x04
#define ASYNC_INTERRUPT_TRANSFER          0x08
#define SYNC_ISOCHRONOUS_TRANSFER         0x10
#define ASYNC_ISOCHRONOUS_TRANSFER        0x20


//
// Enhanced Host Controller Registers definitions
//
extern EFI_DRIVER_BINDING_PROTOCOL  gEhciDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL  gEhciComponentName;

#define USBCMD            0x0     /* Command Register Offset 00-03h */
#define USBCMD_RS         0x01    /* Run / Stop */
#define USBCMD_HCRESET    0x02    /* Host controller reset */
#define USBCMD_FLS_512    0x04    /* 512 elements (2048bytes) in Frame List */
#define USBCMD_FLS_256    0x08    /* 256 elements (1024bytes) in Frame List */
#define USBCMD_PSE        0x10    /* Periodic schedule enable */
#define USBCMD_ASE        0x20    /* Asynchronous schedule enable */
#define USBCMD_IAAD       0x40    /* Interrupt on async advance doorbell */

#define USBSTS            0x04    /* Statue Register Offset 04-07h */
#define USBSTS_HSE        0x10    /* Host system error */
#define USBSTS_IAA        0x20    /* Interrupt on async advance */
#define USBSTS_HCH        0x1000  /* Host controller halted */
#define USBSTS_PSS        0x4000  /* Periodic schedule status */
#define USBSTS_ASS        0x8000  /* Asynchronous schedule status */

#define USBINTR           0x08    /* Command Register Offset 08-0bh */

#define FRINDEX           0x0c    /* Frame Index Offset 0c-0fh */

#define CTRLDSSGMENT      0x10    /* 4G Segment Selector Offset 10-13h */

#define PERIODICLISTBASE  0x14    /* Frame List Base Address Offset 14-17h */

#define ASYNCLISTADDR     0x18    /* Next Asynchronous List Address Offset 18-1bh */

#define CONFIGFLAG        0x40    /* Configured Flag Register Offset 40-43h */
#define CONFIGFLAG_CF     0x01    /* Configure Flag */

#define PORTSC            0x44    /* Port Status/Control Offset 44-47h */
#define PORTSC_CCS        0x01    /* Current Connect Status*/
#define PORTSC_CSC        0x02    /* Connect Status Change */
#define PORTSC_PED        0x04    /* Port Enable / Disable */
#define PORTSC_PEDC       0x08    /* Port Enable / Disable Change */
#define PORTSC_OCA        0x10    /* Over current Active */
#define PORTSC_OCC        0x20    /* Over current Change */
#define PORTSC_FPR        0x40    /* Force Port Resume */
#define PORTSC_SUSP       0x80    /* Port Suspend State */
#define PORTSC_PR         0x100   /* Port Reset */
#define PORTSC_LS_KSTATE  0x400   /* Line Status K-state */
#define PORTSC_LS_JSTATE  0x800   /* Line Status J-state */
#define PORTSC_PP         0x1000  /* Port Power */
#define PORTSC_PO         0x2000  /* Port Owner */

#define CAPLENGTH         0       /* Capability Register Length 00h */

#define HCIVERSION        0x02    /* Interface Version Number  02-03h */

#define HCSPARAMS         0x04    /* Structural Parameters 04-07h */
#define HCSP_NPORTS       0x0f    /* Number of physical downstream ports on host controller */

#define HCCPARAMS         0x08    /* Capability Parameters 08-0bh */
#define HCCP_64BIT        0x01    /* 64-bit Addressing Capability */
#define HCCP_PFLF         0x02    /* Programmable Frame List Flag */
#define HCCP_EECP         0xff00  /* EHCI Extemded Capabilities Pointer */

#define HCSPPORTROUTE     0x0c    /* Companion Port Route Description 60b */

#define CLASSC            0x09    /* Class Code 09-0bh */

#define USBBASE           0x10    /* Base Address to Memory-mapped Host Controller Register Space 10-13h */

#define SBRN              0x60    /* Serial Bus Release Number 60h */

#define FLADJ             0x61    /* Frame Length Adjustment Register 61h */

#define PORTWAKECAP       0x62    /* Port wake capablilities register(OPIONAL)  61-62h */

//
// PCI Configuration Registers
//
#define EHCI_PCI_CLASSC         0x09
#define EHCI_PCI_MEMORY_BASE    0x10

//
// Memory Offset Registers
//
#define EHCI_MEMORY_CAPLENGTH   0x0
#define EHCI_MEMORY_CONFIGFLAG  0x40

//
// USB Base Class Code,Sub-Class Code and Programming Interface
//
#define PCI_CLASSC_PI_EHCI      PCI_IF_EHCI

#define SETUP_PACKET_ID         0x2D
#define INPUT_PACKET_ID         0x69
#define OUTPUT_PACKET_ID        0xE1
#define ERROR_PACKET_ID         0x55

#define bit(a)                (1 << (a))

#define GET_0B_TO_31B(Addr)   (((UINTN) Addr) & (0xffffffff))
#define GET_32B_TO_63B(Addr)  ((UINTN)RShiftU64((UINTN) Addr, 32) & (0xffffffff))


//
// Ehci Data and Ctrl Structures
//
#pragma pack(1)

typedef struct {
  UINT8 PI;
  UINT8 SubClassCode;
  UINT8 BaseCode;
} USB_CLASSC;

//
//32 Bytes Aligned
//
typedef struct {
  UINT32  NextQtdTerminate : 1;
  UINT32  Rsvd1 : 4;
  UINT32  NextQtdPointer : 27;

  UINT32  AltNextQtdTerminate : 1;
  UINT32  Rsvd2 : 4;
  UINT32  AltNextQtdPointer : 27;

  UINT32  Status : 8;
  UINT32  PidCode : 2;
  UINT32  ErrorCount : 2;
  UINT32  CurrentPage : 3;
  UINT32  InterruptOnComplete : 1;
  UINT32  TotalBytes : 15;
  UINT32  DataToggle : 1;

  UINT32  CurrentOffset : 12;
  UINT32  BufferPointer0 : 20;

  UINT32  Rsvd3 : 12;
  UINT32  BufferPointer1 : 20;

  UINT32  Rsvd4 : 12;
  UINT32  BufferPointer2 : 20;

  UINT32  Rsvd5 : 12;
  UINT32  BufferPointer3 : 20;

  UINT32  Rsvd6 : 12;
  UINT32  BufferPointer4 : 20;

  UINT32  PAD[5];
} EHCI_QTD_HW;

//
//32 Bytes Aligned
//
typedef struct {
  UINT32  QhTerminate : 1;
  UINT32  SelectType : 2;
  UINT32  Rsvd1 : 2;
  UINT32  QhHorizontalPointer : 27;

  UINT32  DeviceAddr : 7;
  UINT32  Inactive : 1;
  UINT32  EndpointNum : 4;
  UINT32  EndpointSpeed : 2;
  UINT32  DataToggleControl : 1;
  UINT32  HeadReclamationFlag : 1;
  UINT32  MaxPacketLen : 11;
  UINT32  ControlEndpointFlag : 1;
  UINT32  NakCountReload : 4;

  UINT32  InerruptScheduleMask : 8;
  UINT32  SplitComletionMask : 8;
  UINT32  HubAddr : 7;
  UINT32  PortNum : 7;
  UINT32  Multiplier : 2;

  UINT32  Rsvd2 : 5;
  UINT32  CurrentQtdPointer : 27;

  UINT32  NextQtdTerminate : 1;
  UINT32  Rsvd3 : 4;
  UINT32  NextQtdPointer : 27;

  UINT32  AltNextQtdTerminate : 1;
  UINT32  NakCount : 4;
  UINT32  AltNextQtdPointer : 27;

  UINT32  Status : 8;
  UINT32  PidCode : 2;
  UINT32  ErrorCount : 2;
  UINT32  CurrentPage : 3;
  UINT32  InterruptOnComplete : 1;
  UINT32  TotalBytes : 15;
  UINT32  DataToggle : 1;

  UINT32  CurrentOffset : 12;
  UINT32  BufferPointer0 : 20;

  UINT32  CompleteSplitMask : 8;
  UINT32  Rsvd4 : 4;
  UINT32  BufferPointer1 : 20;

  UINT32  FrameTag : 5;
  UINT32  SplitBytes : 7;
  UINT32  BufferPointer2 : 20;

  UINT32  Rsvd5 : 12;
  UINT32  BufferPointer3 : 20;

  UINT32  Rsvd6 : 12;
  UINT32  BufferPointer4 : 20;

  UINT32  Pad[5];
} EHCI_QH_HW;

typedef struct {
  UINT32  LinkTerminate : 1;
  UINT32  SelectType : 2;
  UINT32  Rsvd : 2;
  UINT32  LinkPointer : 27;
} FRAME_LIST_ENTRY;

#pragma pack()

EFI_FORWARD_DECLARATION (EHCI_QTD_ENTITY);
EFI_FORWARD_DECLARATION (EHCI_QH_ENTITY);

//
//Aligan On 32 Bytes
//
typedef struct _EHCI_QTD_ENTITY {
  EHCI_QTD_HW     Qtd;
  UINT32          TotalBytes;
  UINT32          StaticTotalBytes;
  UINT32          StaticCurrentOffset;
  EHCI_QTD_ENTITY *Prev;
  EHCI_QTD_ENTITY *Next;
  EHCI_QTD_ENTITY *AltNext;
  EHCI_QH_ENTITY  *SelfQh;
} EHCI_QTD_ENTITY;
//
//Aligan On 32 Bytes
//
typedef struct _EHCI_QH_ENTITY {
  EHCI_QH_HW      Qh;
  EHCI_QH_ENTITY  *Next;
  EHCI_QH_ENTITY  *Prev;
  EHCI_QTD_ENTITY *FirstQtdPtr;
  EHCI_QTD_ENTITY *LastQtdPtr;
  EHCI_QTD_ENTITY *AltQtdPtr;
  UINTN            Interval;
  UINT8           TransferType;
} EHCI_QH_ENTITY;

#define GET_QH_ENTITY_ADDR(a)   ((EHCI_QH_ENTITY *) a)
#define GET_QTD_ENTITY_ADDR(a)  ((EHCI_QTD_ENTITY *) a)


//
// Ehci Managment Structures
//
#define USB2_HC_DEV_FROM_THIS(a)  CR (a, USB2_HC_DEV, Usb2Hc, USB2_HC_DEV_SIGNATURE)

#define USB2_HC_DEV_SIGNATURE     EFI_SIGNATURE_32 ('e', 'h', 'c', 'i')

typedef struct _LIST_HEAD {
  struct _LIST_HEAD *pre;
  struct _LIST_HEAD *next;
} LIST_HEAD;

EFI_FORWARD_DECLARATION (EHCI_ASYNC_REQUEST);

typedef struct _EHCI_ASYNC_REQUEST {
  UINT8                           TransferType;
  EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunc;
  VOID                            *Context;
  EHCI_ASYNC_REQUEST              *Prev;
  EHCI_ASYNC_REQUEST              *Next;
  EHCI_QH_ENTITY                  *QhPtr;
} EHCI_ASYNC_REQUEST;

typedef struct _MEMORY_MANAGE_HEADER {
  UINT8                         *BitArrayPtr;
  UINTN                         BitArraySizeInBytes;
  UINT8                         *MemoryBlockPtr;
  UINTN                         MemoryBlockSizeInBytes;
  VOID                          *Mapping;
  struct _MEMORY_MANAGE_HEADER  *Next;
} MEMORY_MANAGE_HEADER;

typedef struct _USB2_HC_DEV {
  UINTN                     Signature;
  EFI_PCI_IO_PROTOCOL       *PciIo;
  EFI_USB2_HC_PROTOCOL      Usb2Hc;
  UINTN                     PeriodicFrameListLength;
  VOID                      *PeriodicFrameListBuffer;
  VOID                      *PeriodicFrameListMap;
  VOID                      *AsyncList;
  EHCI_ASYNC_REQUEST        *AsyncRequestList;
  EFI_EVENT                 AsyncRequestEvent;
  EFI_UNICODE_STRING_TABLE  *ControllerNameTable;
  MEMORY_MANAGE_HEADER      *MemoryHeader;
  UINT8                     Is64BitCapable;
  UINT32                    High32BitAddr;
  EHCI_QH_ENTITY            *NULLQH;
  UINT32                    UsbCapabilityLen;
  UINT16                    DeviceSpeed[16];
} USB2_HC_DEV;


//
// Internal Functions Declaration
//

//
// EhciMem Functions
//
EFI_STATUS
CreateMemoryBlock (
  IN  USB2_HC_DEV               *HcDev,
  OUT MEMORY_MANAGE_HEADER      **MemoryHeader,
  IN  UINTN                     MemoryBlockSizeInPages
  )
/*++

Routine Description:

  Use PciIo->AllocateBuffer to allocate common buffer for the memory block,
  and use PciIo->Map to map the common buffer for Bus Master Read/Write.

Arguments:

  HcDev                  - USB2_HC_DEV
  MemoryHeader           - MEMORY_MANAGE_HEADER to output
  MemoryBlockSizeInPages - MemoryBlockSizeInPages

Returns:

  EFI_SUCCESS           Success
  EFI_OUT_OF_RESOURCES  Fail for no resources
  EFI_UNSUPPORTED       Unsupported currently

--*/
;

EFI_STATUS
FreeMemoryHeader (
  IN USB2_HC_DEV               *HcDev,
  IN MEMORY_MANAGE_HEADER      *MemoryHeader
  )
/*++

Routine Description:

  Free Memory Header

Arguments:

  HcDev         - USB2_HC_DEV
  MemoryHeader  - MemoryHeader to be freed

Returns:

  EFI_SUCCESS            Success
  EFI_INVALID_PARAMETER  Parameter is error

--*/
;

VOID
InsertMemoryHeaderToList (
  IN MEMORY_MANAGE_HEADER     *MemoryHeader,
  IN MEMORY_MANAGE_HEADER     *NewMemoryHeader
  )
/*++

Routine Description:

  Insert Memory Header To List

Arguments:

  MemoryHeader    - MEMORY_MANAGE_HEADER
  NewMemoryHeader - MEMORY_MANAGE_HEADER

Returns:

  VOID

--*/
;

EFI_STATUS
AllocMemInMemoryBlock (
  IN  MEMORY_MANAGE_HEADER     *MemoryHeader,
  OUT VOID                     **Pool,
  IN  UINTN                    NumberOfMemoryUnit
  )
/*++

Routine Description:

  Alloc Memory In MemoryBlock

Arguments:

  MemoryHeader        - MEMORY_MANAGE_HEADER
  Pool                - Place to store pointer to memory
  NumberOfMemoryUnit  - Number Of Memory Unit

Returns:

  EFI_SUCCESS    Success
  EFI_NOT_FOUND  Can't find the free memory

--*/
;

BOOLEAN
IsMemoryBlockEmptied (
  IN MEMORY_MANAGE_HEADER     *MemoryHeaderPtr
  )
/*++

Routine Description:

  Is Memory Block Emptied

Arguments:

  MemoryHeaderPtr - MEMORY_MANAGE_HEADER

Returns:

  TRUE    Empty
  FALSE   Not Empty

--*/
;

VOID
DelinkMemoryBlock (
  IN MEMORY_MANAGE_HEADER     *FirstMemoryHeader,
  IN MEMORY_MANAGE_HEADER     *NeedFreeMemoryHeader
  )
/*++

Routine Description:

  Delink Memory Block

Arguments:

  FirstMemoryHeader     - MEMORY_MANAGE_HEADER
  NeedFreeMemoryHeader  - MEMORY_MANAGE_HEADER

Returns:

  VOID

--*/
;

EFI_STATUS
InitialMemoryManagement (
  IN USB2_HC_DEV     *HcDev
  )
/*++

Routine Description:

  Initialize Memory Management

Arguments:

  HcDev - USB2_HC_DEV

Returns:

  EFI_SUCCESS        Success
  EFI_DEVICE_ERROR   Fail

--*/
;

EFI_STATUS
DeinitialMemoryManagement (
  IN USB2_HC_DEV     *HcDev
  )
/*++

Routine Description:

  Deinitialize Memory Management

Arguments:

  HcDev - USB2_HC_DEV

Returns:

  EFI_SUCCESS        Success
  EFI_DEVICE_ERROR   Fail

--*/
;

EFI_STATUS
EhciAllocatePool (
  IN  USB2_HC_DEV     *HcDev,
  OUT UINT8           **Pool,
  IN  UINTN           AllocSize
  )
/*++

Routine Description:

  Ehci Allocate Pool

Arguments:

  HcDev     - USB2_HC_DEV
  Pool      - Place to store pointer to the memory buffer
  AllocSize - Alloc Size

Returns:

  EFI_SUCCESS        Success
  EFI_DEVICE_ERROR   Fail

--*/
;

VOID
EhciFreePool (
  IN USB2_HC_DEV     *HcDev,
  IN UINT8           *Pool,
  IN UINTN           AllocSize
  )
/*++

Routine Description:

  Uhci Free Pool

Arguments:

  HcDev     - USB_HC_DEV
  Pool      - Pool to free
  AllocSize - Pool size

Returns:

  VOID

--*/
;

//
// EhciReg Functions
//
EFI_STATUS
ReadEhcCapabiltiyReg (
  IN USB2_HC_DEV             *HcDev,
  IN UINT32                  CapabiltiyRegAddr,
  IN OUT UINT32              *Data
  )
/*++

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?