📄 usb.asm
字号:
pop ds
mov eax, DWORD PTR DS:[6Ch]
pop ds
; EAX = Current Tick Counter
; EBX = Last Tick Counter when we left SMI
; Check whether we are in the first 5 second of day
cmp eax, (5 * 18)
jb fUSH_WithinFirst5Sec
; Check whether 5 second had elapsed from last time we left SMI to now
add ebx, (5 * 18)
; EBX - Last time + 5 seconds
cmp ebx, eax ; Is there any USB SMI in last 5 sec?
ja SHORT fUSH_ProcessTimeDone ; Yes ...
fUSH_SetReInitFlag:
; We are getting a USB SMI after 5 or more seconds. Set HC re-initialize
; flag
; Test to see if we are in POST. No need to set this flag in POST
cmp USBAcquiredByOS, TRUE
jne fUSH_ProcessTimeDone
mov bReInitUSB, TRUE
jmp SHORT fUSH_ProcessTimeDone
fUSH_WithinFirst5Sec:
; EAX = Current Tick Counter
; EBX = Last Tick Counter when we left SMI
mov ecx, 17FE80h
; ECX = Int1A ticks in one day...
sub ecx, ebx
; ECX = Int1A ticks left in yesterday...
mov ebx, (5 * 18)
; EBX = Int1A ticks in 5 Secs...
sub ebx, ecx
; EBX = Highest Current Int1A tick counter possible in 5 sec window
cmp ebx, eax ; Are we in 5 sec window?
ja SHORT fUSH_SetReInitFlag
fUSH_ProcessTimeDone:
; Give control to all the HCs
mov si, OFFSET HCTable
mov cx, MKF_USB_MAX_HC
; Save re-init USB flag
mov dl, bReInitUSB
UWIH_TryNextHC:
; Restore re-init USB flag. Re-init USB flag will be cleared by
; HC process interrupt routine after service. So we have to
; re-initialize the value for next HC
mov bReInitUSB, dl
; Structure found
mov bx, (HCStruc PTR [si]).pHCDPointer
or bx, bx
jz UWIH_PrepareForLoop
; SI - HCStruc pointer
call (HCDHEADER PTR cs:[bx]).pHCDProcessInterrupt
; Check for more HCs using same IRQ
UWIH_PrepareForLoop:
add si, SIZE HCStruc
loop UWIH_TryNextHC
; Disable Re-init flag
mov bReInitUSB, FALSE
; Save the time we left the USB SMI
push ds
push 40h
pop ds
mov eax, dword ptr ds:[6Ch] ; EAX = Current Int1A Tick Counter
pop ds
; Store Current Int1A Tick Counter
mov dTimeLastInSMI, eax
UWIH_ExitISR:
popad
pop es
pop ds
ret
farUSBSMIHandler ENDP
ENDIF ; MKF_USB_MODE GE 2
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBCheckPortChange
;
; Description: This routine processes the port status change (like connect,
; disconnect etc) for the root hub and external hubs
;
; Input: DH USB device address of the hub whose status
; has changed
; bit 7 : 1 - Root hub, 0 for other hubs
; bit 6-0 : Device address of the hub
; DL Port number
; SI HCStruc of the host controller
;
; Output: Nothing
;
; Modified: Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBCheckPortChange PROC NEAR SYSCALL PUBLIC USES AX BX CX DX SI
LOCAL bPortStatus:BYTE
; Set look count
xor cx, cx
UCPC_ConnectDeviceAgain:
; Get the port status for the hub
test dh, BIT7
jz UCPC_HubDevice
; Get the status from the root hub
; Call appropriate controller to get the root hub status
; SI - HCStruc pointer
; AL - bPortNum
mov al, dl
push bx
mov bx, (HCStruc PTR [si]).pHCDPointer
call (HCDHEADER PTR cs:[bx]).pHCDGetRootHubStatus
pop bx
jmp SHORT UCPC_CheckStatus
UCPC_HubDevice:
IF MKF_USB_DEV_HUB
; SI HCStruc pointer
call USBHub_GetPortStatus
ELSE
jmp SHORT UHCPC_PortChangeDone
ENDIF
UCPC_CheckStatus:
or al, al
jz UHCPC_PortChangeDone
mov bPortStatus, al
cmp cx, 0
ja UCPC_DetNewDev
; Test connect status change flag
test al, USB_PORT_STAT_DEV_CONNECT_CHANGED
jz UHCPC_PortChangeDone ; If connect status has not changed
; Test device connected status flag
test al, USB_PORT_STAT_DEV_CONNECTED
jz UHCPC_Disconnect ; If device has been disconnected
UCPC_DetNewDev:
; Check hand over in progress flag
cmp bHandOverInProgress, TRUE
jne UCPC_ProceedToDetect
; Disable the hub port
; DH Hub/HC number
; DL Port number
; SI HCStruc pointer
call USBDisableHubPort
jmp SHORT UHCPC_PortChangeDone
UCPC_ProceedToDetect:
; Connect status found
mov al, bPortStatus
; DH - Hub address
; DL - Port number
; SI - HCStruc
; AL - Port status
call USB_DetectNewDevice
or ax, ax
jz UCPC_Beep
; Check for get descriptor 8 error
cmp ax, USB_ERR_DEV_INIT_GET_DESC_8
jne UCPC_Beep ; No beep and exit
; Get descriptor 8 error
; Assume that the device may come back
; Delay for 100ms
mov ax, ((100 * 1000) / 15) ; 100ms delay
call USBMisc_FixedDelay
inc cx
cmp cx, 40 ; Wait for 4 sec
jbe UCPC_ConnectDeviceAgain
; Disable the hub port
; DH Hub/HC number
; DL Port number
; SI HCStruc pointer
call USBDisableHubPort
xor ax, ax
UCPC_Beep:
cmp ax, USB_ERR_DEV_INIT_GET_DESC_200
ja UHCPC_PortChangeDone
or ax, ax
jz UHCPC_PortChangeDone
xor ax, ax ; Return with error
; Issue error beep
mov bl, 64
mov cx, 4000h
call USBMisc_SpeakerBeep
jmp SHORT UHCPC_PortChangeDone
UHCPC_Disconnect:
; Disconnect device and its children from the port
; DH Hub/HC number
; DL Port number
; SI HCStruc pointer
call USBDisconnectDevice
; Issue an error beep indicating that the device is disabled
mov bl, 8
mov cx, 1000h
call USBMisc_SpeakerBeep
UHCPC_PortChangeDone:
ret
USBCheckPortChange ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBDisableHubPort
;
; Description: This routine disables the hub port in the Standard/root hub
;
; Input: DH USB device address of the hub whose status
; has changed
; bit 7 : 1 - Root hub, 0 for other hubs
; bit 6-0 : Device address of the hub
; DL Port number
; SI HCStruc of the host controller
;
; Output: ZR On error
; NZ On success
;
; Modified: Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBDisableHubPort PROC NEAR SYSCALL PUBLIC USES BX SI
; Check for standard/root hub
test dh, BIT7
jz UDHP_StdHub
; Disable the port in the root hub
; Call appropriate controller to disable the root hub status
push bx
mov bx, (HCStruc PTR [si]).pHCDPointer
mov al, dl
call (HCDHEADER PTR cs:[bx]).pHCDDisableRootHub
pop bx
jmp SHORT UDHP_Exit
UDHP_StdHub:
IF MKF_USB_DEV_HUB
; DH Hub/HC number
; DL Port number
; SI HCStruc pointer
call USBHub_DisablePort
ENDIF
UDHP_Exit:
ret
USBDisableHubPort ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBEnableHubPort
;
; Description: This routine disables the hub port in the Standard/root hub
;
; Input: DH USB device address of the hub whose status
; has changed
; bit 7 : 1 - Root hub, 0 for other hubs
; bit 6-0 : Device address of the hub
; DL Port number
; SI HCStruc of the host controller
;
; Output: AX 0 on error, 0FFFFh on success
;
; Modified: Nothing
;
; Referrals:
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBEnableHubPort PROC NEAR SYSCALL PUBLIC USES BX DX SI
; Check for standard/root hub
test dh, BIT7
jz UEHP_StdHub
; Enable the port in the root hub
; Call appropriate controller to enable the root hub status
mov al, dl
; SI HCStruc pointer
; AL port number
mov bx, (HCStruc PTR [si]).pHCDPointer
call (HCDHEADER PTR CS:[bx]).pHCDEnableRootHub
jmp SHORT UEHP_Exit
UEHP_StdHub:
IF MKF_USB_DEV_HUB
; DH Hub/HC number
; DL Port number
; SI HCStruc pointer
call USBHub_EnablePort
ENDIF
UEHP_Exit:
ret
USBEnableHubPort ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBCheckNonCompliantDevice
;
; Description: This function checks for non-compliant USB devices by
; by comparing the device's vendor and device id with
; the non-compliant device table list and updates the
; data structures appropriately to support the device.
;
; Input: SI HCStruc pointer
; BX Device information structure pointer
; DI Pointer to the descriptor structure
; CX End offset of the device descriptor
;
; Output: None
;
; Modified: Nothing
;
; Referrals: MassDeviceInfo, DeviceInfo
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBCheckNonCompliantDevice PROC NEAR SYSCALL PUBLIC
push ax
push edx
push si
; Get the current device's vendor & device ID
mov dx, (DeviceInfo PTR [bx]).wDeviceId
shl edx,16
mov dx, (DeviceInfo PTR [bx]).wVendorId
; Search the bad device table to get the structure for this device
mov si, OFFSET CS:USBBadDeviceTable
UCNCD_Loop:
cmp si, OFFSET CS:USBBadDeviceTableEnd
jae UCNCD_Exit ; NC, ok configure device
cmp edx, DWORD PTR CS:[si] ; Compare with table entry
je UCNCD_DeviceFound
; Prepare to check next device
add si, SIZE stBadUSBDevice
jmp SHORT UCNCD_Loop
UCNCD_DeviceFound:
; Save the incompatibility flag into device info structure
mov ax, (stBadUSBDevice PTR CS:[si]).wFlags
mov (DeviceInfo PTR [bx]).wIncompatFlags, ax
; Check which fields to update in the interface descriptor
; Check for base class field
cmp (stBadUSBDevice PTR CS:[si]).bBaseClass, 0
jz UCNCD_CheckSubClass
; Update base class field in the interface descriptor
mov al, (stBadUSBDevice PTR CS:[si]).bBaseClass
mov (InterfaceDescriptor PTR [di]).bBaseClass, al
UCNCD_CheckSubClass:
; Check for sub class field
cmp (stBadUSBDevice PTR CS:[si]).bSubClass, 0
jz UCNCD_CheckProtocol
; Update sub class field in the interface descriptor
mov al, (stBadUSBDevice PTR CS:[si]).bSubClass
mov (InterfaceDescriptor PTR [di]).bSubClass, al
UCNCD_CheckProtocol:
; Check for protocol field
cmp (stBadUSBDevice PTR CS:[si]).bProtocol, 0
jz UCNCD_Exit
; Update protocol field in the interface descriptor
mov al, (stBadUSBDevice PTR CS:[si]).bProtocol
mov (InterfaceDescriptor PTR [di]).bProtocol, al
UCNCD_Exit:
pop si
pop edx
pop ax
ret
USBCheckNonCompliantDevice ENDP
;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure: USBIdentifyAndConfigureDevice
;
; Description: This routine invokes the device drivers 'check device type'
; routine and identifies the device type.
;
; Input: SI HCStruc pointer
; BX Device information structure pointer
; DI Pointer to the descriptor structure
; CX End offset of the device descriptor
;
; Output: AX New device info structure, 0 on error
;
; Modified: AX
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>
USBIdentifyAndConfigureDevice PROC NEAR SYSCALL PUBLIC USES BX CX EDX SI DI
LOCAL wRetValue:WORD
xor edx, edx
; Set return value
mov wRetValue, dx
; Check for non-compliant device. If non-compliant device found then
; the descriptor values will get updated depending on the need.
; SI - HCStruc, BX - DevInfo, DI - Pointer to InterfaceDescriptor,
; CX - Pointer to descriptor end
call USBCheckNonCompliantDevice
; Check whether to disable the device
test (DeviceInfo PTR [bx]).wIncompatFlags, USB_INCMPT_DISABLE_DEVICE
jnz UIACD_Exit
; Get the base, sub class & protocol values
mov dh, (InterfaceDescriptor PTR [di]).bBaseClass
mov dl, (InterfaceDescriptor PTR [di]).bSubClass
shl edx, 8
mov dl, (InterfaceDescriptor PTR [di]).bProtocol
; Invoke device drivers initialize routine
mov si, OFFSET DeviceDriverTable
UIACD_CheckNextDriver:
push si
; Check for driver validity
mov ax, WORD PTR cs:[si]
or ax, ax
jz UIACD_DriverInitDone
mov si, ax
; Check whether check device type routine is implemented
cmp (USB_DEV_HDR PTR cs:[si]).pChkDevType, 0
je UIACD_TryNextDriver
; Check whether configure device routine is implemented
cmp (USB_DEV_HDR PTR cs:[si]).pCfgDevice, 0
je UIACD_TryNextDriver
; Identify the device
; DL+ - Base class
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -