📄 ohci.asm
字号:
TITLE OHCI.ASM -- Open 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/OHCI.ASM 12 3/17/03 5:49p Sivagarn $
;
; $Revision: 12 $
;
; $Date: 3/17/03 5:49p $
;***************************************************************************;
; Revision History
; ----------------
; $Log: /BIOS/Corebin/800/Modules/USB2/Template/Core/OHCI.ASM $
;
; 12 3/17/03 5:49p Sivagarn
; - Byte flag 'bUSBInitFlag' is changed to double word 'dUSBInitFlag'
; - Stopping of EHCI controller in the OHCI handover is done based on
;
; STOP_EHCI_IN_OHCI_HANDOVER bit in 'dUSBInitFlag'
; - 'pHCDReleasePort' routine is added to host controller driver. This
; routine
;
; is not needed for OHCI host controllers
;
; 11 1/30/03 5:12p Sivagarn
; - Bug in disabling OHCI port is corrected. FS register is not
; initialised properly
;
; 10 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
; - Fixed the bug in OHCI OS handover (shutdown to DOS mode in Win98SE).
; CX register was destroyed causing system hang
;
; 9 1/06/03 5:34p Sivagarn
; - Function 'USBMisc_DisableUnsupportedHC' is modified to FAR routine
;
; 8 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
;
; 7 12/19/02 6:02p Sivagarn
; - New routine is added to stop EHCI host controllers when OHCI host
; controller is stopped by the OS through ownership hand-over call
; - New host controller flag is updated to indicate the state of the OHCI
; host controller (running/stopped)
;
; 6 12/17/02 12:39p Sivagarn
; - Code clean up
; - Changed copyright message year to 2003
; - Random POST hang if keys are pressed from the USB keyboard (connected
; to OHCI controller) is fixed. The retired transfer descriptors are not
; initialized properly before re-enable their schedule (link pointer is
; updated properly)
;
; 5 11/27/02 6:07p Sivagarn
; - Initial code to enable port 60h/64h trapping and to handle the port
; trapping events are added
; - New eLink to install the OHCI host controller driver pointer is
; added
; - Code cleanup
;
; 4 11/06/02 11:56a Sivagarn
; - Building error caused by polling disable token is resolved
;
; 3 10/29/02 6:54p Sivagarn
; - Bulk transfer error conditions are tracked as per new requirement
; - Timeout value for control/bulk/interrupt transfer is taken from a
; variable
;
; 2 10/14/02 8:47p Sivagarn
; * Code clean up
; * USB internal PCI access routines are changed to core access routines
; * OHCI_PowerManagement function is changed to assembly language
; convention
; * 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 usbflag.equ
INCLUDE usb.equ
INCLUDE ohci.equ
INCLUDE mbiosequ.equ
;----------------------------------------------------------------------------
; External data definitions are done here
;----------------------------------------------------------------------------
EXTERN DeviceInfoTable:NEAR
EXTERN DeviceInfoTableEnd:NEAR
EXTERN USBAcquiredByOS:BYTE
EXTERN bEnumFlag:BYTE
EXTERN bLastCommandStatus:BYTE
EXTERN HcdGlobalDataArea:DWORD
EXTERN dOrgGlobalDataArea:DWORD
EXTERN wTimeOutValue:WORD
EXTERN dUSBInitFlag:DWORD
;----------------------------------------------------------------------------
; External function definitions are defined here
;----------------------------------------------------------------------------
read_pci_dword_far PROTO FAR SYSCALL
USBLogError PROTO NEAR SYSCALL
USBMisc_FixedDelay PROTO NEAR SYSCALL
; AX - wCount
USBMiscFormDeviceRequest PROTO NEAR SYSCALL
USBMiscGetFarBufferAddress PROTO NEAR SYSCALL
USBMiscInitFrameList PROTO NEAR SYSCALL
USBMiscGetBulkEndPointInfo PROTO NEAR SYSCALL
USBMiscUpdateBulkDataSync PROTO NEAR SYSCALL
USBMisc_StopUnsupportedHC PROTO FAR SYSCALL
USBMem_Alloc PROTO NEAR SYSCALL
; AL - bNumBlocks
USBMem_Free PROTO NEAR SYSCALL
; AL - bNumBlocks, BX - wMemBlock
USBMem_FreeOne PROTO NEAR SYSCALL
; BX - wMemBlock
USBCaptureHCInterrupt PROTO NEAR SYSCALL
USBCheckPortChange PROTO NEAR SYSCALL
USBDisconnectDevice PROTO NEAR SYSCALL
USBPeriodicInterruptHandler PROTO NEAR SYSCALL
USBPort_EnableResume PROTO NEAR SYSCALL
USBPort_ProgramHardwareInterrupt PROTO NEAR SYSCALL
;----------------------------------------------------------------------------
; Function prototype definitions are here
;----------------------------------------------------------------------------
OHCI_DisableInterrupts PROTO NEAR SYSCALL ; HCStruc in SI
OHCI_AddED PROTO NEAR SYSCALL
OHCI_FreeAllStruc PROTO NEAR SYSCALL
OHCI_ProcessInterrupt PROTO NEAR SYSCALL
OHCI_ProcessTD PROTO NEAR SYSCALL
OHCI_RemoveED PROTO NEAR SYSCALL
OHCI_ResetHC PROTO NEAR SYSCALL
OHCI_ScheduleED PROTO NEAR SYSCALL
OHCI_StartEDSchedule PROTO NEAR SYSCALL
OHCI_ProcessRootHubStatusChange 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
ENDIF
OHCIWaitForTransferComplete PROTO NEAR SYSCALL
;----------------------------------------------------------------------------
; D A T A S E G M E N T
;----------------------------------------------------------------------------
USB_DSEG SEGMENT WORD PUBLIC 'DATA'
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 _OHCI_ASM_START
_OHCI_ASM_START LABEL BYTE
PUBLIC OHCI_HCHeader
OHCI_HCHeader LABEL HCDHeader
BYTE USB_OHCI ; Module type
BYTE 00 ; RESERVED
WORD 0000 ; Reserved
WORD OHCI_Start ; OHCI start controller routine
WORD OHCI_Stop ; OHCI stop controller routine
WORD OHCI_MoveDataArea ; OHCI move data area routine
WORD OHCI_DisableInterrupts ; OHCI disable controller interrupts
WORD OHCI_EnableInterrupts ; OHCI enable controller interrupts
WORD OHCI_ProcessInterrupt ; Interrupt service routine
WORD OHCI_GetRootHubStatus ; Gets the root hub port status
WORD OHCI_DisableRootHub ; Disable root hub ports
WORD OHCI_EnableRootHub ; Enable root hub ports
WORD OHCI_ControlTransfer ; Performs a control transfer
WORD OHCI_BulkTransfer ; Performs a bulk transfer
WORD OHCI_InterruptTransfer ; Performs an interrupt transfer
WORD OHCI_DeactivatePolling ; De-activates polling for a device
WORD OHCI_ActivatePolling ; Activates polling for a device
WORD OHCI_DisableKeyRepeat ; De-activates KB repeat rate polling
WORD OHCI_EnableKeyRepeat ; Activates KB repeat rate polling
WORD OHCI_PowerManagement ; Power manages HC and its ports
WORD OHCI_EnumeratePorts ; Enumerates the ports in the HC
WORD OHCI_EnablePortTrapping ; Enables the port 60h/64h trapping
WORD OHCI_CheckHCStatus ; Checks whether the HC is still with BIOS
WORD 0 ; Not supported
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: farOHCI_InstallHCDriver
;
; Description: This eLink checks whether the request is for OHCI controller
; if so it returns its HCDHeader
;
; Input: ZR HC driver not installed
; AL Host controller type (USB_OHCI 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>
farOHCI_InstallHCDriver PROC FAR SYSCALL PUBLIC
jnz foih_Exit ; HC driver already found
cmp al, USB_OHCI
jne foih_NotOHCI
; Return the HC driver pointer
mov ax, OFFSET OHCI_HCHeader
or sp, sp ; Clear zero flag
jmp SHORT foih_Exit
foih_NotOHCI:
; Set zero flag indicating HC driver is not yet found
cmp sp, sp
foih_Exit:
ret
farOHCI_InstallHCDriver ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: OHCI_Start
;
; Description: This function starts the OHCI 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 OHCI controller
;
; Modified: EAX
;
; Referrals: None
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
OHCI_Start PROC NEAR SYSCALL PUBLIC
LOCAL dTemp:DWORD
push fs
push ebx
push cx
push dx
push si
push edi
; Store the data area address and frame list size in the HCStruc structure
mov (HCStruc PTR [si]).dHcdDataArea, edi
mov (HCStruc PTR [si]).wAsyncListSize, OHCI_FRAME_LIST_SIZE
; Set the max bulk data size
mov (HCStruc PTR [si]).dMaxBulkDataSize, MAX_OHCI_BULK_DATA_SIZE
; Initialize the periodic list
xor eax, eax ; Value to initialize with
call USBMiscInitFrameList ; SI HCStruc pointer
; Get 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
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 GE 2
; Set FS:EDI to the mem base pointer
mov edi, ebx
xor ax, ax
mov fs, ax
ENDIF
; Reset the host controller
call OHCI_ResetHC ; SI - HCStruc pointer
mov bx, dx
; Program chipset to disable USB interrupts
; BX - Bus device function number
mov ax, ((USB_DISABLE_INTERRUPT SHL 8) + USB_OHCI)
call USBPort_ProgramHardwareInterrupt
; Get the number of ports supported by the host controller (Offset 48h)
USBPORT_DWORD_READ_MEM si, OHCI_RH_DESCRIPTOR_A
; Store number of ports supported by the host controller
mov (HCStruc PTR [si]).bNumPorts, al
; Enable per port power switching & No over-current indication bits
; EAX - HcRhDescriptorA register value
and ax, NOT (BIT8 + BIT9) ; Clear bit 9:8 in EAX
or ax, (BIT8 + BIT12)
USBPORT_DWORD_WRITE_MEM si, OHCI_RH_DESCRIPTOR_A, eax
; Make USB device as removable & set power switching state to per port mode
USBPORT_DWORD_WRITE_MEM si, OHCI_RH_DESCRIPTOR_B, 0FFFF0000h
; First stop the host controller if it is at all active
call OHCI_DisableInterrupts ; SI - HCStruc
jz OST_ErrorExit
; Enable the ED schedules
; SI - HCStruc
call OHCI_StartEDSchedule
jz OST_ErrorExit
; Program the frame list base address register
mov eax, (HCStruc PTR [si]).dHcdDataArea
USBPORT_DWORD_WRITE_MEM si, OHCI_HCCA_REG, eax
; Allocate ED/TD for EDControl, TDControlSetup, TDControlData,
; TDControlStatus, EDBulk, TDBulkData, EDInterrupt and TDInterruptData
mov al, 8
call USBMem_Alloc
jz OST_ErrorExit
; Save the 8 ED/TD in their proper position
mov bx, (HCStruc PTR [si]).pDescriptorPtr
mov (OHCIDescriptors PTR [bx]).EDControl, ax
add ax, SIZE OHCI_ED
mov (OHCIDescriptors PTR [bx]).TDControlSetup, ax
add ax, SIZE OHCI_TD
mov (OHCIDescriptors PTR [bx]).TDControlData, ax
add ax, SIZE OHCI_TD
mov (OHCIDescriptors PTR [bx]).TDControlStatus, ax
add ax, SIZE OHCI_TD
mov (OHCIDescriptors PTR [bx]).EDBulk, ax
add ax, SIZE OHCI_ED
mov (OHCIDescriptors PTR [bx]).TDBulkData, ax
add ax, SIZE OHCI_TD
mov (OHCIDescriptors PTR [bx]).EDInterrupt, ax
add ax, SIZE OHCI_ED
mov (OHCIDescriptors PTR [bx]).TDInterruptData, ax
push edi
; Initialize EDInterrupt
mov di, (OHCIDescriptors PTR [bx]).EDInterrupt
mov (OHCI_ED PTR [di]).Control, ED_SKIP_TDQ ; Inactive
mov ax, OHCIDescriptors.ED1ms
; Schedule EDInterrupt to 1ms schedule
; SI HCStruc
; DI ED to schedule
; AX Schedule ED offset
call OHCI_ScheduleED
; Setup ED32ms and TD32ms. It will run a interrupt transaction to a
; nonexistant dummy device. This will have the effect of generating
; a periodic interrupt used to update keyboard LEDs and other periodic
; activities, if any.
mov di, (OHCIDescriptors PTR [bx]).ED32ms
mov cx, (OHCIDescriptors PTR [bx]).TD32ms
; DI - ED32ms
; CX - TD32ms
mov (OHCI_ED PTR [di]).Control, DUMMY_DEVICE_ADDR OR \
ED_IN_PACKET OR (DEFAULT_PACKET_LENGTH SHL 16) OR ED_SKIP_TDQ
;; mov (OHCI_ED PTR [di]).LinkPointer, OHCI_TERMINATE
movzx eax, cx ; TD32ms
add eax, HcdGlobalDataArea
mov (OHCI_ED PTR [di]).HeadPointer, eax
mov (OHCI_ED PTR [di]).TailPointer, OHCI_TERMINATE
push di
mov di, cx ; DI = Pointer to TD32ms
mov eax, GTD_BUFFER_ROUNDING OR GTD_IN_PACKET OR GTD_IntD OR \
(GTD_NOT_ACCESSED SHL 28) OR GTD_ONE_ERROR
mov (OHCI_TD PTR [di]).ControlStatus, eax
mov (OHCI_TD PTR [di]).CSReloadValue, eax
lea ax, (OHCI_TD PTR [di]).SetupData ; AX = ptr to TD's
; data buffer
movzx eax, ax ; Clear upper half of EAX
add eax, HcdGlobalDataArea ; EAX = abs addr of TD's data buffer
mov (OHCI_TD PTR [di]).CurrentBufferPointer, eax
mov (OHCI_TD PTR [di]).BufferEnd, eax
mov (OHCI_TD PTR [di]).LinkPointer, OHCI_TERMINATE
mov (OHCI_TD PTR [di]).pCallback, \
OFFSET cs:OHCI_RepeatTDCallback
mov (OHCI_TD PTR [di]).ActiveFlag, TRUE
pop di
IFE MKF_OHCI_DISABLE_32MS_POLLING
; Activate the 32ms ED by resetting ED_SKIP_TDQ bit
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -