📄 ohci.asm
字号:
;
; Input: SI Pointer to HCStruc
;
; Output: ZR Interrupt not processed
; NZ Interrupt processed
;
; Modified: AX
;
; Referrals: OHCI_TD
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
OHCI_ProcessInterrupt PROC NEAR SYSCALL PUBLIC USES EDX SI EDI EBX
LOCAL wIntProcessFlag:WORD
; Set as interrupt not processed
mov wIntProcessFlag, 0
; Set FS:EDI to the mem base pointer
SET_FS_EDI
IF (MKF_USB_MODE EQ 2)
; Check port 60h/64h trapping SMI
IF (MKF_USB_KBC_EMULATION)
test dUSBInitFlag, USB_PORT_TRAPPING_BIT
jz OPI_NoTrapSet
; Check whether emulation is enabled
USBPORT_DWORD_READ_MEM si, OHCI_HCE_CONTROL
test al, HCE_CNTRL_EMULATION_ENABLE
jz OPI_NoTrapSet
; Set DX with the bus device and function number of the host controller
mov dx, (HCStruc PTR [si]).wBusDevFuncNum
; Check for port 60h read operation (OutputFull = 0) in HceStatus register
USBPORT_DWORD_READ_MEM si, OHCI_HCE_STATUS
test al, HCE_STS_OUTPUTFULL
jnz OPI_Not60hRead
; It is port 60h read. Set the AL accordingly
mov al, BIT0
jmp SHORT OPI_ProcessTrap
OPI_Not60hRead:
; Check for 60h/64h write
test al, HCE_STS_INPUTFULL
jnz OPI_NoTrapSet
; Differentiate between 60h write and 64h write
test al, HCD_STS_CMDDATA
jnz OPI_Port64hWrite
; It is 60h write. Set the AL accordingly
mov al, BIT1
jmp SHORT OPI_ProcessTrap
OPI_Port64hWrite:
mov al, BIT3
OPI_ProcessTrap:
; DX Bus, device, function number of the UHCI controller
; AL Trap status
; BIT0 Port 60h Read Trap Set
; BIT1 Port 60h Write Trap Set
; BIT2 Port 64h Read Trap Set
; BIT3 Port 64h Write Trap Set
call USBKBDHandlePortTrapping
OPI_NoTrapSet:
ENDIF
ENDIF
; Check the interrupt status register for an ownership change. If this bit
; is set, it means that the O/S USB device driver is attempting to takeover
; control of the host controller. In this case the host controller is
; shut down and the interrupt routing bit in the control register is cleared
; (this disables SMI generation and enebles standard IRQ generation from
; the USB host controller.
USBPORT_DWORD_READ_MEM si, OHCI_INTERRUPT_STATUS ; EAX = value from status register
test eax, OWNERSHIP_CHANGE
jz OPI_OwnerShipChangeDone ; Br if no O/S driver not taking control
USBPORT_DWORD_WRITE_MEM si, OHCI_INTERRUPT_STATUS, OWNERSHIP_CHANGE
USBPORT_DWORD_READ_MEM si, OHCI_HCCA_REG ; Read addr of USB data area
cmp eax, (HCStruc PTR [si]).dHcdDataArea
jne OPI_ReInit ; Br if O/S asking to re init USB BIOS
; Stop the HC so that O/S can take care of it from this point
call OHCI_Stop ; SI - HCStruc
; Check whether we have to stop EHCI controllers during this call
test dUSBInitFlag, USB_STOP_EHCI_IN_OHCI_HANDOVER
jz OPI_InterruptProcessingDone
; Call the generic host controller stop routine that can be used to stop other
; controllers if needed
call USBMisc_StopUnsupportedHC
jmp OPI_InterruptProcessingDone ; Exit from interrupt
OPI_ReInit:
; Reinit the USB HC
push ecx
push edi
mov edi, (HCStruc PTR [si]).dHcdDataArea
mov ecx, OHCI_DATA_AREA_SIZE
; SI HCStruc pointer
; EDI HCD data area
; ECX Data area size
call OHCI_Start
pop edi
pop ecx
jmp OPI_InterruptProcessingDone ; Exit from interrupt
OPI_OwnerShipChangeDone:
; Check whether the controller is still under BIOS control
; Read the base address of the Periodic Frame List to the OHCI HCCA
; register and compare with stored value
USBPORT_DWORD_READ_MEM si, OHCI_HCCA_REG
and eax, (NOT 0FFh)
cmp eax, (HCStruc PTR [si]).dHcdDataArea
jne OPI_Exit ; Control is not with BIOS
; Check the interrupt status register for a root hub status change. If
; this bit is set, then a device has been attached or removed from one of
; the ports on the root hub.
USBPORT_DWORD_READ_MEM si, OHCI_INTERRUPT_STATUS ; EAX = value from status register
test eax, RH_STATUS_CHANGE
jz OPI_RootHubStatusProcessed ; No root hub status change
; Set as interrupt processed
mov wIntProcessFlag, 0FFFFh
; Stop the periodic list processing to avoid more interrupts from HC
USBPORT_DWORD_RESET_MEM si, OHCI_CONTROL_REG, PERIODIC_LIST_ENABLE
; Handle root hub change
; SI HCStruc pointer
call OHCI_ProcessRootHubStatusChange
; Re-enable the periodic list processing
USBPORT_DWORD_SET_MEM si, OHCI_CONTROL_REG, PERIODIC_LIST_ENABLE
OPI_RootHubStatusProcessed:
; Check the interrupt status register for a one or more TDs completing.
USBPORT_DWORD_READ_MEM si, OHCI_INTERRUPT_STATUS
; EAX = value from status register
test eax, WRITEBACK_DONEHEAD
jz OPI_InterruptProcessingDone
; Br if no TDs have completed
; Set as interrupt processed
mov wIntProcessFlag, 0FFFFh
; The memory dword at HCCADONEHEAD has been updated to contain the head
; pointer of the linked list of TDs that have completed. Walk through
; this list processing TDs as we go.
OPI_CheckForMoreTds:
; Point data area to HC's common data area
IF MKF_USB_MODE GE 2
push es
push edi
xor ax, ax
mov es, ax
mov edi, (HCStruc PTR [si]).dHcdDataArea
xor ebx, ebx
xchg ebx, (OHCIHCCA PTR ES:[edi]).HCCADoneHead
; EBX = abs addr of 1st completed TD
pop edi
pop es
ELSE
push es
push di
mov eax, (HCStruc PTR [si]).dHcdDataArea
shr eax, 4
mov es, ax
xor di, di
xor ebx, ebx
xchg ebx, (OHCIHCCA PTR ES:[di]).HCCADoneHead
; EBX = abs addr of 1st completed TD
pop di
pop es
ENDIF
or ebx, ebx
jz OPI_InterruptProcessingDone
; Br if no TDs in list
; Clear the WRITEBACK_DONEHEAD bit of the interrupt status register
; in the host controller
; Write 1 to bit to clear it
USBPORT_DWORD_WRITE_MEM si, OHCI_INTERRUPT_STATUS, WRITEBACK_DONEHEAD
OPI_ProcessNextTd:
sub ebx, HcdGlobalDataArea ; DI = offset of 1st completed TD
and bx, 0FFF0h ; Ignore any lower bits that may be set
; SI HCStruc pointer
; BX TD pointer
; FS:EDI Pointer to mem base address
mov eax, (OHCI_TD PTR [bx]).LinkPointer
push eax
call OHCI_ProcessTD
pop ebx
or ebx, ebx
jnz OPI_ProcessNextTd ;Br if more TDs in list
jmp OPI_CheckForMoreTds ;Check if any TDs completed while processing
OPI_InterruptProcessingDone:
OPI_Exit:
RESTORE_FS_EDI
; Set return flag
mov ax, wIntProcessFlag
ret
OHCI_ProcessInterrupt ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: OHCI_GetRootHubStatus
;
; Description: This function returns the port connect status for the
; root hub port
;
; Input: SI Pointer to HCStruc of the host controller
; AL Port in the HC whose status is requested
;
; Output: AL Port status flags (see USB_PORT_STAT_XX equates)
;
;
; Modified: AL
;
; Referrals: None
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
OHCI_GetRootHubStatus PROC NEAR SYSCALL USES EBX
; Get the correct root hub port register offset
movzx ebx, al
shl bl, 2
add bx, (OHCI_RH_PORT1_STATUS - 4)
; Read the status of the port
IF MKF_USB_MODE EQ 1
INVOKE USBMiscDwordReadMemReg, si, bx
ELSE
push fs
push edi
mov edi, (HCStruc PTR [si]).dBaseAddress
mov eax, DWORD PTR FS:[EDI+EBX]
pop edi
pop fs
ENDIF
xor bl, bl ; Init the output values
test eax, CURRENT_CONNECT_STATUS
jz OGRHS_ChkSpeed ; Br if no device present
or bl, USB_PORT_STAT_DEV_CONNECTED ; Set connect status bit
OGRHS_ChkSpeed:
; Assume full speed and set the flag
or bl, USB_PORT_STAT_DEV_FULLSPEED
test eax, LOW_SPEED_DEVICE_ATTACHED
jz OGRHS_ChkConnect ; Br if full speed device
; Reset full speed
and bl, (NOT USB_PORT_STAT_DEV_FULLSPEED)
; Set low speed flag
or bl, USB_PORT_STAT_DEV_LOWSPEED
OGRHS_ChkConnect:
test eax, CONNECT_STATUS_CHANGE
jz OGRHS_Exit ; Br if connect status not changed
; Set connect status change flag
or bl, USB_PORT_STAT_DEV_CONNECT_CHANGED
OGRHS_Exit:
mov al, bl
ret
OHCI_GetRootHubStatus ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: OHCI_DisableRootHub
;
; Description: This function starts the OHCI controller. The necessary
; memory for running the controller should be provided
; as input.
;
; Input: SI Pointer to HCStruc of the host controller
; AL Port in the HC whose status is requested
; DS USB_DATA_AREA
;
; Output: AX 0xFFFF SUCCESS
;
; Modified: EAX
;
; Referrals: None
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
OHCI_DisableRootHub PROC NEAR SYSCALL PUBLIC USES EBX
; Get the correct root hub port register offset
movzx ebx, al
shl bl, 2
add bx, (OHCI_RH_PORT1_STATUS - 4)
; Write only clear port enable bit
IF MKF_USB_MODE EQ 1
INVOKE USBMiscDwordWriteMemReg, si, bx, CLEAR_PORT_ENABLE
ELSE
push fs
push edi
push 0
pop fs
mov edi, (HCStruc PTR [si]).dBaseAddress
mov DWORD PTR FS:[EDI+EBX], CLEAR_PORT_ENABLE
pop edi
pop fs
ENDIF
mov ax, 0FFFFh
ret
OHCI_DisableRootHub ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: OHCI_EnableRootHub
;
; Description: This function enables the root hub port specified
;
; Input: SI Pointer to HCStruc of the host controller
; AL Port in the HC whose status is requested
;
; Output: AX 0xFFFF SUCCESS
;
; Modified: AX
;
; Referrals: None
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
OHCI_EnableRootHub PROC NEAR SYSCALL PUBLIC USES EBX
; Set FS:EDI to the mem base pointer
SET_FS_EDI
; Get the correct root hub port register offset
movzx ebx, al
shl bl, 2
add bx, (OHCI_RH_PORT1_STATUS - 4)
; Enable the root hub port
USBPORT_DWORD_WRITE_MEM si, ebx, SET_PORT_ENABLE
; Wait for port enable to stabilize (100ms delay)
mov ax, ((100 * 1000) / 15) ; 100ms delay
call USBMisc_FixedDelay
; Reset the port
USBPORT_DWORD_WRITE_MEM si, ebx, SET_PORT_RESET
; Wait for reset to complete
OERH_WaitForReset:
USBPORT_DWORD_READ_MEM si, ebx
test eax, PORT_RESET_STATUS
jnz OERH_WaitForReset
; Clear the reset status change status
USBPORT_DWORD_WRITE_MEM si, ebx, PORT_RESET_STATUS_CHANGE
; Wait for devices connected to the port to stabilize (100ms delay)
mov ax, ((100 * 1000) / 15) ; 100ms delay
call USBMisc_FixedDelay
RESTORE_FS_EDI
mov ax, 0FFFFh
ret
OHCI_EnableRootHub ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: OHCI_ControlTransfer
;
; Description: This function executes a device request command transaction
; on the USB. One setup packet is generated containing the
; device request parameters supplied by the caller. The setup
; packet may be followed by data in or data out packets
; containing data sent from the host to the device
; or vice-versa. This function will not return until the
; request either completes successfully or completes in error
; (due to time out, etc.)
;
; Input: BX DeviceInfo structure (if available else 0)
; The temp data area in the BX contains the following data:
; pDevInfo DeviceInfo structure (if available else 0)
; wRequest Request type (low byte)
; Bit 7 : Data direction
; 0 = Host sending data to device
; 1 = Device sending data to host
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -