⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uhci.asm

📁 AMI 主板的BIOS源码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	add	bx, offset DeviceTable	;BX = ptr to DeviceTableEntry
	pop	ax

	call	(DeviceTableEntry ptr [bx]).pDeviceCallback

PollingTdError:
	mov	eax, (Transfer_Descriptor ptr [di]).CSReloadValue
	mov	(Transfer_Descriptor ptr [di]).TD_Control_Status, eax

	xor	(Transfer_Descriptor ptr [di]).TD_Token, DATA_TOGGLE

	mov	(Transfer_Descriptor ptr [di]).ActiveFlag, TRUE

	pop	si
	pop	bx
	pop	eax
	ret
PollingTdCallback	endp


;---------------------------------------;
; ControlTdCallback                     ;
;---------------------------------------;--------------------------------------;
; This function is called when the ControlSetup and ControlData TDs complete a ;
; control transaction to the assigned device.                                  ;
;                                                                              ;
; Input:  DS:DI = Pointer to TD that completed                                 ;
;                                                                              ;
; Output: Nothing                                                              ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
ControlTdCallback	proc near
	push	eax
	push	ebx

; Check to see if the TD that just completed has any error bits set.  If
; any of the ControlTds (Setup, Data, or Status) complete with an error, set
; ActiveFlag of the TdControlStatus and copy the error information from the
; TD that just completed into the TdControlStatus.

	mov	eax, (Transfer_Descriptor ptr [di]).TD_Control_Status
	test	eax, STATUS_FIELD
	jz	ControlNoError		;Br if the TD completed with no error

	mov	TdControlStatus.TD_Control_Status, eax
	mov	TdControlStatus.ActiveFlag, FALSE
	jmp	short ControlDone

; Check the amount of data tranferred by the TD that just completed.  If
; less than a full packet was transferred, then the device has no more
; data to send.  In this case we should point the QhControl's
; Q_Element_Link_Pointer field to the TdControlStatus because that the
; remaining TdControlData TDs are not needed.

ControlNoError:
	mov	eax, (Transfer_Descriptor ptr [di]).TD_Control_Status
	and	ax, ACTUAL_LENGTH	;AX = actual byte count - 1
	mov	ebx, (Transfer_Descriptor ptr [di]).TD_Token
	shr	ebx, 21			;BX = expected byte count - 1
	cmp	ax, bx
	je	ControlDone		;Br if actual = expected count

	mov	bx, offset QhControl
	mov	eax, HcdDataArea	;EAX = seg containing TDs
	add	eax, offset TdControlStatus ;EAX = abs addr of TdControlStatus
	mov	(Q_Head ptr [bx]).Q_Element_Link_Pointer, eax

; Make the TD that just completed inactive.  It may be the TdControlSetup,
; one of the TdControlData TDs, or the TdControlStatus.

ControlDone:
	mov	(Transfer_Descriptor ptr [di]).ActiveFlag, FALSE

	pop	ebx
	pop	eax
	ret
ControlTdCallback	endp


;---------------------------------------;
; RootHubTdCallback                     ;
;---------------------------------------;--------------------------------------;
; This function is called when the TdRootHub completes a transaction.  This    ;
; TD runs a dummy interrupt transaction to a non-existant device address for   ;
; the purpose of generating a periodic timeout interrupt.  This periodic       ;
; interrupt may be used to check for new devices on the root hub etc.          ;
;                                                                              ;
; Input:  DS:DI = Pointer to TD that completed                                 ;
;                                                                              ;
; Output: Nothing                                                              ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
RootHubTdCallback	proc near
	push	eax
	push	dx

; First deactivate the TdRootHub so this callback function will not get
; reentered.

	mov	(Transfer_Descriptor ptr [di]).ActiveFlag, FALSE

; Mask the Host Controller interrupt so the ISR does not get re-entered due
; to an IOC interrupt from any TDs that complete in frames while we are
; configuring a new device that has just been plugged in.

	xor	ax, ax
	mov	dx, USB_INTERRUPT_ENABLE
	call	WriteUsbIoRegWord	;Disable IOC, timeout, CRC interrupts

; Check ports 1 and 2 on the root hub for any change in connect status.  If the
; connect status has been changed on either or both of these ports, then call the
; routine UsbHubPortChange for each changed port.

	mov	dx, USB_PORT1_CONTROL
	call	ReadUsbIoRegWord	;AX = value from port 1 control reg
	test	al, CONNECT_STATUS_CHANGE
	jz	@f			;Br if no change for port 1
	mov	ax, 01FFh		;AH = port number, AL = device addr (FF=root hub)
	call	UsbHubPortChange	;Process the connection/disconnection
	mov	dx, USB_PORT1_CONTROL
	call	ReadUsbIoRegWord	;AX = value from port 1 control reg
	call	WriteUsbIoRegWord	;Write back to clear the change bit
@@:
	mov	dx, USB_PORT2_CONTROL
	call	ReadUsbIoRegWord	;AX = value from port 2 control reg
	test	al, CONNECT_STATUS_CHANGE
	jz	@f			;Br if no change for port 2
	mov	ax, 02FFh		;AH = port number, AL = device addr (FF=root hub)
	call	UsbHubPortChange	;Process the connection/disconnection
	mov	dx, USB_PORT2_CONTROL
	call	ReadUsbIoRegWord	;AX = value from port 2 control reg
	call	WriteUsbIoRegWord	;Write back to clear the change bit
@@:

; Call the USB keyboard code's periodic entry point.  The keyboard code uses
; this periodic call to check the state of the keyboard LED status byte
; (at 40:17) and resync the USB keyboard's LEDs to match that byte if needed.

	call	OneSecondPeriodicHandler

; Renable interrupts from the host controller

	mov	ax, IOC_ENABLE OR TIMEOUT_CRC_ENABLE
	mov	dx, USB_INTERRUPT_ENABLE
	call	WriteUsbIoRegWord	;Enable IOC, timeout, CRC interrupts

; Reactivate the TdRootHub

	mov	eax, (Transfer_Descriptor ptr [di]).CSReloadValue
	mov	(Transfer_Descriptor ptr [di]).TD_Control_Status, eax
	xor	(Transfer_Descriptor ptr [di]).TD_Token, DATA_TOGGLE
	mov	(Transfer_Descriptor ptr [di]).ActiveFlag, TRUE

	pop	dx
	pop	eax
	ret
RootHubTdCallback	endp


;---------------------------------------;
; RepeatTdCallback                      ;
;---------------------------------------;--------------------------------------;
; This function is called when TdRepeat completes a transaction.  This         ;
; TD runs a dummy interrupt transaction to a non-existant device address for   ;
; the purpose of generating a periodic timeout interrupt which in turn is used ;
; to generate keyboard repeat.                                                 ;
;                                                                              ;
; Input:  DS:DI = Pointer to TD that completed                                 ;
;                                                                              ;
; Output: Nothing                                                              ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
RepeatTdCallback	proc near
	push	eax

; First deactivate the TdRepeat so this callback function will not get
; reentered.

	mov	(Transfer_Descriptor ptr [di]).ActiveFlag, FALSE

	call	PeriodicInterruptHandler 
; Reactivate the TdRepeat

	mov	eax, (Transfer_Descriptor ptr [di]).CSReloadValue
	mov	(Transfer_Descriptor ptr [di]).TD_Control_Status, eax
	xor	(Transfer_Descriptor ptr [di]).TD_Token, DATA_TOGGLE
;;;	mov	(Transfer_Descriptor ptr [di]).ActiveFlag, TRUE

	pop	eax
	ret
RepeatTdCallback	endp


;---------------------------------------;
; EnablePeriodicInterrupt		;
;---------------------------------------;--------------------------------------;
; This function enables the periodic interrupt.                                ;
;                                                                     
       ;
;         AL = Value to write to register                                      ;
;         DS = Segment containing IO_Space_Base_Address variable               ;
;                                                                              ;
; Output: Nothing                                                              ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
WriteUsbIoRegByte	proc	near
	push	dx
	add	dx, IO_Space_Base_Address
	out	dx, al
	pop	dx
	ret
WriteUsbIoRegByte	endp


;---------------------------------------;
; ReadUsbIoRegWord                      ;
;---------------------------------------;--------------------------------------;
; This function reads a word from the given register in the USB host           ;
; controller.                                                                  ;
;                                                                              ;
; Input:  DX = Register offset to read                                         ;
;         DS = Segment containing IO_Space_Base_Address variable               ;
;                                                                              ;
; Output: AX = Value read from register                                        ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
ReadUsbIoRegWord	proc	near
	push	dx
	add	dx, IO_Space_Base_Address
	in	ax, dx
	pop	dx
	ret
ReadUsbIoRegWord	endp


;---------------------------------------;
; WriteUsbIoRegWord                     ;
;---------------------------------------;--------------------------------------;
; This function writes a word to the given register in the USB host            ;
; controller.                                                                  ;
;                                                                              ;
; Input:  DX = Register offset to write                                        ;
;         AX = Value to write to register                                      ;
;         DS = Segment containing IO_Space_Base_Address variable               ;
;                                                                              ;
; Output: Nothing                                                              ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
WriteUsbIoRegWord	proc	near
	push	dx
	add	dx, IO_Space_Base_Address
	out	dx, ax
	pop	dx
	ret
WriteUsbIoRegWord	endp


;---------------------------------------;
; ReadUsbIoRegDword                     ;
;---------------------------------------;--------------------------------------;
; This function reads a dword from the given register in the USB host          ;
; controller.                                                                  ;
;                                                                              ;
; Input:  DX = Register offset to read                                         ;
;         DS = Segment containing IO_Space_Base_Address variable               ;
;                                                                              ;
; Output: EAX = Value read from register                                       ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
ReadUsbIoRegDword	proc	near
	push	dx
	add	dx, IO_Space_Base_Address
	in	eax, dx
	pop	dx
	ret
ReadUsbIoRegDword	endp


;---------------------------------------;
; WriteUsbIoRegDword                    ;
;---------------------------------------;--------------------------------------;
; This function writes a dword to the given register in the USB host           ;
; controller.                                                                  ;
;                                                                              ;
; Input:  DX = Register offset to write                                        ;
;         EAX = Value to write to register                                     ;
;         DS = Segment containing IO_Space_Base_Address variable               ;
;                                                                              ;
; Output: Nothing                                                              ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
WriteUsbIoRegDword	proc	near
	push	dx
	add	dx, IO_Space_Base_Address
	out	dx, eax
	pop	dx
	ret
WriteUsbIoRegDword	endp

	assume	ds:nothing
	assume	es:nothing
	assume	cs:nothing

_text	ends
	end
;*****************************************************************;
;*****************************************************************;
;**                                                             **;
;**      (C)Copyright 1985-1996, American Megatrends, Inc.      **;
;**                                                             **;
;**                     All Rights Reserved.                    **;
;**                                                             **;
;**           6145-F Northbe

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -