📄 uhci.asm
字号:
mov di, (UHCIDescriptors PTR [bx]).QHBulk
mov (UHCI_QH PTR [di]).ElementPointer, UHCI_TERMINATE
or di, UHCI_QUEUE_HEAD ; Indicate it as queue head
; Schedule QHBulk to 1ms schedule
mov ax, UHCIDescriptors.TD1ms
call UHCI_ScheduleTD ; Input - SI, EDI, AX
; Initialize TDInterruptData
mov di, (UHCIDescriptors PTR [bx]).TDInterruptData
mov (UHCI_TD PTR [di]).ControlStatus, 0 ; Inactive
; Schedule TDInterruptData to 1ms schedule
mov ax, UHCIDescriptors.TD1ms
call UHCI_ScheduleTD ; Input - SI, EDI, AX
; Start the host controller and set the configured flag in the host
; controller to signal that it is up and running under BIOS control.
mov dx, wIOPort
add dx, UHCI_COMMAND_REG
mov ax, (UHC_HOST_CONTROLLER_RUN OR UHC_CONFIGURE_FLAG OR \
UHC_MAX_PACKET_64_BYTE)
out dx, ax
Comment ~ ; Moved to UHCI_EnumeratePorts routine for quicker keyboard
; enumeration during POST
; Check whether enumeration is already began
cmp bEnumFlag, TRUE
je UST_SkipPortEnumeration
; Set enumeration flag and avoid hub port enumeration
mov bEnumFlag, TRUE
; Handle device attachment
; Check port1 for connect status and perform device attachement appropriately
; Form Hub address for the first port
mov dh, (HCStruc PTR [si]).bHCNumber
or dh, BIT7 ; Indicate as root hub
mov dl, 1
; DH HC number
; DL port number
; SI HCStruc pointer
call USBCheckPortChange
; Clear the status bits
push dx
mov dx, wIOPort
add dx, UHCI_PORT1_CONTROL
in ax, dx
jcxz SHORT $+2
jcxz SHORT $+2
out dx, ax
pop dx
; Check port2 for connect status and perform device attachement appropriately
; Form Hub address for the second port
inc dl
; DH HC number
; DL port number
; SI HCStruc pointer
call USBCheckPortChange
; Clear the status bits
mov dx, wIOPort
add dx, UHCI_PORT2_CONTROL
in ax, dx
jcxz SHORT $+2
jcxz SHORT $+2
out dx, ax
; Reset enumeration flag and enable hub enumeration
mov bEnumFlag, FALSE
UST_SkipPortEnumeration:
EndComment ~
; Capture the HC IRQ to point to the common IRQ handler
; SI HCStruc pointer
call USBCaptureHCInterrupt
; Program chipset to enable USB interrupts
push bx
mov bx, (HCStruc PTR [si]).wBusDevFuncNum
mov ax, ((USB_ENABLE_INTERRUPT SHL 8) + USB_UHCI)
call USBPort_ProgramHardwareInterrupt
pop bx
;;;IFE MKF_UHCI_DISABLE_ROOTHUB_POLLING xiao
; Enable root hub polling
mov eax, (UHCI_TD_INTERRUPT_ON_COMPLETE OR UHCI_TD_ONE_ERROR OR UHCI_TD_ACTIVE)
mov di, (UHCIDescriptors PTR [bx]).TDRootHub ; TDRootHub
mov (UHCI_TD PTR [di]).CSReloadValue, eax
mov (UHCI_TD PTR [di]).ActiveFlag, TRUE
mov (UHCI_TD PTR [di]).ControlStatus, eax
;ENDIF
; Allocate a TD for TDRepeat
call USBMem_AllocOne
jz UST_RepeatTDDone
push di
mov di, (HCStruc PTR [si]).pDescriptorPtr
mov (UHCIDescriptors PTR [di]).TDRepeat, ax
mov di, ax
; Initialize the body of TdRepeat. It will run a interrupt transaction
; to a non-existant dummy device. This will have the effect of generating
; a periodic interrupt used to generate keyboard repeat. This TD is normally
; inactive, and is only activated when a key is pressed. TdRepeat will be
; set to timeout after two attempts. Since the TD is in the schedule
; at 16ms intervals, this will generate an interrupt at intervals of 32ms
; (when the TD is active). This 32ms periodic interrupt may then
; approximate the fastest keyboard repeat rate of 30 characters per second.
mov (UHCI_TD PTR [di]).ControlStatus, UHCI_TD_TWO_ERRORS ; Inactive
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 = TD's data ptr
movzx eax, ax ; Clear AX+
add eax, HcdGlobalDataArea ; EAX = TD data buffer addr
mov (UHCI_TD PTR [di]).BufferPointer, eax
mov (UHCI_TD PTR [di]).CSReloadValue, UHCI_TD_TWO_ERRORS
mov (UHCI_TD PTR [di]).pCallback, OFFSET cs:UHCI_RepeatTDCallback
mov (UHCI_TD PTR [di]).ActiveFlag, FALSE
; Schedule TDRepeat to 8ms schedule
mov ax, UHCIDescriptors.TD8ms
call UHCI_ScheduleTD ; Input - SI, EDI, AX
pop di
UST_RepeatTDDone:
; Finally enable interrupts (SMIs) from the host controller.
mov dx, wIOPort
add dx, UHCI_INTERRUPT_ENABLE
mov ax, (UHC_IOC_ENABLE OR UHC_TIMEOUT_CRC_ENABLE)
out dx, ax
; Set the HC state to running
or (HCStruc PTR [si]).bHCFlag, HC_STATE_RUNNING
; Take 4K from the data segment
mov eax, UHCI_DATA_AREA_SIZE
jmp SHORT UST_Exit
UST_ErrorExit:
; Free all allocated structure
call UHCI_FreeAllStruc ; SI - HCStruc
UST_ErrorExit0:
xor eax, eax
UST_Exit:
pop es
pop edi
pop si
pop dx
pop ebx
ret
UHCI_Start ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: UHCI_EnumeratePorts
;
; Description: This function gets the USB ports ownership - makes sure the
; ports are connected to HC.
;
; Input: SI Host controller's HCStruc structure
; DS USB data area
;
; Output: None
;
; Modified: Nothing
;
; Referrals: None
;
; Notes: This function Mainly used in EHCI to switch the ownership from
; companion controller to EHCI controller. In UHCI and OHCI it has
; no code, needed only for the API consistency.
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
UHCI_EnumeratePorts PROC NEAR SYSCALL PUBLIC
push ax
push bx
push dx
mov bx, WORD PTR (HCStruc PTR [si]).dBaseAddress
; Check whether enumeration is already began
cmp bEnumFlag, TRUE
je UEP_SkipPortEnumeration
; Set enumeration flag and avoid hub port enumeration
mov bEnumFlag, TRUE
; Handle device attachment
; Check port1 for connect status and perform device attachement appropriately
; Form Hub address for the first port
mov dh, (HCStruc PTR [si]).bHCNumber
or dh, BIT7 ; Indicate as root hub
mov dl, 1
; DH HC number
; DL port number
; SI HCStruc pointer
call USBCheckPortChange
; Clear the status bits
push dx
mov dx, bx
add dx, UHCI_PORT1_CONTROL
in ax, dx
jcxz SHORT $+2
jcxz SHORT $+2
out dx, ax
pop dx
; Check port2 for connect status and perform device attachement appropriately
; Form Hub address for the second port
inc dl
; DH HC number
; DL port number
; SI HCStruc pointer
call USBCheckPortChange
; Clear the status bits
mov dx, bx
add dx, UHCI_PORT2_CONTROL
in ax, dx
jcxz SHORT $+2
jcxz SHORT $+2
out dx, ax
; Reset enumeration flag and enable hub enumeration
mov bEnumFlag, FALSE
UEP_SkipPortEnumeration:
pop dx
pop bx
pop ax
ret
UHCI_EnumeratePorts ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: UHCI_EnablePortTrapping
;
; Description: This function enables the port 60h/64h emulation
;
; Input: SI Host controller's HCStruc structure
; DS USB data area
;
; Output: None
;
; Modified: Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
UHCI_EnablePortTrapping PROC NEAR SYSCALL PUBLIC
IF (MKF_USB_MODE EQ 2) AND (MKF_USB_KBC_EMULATION)
push ax
push ebx
push dx
; Enable the port 60h/64h trapping SMI
test dUSBInitFlag, USB_PORT_TRAPPING_BIT
jz UST_SkipPortTrapping
mov dx, (HCStruc PTR [si]).wBusDevFuncNum
mov ah, PCI_REG_LEGACY_SUPPORT
call read_pci_dword_far
or bl, 0Bh ; Enable port 60h R/W and 64h W
call write_pci_dword_far
IF MKF_USB_DEV_KBD
push ds
push 0
pop ds
mov al, DS:[417h] ; KB LED status
pop ds
and al, 70h
shr al, 1
test al, 08h
jz UST_Continue0
xor al, 48h
UST_Continue0:
and bNonUSBKBShiftKeyStatus, NOT (BIT4+BIT5+BIT6)
or bNonUSBKBShiftKeyStatus, al
ENDIF
UST_SkipPortTrapping:
pop dx
pop ebx
pop ax
ENDIF
ret
UHCI_EnablePortTrapping ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: UHCI_CheckHCStatus
;
; Description: This function checks whether the host controller is still
; under BIOS
;
; Input: SI Host controller's HCStruc structure
; DS USB data area
;
; Output: ZR If the control is with the BIOS
; NZ If the control is not with the BIOS
;
; Modified: Nothing
;
; Referrals: HCDHeader, HCStruc
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
UHCI_CheckHCStatus PROC NEAR
push eax
push dx
mov dx, WORD PTR (HCStruc PTR [si]).dBaseAddress
; Check whether the controller is still under BIOS control
; Read the frame list base address and compare with stored value
add dx, UHCI_FRAME_LIST_BASE
in eax, dx
and eax, (NOT 0FFFh)
cmp eax, (HCStruc PTR [si]).dHcdDataArea
; ZR On success (Control is with BIOS)
; NZ On error
pop dx
pop eax
ret
UHCI_CheckHCStatus ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: UHCI_Stop
;
; Description: This function stops the UHCI controller.
;
; Input: SI Host controller's HCStruc structure
; DS USB data area
;
; Output: CY On error
; NC On success
;
; Modified: Nothing
;
; Referrals: None
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
UHCI_Stop PROC NEAR SYSCALL
push ax
push bx
; Stop the host controller
call UHCI_DisableInterrupts ; SI - HCStruc
;; RETURNED ERROR STATUS IS NOT HANDLED
; Disable HC ports
call UHCI_DisableHCPorts ; SI - HCStruc
mov dx, WORD PTR (HCStruc PTR [si]).dBaseAddress
; 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
mov bx, (HCStruc PTR [si]).wBusDevFuncNum
mov ax, ((USB_DISABLE_INTERRUPT SHL 8) + USB_UHCI)
call USBPort_ProgramHardwareInterrupt
; Clear the frame list pointers
mov eax, UHCI_TERMINATE
call USBMiscInitFrameList ; SI - HCStruc
; Disable TD schedule and free the data structures
call UHCI_FreeAllStruc ; SI - HCStruc
; Set the HC state to stopped
and (HCStruc PTR [si]).bHCFlag, NOT HC_STATE_RUNNING
pop bx
pop ax
ret
UHCI_Stop ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: UHCI_DisableInterrupts
;
; Description: This function disables the HC interrupts by setting the
; stop bit in the controller
;
; Input: SI Pointer to the HCStruc structure
; DS USB global data area
;
; Output: ZR On error
; NZ On success
;
; Modified: None
;
; Referrals: HCStruc
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
UHCI_DisableInterrupts PROC NEAR SYSCALL
push ax
push bx
push cx
push dx
; Get the IO port address for this controller
mov dx, WORD PTR (HCStruc PTR [si]).dBaseAddress
; Check whether HC is stopped
add dx, UHCI_COMMAND_REG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -