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

📄 uhci.asm

📁 dos下的USB源码(包括UHCI
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	mov	di, (UHCIDescriptors PTR [bx]).QHBulk
	mov	(UHCI_QH PTR [di]).ElementPointer, UHCI_TERMINATE
	or	di, UHCI_QUEUE_HEAD		; Indicate it as queue head
; Schedule QHBulk to 1ms schedule
	mov	ax, UHCIDescriptors.TD1ms
	call	UHCI_ScheduleTD		; Input - SI, EDI, AX

; Initialize TDInterruptData
	mov	di, (UHCIDescriptors PTR [bx]).TDInterruptData
	mov	(UHCI_TD PTR [di]).ControlStatus, 0	; Inactive

; Schedule TDInterruptData to 1ms schedule
	mov	ax, UHCIDescriptors.TD1ms
	call	UHCI_ScheduleTD		; Input - SI, EDI, AX

; 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	dx, wIOPort
	add	dx, UHCI_COMMAND_REG
	mov	ax, (UHC_HOST_CONTROLLER_RUN OR UHC_CONFIGURE_FLAG OR \
			 UHC_MAX_PACKET_64_BYTE)
	out	dx, ax


Comment ~	; Moved to UHCI_EnumeratePorts routine for quicker keyboard
		; enumeration during POST
; Check whether enumeration is already began
	cmp	bEnumFlag, TRUE
	je	UST_SkipPortEnumeration

; Set enumeration flag and avoid hub port enumeration
	mov	bEnumFlag, TRUE

; Handle device attachment

; Check port1 for connect status and perform device attachement appropriately
; Form Hub address for the first port
	mov	dh, (HCStruc PTR [si]).bHCNumber
	or	dh, BIT7		; Indicate as root hub
	mov	dl, 1
; DH	HC number
; DL	port number
; SI	HCStruc pointer
	call	USBCheckPortChange

; Clear the status bits
	push	dx
	mov	dx, wIOPort
	add	dx, UHCI_PORT1_CONTROL
	in	ax, dx
	jcxz	SHORT $+2
	jcxz	SHORT $+2
	out	dx, ax
	pop	dx

; Check port2 for connect status and perform device attachement appropriately
; Form Hub address for the second port
	inc	dl
; DH	HC number
; DL	port number
; SI	HCStruc pointer
	call	USBCheckPortChange
; Clear the status bits
	mov	dx, wIOPort
	add	dx, UHCI_PORT2_CONTROL
	in	ax, dx
	jcxz	SHORT $+2
	jcxz	SHORT $+2
	out	dx, ax

; Reset enumeration flag and enable hub enumeration
	mov	bEnumFlag, FALSE

UST_SkipPortEnumeration:

EndComment ~


; Capture the HC IRQ to point to the common IRQ handler
; SI	HCStruc pointer
	call	USBCaptureHCInterrupt

; Program chipset to enable USB interrupts
	push	bx
	mov	bx, (HCStruc PTR [si]).wBusDevFuncNum
	mov	ax, ((USB_ENABLE_INTERRUPT SHL 8) + USB_UHCI)
	call	USBPort_ProgramHardwareInterrupt
	pop	bx

;;;IFE	MKF_UHCI_DISABLE_ROOTHUB_POLLING  xiao
; Enable root hub polling
	mov	eax, (UHCI_TD_INTERRUPT_ON_COMPLETE OR UHCI_TD_ONE_ERROR OR UHCI_TD_ACTIVE)
	mov	di, (UHCIDescriptors PTR [bx]).TDRootHub	; TDRootHub
	mov	(UHCI_TD PTR [di]).CSReloadValue, eax
	mov	(UHCI_TD PTR [di]).ActiveFlag, TRUE
	mov	(UHCI_TD PTR [di]).ControlStatus, eax
;ENDIF

; Allocate a TD for TDRepeat
	call	USBMem_AllocOne
	jz	UST_RepeatTDDone

	push	di

	mov	di, (HCStruc PTR [si]).pDescriptorPtr
	mov	(UHCIDescriptors PTR [di]).TDRepeat, ax
	mov	di, ax

; Initialize the body of TdRepeat. It will run a interrupt transaction
; to a non-existant dummy device.  This will have the effect of generating
; a periodic interrupt used to generate keyboard repeat.  This TD is normally
; inactive, and is only activated when a key is pressed.  TdRepeat will be
; set to timeout after two attempts.  Since the TD is in the schedule
; at 16ms intervals, this will generate an interrupt at intervals of 32ms
; (when the TD is active).  This 32ms periodic interrupt may then
; approximate the fastest keyboard repeat rate of 30 characters per second.
	mov	(UHCI_TD PTR [di]).ControlStatus, UHCI_TD_TWO_ERRORS	; Inactive

	mov	(UHCI_TD PTR [di]).Token, (IN_PACKET OR \
			(DUMMY_DEVICE_ADDR SHL 8) OR \
			((DEFAULT_PACKET_LENGTH - 1) SHL 21))
			; Set PID=In, Dev=Dummy, and MaxLen

	lea	ax, (UHCI_TD PTR [di]).DataArea	; AX = TD's data ptr
	movzx	eax, ax				; Clear AX+
	add	eax, HcdGlobalDataArea		; EAX = TD data buffer addr
	mov	(UHCI_TD PTR [di]).BufferPointer, eax
	mov	(UHCI_TD PTR [di]).CSReloadValue, UHCI_TD_TWO_ERRORS
	mov	(UHCI_TD PTR [di]).pCallback, OFFSET cs:UHCI_RepeatTDCallback
	mov	(UHCI_TD PTR [di]).ActiveFlag, FALSE

; Schedule TDRepeat to 8ms schedule
	mov	ax, UHCIDescriptors.TD8ms
	call	UHCI_ScheduleTD		; Input - SI, EDI, AX

	pop	di
UST_RepeatTDDone:


; Finally enable interrupts (SMIs) from the host controller.
	mov	dx, wIOPort
	add	dx, UHCI_INTERRUPT_ENABLE
	mov	ax, (UHC_IOC_ENABLE OR UHC_TIMEOUT_CRC_ENABLE)
	out	dx, ax


; Set the HC state to running
	or	(HCStruc PTR [si]).bHCFlag, HC_STATE_RUNNING

; Take 4K from the data segment
	mov	eax, UHCI_DATA_AREA_SIZE

	jmp	SHORT UST_Exit

UST_ErrorExit:
; Free all allocated structure
	call	UHCI_FreeAllStruc	; SI - HCStruc

UST_ErrorExit0:
	xor	eax, eax

UST_Exit:
	pop	es
	pop	edi
	pop	si
	pop	dx
	pop	ebx
	ret

UHCI_Start	ENDP


;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	UHCI_EnumeratePorts
;
; Description:	This function gets the USB ports ownership - makes sure the
;		ports are connected to HC.
;
; Input: 	SI	Host controller's HCStruc structure
;        	DS	USB data area
;
; Output: 	None
;
; Modified:	Nothing
;
; Referrals:	None
;
; Notes:	This function Mainly used in EHCI to switch the ownership from
;		companion controller to EHCI controller. In UHCI and OHCI it has
;		no code, needed only for the API consistency.
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

UHCI_EnumeratePorts		PROC NEAR SYSCALL PUBLIC
	push	ax
	push	bx
	push	dx

	mov	bx, WORD PTR (HCStruc PTR [si]).dBaseAddress

; Check whether enumeration is already began
	cmp	bEnumFlag, TRUE
	je	UEP_SkipPortEnumeration

; Set enumeration flag and avoid hub port enumeration
	mov	bEnumFlag, TRUE

; Handle device attachment

; Check port1 for connect status and perform device attachement appropriately
; Form Hub address for the first port
	mov	dh, (HCStruc PTR [si]).bHCNumber
	or	dh, BIT7		; Indicate as root hub
	mov	dl, 1
; DH	HC number
; DL	port number
; SI	HCStruc pointer
	call	USBCheckPortChange

; Clear the status bits
	push	dx
	mov	dx, bx
	add	dx, UHCI_PORT1_CONTROL
	in	ax, dx
	jcxz	SHORT $+2
	jcxz	SHORT $+2
	out	dx, ax
	pop	dx

; Check port2 for connect status and perform device attachement appropriately
; Form Hub address for the second port
	inc	dl
; DH	HC number
; DL	port number
; SI	HCStruc pointer
	call	USBCheckPortChange
; Clear the status bits
	mov	dx, bx
	add	dx, UHCI_PORT2_CONTROL
	in	ax, dx
	jcxz	SHORT $+2
	jcxz	SHORT $+2
	out	dx, ax

; Reset enumeration flag and enable hub enumeration
	mov	bEnumFlag, FALSE

UEP_SkipPortEnumeration:
	pop	dx
	pop	bx
	pop	ax
	ret

UHCI_EnumeratePorts		ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	UHCI_EnablePortTrapping
;
; Description:	This function enables the port 60h/64h emulation
;
; Input: 	SI	Host controller's HCStruc structure
;        	DS	USB data area
;
; Output: 	None
;
; Modified:	Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

UHCI_EnablePortTrapping		PROC NEAR SYSCALL PUBLIC

IF	(MKF_USB_MODE EQ 2) AND (MKF_USB_KBC_EMULATION)
	push	ax
	push	ebx
	push	dx

; Enable the port 60h/64h trapping SMI
	test	dUSBInitFlag, USB_PORT_TRAPPING_BIT
	jz	UST_SkipPortTrapping

	mov	dx, (HCStruc PTR [si]).wBusDevFuncNum
	mov	ah, PCI_REG_LEGACY_SUPPORT
	call	read_pci_dword_far
	or	bl, 0Bh			; Enable port 60h R/W and 64h W
	call	write_pci_dword_far

IF	MKF_USB_DEV_KBD
	push	ds
	push	0
	pop	ds
	mov	al, DS:[417h]	; KB LED status
	pop	ds
	and	al, 70h
	shr	al, 1
	test	al, 08h
	jz	UST_Continue0
	xor	al, 48h
UST_Continue0:
	and	bNonUSBKBShiftKeyStatus, NOT (BIT4+BIT5+BIT6)
	or	bNonUSBKBShiftKeyStatus, al
ENDIF

UST_SkipPortTrapping:

	pop	dx
	pop	ebx
	pop	ax
ENDIF
	ret

UHCI_EnablePortTrapping		ENDP


;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	UHCI_CheckHCStatus
;
; Description:	This function checks whether the host controller is still
;		under BIOS
;
; Input: 	SI	Host controller's HCStruc structure
;        	DS	USB data area
;
; Output: 	ZR	If the control is with the BIOS
;		NZ	If the control is not with the BIOS
;
; Modified:	Nothing
;
; Referrals:	HCDHeader, HCStruc
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

UHCI_CheckHCStatus	PROC	NEAR

	push	eax
	push	dx

	mov	dx, WORD PTR (HCStruc PTR [si]).dBaseAddress
; Check whether the controller is still under BIOS control
; Read the frame list base address and compare with stored value
	add	dx, UHCI_FRAME_LIST_BASE
	in	eax, dx
	and	eax, (NOT 0FFFh)
	cmp	eax, (HCStruc PTR [si]).dHcdDataArea

; ZR	On success (Control is with BIOS)
; NZ	On error
	pop	dx
	pop	eax
	ret
UHCI_CheckHCStatus	ENDP


;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	UHCI_Stop
;
; Description:	This function stops the UHCI controller.
;
; Input: 	SI	Host controller's HCStruc structure
;        	DS	USB data area
;
; Output: 	CY	On error
;		NC	On success
;
; Modified:	Nothing
;
; Referrals:	None
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

UHCI_Stop	PROC NEAR SYSCALL

	push	ax
	push	bx

; Stop the host controller
	call	UHCI_DisableInterrupts		; SI - HCStruc
	;; RETURNED ERROR STATUS IS NOT HANDLED

; Disable HC ports
	call	UHCI_DisableHCPorts	; SI - HCStruc

	mov	dx, WORD PTR (HCStruc PTR [si]).dBaseAddress
; Reset the host controller
	add	dx, UHCI_COMMAND_REG
	mov	al, UHC_GLOBAL_RESET
	out	dx, al
; Wait for 100ms

	mov	ax, ((100 * 1000) / 15)	; 100ms delay
	call	USBMisc_FixedDelay
; Reset the UHCI command register
	xor	al, al
	out	dx, al

; Program chipset to disable USB interrupts
	mov	bx, (HCStruc PTR [si]).wBusDevFuncNum
	mov	ax, ((USB_DISABLE_INTERRUPT SHL 8) + USB_UHCI)
	call	USBPort_ProgramHardwareInterrupt

; Clear the frame list pointers
	mov	eax, UHCI_TERMINATE
	call	USBMiscInitFrameList	; SI - HCStruc

; Disable TD schedule and free the data structures
	call	UHCI_FreeAllStruc	; SI - HCStruc

; Set the HC state to stopped
	and	(HCStruc PTR [si]).bHCFlag, NOT HC_STATE_RUNNING

	pop	bx
	pop	ax
	ret
UHCI_Stop	ENDP


;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	UHCI_DisableInterrupts
;
; Description:	This function disables the HC interrupts by setting the
;		stop bit in the controller
;
; Input: 	SI	Pointer to the HCStruc structure
;        	DS	USB global data area
;
; Output: 	ZR	On error
;		NZ	On success
;
; Modified:	None
;
; Referrals:	HCStruc
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

UHCI_DisableInterrupts	PROC NEAR SYSCALL

	push	ax
	push	bx
	push	cx
	push	dx

; Get the IO port address for this controller
	mov	dx, WORD PTR (HCStruc PTR [si]).dBaseAddress

; Check whether HC is stopped
	add	dx, UHCI_COMMAND_REG

⌨️ 快捷键说明

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