📄 ohci.asm
字号:
;*****************************************************************;
;*****************************************************************;
;** **;
;** (C)Copyright 1985-1996, American Megatrends, Inc. **;
;** **;
;** All Rights Reserved. **;
;** **;
;** 6145-F Northbelt Pkwy, Norcross, GA 30071 **;
;** **;
;** Phone (770)-246-8600 **;
;** **;
;*****************************************************************;
;*****************************************************************;
;---------------------------------------;
include cssgpm.dat
include makeflag.equ
include ohci.equ
include usb.equ
include pci.equ
include usbdata.dat
;---------------------------------------;
public _UsbHcInit
public _UsbHcClose
public _UsbActivatePolling
public _UsbDeactivatePolling
public UsbDeviceRequest
public UsbGetRootHubPortStatus
public UsbEnableRootHubPort
public UsbDisableRootHubPort
;---------------------------------------;
extrn UsbDataInit :near
extrn UsbHubPortChange :near
extrn OneSecondPeriodicHandler :near
extrn PeriodicInterruptHandler :near
extrn EnableKBCTraps :near
extrn pm_fixed_delay :near
extrn smi_pci_read_cfg :near
extrn smi_pci_write_cfg :near
extrn smi_pci_find_device :near
;;;; extrn cpu_gen_purpose_reg_entry :abs
extrn UsbGetHostControllerId :near
extrn UsbHcChipsetInit :near
extrn UsbHcChipsetShutdown :near
extrn UsbHcChipsetGetStatus :near
extrn UsbHcChipsetHandler :near
;---------------------------------------;
cgroup group _text
_text segment word public 'CODE'
assume cs:cgroup
assume ds:usbdgroup
assume es:usbdgroup
.386
;---------------------------------------;
; UsbHcHandler ;
;---------------------------------------;--------------------------------------;
; Input: DS = PM BIOS Data segment in SMRam ;
; ;
; Output: Nothing ;
; ;
; Destroys: Any general purpose ;
;------------------------------------------------------------------------------;
UsbHcHandler proc near
; mov dx,USB_COMMAND_REG
; call ReadUsbIoRegWord ;AX = contents of USB command reg
; test ax,CONFIGURE_FLAG
; jnz @f ;Br if USB HC is already configured
; call _UsbHcInit ;Re-Init the USB HC after O/S shutdown
; ret
;@@:
mov bx, UsbHcBusDevFuncNum ;BX = bus/dev/func of USB HC
call UsbHcChipsetHandler
ret
UsbHcHandler endp
;---------------------------------------;
; UsbActivatePolling ;
;---------------------------------------;--------------------------------------;
; This function activates a polling TD for the given device so the host ;
; controller will run an interrupt transaction to the device according to the ;
; schedule that was setup in UsbHcInit. This routine is used to activate ;
; polling for HID devices and Hubs. ;
; ;
; Input: SI = Pointer to device table entry ;
; ;
; Output: Nothing ;
; ;
; Destroys: Nothing ;
;------------------------------------------------------------------------------;
_UsbActivatePolling proc near
push eax
push di
; Get a pointer to the device's TD in the TdPool and make the TD active in the
; TD's TD_Control and CSReloadValue.
mov eax, NOT_ACCESSED shl 28
mov di, (DeviceTableEntry ptr [si]).TdPoolPtr
or (General_Transfer_Descriptor ptr [di]).GTD_CONTROL, eax
or (General_Transfer_Descriptor ptr [di]).CSReloadValue, eax
mov (General_Transfer_Descriptor ptr [di]).ActiveFlag, TRUE
; Get a pointer to the device's ED in the EdPool and set the address, endpoint,
; and speed fields in the ED.
movzx eax,(DeviceTableEntry ptr [si]).LowSpeedFlag ;EAX[13] = 0/1 for full/low
shl eax, 6
or al, (DeviceTableEntry ptr [si]).EndpointNum ;EAX[10:7] = Endp
shl eax, 7
or al, (DeviceTableEntry ptr [si]).DeviceAddress ;EAX[6:0] = Addr
mov di, (DeviceTableEntry ptr [si]).EdPoolPtr
and (Endpoint_Descriptor ptr [di]).ED_Control, (not ENDPOINT) and (not LOW_SPEED) and (not FUNCTION_ADDRESS)
or (Endpoint_Descriptor ptr [di]).ED_Control, eax
; Finally clear the Skip bit in the device's ED. This will cause the HC
; to process the ED and TD.
and (Endpoint_Descriptor ptr [di]).ED_Control, NOT SKIP_TDQ
pop di
pop eax
ret
_UsbActivatePolling endp
;---------------------------------------;
; UsbDeactivatePolling ;
;---------------------------------------;--------------------------------------;
; This function deactivates the polling TD for the given device. ;
; ;
; Input: SI = Pointer to device table entry ;
; ;
; Output: Nothing ;
; ;
; Destroys: Nothing ;
;------------------------------------------------------------------------------;
_UsbDeactivatePolling proc near
push di
; Get a pointer to the device's ED in the EdPool and set its Skip bit.
mov di, (DeviceTableEntry ptr [si]).EdPoolPtr
or (Endpoint_Descriptor ptr [di]).ED_Control, SKIP_TDQ
; Get a pointer to the device's TD in the TdPool and make it inactive.
mov di, (DeviceTableEntry ptr [si]).TdPoolPtr
mov (General_Transfer_Descriptor ptr [di]).ActiveFlag, FALSE
pop di
ret
_UsbDeactivatePolling endp
;---------------------------------------;
; UsbDeviceRequest ;
;---------------------------------------;--------------------------------------;
; 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: AL = Destination USB device address (valid range: 00h - 7Fh) ;
; AH = Destination endpoint within the device (valid range 00h - 0Fh) ;
; BL = Request type ;
; Bit 7: Data direction ;
; 0 = Host sending data to device ;
; 1 = Device sending data to host ;
; Bit 6-5: Type ;
; 00 = Standard USB request ;
; 01 = Class specific ;
; 10 = Vendor specific ;
; 11 = Reserved ;
; Bit 4-0: Recipient ;
; 00000 = Device ;
; 00001 = Interface ;
; 00010 = Endpoint ;
; 00011 = Other ;
; 00100 - 11111 = Reserved ;
; BH = Request code, a one byte code describing the actual device ;
; request to be executed (ex: get configuration, set address, etc.);
; CX = wValue request parameter (meaning varies with each request type) ;
; DX = wIndex request parameter (meaning varies with each request type) ;
; SI = wLength request parameter, number of bytes of data to be ;
; transferred in or out of the host controller ;
; ES:DI = Seg:Offset of buffer containing data to be sent to the device ;
; or space to be used to receive data from the device ;
; ;
; Output: CF = Clear if device request completed successfully ;
; Set if device request completed with error or timed out ;
; ;
; Destroys: Nothing ;
;------------------------------------------------------------------------------;
UsbDeviceRequest proc near
pushad
push cx
mov cx, 0C8h ;3ms / 15us
call pm_fixed_delay ;Delay 10ms
pop cx
xor ebp, ebp ;Build abs addr of data area in EBP
mov bp, es
shl ebp, 4
movzx edi, di
add ebp, edi ;EBP = abs addr of data area
; Build the device request in the data area of the TdControlSetup
mov di, offset TdControlSetup.GTD_Setup
mov (DeviceRequest ptr [di]).RequestType, bl
mov (DeviceRequest ptr [di]).RequestCode, bh
mov (DeviceRequest ptr [di]).Value, cx
mov (DeviceRequest ptr [di]).Index, dx
mov (DeviceRequest ptr [di]).DataLength, si
; Prepare some registers that will be used in building the TDs below.
; SI contains the data length.
; EBP contains the absolute address of the data buffer.
; DL will contain the request type (bit 7 = 0/1 for Out/In).
; ECX will contain the device address and endpoint shifted and ready to go
; into the ED's ED_Control field.
; BX will contain a pointer to the DeviceTableEntry for the given device.
; DI will be left free to use as a pointer to the TD being built.
; EAX will be left free to use as a scratch register.
movzx dx, ah ;DX[3:0] = Endpoint (0-F)
shl dx, 7 ;DX[10:7] = Endpoint (0-F)
movzx ecx, al ;ECX[6:0] = Device address (00-7F)
or cx, dx ;ECX[10:0] = Device address / endpoint
mov dl, bl ;DL = Request type
mov bx, offset DeviceTable ;BX = ptr to DeviceTable[0]
DevReqFindEntryNextEntry:
cmp (DeviceTableEntry ptr [bx]).Present, TRUE
jne DevReqFindEntrySkipEntry ;Br if this DeviceTableEntry is not in use
cmp (DeviceTableEntry ptr [bx]).DeviceAddress, al
clc ;Indicate entry found
je DevReqFindEntryDone ;Br if matching entry found
DevReqFindEntrySkipEntry:
add bx, size DeviceTableEntry
cmp bx, offset DeviceTableEnd
jb DevReqFindEntryNextEntry ;Br if more entries to check
stc
jmp DeviceRequestDone ;Could not find matching DeviceTableEntry
DevReqFindEntryDone:
; Initialize the EdControl.
; The ED_Control field will be set so FUNCTION_ADDRESS/ENDPOINT_NUMBER = ECX,
; DIRECTION=FROM TD, SPEED=DeviceTableEntry.LowSpeedFlag, SKIP=1,
; FORMAT=0, MAX_PACK_SIZE=DeviceTableEntry.Endp0MaxPacket
; The TDQ_Head_Pointer field will be set to TdControlSetup
; The TDQ_Tail_Pointer field will be set to TERMINATE
; The Next_ED field will be set to TERMINATE
mov di, offset EdControl
movzx eax, (DeviceTableEntry ptr [bx]).Endp0MaxPacket
cmp ax, 40h ;ALI cannot handle packet size of 80h
jbe @f
mov ax, 40h
@@:
shl eax, 16 ;EAX[26:16] = device's packet size
movzx ax, (DeviceTableEntry ptr [bx]).LowSpeedFlag ;AL = 0/1 for hi/lo
shl ax, 13 ;EAX[13] = full/low speed flag
or eax, ecx ;EAX[10:0] = Endp/Addr
or eax, SKIP_TDQ
mov (Endpoint_Descriptor ptr [di]).ED_Control,eax
mov ax, offset TdControlSetup
movzx eax, ax
add eax, HcdDataArea
mov (Endpoint_Descriptor ptr [di]).TDQ_Head_Pointer,eax
mov eax, TERMINATE
mov (Endpoint_Descriptor ptr [di]).TDQ_Tail_Pointer, eax
mov (Endpoint_Descriptor ptr [di]).Next_ED, eax
; Fill in various fields in the TdControlSetup.
; The TD_Control field will be set so BUFFER_ROUNDING=1,
; DIRECTION_PID=SETUP_PACKET, DELAY_INTERRUPT=IntD,
; DATA_TOGGLE=SETUP_TOGGLE, ERROR_COUNT=NO_ERRORS, CONDITION_CODE=NOT_ACCESSED
; The GTD_Current_Buffer_Pointer field will point to the TD's GTD_Setup buffer
; which was just initialized to contain a DeviceRequest struc.
; The GTD_Buffer_End field will point to the last byte of the TD's GTD_Setup
; buffer.
; The GTD_Next_TD field will point to the TdControlData if data will
; be sent/received or to the TdControlStatus if no data is expected.
; The CSReloadValue field will contain 0 because this is a "one shot" packet.
; The pCallback will be set to point to the ControlTdCallback routine.
; The ActiveFlag field will be set to TRUE.
; The DeviceAddress field does not need to be set since the Control TDs do
; not need rebinding to the EdControl.
mov di, offset TdControlSetup ;DI = ptr to TdControlSetup
mov (General_Transfer_Descriptor ptr [di]).GTD_Control, BUFFER_ROUNDING or SETUP_PACKET or DELAY_INTERRUPT or SETUP_TOGGLE or NO_ERRORS or (NOT_ACCESSED shl 28)
lea ax, (General_Transfer_Descriptor ptr [di]).GTD_Setup ;AX = ptr to TD's data buffer
movzx eax, ax ;Clear upper half of EAX
add eax, HcdDataArea ;EAX = abs addr of TD's 8 byte data buffer
mov (General_Transfer_Descriptor ptr [di]).GTD_Current_Buffer_Pointer, eax
add eax, (size (General_Transfer_Descriptor ptr [di]).GTD_Setup) - 1
mov (General_Transfer_Descriptor ptr [di]).GTD_Buffer_End, eax
mov eax, offset TdControlData ;EAX = offset of TdControlData
or si, si
jnz @f ;Br if data length is non-zero
mov eax, offset TdControlStatus ;EAX = offset of TdControlStatus
@@: add eax, HcdDataArea ;EAX = abs addr
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -