📄 ehci.asm
字号:
TITLE EHCI.ASM -- Enhanced Host Controller Interface Code
;***************************************************************************;
;***************************************************************************;
;** **;
;** (C)Copyright 1985-2003, American Megatrends, Inc. **;
;** **;
;** All Rights Reserved. **;
;** **;
;** 6145-F Northbelt Pkwy, Norcross, GA 30071 **;
;** **;
;** Phone (770)-246-8600 **;
;** **;
;***************************************************************************;
;***************************************************************************;
;***************************************************************************;
; $Header: /BIOS/Corebin/800/Modules/USB2/Template/Core/EHCI.ASM 14 3/17/03 5:49p Sivagarn $
;
; $Revision: 14 $
;
; $Date: 3/17/03 5:49p $
;***************************************************************************;
; Revision History
; ----------------
; $Log: /BIOS/Corebin/800/Modules/USB2/Template/Core/EHCI.ASM $
;
; 14 3/17/03 5:49p Sivagarn
; - Byte flag 'bUSBInitFlag' is changed to double word 'dUSBInitFlag'
; - 'pHCDReleasePort' routine is added to host controller driver. This
; routine is currently used only by EHCI to release the hi-speed device
; - 'QH1ms' schedule is created and used for EHCI interrupt transaction
; - The 200ms delay used after port powerup is reduced to 100ms as
; EPSON scanner issue was diagnosed as different issue
; - Code to check whether the host controller is under BIOS control,
; before
;
; stopping EHCI host controller, is added
; - EHCIGetRootHubStatus routine returns appropriate value (AX register
; was used instead of DX)
;
; 13 1/30/03 5:11p Sivagarn
; - Delay after port power enable is increased from 10ms to 200ms to
; enumerate Epson 2450 scanner properly during power on & hibernate (hot
; plug worked fine)
;
; 12 1/27/03 8:47p Sivagarn
; - A new call is added to HC drivers to return the ownership status of
; the host controller. This fixes the OS hangs, when OS tries to access
; USB drives using INT13h after it takes control of the USB HC
;
; 11 1/16/03 4:19p Sivagarn
; - Changes related to EHCI handover for Windows ME
;
; 10 1/03/03 7:01p Sivagarn
; - 'bLastBulkCommandStatus' variable name changed to
; 'bLastCommandStatus' as it stores status of control transfer also
; - Control transfer stall condition is recorded in the
; 'bLastCommandStatus' variable
;
; 9 12/20/02 6:04p Sivagarn
; Fixed the bug while recovering from a bulk transfer error. Previous
; error status was not cleared so all the bulk transfer after that were
; considered error.
;
; 8 12/19/02 6:02p Sivagarn
; - New host controller flag is updated to indicate the state of the EHCI
; host controller (running/stopped)
; - Code cleanup
;
; 7 12/17/02 12:31p Sivagarn
; - Code clean up and macros are moved to EHCI.EQU file
; - Changed copyright message year to 2003
; BugFix:
; - Bug in enumerating hi-speed devices during POST is fixed
; - Implemented code to return correct USB 2.0 hub device and port number
; for split transactions. Also split transaction is enabled for polling
; TD.
; - Bug in disabling root hub port is fixed
; - Bug in removing polling QH from the schedule is fixed
; - Implemented 128 microsecond polling for interrupt transaction but the
; code is commented out as it is giving trouble to keyboard functionality
;
; 6 11/27/02 6:04p Sivagarn
; Features:
; - New eLink to install the EHCI host controller driver is added
; BugFix:
; - Bug in checking the 64bit data structure support is fixed
; - Bug in getting the extended capability register offset is fixed
;
; 5 11/20/02 5:51p Sivagarn
; - New POST error message is posted if the host controller needs 64bit
; data structure but the build option is not enabled
;
; 4 11/17/02 8:05p Sivagarn
; - Support for EHCI async bell feature is added
; - Code to program EHCI legacy registers, if present, is added. This
; enables SMI generation for EHCI events
; - Bug in stop/resetting the EHCI controller is fixed
;
; 3 10/29/02 6:55p Sivagarn
; - Bulk transfer error conditions are tracked as per new requirement
; - Timeout value for control/bulk/interrupt transfer is taken from a
; variable
; - Process interrupt is changed to handle asynchronous transfer properly
;
; 2 10/14/02 8:45p Sivagarn
; * Code clean up
; * USB internal PCI access routines are changed to core access routines
; * EHCISuspend function name is changed to EHCIPowerManagement
; * All the MKF_ flags are removed
;
; 1 9/15/02 5:39p Sivagarn
; Initial AMIUSB 2.20 check-in
;
;***************************************************************************;
;----------------------------------------------------------------------------
; Global options are defined here
;----------------------------------------------------------------------------
OPTION PROC:PRIVATE
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
; Macro and equate files are included here
;----------------------------------------------------------------------------
; INCLUDE equates.equ
; INCLUDE mbiosequ.equ
; INCLUDE usbflag.equ
INCLUDE usb.equ
INCLUDE ehci.equ
MKF_USB_MODE = 2
TRUE EQU 0FFh
FALSE EQU 00
USB_MEM_BLK_SIZE EQU 32 ; 32 bytes
USB_MEM_BLK_SIZE_SHIFT EQU 5 ; log2 (USB_MEM_BLK_SIZE)
MKF_EHCI_64BIT_DATA_STRUCTURE EQU 1
BIT16 equ 10000h
IFDEF MKF_USB_CSP_TEMPLATE_VERSION
IF MKF_USB_CSP_TEMPLATE_VERSION LT 3
MKF_EHCI_ASYNC_BELL_SUPPORT EQU 0
ENDIF ; IF MKF_USB_CSP_TEMPLATE_VERSION LT 3
ENDIF ; IFDEF MKF_USB_CSP_TEMPLATE_VERSION
;----------------------------------------------------------------------------
; External data definitions are done here
;----------------------------------------------------------------------------
EXTERN bEnumFlag:BYTE
EXTERN dUSBInitFlag:DWORD
EXTERN HcdGlobalDataArea:DWORD
EXTERN dOrgGlobalDataArea:DWORD
EXTERN bLastCommandStatus:BYTE
EXTERN wTimeOutValue:WORD
;----------------------------------------------------------------------------
; External function definitions are defined here
;----------------------------------------------------------------------------
read_pci_dword_far PROTO FAR SYSCALL
write_pci_dword_far PROTO FAR SYSCALL
USBPort_ProgramHardwareInterrupt PROTO NEAR SYSCALL
USBLogError PROTO NEAR SYSCALL
USBCaptureHCInterrupt PROTO NEAR SYSCALL
USBCheckPortChange PROTO NEAR SYSCALL
USBMem_Alloc PROTO NEAR SYSCALL
; AL - bNumBlocks
USBMem_Free PROTO NEAR SYSCALL
; AL - bNumBlocks, BX - wMemBlock
USBMisc_FixedDelay PROTO NEAR SYSCALL
; AX - wCount
USBMiscInitFrameList PROTO NEAR SYSCALL
USBMiscGetFarBufferAddress PROTO NEAR SYSCALL
USBMiscFormDeviceRequest PROTO NEAR SYSCALL
USBMiscGetBulkEndPointInfo PROTO NEAR SYSCALL
USBMiscUpdateBulkDataSync PROTO NEAR SYSCALL
USBDisconnectDevice PROTO NEAR SYSCALL
USBPeriodicInterruptHandler PROTO NEAR SYSCALL
USBGetDeviceInfoFromDevAddr PROTO NEAR SYSCALL
IF MKF_USB_MODE EQ 1
USBMiscDwordReadMemReg PROTO NEAR C pHCStruc:NEAR, wMemOffs:DWORD
USBMiscDwordWriteMemReg PROTO NEAR C pHCStruc:NEAR, wMemOffs:DWORD,
dValue:DWORD
EHCIDwordReadMemReg PROTO NEAR C pHCStruc:NEAR, wMemOffs:DWORD
EHCIDwordWriteMemReg PROTO NEAR C pHCStruc:NEAR, wMemOffs:DWORD,
dValue:DWORD
ENDIF
;----------------------------------------------------------------------------
; Function prototype definitions are here
;----------------------------------------------------------------------------
EHCIResetHC PROTO NEAR SYSCALL
EHCISetQTDBufferPointers PROTO NEAR SYSCALL
EHCIWaitForTransferComplete PROTO NEAR SYSCALL
EHCIProcessQH PROTO NEAR SYSCALL
EHCIStartPeriodicSchedule PROTO NEAR SYSCALL
EHCIStopPeriodicSchedule PROTO NEAR SYSCALL
EHCIStartAsyncSchedule PROTO NEAR SYSCALL
EHCIStopAsyncSchedule PROTO NEAR SYSCALL
EHCIRemoveQH PROTO NEAR SYSCALL
EHCIInitializePeriodicSchedule PROTO NEAR SYSCALL
EHCIAddPeriodicQH PROTO NEAR SYSCALL
EHCIScheduleQH PROTO NEAR SYSCALL
EHCIProcessPeriodicList PROTO NEAR SYSCALL
EHCIInitializeQueueHead PROTO NEAR SYSCALL
;----------------------------------------------------------------------------
; D A T A S E G M E N T
;----------------------------------------------------------------------------
USB_DSEG SEGMENT WORD PUBLIC 'DATA'
; Control setup data
aControlSetupData DB 8 dup (?)
; Flag to indicate whether periodic list processing is in progress or not
bProcessingPeriodicList DB ?
IF MKF_EHCI_ASYNC_BELL_SUPPORT
pQHAsyncXfer WORD ?
ENDIF ; IF MKF_EHCI_ASYNC_BELL_SUPPORT
dHCCParams DWORD ?
bIgnoreConnectStsChng BYTE ?
USB_DSEG ENDS
;----------------------------------------------------------------------------
; C O D E S E G M E N T
;----------------------------------------------------------------------------
USB_CSEG SEGMENT WORD USE16 PUBLIC 'CODE'
.586p
ASSUME CS:USB_CSEG
ASSUME DS:USB_DSEG
PUBLIC _EHCI_ASM_START
_EHCI_ASM_START LABEL BYTE
PUBLIC EHCI_HCHeader
EHCI_HCHeader LABEL HCDHeader
BYTE USB_EHCI ; Module type
BYTE 00 ; RESERVED
WORD 0000 ; Reserved
WORD EHCIStart ; EHCI start controller routine
WORD EHCIStop ; EHCI stop controller routine
WORD EHCIMoveDataArea ; EHCI move data area routine
WORD EHCIDisableInterrupts ; EHCI disable controller interrupts
WORD EHCIEnableInterrupts ; EHCI enable controller interrupts
WORD EHCIProcessInterrupt ; Interrupt service routine
WORD EHCIGetRootHubStatus ; Gets the root hub port status
WORD EHCIDisableRootHub ; Disable root hub ports
WORD EHCIEnableRootHub ; Enable root hub ports
WORD EHCIControlTransfer ; Performs a control transfer
WORD EHCIBulkTransfer ; Performs a bulk transfer
WORD EHCIInterruptTransfer ; Performs an interrupt transfer
WORD EHCIDeactivatePolling ; De-activates polling for a device
WORD EHCIActivatePolling ; Activates polling for a device
WORD EHCIDisableKeyRepeat ; De-activates KB repeat rate polling
WORD EHCIEnableKeyRepeat ; Activates KB repeat rate polling
WORD EHCIPowerManagement ; Suspends HC and its ports
WORD EHCIEnumeratePorts ; Enumerates the ports in the HC
WORD 0 ; Enables the port 60h/64h trapping
WORD EHCICheckHCStatus ; Checks whether the HC is still with BIOS
WORD EHCIReleasePort ; Releases the hi-speed port to USB 1.1 controller
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: farEHCI_InstallHCDriver
;
; Description: This eLink checks whether the request is for EHCI controller
; if so it returns its HCDHeader
;
; Input: ZR HC driver not installed
; AL Host controller type (USB_EHCI etc)
; NZ HC driver installed
; AX HCDHeader pointer for the HC
; DS USB global data area
;
; Output: NZ If the HC driver is already found (AX pointer)
; ZR If the HC driver is not found
;
; Modified: AX
;
; Referrals: HCDHeader
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
farEHCI_InstallHCDriver PROC FAR SYSCALL PUBLIC
jnz feih_Exit ; HC driver already found
cmp al, USB_EHCI
jne feih_NotEHCI
; Return the HC driver pointer
mov ax, OFFSET EHCI_HCHeader
or sp, sp ; Clear zero flag
jmp SHORT feih_Exit
feih_NotEHCI:
; Set zero flag indicating HC driver is not yet found
cmp sp, sp
feih_Exit:
ret
farEHCI_InstallHCDriver ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: EHCIStart
;
; Description: This function starts the EHCI controller. The necessary
; memory for running the controller should be provided
; as input.
;
; Input: SI Pointer to the HCStruc pointer
; EDI Address of the data area for the HC
; ECX Data area size
; DS USB global data area
;
; Output: EAX 0 On error
; EAX Data area used by the EHCI controller
;
; Modified: EAX
;
; Referrals: HCStruc, EHCIGetRootHubStatus
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
EHCIStart PROC NEAR SYSCALL PUBLIC
push ebx
push cx
push dx
push edi
IF MKF_USB_MODE NE 1
push fs
push 0
pop fs
ENDIF
; Check whether we have enough memory for the UHCI HC frame list
cmp ecx, EHCI_DATA_AREA_SIZE
jb esErrorExit
; Store the data area address in the HCStruc structure
mov (HCStruc PTR [si]).dHcdDataArea, edi
; Get host controllers bus, device and function number in BX
mov dx, (HCStruc PTR [si]).wBusDevFuncNum
; Get memory base address of the HC and store it in the HCStruc
; IO_Space_Base_Address in the USB data segment.
mov ah, USB_MEM_BASE_ADDRESS
call read_pci_dword_far
and bl, 0F0h ; Mask lower bits
mov (HCStruc PTR [si]).dBaseAddress, ebx
IF MKF_USB_MODE NE 1
; Save the base address in a local register
mov edi, ebx
ENDIF
; Get the number of ports supported by the host controller (Offset 4)
; and store it in HCStruc
USBPORT_DWORD_READ_MEM si, EHCI_HCSPARAMS
and al, EHCI_N_PORTS
mov (HCStruc PTR [si]).bNumPorts, al
; Read the Capability Registers Length to find the Offset address for the
; beginning of the operational registers
USBPORT_DWORD_READ_MEM si, EHCI_VERCAPLENGTH
mov (HCStruc PTR [si]).bOpRegOffset, al
; Read and store the HCCPARAMS value
USBPORT_DWORD_READ_MEM si, EHCI_HCCPARAMS
mov dHCCParams, eax
IFE MKF_EHCI_64BIT_DATA_STRUCTURE
; 64bit data structures are not enabled. So check whether this host controller
; needs 64bit data structure or not.
test al, EHCI_64BIT_CAP
jz esEverythingIsFine
; Engineer has to enable the 64bit capability. Post an error message
mov ax, ERRUSB_EHCI_64BIT_DATA_STRUC
call USBLogError
; Adjust EDI to point to operation registers
movzx eax, (HCStruc PTR [si]).bOpRegOffset
add edi, eax
; Connect all ports to the classic host controller
EHCI_DWORD_RESET_MEM si, EHCI_CONFIGFLAG, BIT0
jmp esErrorExit
esEverythingIsFine:
ENDIF
; Adjust EDI to point to operation registers
movzx eax, (HCStruc PTR [si]).bOpRegOffset
add edi, eax
;----------------------------------------------------------------------------
; Note: after this point any access to the operational registers is through
; the macros EHCI_DWORD_READ_MEM and EHCI_DWORD_WRITE_MEM; access to the
; capability registers is through the macro USBPORT_DWORD_READ_MEM and
; there is no macro to write to the registers
;----------------------------------------------------------------------------
mov bx, dx
; Program chipset to disable USB interrupts
; BX - Bus, device and function number of the HC
mov ax, ((USB_DISABLE_INTERRUPT SHL 8) + USB_EHCI)
call USBPort_ProgramHardwareInterrupt
; Depending on the setup option enable/disable the hi-speed device support
test dUSBInitFlag, USB_HISPEED_SUPPORT
jnz esProceedNormally
; Connect all ports to the classic host controller
EHCI_DWORD_RESET_MEM si, EHCI_CONFIGFLAG, BIT0
jmp esErrorExit
esProceedNormally:
; Reset the host controller (HC must be halted)
call EHCIResetHC ; SI - HCStruc
jz esErrorExit ; HC reset error, error log is updated
; Get the frame list size from the EHCI command register
EHCI_DWORD_READ_MEM si, EHCI_USBCMD
; Try to set the frame list size to 256 elements
and ax, NOT (BIT2 + BIT3) ; Mask off BIT 2&3
or ax, BIT3
EHCI_DWORD_WRITE_MEM si, EHCI_USBCMD, eax
; Read it back
EHCI_DWORD_READ_MEM si, EHCI_USBCMD
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -