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

📄 usb.asm

📁 AMI 主板的BIOS源码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;---------------------------------------;--------------------------------------;
; This function checks an interface descriptor of a device to see if it        ;
; describes a HID/Boot/Mouse device.  If the device is a mouse, then           ;
; it is configured and initialized.                                            ;
;                                                                              ;
; Input: DL = USB Device address of new device                                 ;
;        ES:DI+BX = Pointer to an interface descriptor supported by device     ;
;        ES:DI+BP = Limit of the data returned by device during the last       ;
;                   Get Configuration Descriptor command                       ;
;        DS:SI = Pointer to DeviceTableEntry for the device                    ;
;                                                                              ;
; Output: CF = Set if mouse was not found                                      ;
;              Clear if mouse was found and initialized                        ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
CheckForAndConfigureMouse	proc near
	pusha

; ES:DI+BX points to an InterfaceDescriptor.  Check its BaseClass, SubClass,
; and Protocol fields for a HID/Boot/Mouse device.

	cmp	es:(InterfaceDescriptor ptr [di+bx]).BaseClass, BASS_CLASS_HID
	stc
	jne	CheckMouseDone		;Br if this interface is not a HID device
	cmp	es:(InterfaceDescriptor ptr [di+bx]).SubClass, SUB_CLASS_BOOT_DEVICE
	stc
	jne	CheckMouseDone		;Br if this interface is not a boot device
	cmp	es:(InterfaceDescriptor ptr [di+bx]).Protocol, PROTOCOL_MOUSE
	stc
	jne	CheckMouseDone		;Br if this interface is not a mouse

; Set the BiosDeviceType field in DeviceTableEntry[0].  This serves as a flag
; that indicates a usable interface has been found in the current configuration.
; This is needed so we can check for other usable interfaces in the current
; configuration (i.e. composite device), but not try to search in other
; configurations.

	mov     (DeviceTableEntry ptr [si]).BiosDeviceType, BIOS_DEV_TYPE_MOUSE
	mov     (DeviceTableEntry ptr [si]).pDeviceCallback, offset cgroup:ProcessMouseData
	add     (DeviceTableEntry ptr [si]).pDeviceCallback, orgbase

; Call a common routine to handle the remaining initialization that is done
; for all devices.

	call	ConfigureNewDevice	;Finish init for new device
					; Returns CF set/clear appropriately
CheckMouseDone:
	popa
	ret
CheckForAndConfigureMouse	endp


;---------------------------------------;
; CheckForAndConfigureHub               ;
;---------------------------------------;--------------------------------------;
; This function checks an interface descriptor of a device to see if it        ;
; describes a USB hub.  If the device is a hub, then it is configured and      ;
; initialized.                                                                 ;
;                                                                              ;
; Input: ES:DI+BX = Pointer to an interface descriptor supported by device     ;
;        ES:DI+BP = Limit of the data returned by device during the last       ;
;                   Get Configuration Descriptor command                       ;
;        DS:SI = Pointer to DeviceTableEntry[0] which contains some info       ;
;                from the device, config, and interface descriptors            ;
;                                                                              ;
; Output: CF = Set if hub was not found                                        ;
;              Clear if hub was found and initialized                          ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
CheckForAndConfigureHub	proc near
	pusha

; ES:DI+BX points to an InterfaceDescriptor.  Check its BaseClass, SubClass,
; and Protocol fields for a hub device.

; Samsung & Acer hub have class info in device desc (and 00s here)..........................
	cmp	es:(InterfaceDescriptor ptr [di+bx]).BaseClass, BASE_CLASS_HUB
	stc
	jne	CheckHubDone		;Br if this interface is not a hub device

; Many hubs don't have subclass
;	cmp	es:(InterfaceDescriptor ptr [di+bx]).SubClass, SUB_CLASS_HUB
;	stc
;	jne	CheckHubDone		;Br if this interface is not a hub device

; Set the BiosDeviceType field in DeviceTableEntry[0].  This serves as a flag
; that indicates a usable interface has been found in the current configuration.
; This is needed so we can check for other usable interfaces in the current
; configuration (i.e. composite device), but not try to search in other
; configurations.

	mov     (DeviceTableEntry ptr [si]).BiosDeviceType, BIOS_DEV_TYPE_HUB
	mov     (DeviceTableEntry ptr [si]).pDeviceCallback, offset cgroup:ProcessHubData
	add     (DeviceTableEntry ptr [si]).pDeviceCallback, orgbase

; Call a common routine to handle the remaining initialization that is done
; for all devices.

	call	ConfigureNewDevice	;Finish init for new device
					; Returns CF set/clear appropriately
CheckHubDone:
	popa
	ret
CheckForAndConfigureHub	endp


;---------------------------------------;
; ConfigureNewDevice                    ;
;---------------------------------------;--------------------------------------;
; This device completes the initialization of USB devices once they have been  ;
; identified.                                                                  ;
;                                                                              ;
; Input: ES:DI+BX = Pointer to an interface descriptor supported by device     ;
;        ES:DI+BP = Limit of the data returned by device during the last       ;
;                   Get Configuration Descriptor command                       ;
;        DS:SI = Pointer to DeviceTableEntry[0] which contains some info       ;
;                from the device, config, and interface descriptors            ;
;                                                                              ;
; Output: CF = Set if device was not initialized successfully                  ;
;              Clear if device was initialized successfully                    ;
;                                                                              ;
; Destroys: Nothing                                                            ;
;------------------------------------------------------------------------------;
ConfigureNewDevice	proc near
	pusha
	push	es

; First find a free entry in the DeviceTable.  Select a entry number in the range
; MIN_xxx_DEVICE_INDEX - MAX_xxx_DEVICE_INDEX.  The index into the DeviceTableEntry
; array no longer corresponds to the address assigned to the new device.

	mov	dx, di			;Save DI+BX = ptr to Interface desc

	mov	di, offset DeviceTable	;DI = ptr to DeviceTable[0]
	add	di, MIN_HID_DEVICE_INDEX * size DeviceTableEntry
	mov	cl, MIN_HID_DEVICE_INDEX ;CL will count device addresses
	mov	ch, MAX_HID_DEVICE_INDEX ;CH is is max device address

	cmp	(DeviceTableEntry ptr [si]).BiosDeviceType, BIOS_DEV_TYPE_HUB
	jne	ConfigNewNextEntry	;Br if new device is not a hub

	mov	di, offset DeviceTable	;DI = ptr to DeviceTable[0]
	add	di, MIN_HUB_DEVICE_INDEX * size DeviceTableEntry
	mov	cl, MIN_HUB_DEVICE_INDEX ;CL will count device addresses
	mov	ch, MAX_HUB_DEVICE_INDEX ;CH is is max device address

ConfigNewNextEntry:
	cmp	(DeviceTableEntry ptr [di]).Present, TRUE
	jne	ConfigNewFoundEntry	;Br if found unused entry
	inc	cl			;Inc device address
	add	di, size DeviceTableEntry
	cmp	cl, ch
	jbe	ConfigNewNextEntry	;Br if not to end of DeviceTable
	jmp	ConfigNewSkipInterface	;No free entry was found so abort

; DI now points to a free DeviceTable entry.  Since DeviceTableEntry[0] (at SI)
; already has many fields filled in, the new entry should be initialized with a
; copy of DeviceTableEntry[0].  But, the new DeviceTableEntry should not be
; marked as "present" until the device is successfully initialized.

ConfigNewFoundEntry:
	mov	ax, (DeviceTableEntry ptr [di]).TdPoolPtr ;Save TdPoolPtr
	shl	eax,16
	mov	ax, (DeviceTableEntry ptr [di]).EdPoolPtr ;Save EdPoolPtr
	push	es			;Save ES
	push	ds			;Set ES = DS
	pop	es
	push	di			;Save ptr to new DeviceTableEntry
	mov	cx, size DeviceTableEntry
	rep	movsb
	pop	si			;SI = ptr to new DeviceTableEntry
	pop	es			;Restore ES

	mov	di, dx			;Restore DI+BX = ptr to Interface desc
	mov	(DeviceTableEntry ptr [si]).Present, FALSE
	mov	(DeviceTableEntry ptr [si]).EdPoolPtr, ax ;Restore EdPoolPtr
	shr	eax,16
	mov	(DeviceTableEntry ptr [si]).TdPoolPtr, ax ;Restore TdPoolPtr

; Adjust BX so that ES:DI+BX points to the next descriptor, abort if we're past
; the end of the data.

	movzx	ax, es:(InterfaceDescriptor ptr [di+bx]).DescLength
	add	bx, ax			;BX = ptr to next desc
	cmp	bx, bp
	jae	ConfigNewSkipInterface	;Br if past end of data

; ES:DI+BX should now point to an EndpointDescriptor.  If it does not, search
; down until we either find an EndpointDescriptor or go past the limit in BP.

ConfigNewNextDesc :
	cmp	es:(EndpointDescriptor ptr [di+bx]).DescType, DESC_TYPE_ENDPOINT
	je	ConfigNewFoundEndpoint	;Br if on an endpoint desc
	movzx	ax, es:(EndpointDescriptor ptr [di+bx]).DescLength
	or	ax, ax
	jz	ConfigNewSkipInterface	;Br if 0 length desc (should never happen, but...)
	add	bx, ax			;BX = ptr to next desc
	cmp	bx, bp
	jb	ConfigNewNextDesc	;Br if not past end of data
	jmp	ConfigNewSkipInterface	;Br if endpoint desc was not found

; Save some of the fields from the EndpointDescriptor into the DeviceTable
; entry for this device.

ConfigNewFoundEndpoint:
	mov	al, es:(EndpointDescriptor ptr [di+bx]).EndpointAddr
	and	al, EP_DESC_ADDR_EP_NUM
	mov	(DeviceTableEntry ptr [si]).EndpointNum, al

; Do a SetConfiguration command to the device to set it to its
; HID/Boot configuration.

	mov	al, (DeviceTableEntry ptr [si]).DeviceAddress ;AL = device address
	mov	ah, 0			;Send command to endpoint 0 on device
	movzx	cx, (DeviceTableEntry ptr [si]).ConfigNum
	call	_UsbSetConfiguration	;Set config of device/endp AL/AH to CX
	jc	ConfigNewSkipInterface	;Br if error during command

; If the new device is a hub, then do some hub specific initialization.

	mov	ah, (DeviceTableEntry ptr [si]).BiosDeviceType
	cmp	ah, BIOS_DEV_TYPE_HUB
	jne	ConfigNewNotHub		;Br if new device is not a hub

	; Do a GetDescriptor call to get the hub's HubDescriptor and save some
	; fields from this descriptor in the DeviceTableEntry.

	push	si			;Save ptr to device table entry

	mov	al, (DeviceTableEntry ptr [si]).DeviceAddress ;AL = device address
	mov	ah, 0			;Send command to endpoint 0 on device
	mov	bx, USB_RQ_GET_CLASS_DESCRIPTOR ;Request type is "Get Class Descriptor"
	mov	ch, DESC_TYPE_CLASS_HUB	;CH = Descriptor type
	mov	cl, 0
	xor	dx, dx			;DX = wIndex parameter = 0
	mov	si, MAX_CONTROL_DATA_SIZE - 1 ;SI = Max size of descriptor
	mov	di, offset DeviceRequestDataBuf ;ES:DI = ptr DeviceRequestDataBuff
	call	UsbDeviceRequest	;Execute the device request, returns CF

	pop	si			;Restore ptr to device table entry
	jc	ConfigNewSkipInterface	;Br if error during command

	mov	al, es:(HubDescriptor ptr [di]).NumPorts ;AL = # of ports on hub
	mov	(DeviceTableEntry ptr [si]).HubNumPorts, al
	mov	al, es:(HubDescriptor ptr [di]).PowerOnDelay ;AL = Port power on delay
	mov	(DeviceTableEntry ptr [si]).HubPowerOnDelay, al
	mov	(DeviceTableEntry ptr [si]).HubEnumFlag, FALSE ;Hub's ports have not been enumerated

	; Turn on power to all of the hub's ports by setting its port power features.
	; This is needed because hubs cannot detect a device attach until port power
	; is turned on.

	mov	dx, 1			;DL will count hub ports and
					;  DX will be used as wIndex parameter
InitHubNextPort:
	mov	al, (DeviceTableEntry ptr [si]).DeviceAddress ;AL = device address
	mov	ah, 0			;Send command to endpoint 0 on device
	mov	bx, HUB_RQ_SET_PORT_FEATURE ;BX = Request type
	mov	cx, HUB_FEATURE_PORT_POWER  ;CX = wValue parameter = Feature selector
	push	si			;Save ptr to device table entry
	xor	si, si			;SI = wLength parameter = 0
	call	UsbDeviceRequest	;Execute the device request, returns CF
	pop	si			;Restore ptr to device table entry
	jc	ConfigNewSkipInterface	;Br if error during command

	inc	dx			;Next port number
	cmp	dl, (DeviceTableEntry ptr [si]).HubNumPorts
	jbe	InitHubNextPort		;Br if still more ports to power on

	;;;;; Delay the amount of time specified in the PowerOnDelay field of
	;;;;; the hub descriptor.
	;;;;
	;;;;	push	ax
	;;;;	mov	al, (DeviceTableEntry ptr [di]).HubPowerOnDelay ;In 2ms units
	;;;;	cmp	al, 5
	;;;;	jae	EnablePortDelayNext	;Br if hub's delay is >= 10ms
	;;;;	mov	al, 5			;Force delay to at least 10ms
	;;;;
	;;;;EnablePortDelayNext:
	;;;;	mov	cx, 134d		;2ms / 15us
	;;;;	call	pm_fixed_delay		;Delay 2ms
	;;;;
	;;;;	dec	al			;Dec 2ms delay counter
	;;;;	jnz	EnablePortDelayNext	;Br if not done with hub's delay
	;;;;	pop	ax

ConfigNewNotHub:

; If new device is a keyboard or mouse, notify keyboard/mouse cod

⌨️ 快捷键说明

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