📄 uhci.asm
字号:
;*****************************************************************;
;*****************************************************************;
;** **;
;** (C)Copyright 1985-1996, American Megatrends, Inc. **;
;** **;
;** All Rights Reserved. **;
;** **;
;** 6145-F Northbelt Pkwy, Norcross, GA 30071 **;
;** **;
;** Phone (770)-246-8600 **;
;** **;
;*****************************************************************;
;*****************************************************************;
;---------------------------------------;
include makeflag.equ
include uhci.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: AL = USB device address to start polling ;
; AH = Endpoint within device to poll ;
; ;
; Output: Nothing ;
; ;
; Destroys: Nothing ;
;------------------------------------------------------------------------------;
_UsbActivatePolling proc near
pushad
mov bx, ax ;BX = Device addr / Endpoint
dec al
cmp al, MAX_DEVICES
jae ActivateDone ;Br if device number is too high
; Get a pointer to the device's TD in the TdPool.
mov ah, size Transfer_Descriptor
mul ah ;AX = offset of TD within TD pool
mov di, ax
add di, offset TdPool ;DI = offset of TD
; Get a pointer to the device's entry in the DeviceTable.
mov al, size DeviceTableEntry
mul bl ;AX = offset of entry within DeviceTable
mov si, ax
add si, offset DeviceTable ;SI = ptr to entry for device
; Set the endpoint field in the TD's Token.
and (Transfer_Descriptor ptr [di]).TD_Token, not ENDPOINT
movzx eax, bh ;EAX = Endpoint
shl eax, 15 ;Put endpoint in bit 18:15
or (Transfer_Descriptor ptr [di]).TD_Token, eax
; Make the TD active and set the high/low speed flag in the TD's
; TD_Control_Status and CSReloadValue.
movzx eax, (DeviceTableEntry ptr [si]).LowSpeedFlag ;AL = 0/1 for hi/lo
shl eax, 26
or eax, ACTIVE OR INTERRUPT_ON_COMPLETE OR THREE_ERRORS
mov (Transfer_Descriptor ptr [di]).CSReloadValue, eax
mov (Transfer_Descriptor ptr [di]).TD_Control_Status, eax
mov (Transfer_Descriptor ptr [di]).ActiveFlag, TRUE
ActivateDone:
popad
ret
_UsbActivatePolling endp
;---------------------------------------;
; UsbDeactivatePolling ;
;---------------------------------------;--------------------------------------;
; This function deactivates the polling TD for the given device. ;
; ;
; Input: AL = USB device address to stop polling ;
; ;
; Output: Nothing ;
; ;
; Destroys: Nothing ;
;------------------------------------------------------------------------------;
_UsbDeactivatePolling proc near
pusha
dec al
cmp al, MAX_DEVICES
jae ActivateDone ;Br if device number is too high
mov ah, size Transfer_Descriptor
mul ah ;AX = offset of TD within pool
mov di, ax
add di, offset TdPool ;DI = offset of TD
mov (Transfer_Descriptor ptr [di]).TD_Control_Status, THREE_ERRORS
mov (Transfer_Descriptor ptr [di]).CSReloadValue, THREE_ERRORS
mov (Transfer_Descriptor ptr [di]).ActiveFlag, FALSE
ActivateDone:
popa
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
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.DataArea
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
; Init Active flag in all data TDs to FALSE.
mov di, offset TdControlData ;DI = ptr of TdControlData
mov cx, CONTROL_DATA_TD_COUNT
DevReqInitNextTd:
mov (Transfer_Descriptor ptr [di]).ActiveFlag, FALSE
add di, size Transfer_Descriptor ;Point to next data TD
loop DevReqInitNextTd
; 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 TDs' token 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
shl ecx, 8 ;ECX[18:8] = Device address / endpoint
mov dl, bl ;DL = Request type
mov ah, size DeviceTableEntry
mul ah ;AX = USB device address * table entry size
mov bx, ax ;BX = USB device address * table entry size
add bx, offset DeviceTable ;BX = ptr to DeviceTableEntry
; Fill in various fields in the TdControlSetup.
; The TD_Link_Pointer field will point to the TdControlData if data will
; be sent/received or to the TdControlStatus if no data is expected.
; The TD_Control_Status field will be set to active and interrupt on complete.
; The TD_Token field will contain the packet size (size of DeviceRequest
; struc), the device address, endpoint, and a setup PID.
; The TD_Buffer_Pointer field will point to the TD's DataArea buffer which
; was just initialized to contain a DeviceRequest struc.
; 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.
mov di, offset TdControlSetup ;DI = ptr to TdControlSetup
mov eax, offset TdControlData ;EAX = abs addr of TdControlData
or si, si
jnz @f ;Br if data length is non-zero
mov eax, offset TdControlStatus ;EAX = abs addr of TdControlStatus
@@: add eax, HcdDataArea ;EAX = seg containing TDs
mov (Transfer_Descriptor ptr [di]).TD_Link_Pointer, eax
movzx eax, (DeviceTableEntry ptr [bx]).LowSpeedFlag ;AL = 0/1 for hi/lo
shl eax, 26
or eax, INTERRUPT_ON_COMPLETE or THREE_ERRORS or ACTIVE
mov (Transfer_Descriptor ptr [di]).TD_Control_Status, eax
mov eax, ecx ;EAX[18:8] = Device address / endpoint
or eax, SETUP_PACKET or ((size DeviceRequest - 1) shl 21) ;Set PID=Setup, and MaxLen
mov (Transfer_Descriptor ptr [di]).TD_Token, eax
lea ax, (Transfer_Descriptor ptr [di]).DataArea ;AX = ptr to TD's data buffer
movzx eax, ax ;Clear upper half of EAX
add eax, HcdDataArea ;EAX = abs addr of TD's data buffer
mov (Transfer_Descriptor ptr [di]).TD_Buffer_Pointer, eax
mov (Transfer_Descriptor ptr [di]).CSReloadValue, 0
mov (Transfer_Descriptor ptr [di]).pCallback, offset cgroup:ControlTdCallback
add (Transfer_Descriptor ptr [di]).pCallback, orgbase
mov (Transfer_Descriptor ptr [di]).ActiveFlag, TRUE
; Fill in various fields in the TdControlData array. Enough TdControlData TDs
; must be initialized to handle the amount of data expected. The length of the
; data transfer is currently in SI.
; The TD_Link_Pointer field will be set to the next data TD or the status TD.
; The TD_Control_Status field will be se to active and interrupt on complete.
; The TD_Token field will contain the data transfer size (still in SI),
; the device address (in ECX), endpoint (in ECX), and an in or out PID.
; The TD_Buffer_Pointer field will point to the data buffer passed in by the
; caller (currently in EBP).
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -