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

📄 ehci.asm

📁 dos下的USB源码(包括UHCI
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	and	ax, BIT2 + BIT3		; Mask off unwanted bits
	shr	ax, 2

; AX = 0 or 1 or 2
; Convert AL to 5 if original value is 0, 4 if 1 and 3 if 2
	mov	ah, al
	neg	al
	add	al, 10
	mov	cl, al
	xor	ax, ax
	inc	ax
	shl	ax, cl
; AX	Number of elements in the asynchronous list
; Store the value in the HCStruc
	mov	(HCStruc PTR [si]).wAsyncListSize, ax
; Set the max bulk data size
	mov	(HCStruc PTR [si]).dMaxBulkDataSize, MAX_EHCI_DATA_SIZE

; Initialize the frame list pointers
	mov	eax, EHCI_TERMINATE	; Value to initialize with
	call	USBMiscInitFrameList	; SI	HCStruc pointer

; Write the base address of the Periodic Frame List to the PERIODIC BASE
; register
	mov	eax, (HCStruc PTR [si]).dHcdDataArea
	EHCI_DWORD_WRITE_MEM	si, EHCI_PERIODICLISTBASE, eax

;Initialize the periodic schedule
	call	EHCIInitializePeriodicSchedule	; SI	HCStruc pointer

IF	MKF_EHCI_ASYNC_BELL_SUPPORT
; Allocate and initialize an queue head for Async transfer
; Set the QHDummy as Async list head
	mov	al, USB_EHCI_QH_SIZE_BLK
	call	USBMem_Alloc
	jz	esErrorExit

	mov	pQHAsyncXfer, ax
	mov	bx, ax
	mov	(EHCI_QH PTR [bx]).dEndPntCap, QH_ONE_XFER
	xor	eax, eax
	mov	(EHCI_QH PTR [bx]).pFirstqTD, ax
	inc	eax					; EHCI_TERMINATE
	mov	(EHCI_QH PTR [bx]).dAltNextqTDPtr, eax
	mov	(EHCI_QH PTR [bx]).dNextqTDPtr, eax

; Assume as a high speed device
	mov	eax, QH_HIGH_SPEED	; 10b - High speed
; Use data toggle from qTD and this QH is the head of the queue
	or	eax, (QH_USE_QTD_DT OR QH_HEAD_OF_LIST)
	or	al, DUMMY_DEVICE_ADDR	; Endpoint is 0
; EAX[6:0] = Dev. Addr, EAX[7] = I bit(0) & EAX[11:8] = Endpoint (0)
	mov	(EHCI_QH PTR [bx]).dEndPntCharac, eax

; Set the ASYNCLISTADDR register to point to the QHDummy
	movzx	eax, bx
	add	eax, HcdGlobalDataArea
	EHCI_DWORD_WRITE_MEM	si, EHCI_ASYNCLISTADDR, eax

; Set next QH pointer to itself (circular link)
	or	eax, EHCI_QUEUE_HEAD
	mov	(EHCI_QH PTR [bx]).dLinkPointer, eax
	mov	(EHCI_QH PTR [bx]).bActive, TRUE
ENDIF	; IF	MKF_EHCI_ASYNC_BELL_SUPPORT


; Allocate QH/qTD for QHControl, qTDControlSetup, qTDControlData,
; qTDControlStatus, QHBulk, qTDBulkData, QHInterrupt & qTDInterruptData (3 QH & 5 qTDs)
	mov	al, ((3 * USB_EHCI_QH_SIZE_BLK) + (5 * USB_EHCI_QTD_SIZE_BLK))
	call	USBMem_Alloc
	jz	esErrorExit

; Save the 2 QH and 4 qTDs in appropriate location
	mov	bx, (HCStruc PTR [si]).pDescriptorPtr
	mov	(EHCIDescriptors PTR [bx]).QHControl, ax
	add	ax, SIZE EHCI_QH
	mov	(EHCIDescriptors PTR [bx]).qTDControlSetup, ax
	add	ax, SIZE EHCI_QTD
	mov	(EHCIDescriptors PTR [bx]).qTDControlData, ax
	add	ax, SIZE EHCI_QTD
	mov	(EHCIDescriptors PTR [bx]).qTDControlStatus, ax
	add	ax, SIZE EHCI_QTD
	mov	(EHCIDescriptors PTR [bx]).QHBulk, ax
	add	ax, SIZE EHCI_QH
	mov	(EHCIDescriptors PTR [bx]).qTDBulkData, ax
	add	ax, SIZE EHCI_QTD
	mov	(EHCIDescriptors PTR [bx]).QHInterrupt, ax
	add	ax, SIZE EHCI_QH
	mov	(EHCIDescriptors PTR [bx]).qTDInterruptData, ax

; Schedule QHInterrupt to 1millisec schedule
	sub	ax, SIZE EHCI_QH
; AX - QHInterrupt
	push	edi
	mov	di, ax
; Intialize the queue head
	xor	eax, eax
	inc	eax
	mov	(EHCI_QH PTR [di]).dNextqTDPtr, eax
	mov	(EHCI_QH PTR [di]).dAltNextqTDPtr, eax
	mov	(EHCI_QH PTR [di]).dLinkPointer, eax
; Schedule the QHInterrupt to 1msec schedule
	movzx	edi, di
	add	edi, HcdGlobalDataArea
	mov	ax, EHCIDescriptors.QH1ms
	call	EHCIScheduleQH
	pop	edi

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

; Program the HC BIOS owned bit and return the legacy
; support register offset
	mov	al, 1		; Set HC BIOS owned semaphore
	call	EHCIProgramLegacyRegisters
	jz	esLegacyDone
; AH	Legacy register start offset

; If SMI mode is chosen then enable the SMI generation
IF	MKF_USB_MODE EQ 2
	add	ah, 4
; Enable USB SMI, SMI on port change
	xor	ebx, ebx
	mov	bl, BIT0+BIT2
	call	write_pci_dword_far
ENDIF

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

; Turn HC on
	EHCI_DWORD_SET_MEM	si, EHCI_USBCMD, \
		(EHCI_RUNSTOP OR EHCI_INTTHRESHOLD OR EHCI_PER_SCHED_ENABLE)

; Disconnect all ports from companion HC (if any) and route them to EHCI
	EHCI_DWORD_SET_MEM	si, EHCI_CONFIGFLAG, BIT0


	jmp	esExit

esErrorExit:
	xor	eax, eax
	jmp	SHORT esRet

esExit:
; Set the HC state to running
	or	(HCStruc PTR [si]).bHCFlag, HC_STATE_RUNNING
	mov	eax, EHCI_DATA_AREA_SIZE

esRet:

IF	MKF_USB_MODE NE 1
	pop	fs
ENDIF
	pop	edi
	pop	dx
	pop	cx
	pop	ebx
	ret

EHCIStart	ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	EHCIGetLegacySupportOffset
;
; Description:	This function returns the PCI register offset for the legacy
;		support in EHCI controller
;
; Input: 	DX	PCI address of the EHCI host controller
;		SI	HCStruc pointer
;
; Output: 	ZR	If the feature is not present
;		NZ	If the feature is present
;			AH	Legacy support capability offset
;
; Modified:	AH only
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

EHCIGetLegacySupportOffset	PROC NEAR PUBLIC
	push	ebx
	push	eax

; Check whether EHCI extended capabilities  pointer is present
	mov	eax, dHCCParams

eglso_CheckNext:
	or	ah, ah
	jz	eglso_Exit	; Not present

; Value in AH. Look for legacy support capability value
; DX	PCI address of the HC
	call	read_pci_dword_far
	cmp	bl, 01h
	je	eglso_Found
; Pointer to the next capability pointer is in AH
	jmp	SHORT eglso_CheckNext

eglso_Found:
; AH	Legacy support capability offset
	mov	bl, ah
; Clear zero flag
	or	sp, sp

eglso_Exit:
	pop	eax
	mov	ah, bl
	pop	ebx
	ret
EHCIGetLegacySupportOffset	ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	EHCIProgramLegacyRegisters
;
; Description:	This function programs the EHCI legacy registers as per the
;		input. Also this routine returns the PCI register offset
;		for the legacy support in EHCI controller
;
; Input: 	AL	0	Reset HC BIOS owned bit
;			1	Set HC BIOS owned bit
;		SI	HCStruc pointer
;
; Output: 	ZR	If the feature is not present
;		NZ	If the feature is present
;			AH	Legacy support capability offset
;
; Modified:	CX, DX, EBX, AH
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

EHCIProgramLegacyRegisters	PROC NEAR SYSCALL

	mov	ch, al			; Save AL
; Get the PCI address for this HC
	mov	dx, (HCStruc PTR [si]).wBusDevFuncNum

; Get the legacy support register offset
; DX	PCI address of the HC
	call	EHCIGetLegacySupportOffset
	jz	eplrLegacyDone

; AH	Register offset. Save it in CL
	mov	cl, ah

; Program 'HC BIOS owned semaphore bit'
	call	read_pci_dword_far
; Reset bit 16
	and	ebx, NOT BIT16
	or	ch, ch
	jz	eplr_ProgramSemaphore
; Set bit 16
	or	ebx, BIT16
eplr_ProgramSemaphore:
	call	write_pci_dword_far

; Reset all enable bits and clear the status
	mov	ebx, 0FFFF0000h
	mov	ah, cl
	push	ax
	add	ah, 4
	call	write_pci_dword_far
	pop	ax

eplrLegacyDone:
	ret
EHCIProgramLegacyRegisters	ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	EHCIEnumeratePorts
;
; Description:	This function enumerates the HC ports for devices
;
; Input: 	SI	Host controller's HCStruc structure
;        	DS	USB data area
;
; Output: 	None
;
; Modified:	Nothing
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

EHCIEnumeratePorts		PROC NEAR SYSCALL PUBLIC
	push	eax
	push	ebx
	push	dx

	EHCI_SET_FS_EDI

; Enable port power so that new devices can be detected.

; Check whether enumeration flag is set by us or by somebody else by checking
; local enum flag
	cmp	bEnumFlag, TRUE
	je	esPortEnumerationComplete	; Set by somebody else

	mov	bIgnoreConnectStsChng, TRUE

; Set enumeration flag and avoid hub port enumeration
	mov	bEnumFlag, TRUE
	pushf
	cli
; Check the root hub ports to see if a device is connected.  If so, then
; call UsbHubPortChange to handle the attachment of a new device.
	mov	dl, 1			; CL will count through port numbers
	mov	ebx, EHCI_PORTSC	; Port Status and Control Register (44h)
	mov	dh, (HCStruc PTR [si]).bHCNumber
	or	dh, BIT7		; Indicate as root hub
esInitRootHubNextPort:

; Enable port power
	EHCI_DWORD_SET_MEM	si, ebx, EHCI_PORTPOWER

; Delay till the port power is stabilised
	mov	ax, ((100 * 1000) / 15)	; 100ms delay
	call	USBMisc_FixedDelay

; Process device connect/disconnect
; Note: port connect status is cleared while processing
; connect/disconnect (EHCIGetRootHubStatus)
; DH	HC number
; DL	port number
; SI	HCStruc pointer
	call	USBCheckPortChange

	add	bx, 4			; BX = next root hub status port
	inc	dl			; CL = next port number
	cmp	dl, (HCStruc PTR [si]).bNumPorts
	jbe	esInitRootHubNextPort	;Br if still more ports to check

; Clear the EHCI_PCD bit of the interrupt status register EHCI_USBSTS
	EHCI_DWORD_WRITE_MEM	si, EHCI_USBSTS, EHCI_PORT_CHANGE_DETECT

	mov	bIgnoreConnectStsChng, FALSE

; Reset enumeration flag and enable hub enumeration
	mov	bEnumFlag, FALSE
	popf
esPortEnumerationComplete:

; Enable appropriate interrupts
	EHCI_DWORD_WRITE_MEM	si, EHCI_USBINTR, (EHCI_USBINT_EN + EHCI_PCDINT_EN)

	RESTORE_FS_EDI

	pop	dx
	pop	ebx
	pop	eax
	ret
EHCIEnumeratePorts		ENDP

;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	EHCICheckHCStatus
;
; 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>

EHCICheckHCStatus	PROC	NEAR

	push	eax

	EHCI_SET_FS_EDI

; Check whether the controller is still under BIOS control
; Read the base address of the Periodic Frame List to the PERIODIC BASE
; register and compare with stored value
	EHCI_DWORD_READ_MEM	si, EHCI_PERIODICLISTBASE
	and	eax, (NOT 0FFFh)

	RESTORE_FS_EDI

	cmp	eax, (HCStruc PTR [si]).dHcdDataArea
; ZR	On success (Control is with BIOS)
; NZ	On error
	pop	eax
	ret
EHCICheckHCStatus	ENDP


;<AMI_PHDR_START>
;----------------------------------------------------------------------------
; Procedure:	EHCIStop
;
; Description:	This function stops the EHCI controller.
;
; Input: 	SI	Host controller's HCStruc structure
;        	DS	USB Data Area
;
; Output: 	None
;
; Modified:	Nothing
;
;----------------------------------------------------------------------------
;<AMI_PHDR_END>

EHCIStop	PROC	NEAR SYSCALL PUBLIC

	push	ax
	push	bx
	push	dx

	EHCI_SET_FS_EDI

; Check whether the control is with BIOS or not
	call	EHCICheckHCStatus
	jnz	esExit		; Control is with OS

; Disconnect all the devices connected to its ports
	mov	dl, 1			; DL will count through port numbers
	mov	dh, (HCStruc PTR [si]).bHCNumber
	or	dh, BIT7		; Indicate as root hub

esDisConnectNextPort:
; DH	Hub/HC number
; DL	Port number
; SI	HCStruc pointer
	call	USBDisconnectDevice
	inc	dl			;CL = next port number
	cmp	dl, (HCStruc PTR [si]).bNumPorts
	jbe	esDisConnectNextPort	;Br if still more ports to check

; Stop the host controller (Reset bit 0)
	EHCI_DWORD_RESET_MEM	si, EHCI_USBCMD, EHCI_RUNSTOP

; Wait for 1ms
	mov	ax, ((1 * 1000) / 15)	; 1ms delay
	call	USBMisc_FixedDelay

; Reset the host controller
	call	EHCIResetHC	; SI - HCStruc
		; ERROR CONDITION RETURNED IS NOT TAKEN CARE

⌨️ 快捷键说明

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