📄 uhci.asm
字号:
TITLE UHCI.ASM -- Universal 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/UHCI.ASM 15 3/17/03 5:49p Sivagarn $
;
; $Revision: 15 $
;
; $Date: 3/17/03 5:49p $
;***************************************************************************;
; Revision History
; ----------------
; $Log: /BIOS/Corebin/800/Modules/USB2/Template/Core/UHCI.ASM $
;
; 15 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 not needed for UHCI host controllers
; - UHCI_ProcessInterrupt routine is split into two routines to reduce
;
; complexity and unwanted behaviour change
; - Port 60h/64h emulation status bits are cleared/disabled for all
; UHCI
;
; controllers at the same time instead of handling them separately
;
; 14 1/27/03 8:48p 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
;
; 13 1/16/03 4:22p Sivagarn
; - CSP compatibility checking added for the routine
; USBPort_DisableResume
;
; 12 1/06/03 5:34p Sivagarn
; - UHCI_PowerManagement routine is modified as per the notebook PM
; eModule requirements
;
; 11 1/03/03 7:02p 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
;
; 10 12/19/02 6:04p Sivagarn
; - Year in the copyright message is changed to 2003
; - New host controller flag is updated to indicate the state of the UHCI
; host controller (running/stopped)
;
; 9 11/27/02 6:07p Sivagarn
; - New eLink to install the UHCI host controller driver pointer is
; added
; - Code cleanup
;
; 8 11/20/02 5:53p Sivagarn
; - Procedure header update and comment update
;
; 7 11/17/02 8:06p Sivagarn
; - Bug in stop/resetting UHCI controller is fixed
;
; 6 11/06/02 11:56a Sivagarn
; - Building error caused by polling disable token is resolved
;
; 5 11/05/02 6:56p Sivagarn
; Enumeration of USB 1.1 devices is refined. If EHCI controller is
; enabled then devices connected to the UHCI controllers are enumerated
; slowly. This affects the usage of USB keyboards during the POST.
; Problem is fixed by moving the enumeration code to UHCI_EnumeratePorts
; routine.
;
; 4 10/29/02 6:54p Sivagarn
; - Support for port 60h/64h trapping is added
; - New driver API added to enable trapping
; - Process interrupt is changed to handle trapping events
; - Bulk transfer error conditions are tracked as per new requirement
; - Timeout value for control/bulk/interrupt transfer is taken from a
; variable
;
; 3 10/14/02 8:49p Sivagarn
; * Transfer speed is increased by setting the vertical flag in the
; queue
; * Code clean up and equate names are changed
; * USB internal PCI access routines are changed to core access routines
; * UHCI_PowerManagement function is changed to assembly language
; convention
; * All the MKF_ flags are removed
;
; 2 9/24/02 6:28p Sivagarn
; BugFix: Data sync value for the Interrupt endpoints is updated
; incorrectly.
; NOTE: This fixes the Y-E Data USB FDD boot issue
;
; 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 usbflag.equ
INCLUDE usb.equ
INCLUDE uhci.equ
INCLUDE mbiosequ.equ
;----------------------------------------------------------------------------
; Compatibility related flags
IFNDEF MKF_USB_CSP_TEMPLATE_VERSION
MKF_USB_CSP_TEMPLATE_VERSION EQU 0
ENDIF
;----------------------------------------------------------------------------
; External data definitions are defined here
;----------------------------------------------------------------------------
EXTERN DeviceInfoTable:NEAR
EXTERN DeviceInfoTableEnd:NEAR
EXTERN bReInitUSB:BYTE
EXTERN bLastCommandStatus:BYTE
EXTERN bUSBMode:BYTE
EXTERN dUSBInitFlag:DWORD
EXTERN wTimeOutValue:WORD
IF MKF_USB_DEV_KBD
EXTERN bNonUSBKBShiftKeyStatus:BYTE
ENDIF
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
; External function definitions are defined here
;----------------------------------------------------------------------------
read_pci_dword_far PROTO FAR
write_pci_dword_far PROTO FAR
USBPort_ProgramHardwareInterrupt PROTO NEAR SYSCALL
; Available only from versions 6 or higher
IF MKF_USB_CSP_TEMPLATE_VERSION GE 6
USBPort_DisableResume PROTO NEAR SYSCALL
ENDIF
USBPort_EnableResume PROTO NEAR SYSCALL
USBCaptureHCInterrupt PROTO NEAR SYSCALL
USBGetDeviceInfoFromDevAddr PROTO NEAR SYSCALL
USBPeriodicInterruptHandler PROTO NEAR SYSCALL
USBCheckPortChange PROTO NEAR SYSCALL
USBDisconnectDevice PROTO NEAR SYSCALL
USBLogError PROTO NEAR SYSCALL
USBGetNextHCStruc PROTO NEAR SYSCALL ; HCStruc in SI
USBMem_Alloc PROTO NEAR SYSCALL
USBMem_AllocOne PROTO NEAR SYSCALL
USBMem_Free PROTO NEAR SYSCALL
USBMem_FreeOne PROTO NEAR SYSCALL
USBMisc_FixedDelay PROTO NEAR SYSCALL
USBMiscInitFrameList PROTO NEAR SYSCALL
USBMiscGetFarBufferAddress PROTO NEAR SYSCALL
USBMiscFormDeviceRequest PROTO NEAR SYSCALL
USBMiscGetBulkEndPointInfo PROTO NEAR SYSCALL
USBMiscUpdateBulkDataSync PROTO NEAR SYSCALL
IF MKF_USB_DEV_KBD AND MKF_USB_KBC_EMULATION
USBKBDHandlePortTrapping PROTO NEAR SYSCALL
ENDIF
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
; Public function definitions are defined here
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
; Function prototype definitions are here
;----------------------------------------------------------------------------
UHCI_DisableInterrupts PROTO NEAR SYSCALL ; HCStruc in SI
UHCI_EnableInterrupts PROTO NEAR SYSCALL ; HCStruc in SI
UHCI_DisableHCPorts PROTO NEAR SYSCALL ; HCStruc in SI
UHCI_FreeAllStruc PROTO NEAR SYSCALL ; HCStruc in SI
UHCI_StartTDSchedule PROTO NEAR SYSCALL ; HCStruc in SI
UHCI_FreeTD PROTO NEAR SYSCALL ; pTDList in AX
UHCIWaitForTransferComplete PROTO NEAR SYSCALL
UHCI_ProcessInterrupt PROTO NEAR SYSCALL ; HCStruc in AX
UHCI_AddTD PROTO NEAR SYSCALL
UHCI_ControlTDCallback PROTO NEAR SYSCALL
UHCI_ProcessTD PROTO NEAR SYSCALL
UHCI_ProcessQH PROTO NEAR SYSCALL
UHCIParseAndProcessTD PROTO NEAR SYSCALL
UHCI_RemoveTD PROTO NEAR SYSCALL
UHCI_RootHubTDCallback PROTO NEAR SYSCALL
UHCI_ScheduleTD PROTO NEAR SYSCALL
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
; External data definitions are done here
;----------------------------------------------------------------------------
EXTERN HcdGlobalDataArea:DWORD
EXTERN bEnumFlag:BYTE
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
; D A T A S E G M E N T
;----------------------------------------------------------------------------
USB_DSEG SEGMENT WORD PUBLIC 'DATA'
wTrapSet WORD ?
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 _UHCI_ASM_START
_UHCI_ASM_START LABEL BYTE
Public UHCI_HCHeader
UHCI_HCHeader LABEL HCDHeader
BYTE USB_UHCI ; Module type
BYTE 00 ; RESERVED
WORD 0000 ; Reserved
WORD UHCI_Start ; UHCI start controller routine
WORD UHCI_Stop ; UHCI stop controller routine
WORD UHCI_MoveDataArea ; UHCI move data area routine
WORD UHCI_DisableInterrupts ; UHCI disable controller interrupts
WORD UHCI_EnableInterrupts ; UHCI enable controller interrupts
WORD UHCI_ProcessInterrupt ; Interrupt service routine
WORD UHCI_GetRootHubStatus ; Gets the root hub port status
WORD UHCI_DisableRootHub ; Disable root hub ports
WORD UHCI_EnableRootHub ; Enable root hub ports
WORD UHCI_ControlTransfer ; Performs a control transfer
WORD UHCI_BulkTransfer ; Performs a bulk transfer
WORD UHCI_InterruptTransfer ; Performs an interrupt transfer
WORD UHCI_DeactivatePolling ; De-activates polling for a device
WORD UHCI_ActivatePolling ; Activates polling for a device
WORD UHCI_DisableKeyRepeat ; De-activates KB repeat rate polling
WORD UHCI_EnableKeyRepeat ; Activates KB repeat rate polling
WORD UHCI_PowerManagement ; Power manages HC and its ports
WORD UHCI_EnumeratePorts ; Enumerates the ports in the HC
WORD UHCI_EnablePortTrapping ; Enables the port 60h/64h trapping
WORD UHCI_CheckHCStatus ; Checks whether the HC is under BIOS control
WORD 0 ; Not supported
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: farUHCI_InstallHCDriver
;
; Description: This eLink checks whether the request is for UHCI controller
; if so it returns its HCDHeader
;
; Input: ZR HC driver not installed
; AL Host controller type (USB_UHCI 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>
farUHCI_InstallHCDriver PROC FAR SYSCALL PUBLIC
jnz fuih_Exit ; HC driver already found
cmp al, USB_UHCI
jne fuih_NotUHCI
; Return the HC driver pointer
mov ax, OFFSET UHCI_HCHeader
or sp, sp ; Clear zero flag
jmp SHORT fuih_Exit
fuih_NotUHCI:
; Set zero flag indicating HC driver is not yet found
cmp sp, sp
fuih_Exit:
ret
farUHCI_InstallHCDriver ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: UHCI_Start
;
; Description: This function starts the UHCI 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 UHCI controller
;
; Modified: Nothing
;
; Referrals: HCStruc
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
UHCI_Start PROC NEAR SYSCALL PUBLIC
LOCAL wIOPort:WORD
push ebx
push dx
push si
push edi
push es
; Check whether we have enough memory for the UHCI HC frame list
cmp ecx, UHCI_DATA_AREA_SIZE
jb UST_ErrorExit0
; Store the data area address in the HCStruc structure
mov (HCStruc PTR [si]).dHcdDataArea, edi
; Fill number of ports supported by the host controller
mov (HCStruc PTR [si]).bNumPorts, 2
mov (HCStruc PTR [si]).wAsyncListSize, UHCI_FRAME_LIST_SIZE
; Set the max bulk data size
mov (HCStruc PTR [si]).dMaxBulkDataSize, MAX_UHCI_BULK_DATA_SIZE
; Initialize the frame list pointers
mov eax, UHCI_TERMINATE
call USBMiscInitFrameList ; SI HCStruc
; Get I/O base address of the HC and store it in the variable
; IO_Space_Base_Address in the USB data segment.
mov ah, USB_IO_BASE_ADDRESS
mov dx, (HCStruc PTR [si]).wBusDevFuncNum
call read_pci_dword_far
mov ax, bx
and ax, 0FFFCh ; Mask lower bits
mov (HCStruc PTR [si]).dBaseAddress, eax
; Save the IO address locally (to save space)
mov wIOPort, ax
mov dx, ax
; First stop the host controller if it is at all active
call UHCI_DisableInterrupts ; SI - HCStruc
jz UST_ErrorExit
; Disable HC ports
call UHCI_DisableHCPorts ; SI - HCStruc
; Reset the host controller
add dx, UHCI_COMMAND_REG
mov al, UHC_GLOBAL_RESET
out dx, al
; Wait for 100ms
mov ax, ((100 * 1000) / 15) ; 100ms delay
call USBMisc_FixedDelay
; Reset the UHCI command register
xor al, al
out dx, al
; Program chipset to disable USB interrupts
; BX BusDeviceFunction number
mov bx, (HCStruc PTR [si]).wBusDevFuncNum
mov ax, ((USB_DISABLE_INTERRUPT SHL 8) + USB_UHCI)
call USBPort_ProgramHardwareInterrupt
; Enable the TD schedules
call UHCI_StartTDSchedule ; SI - HCStruc
jz UST_ErrorExit
; Program the frame list base address register
mov dx, wIOPort
add dx, UHCI_FRAME_LIST_BASE
mov eax, (HCStruc PTR [si]).dHcdDataArea
out dx, eax
; Allocate TD/QH for TDRootHub, QHBulk, QHControl & TDInterruptData
mov al, 4 ; Allocate 4 blocks of memory
call USBMem_Alloc
jz UST_ErrorExit
; Save the 4 TD/QH in their proper position. AX - Pointer to 4 blocks
mov bx, (HCStruc PTR [si]).pDescriptorPtr
mov (UHCIDescriptors PTR [bx]).TDRootHub, ax
add ax, SIZE UHCI_TD
mov (UHCIDescriptors PTR [bx]).QHBulk, ax
add ax, SIZE UHCI_TD
mov (UHCIDescriptors PTR [bx]).QHControl, ax
add ax, SIZE UHCI_TD
mov (UHCIDescriptors PTR [bx]).TDInterruptData, ax
; Initialize the body of TDRootHub. It will run a interrupt transaction to a
; nonexistant dummy device. This will have the effect of generating a
; periodic interrupt for the purpose of checking for attach/detach
; on the root hub's ports.
mov di, (UHCIDescriptors PTR [bx]).TDRootHub ; TDRootHub
mov (UHCI_TD PTR [di]).Token, IN_PACKET or \
(DUMMY_DEVICE_ADDR shl 8) or ((DEFAULT_PACKET_LENGTH - 1) \
shl 21) ; Set PID=In, Dev=Dummy, and MaxLen
lea ax, (UHCI_TD PTR [di]).DataArea ; AX = Ptr to TD data area
movzx eax, ax
add eax, HcdGlobalDataArea
mov (UHCI_TD PTR [di]).BufferPointer, eax
xor eax, eax
mov (UHCI_TD PTR [di]).ControlStatus, eax
mov (UHCI_TD PTR [di]).CSReloadValue, eax
mov (UHCI_TD PTR [di]).pCallback, OFFSET cs:UHCI_RootHubTDCallback
mov (UHCI_TD PTR [di]).ActiveFlag, FALSE
; SI - HCStruc
; DI - TDRootHub
; BX - UHCIDescritor PTR
; Attach TDRootHub to 256ms schedule
mov ax, UHCIDescriptors.TD256ms
call UHCI_ScheduleTD ; Input - SI, EDI, AX
; Initialize QHControl
mov di, (UHCIDescriptors PTR [bx]).QHControl
mov (UHCI_QH PTR [di]).ElementPointer, UHCI_TERMINATE
or di, UHCI_QUEUE_HEAD ; Indicate it as queue head
; Schedule QHControl to 2ms schedule
mov ax, UHCIDescriptors.TD2ms
call UHCI_ScheduleTD ; Input - SI, EDI, AX
; Initialize QHBulk
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -