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

📄 uhci.asm

📁 AMI 主板的BIOS源码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	mov	(Transfer_Descriptor ptr [di]).TD_Buffer_Pointer, eax
	mov	(Transfer_Descriptor ptr [di]).CSReloadValue, TWO_ERRORS
	mov	(Transfer_Descriptor ptr [di]).pCallback, offset cgroup:RepeatTdCallback
	add	(Transfer_Descriptor ptr [di]).pCallback, orgbase
	mov	(Transfer_Descriptor ptr [di]).ActiveFlag, FALSE

; Set TdRepeat's Link Pointer to Control Queue Head

	mov	eax, HcdDataArea
	add	eax, offset QhControl
	or 	eax, QUEUE_HEAD 	;EDX = seg containing TDs
	mov	(Transfer_Descriptor ptr [di]).TD_Link_Pointer, eax

; Initialize QhControl.  The queue normally has no TDs in it.  TDs are placed
; into the queue only when initializing a device (see UsbDeviceRequest
; function above).

	mov	di, offset QhControl
	mov	(Q_Head ptr [di]).Q_Head_Link_Pointer, TERMINATE
	mov	(Q_Head ptr [di]).Q_Element_Link_Pointer, TERMINATE

; Hook the interrupt that has been assigned to the host controller.

ifdef DOS_DEBUG
	mov	bx, UsbHcBusDevFuncNum
	mov	di, USB_IRQ_LEVEL
	mov	si, PCI_REG_ADDRESS_BYTE
	call	smi_pci_read_cfg	;Returns CL = IRQ level assigned to HC
	mov	HC_Interrupt_Level, cl

	add	cl, 8			;IRQ 0/1/../7 -> INT 8/9/../F
	cmp	cl, 10h
	jb	InitVector		;Br if IRQ 0..7
	add	cl, 70h - 10h 		;Add offset of second 8259's vectors
InitVector:
	movzx	bx, cl			;BX = HC's interrupt vector
	shl	bx, 2			;BX = addr of interrupt vector to hook

	mov	ax, cs			;AX = CS
	shl	eax, 16			;Put CS in upper half of EAX
	mov	ax, offset cgroup:UsbHcIsr ;EAX = CS:Offset of USB's ISR
	push	ds
	push	0			;Set DS = 0
	pop	ds
	mov	dword ptr [bx], eax	;Hook interrupt
	pop	ds
else

; Enable the HC's SMI generation on port 60/64 read/write and USB interrupt.
	mov	bx, UsbHcBusDevFuncNum
        call	EnableKBCTraps		;Returns CL[3:0] = 60/64 r/w trap flags
	or	cl, 10h			;Always enable SMI on USB interrupt
	call	UsbHcChipsetInit
endif

; Unmask the host controller's IRQ level in the 8259

ifdef DOS_DEBUG
	mov	cl, HC_Interrupt_Level	;CL = IRQ used by the HC (0..15)
	mov	bx, 1
	shl	bx, cl			;BX = bit map with one bit set
	not	bx			;BX = bit map with one bit clear

	in	al, 21h			;AL = First 8259's mask reg
	and	al, bl			;Adjust mask
	out	21h, al			;Write mask back

	in	al, 0A1h		;AL = Second 8259's mask reg
	and	al, bh			;Adjust mask
	out	0A1h, al		;Write mask back
endif

; Enable 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

; Start the host controller and set the configured flag in the host controller
; to signal that it is up and running under BIOS control.

	mov	ax, HOST_CONTROLLER_RUN or CONFIGURE_FLAG
	mov	dx, USB_COMMAND_REG
	call	WriteUsbIoRegWord	;Start the host controller running

UsbInitDone:
ifdef DOS_DEBUG
	pop	es
	pop	ds
endif

	popad
	ret
_UsbHcInit	endp


;---------------------------------------;
; UsbHcClose                            ;
;---------------------------------------;--------------------------------------;
; This function shuts down and disables the USB host controller.               ;
;                                                                              ;
; Input:  Nothing                                                              ;
;                                                                              ;
; Output: Nothing                                                              ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
_UsbHcClose	proc near
	pusha

ifdef DOS_DEBUG
	push	ds
	push	es
	push	DOS_DEBUG_DATA_AREA
	push	DOS_DEBUG_DATA_AREA
	pop	ds
	pop	es
endif

; Stop the host controller
	mov	dx, USB_COMMAND_REG
	call	ReadUsbIoRegWord	;AX = HC command reg
	and	al, NOT HOST_CONTROLLER_RUN
	call	WriteUsbIoRegWord	;Write back to HC command reg

; Disable interrupts from the host controller
	xor	ax, ax
	mov	dx, USB_INTERRUPT_ENABLE
	call	WriteUsbIoRegWord	;Disable all HC interrupts

; Disable the HC's SMI generation on port 60/64 read/write and USB interrupt.
;;	mov	bx, UsbHcBusDevFuncNum
	call	GetUsbHcBusDevFunc	;Returns BX = b/d/f, destroys AX,ECX,EDX
	jc	@f			;Br if USB HC not found
	call	UsbHcChipsetShutdown
@@:
; Turn off ports
	mov	ax,01ffh
	call	UsbDisableRootHubPort
	mov	ax,02ffh
	call	UsbDisableRootHubPort

; Unconfigure everything
	mov	dx, USB_COMMAND_REG
	mov	ax,0
	call	WriteUsbIoRegWord	;Write to HC command reg

; Mask the host controller's IRQ level in the 8259

ifdef DOS_DEBUG
	mov	cl, HC_Interrupt_Level	;CL = IRQ used by the HC (0..15)
	mov	bx, 1
	shl	bx, cl			;BX = bit map with one bit set

	in	al, 21h			;AL = First 8259's mask reg
	or	al, bl			;Adjust mask
	out	21h, al			;Write mask back

	in	al, 0A1h		;AL = Second 8259's mask reg
	or	al, bh			;Adjust mask
	out	0A1h, al		;Write mask back
endif

; Unhook the interrupt that has been assigned to the host controller.

ifdef DOS_DEBUG
	;..........................
endif

ifdef DOS_DEBUG
	pop	es
	pop	ds
endif

	popa
	ret
_UsbHcClose	endp


;---------------------------------------;
; UsbHcIsr                              ;
;---------------------------------------;--------------------------------------;
; This is the main entry point that handles all interrupts generated by the    ;
; USB host controller.                                                         ;
;                                                                              ;
; Input:  DS = ES 	Usb Data Area                                          ;
;                                                                              ;
; Output: Nothing                                                              ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
UsbHcIsr	proc near
	pushad

ifdef DOS_DEBUG
	push	ds
	push	es
	push	DOS_DEBUG_DATA_AREA
	push	DOS_DEBUG_DATA_AREA
	pop	ds
	pop	es
endif

; Clear interrupt status in the host controller

 	mov	dx, USB_STATUS_REG
	call	ReadUsbIoRegWord	;AX = HC status reg
 	call	WriteUsbIoRegWord	;Write back to HC status reg to clear

; Loop through all of the TDs.  For any TD whose ActiveFlag is TRUE and
; is completed (TD_Control_Status bit 23 clear), process the TD by calling
; its callback routine.

	mov	di, offset TdPool	;DI = offset of first TD in array

ServiceTdNextTd:
	call	ProcessTdIfNeeded	;Check if complete and do callback
	add	di, size Transfer_Descriptor
	cmp	di, offset TdPoolEnd
	jb	ServiceTdNextTd		;Br if more TDs to service

; Clear interrupt status in the host controller again..................

 	mov	dx, USB_STATUS_REG
	call	ReadUsbIoRegWord	;AX = HC status reg
 	call	WriteUsbIoRegWord	;Write back to HC status reg to clear

; Issue EOI to the 8259

ifdef DOS_DEBUG

	mov	al, 20h			;AL = EOI command
	cmp	HC_Interrupt_Level, 8
	jb	IsrEoiPri		;Br if using IRQ 0..7 (2nd 8259 needs no EOI)
	out	0A0h, al
	jcxz	$+2
	jcxz	$+2
IsrEoiPri:
	out	20h, al
	jcxz	$+2
	jcxz	$+2

endif

ifdef DOS_DEBUG
	pop	es
	pop	ds
endif
	popad

ifdef DOS_DEBUG
	iret
else
	ret
endif

UsbHcIsr	endp


;---------------------------------------;
; ProcessTdIfNeeded                     ;
;---------------------------------------;--------------------------------------;
; This function examines a TD and determines if it has completed.  If the TD   ;
; has completed, the TD's callback routine is given control.                   ;
;                                                                              ;
; Input:  DS:DI = Pointer to TD that completed                                 ;
;                                                                              ;
; Output: Nothing                                                              ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
ProcessTdIfNeeded	proc near

	cmp	(Transfer_Descriptor ptr [di]).ActiveFlag, TRUE
	jne	@f			;Br if TD is not active
	test	(Transfer_Descriptor ptr [di]).TD_Control_Status, ACTIVE
	jnz	@f			;Br if TD is not completed
	cmp	(Transfer_Descriptor ptr [di]).pCallback, 0
	jz	@f			;Br if TD's callback ptr is NULL
	call	(Transfer_Descriptor ptr [di]).pCallback
@@:
	ret
ProcessTdIfNeeded	endp


;---------------------------------------;
; PollingTdCallback                     ;
;---------------------------------------;--------------------------------------;
; This function is called when a polling TD from the TD pool completes an      ;
; interrupt transaction to its assigned device.  This routine should process   ;
; any data in the TD's data buffer, handle any errors, and then copy the       ;
; TD's CSReloadValue field into its TD_Control_Status field to put the TD back ;
; into service.                                                                ;
;                                                                              ;
; Input:  DS:DI = Pointer to TD that completed                                 ;
;                                                                              ;
; Output: Nothing                                                              ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
PollingTdCallback	proc near
	push	eax
	push	bx
	push	si

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

	test	(Transfer_Descriptor ptr [di]).TD_Control_Status, STATUS_FIELD
	jnz	PollingTdError		;Br if any error bit is set in status

 	mov	dx, USB_FRAME_NUM
	call	ReadUsbIoRegWord	;AX[10:0] = Frame number
	mov	cx, ax			;BX[10:0] = Frame number
	mov	ax, word ptr ((Transfer_Descriptor ptr [di]).TD_Token)
	and	ah, (DEVICE_ADDRESS shr 8) ;AH = Device address (1..7F)
	lea	si, (Transfer_Descriptor ptr [di]).DataArea

	push	ax
	mov	al, size DeviceTableEntry
	mul	ah			;AX = offset of DeviceTableEntry in DeviceTable
	mov	bx, ax

⌨️ 快捷键说明

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