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

📄 gxmsize.asm

📁 X86 GX1 BOOTLOAD代码 ,支持WINCE操作系统!
💻 ASM
📖 第 1 页 / 共 2 页
字号:
	mov	di, CPU_MC_BANK_CFG
	mov	es:[edi], edx			; Put in new page setting
	DO_REFRESH
	shr	si, 1				; Divide test address by 2
	jmp	pageSizeLoop

pageSizeFound:
	mov	eax, DIMM0_PAGE_CLR
	rol	eax, cl
	and	ebp, eax			; Clear page field
	mov	eax, ebx			; Save bx for next step
	shl	eax, cl				; Compensate for Dimm
	or	ebp, eax			; Set page field

;
; Component Banks   1=4  0=2
; Default for Dimm under test = 1
; Default for Dimm not under test = 0
; How it works:  The default is for 4 component banks.  Since the min page
; size is 1KB, set the test address to be 2KB, which is the 1st byte of the
; 3rd component bank.  Then multiply this by the page size just calculated.
; If data wraps at this address then there are only 2 component banks and the
; bit in MC_BANK_CFG can be reset to reflect 2 component banks.
;
	shl	ecx, 16				; Save DSV
	shr	bx, 4				; Calc page size to low nibble
	mov	esi, 0800h			; Page=1KB * compbank=2
	mov	cl, bl				; Use actual page size just
	shl	esi, cl				;  calc to set test address
	shr	ecx, 16				; Restore DSV

compBanks:
	mov	DWORD PTR es:[0], TEST_DATA1	; Write to location 0
	mov	DWORD PTR es:[esi], TEST_DATA2	; Write to top of page
	mov	DWORD PTR es:[100h], 0		; Clear the bus
	mov	eax, DWORD PTR es:[0]		; Read location 0

compVerify:
	cmp	eax, TEST_DATA1			; If TOP data, wrap occured
	je	compBanks4			; If no wrap then leave 4 comp banks
	mov	eax, DIMM0_COMP_CLR
	rol	eax, cl
	and	ebp, eax			; Comp bank = 2
	and	edx, eax			; EDX value for CPU_MC_BANK_CFG
	mov	di, CPU_MC_BANK_CFG
	mov	es:[edi], edx			; Put in comp bank setting
	DO_REFRESH
	jmp	moduleBanksCheck

compBanks4:
	mov	eax, DIMM0_COMP_SET
	rol	eax, cl
	or	ebp, eax			; Comp bank = 4

;
; Module Banks   1=2  0=1
; Default for Dimm under test = 1
; Default for Dimm not under test = 0
; How it works:  The Dimm is set for 2 Module Banks.  A write is done to the
; 2nd module bank.  The offset to write too is computed by knowing the page
; size that has been computed and the number of component banks.  So the next
; address would go to the second module bank if it exists.  If the data cannot
; be read back then it is assumed that there is no second module bank
; and the value is set to 0 in theMC_ BANK_CFG register
;
moduleBanksCheck:
	mov	esi, 0800h			; Min 1K page x 2 comp banks
	mov	eax, edx			; Isolate the page size
	shr	eax, cl
	shr	ax, 4
	and	al, 7h
	shl	ecx, 16
	mov	cl, al
	shl	esi, cl				; Multiply by actual page size
	shr	ecx, 16			
	mov	eax, edx			; Isolate comp banks
	shr	eax, cl
	shr	ax, 12
	and	ax, 1
	shl	ecx, 16
	mov	cl, al
	shl	esi, cl				; If 4 comp banks x by 2
	shr	ecx, 16

moduleBanks:
	mov	DWORD PTR es:[0], TEST_DATA1	; Write to location 0
	mov	DWORD PTR es:[esi], TEST_DATA2	; Attempt write to mod bank 2
	mov	DWORD PTR es:[100h], 0		; Clear the bus
	mov	eax, DWORD PTR es:[esi]		; Read location in 2nd Module

moduleVerify:
	cmp	eax, TEST_DATA2			; If good data then 2nd mod bank
	je	moduleBanks2			; Leave set to 2 mod banks
	mov	eax, DIMM0_MODULE_CLR
	rol	eax, cl
	and	ebp, eax			; Module bank = 1
	and	edx, eax			; EDX value for BANK_CFG
	mov	di, CPU_MC_BANK_CFG
	mov	es:[edi], edx			; Put in module bank setting
	DO_REFRESH
	jmp	dimmSize

moduleBanks2:
	mov	eax, DIMM0_MODULE_SET
	rol	eax, cl
	or	ebp, eax			; Module bank = 2

;
; DIMM Size   0=4MB  1=8MB  2=16MB  3=32MB  4=64MB  5=128MB  6=256MB  7=512MB
; Default for Dimm under test = 7
; Default for Dimm not under test = 0
;
; How it works:  We now know the page size, component banks and module banks.
; For this test just start at 512 MB and a test address of 1/2 of that.  If
; the write aliases then the size is smaller.  So keep dividing by 2 until
; the alias goes away.  The value last held in ebx is the value to program
; the dimm size field in MC_BANK_CFG
;
dimmSize:
	mov	ebx, 0700h			; Represents 512MB
	mov	esi, 10000000h			; Start at 256MB boundary

dimmSizeLoop:
	mov	DWORD PTR es:[0], TEST_DATA1	; Write to location 0
	mov	DWORD PTR es:[esi], TEST_DATA2	; Write to TOP/2
	mov	DWORD PTR es:[100h], 0		; Clear the bus
	mov	eax, DWORD PTR es:[0]		; Read location 0

dimmSizeVerify:
	cmp	eax, TEST_DATA1			; If TOP/2 data, wrap occured
	je	dimmSizeFound

	mov	di, CPU_MC_BANK_CFG
	mov	edx, es:[edi]			; BANK_CFG setting in edx
	mov	eax, DIMM0_SIZE_CLR
	rol	eax, cl
	and	edx, eax			; Clear page field
	dec	ebx
	cmp	bh, 0FFh			; Went thru all combo's
	je	failedID
	and	ebx, 700h			; Must be {0..7}
	shl	ebx, cl				; Move to Dimm word in reg
	or	edx, ebx
	shr	ebx, cl
	mov	di, CPU_MC_BANK_CFG
	mov	es:[edi], edx			; Put in new size setting
	DO_REFRESH
	shr	esi, 1				; Divide test address by 2
	jmp	dimmSizeLoop

dimmSizeFound:
	mov	eax, DIMM0_SIZE_CLR
	rol	eax, cl
	and	ebp, eax			; Clear dimm size field
	shl	ebx, cl				; Compensate for Dimm
	or	ebp, ebx			; Set dimm size field
	jmp	tryNextDimm

failedID:
	mov	eax, 0FFFF0000h			; Could not determine page
	rol	eax, cl				;  size or DIMM size
	and	ebp, eax
	mov	eax, DIMM_MISSING
	shl	eax, cl
	or	ebp, eax			; Indicate not installed

tryNextDimm:
	mov	DWORD PTR es:[0], 12345678h
	jmp	tryDimm1 			; Check next dimm

doneSizing:
	stc					; Assume no Dimms installed
	cmp	ebp,00700070h
	je	exitSizing			; No Dimms so leave carry set
	clc

exitSizing:
	mov	bx, gs				; Restore return address
	jmp	bx
csSdramAutoSize ENDP

;**************************************************************************
;*
;*      csGeodeGetMmrBase
;*
;*	Get Memory-Mapped Register Base Address (STACKLESS)
;*
;*	Entry:
;*	  None
;*
;*	Exit:
;*	  EDI - Base of memory mapped Cpu registers
;*
;*	Destroys: 
;*
;**************************************************************************
csGeodeGetMmrBase PROC NEAR PUBLIC

	;MAPEN MUST ALREADY BE ENABLED
	mov	al, CPU_GXI_GCR
	out	CPU_INDEX, al
	in	al, CPU_DATA 		; Read upper 2 addr bits from GCR reg in core
	shl	eax, 30
	mov	edi, eax

	jmp	bx
csGeodeGetMmrBase ENDP

;**************************************************************************
;*
;*	CpuMemRegRead
;*
;*	Read Data (DWORD) from Config Register (STACKLESS)
;*
;*	Entry:
;*	  EAX - Register Index
;*	  BX - Return Address
;*
;*	Exit:
;*	  EAX - Register Index
;*	  EDX - Register Data
;*	  BX - Return Address
;*
;*	Destroys: EDI
;*
;**************************************************************************
CpuMemRegRead PROC NEAR PUBLIC
;
; Generate an SMI to write the GX registers
;
	and	eax, 0000FFFFh		; Clear EAX[31:16]
	mov	edi, eax			; Save EAX

	mov	al, CPU_CCR1
	out	CPU_INDEX, al
	in	al, CPU_DATA		; VSA turns on USE_SMI. If USE_SMI is 0 then skip Soft SMI access.
	test al, 02h
	jz csRegReadMemMap

	mov	dx, 0CF8h			; PCI Index
	mov	eax, 800090D0h		; MediaGxi PFA
	out	dx, eax

	mov	eax, edi			; Restore EAX
	shl	eax, 16				; Save ax to upper eax

	mov	dx, 0CFCh
	mov	ax, -3				; Read operation
	stc						; Assume read operation fails
	out	dx, ax				; Generate software SMI

	out	0EDh, al			; Do NOT remove, required for SMI to work.

	nop						; Delay
	jc	csRegReadMemMap		; Use alternative register access
							; mechanism if VSA inactive

	mov	edx, eax			; EAX = Data Read
	mov	eax, edi			; Restore EAX
	jmp	bx					; Return to caller

csRegReadMemMap:
	mov	eax, edi			; Restore register index

	; MAPEN MUST ALREADY BE ENABLED
	mov	al, CPU_GXI_GCR
	out	CPU_INDEX, al
	in	al, CPU_DATA		; Read upper 2 addr bits from GCR
	shl	eax, 30
	mov	ax, di				; Calculate address of register
	; check if register is less than 8000h if so add 10000h to address
	; this is so we behave like the software smi
	.IF (ax < 8000h)
	  add	eax,00010000h
	.ENDIF

	mov	edx, es:[eax]		; Read data from register

	mov	eax, edi			; Restore EAX
	jmp	bx
CpuMemRegRead ENDP

;**************************************************************************
;*
;*	CpuMemRegWrite
;*
;*	Write Data (DWORD) to Config Register (STACKLESS)
;*
;*	Entry:
;*	  EAX - Register Index
;*	  EDX - Register Data
;*	  BX - Return Address
;*
;*	Exit:
;*	  EAX - Register Index
;*	  EDX - Register Data
;*	  BX - Return Address
;*
;*	Destroys:
;*	  EDI
;*
;**************************************************************************
CpuMemRegWrite PROC NEAR PUBLIC

;
; Generate an SMI to write the Geode registers
;
	and	eax, 0000FFFFh		; Clear EAX[31:16]
	mov	edi, edx			; Save register data
	shl	eax, 16				; Save register index
	mov	edx, eax			; Save register index to upper edx

	mov	al, CPU_CCR1
	out	CPU_INDEX, al
	in	al, CPU_DATA		; VSA turns on USE_SMI. If USE_SMI is 0 then skip Soft SMI access.
	test al, 02h
	jz csRegWriteMemMap

	mov	dx, 0CF8h			; PCI Index
	mov	eax, 800090D0h		; MediaGxi PFA
	out	dx, eax

	mov	eax, edx			; Restore register index

	mov	dx, 0CFCh
	mov	ax, -4				; Write operation
	stc						; Assume write operation fails
	out	dx, ax				; Generate software SMI

	out	0EDh, al			; Do NOT remove, required for SMI to work.

	nop						; Delay
	jc	csRegWriteMemMap	; Use alternative register access
							; mechanism if VSA inactive

	mov	edx, edi			; Restore register data
	shr	eax, 16				; Restore register index
	jmp	bx					; Return to caller

csRegWriteMemMap:
	shr	eax, 16				; Restore register index
	mov	edx, edi			; EDX <- Register Data
	mov	edi, eax			; Save register index

	; MAPEN MUST ALREADY BE ENABLED
	mov	al, CPU_GXI_GCR
	out	CPU_INDEX, al
	in	al, CPU_DATA		; Read upper 2 addr bits from GCR
	shl	eax, 30
	mov	ax, di				; Calculate address of register
	; check if register is less than 8000h if so add 10000h to address
	; this is so we behave like the software smi
	.IF (ax < 8000h)
	  add	eax,00010000h
	.ENDIF

	mov	es:[eax], edx		; Write data to register

	mov	eax, edi			; Restore register index
	jmp	bx

CpuMemRegWrite ENDP

;**************************************************************************
;*
;*	CpuMemRegReadStack
;*
;*	Read Data (DWORD) from Config Register
;*
;*	Entry:
;*	  EAX - Register Index
;*
;*	Exit:
;*	  EAX - Register Index
;*	  EDX - Register Data
;*
;*	Destroys:
;*	  None
;*
;**************************************************************************
CpuMemRegReadStack PROC NEAR PUBLIC
	push	eax
	push	edi
	push	es
	push	bx
	NOSTACK	bx, CpuMemRegRead
	pop	bx
	pop	es
	pop	edi
	pop	eax
	ret
CpuMemRegReadStack ENDP

;**************************************************************************
;*
;*	CpuMemRegWriteStack
;*
;*	Write Data (DWORD) to Config Register
;*
;*	Entry:
;*	  EAX - Register Index
;*	  EDX - Register Data
;*
;*	Exit:
;*	  None
;*
;*	Destroys:
;*	  None
;*
;**************************************************************************
CpuMemRegWriteStack PROC NEAR PUBLIC
	push	eax
	push	edx
	push	edi
	push	es
	push	bx
	NOSTACK	bx, CpuMemRegWrite
	pop	bx
	pop	es
	pop	edi
	pop	edx
	pop	eax
	ret
CpuMemRegWriteStack ENDP

_TEXT ENDS

	END

⌨️ 快捷键说明

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