📄 gxmsize.asm
字号:
;**************************************************************************
;*
;* CPUSIZE.ASM
;*
;* Copyright (c) 1999 National Semiconductor Corporation.
;* All Rights Reserved.
;*
;* Function:
;* Routines for sizing the memory installed in the system. The
;* memory controller is partially configured.
;*
;* $Revision:: 2 $
;*
;**************************************************************************
;.MODEL TINY
.386
INCLUDE DEF.INC
INCLUDE MACROS.INC
INCLUDE PORT80.INC
INCLUDE CPU.INC
_TEXT SEGMENT PUBLIC use16 'CODE'
;**************************************************************************
;*
;* CpumRamAutosizeJ
;*
;* Detect SDRAM size (NOT STACKLESS)
;* This routine determines if SDRAM DIMM's are installed and
;* sets the Memory Controller appropriately.
;* 1. Set defaults in MC
;* 2. Autosize - Autosize DIMM0 and DIMM1
;* 3. Enable the DIMM's
;* 4. Setup DRAM TOP and the GBASE
;*
;* Entry:
;* BX - Standard POST task
;*
;* Exit:
;* None
;*
;**************************************************************************
memSetup PROC NEAR PUBLIC
mov fs, bx ; Save POST task pointer
PORT80 POST_MEM_SETUP ; post_70h
; Set the clock drive strength and shift value, also mask the clocks
mov ax, CPU_MC_MEM_CNTRL2
NOSTACK bx, CpuMemRegRead
and edx, SDCLK_DRIVE_CLR AND SDCLK_SHIFT_CLR
or edx, SDCLKOUT_MASK_SET OR SDCLK_MASK_SET
or edx, SDCLK_SHIFT_SET15
NOSTACK bx, CpuMemRegWrite ; Set up some ratios
PORT80 POST_MEM_SETUP2 ; post_72h
; Set the data,address,and control drive and clear ref timer and VGA wrap
mov ax, CPU_MC_MEM_CNTRL1
NOSTACK bx, CpuMemRegRead
and edx, SDCLK_START_CLR AND REF_STAGGERING_CLR AND REF_INTERVAL_CLR
and edx, SDCLK_RATIO_CLR AND 007FFFFFh AND VGA_WRAP_CLR
or edx, CNTRL_DRIVE_SET5 OR MA_DRIVE_SET5 OR MD_DRIVE_SET5
or edx, SDCLK_RATIO_SET4
NOSTACK bx, CpuMemRegWrite ; Stop the SDCLK
PORT80 POST_MEM_SETUP3 ; post_73h
; Set the register to indicate no DIMM's installed
mov ax, CPU_MC_BANK_CFG
NOSTACK bx, CpuMemRegRead
and edx, 00700070h
or edx, 00700070h
NOSTACK bx, CpuMemRegWrite ; Set up for no DIMM's installed
PORT80 POST_MEM_SETUP4 ; post_74h
; Default CAS latency to 3 until the advanced chipset config
mov ax, CPU_MC_SYNC_TIM1
NOSTACK bx, CpuMemRegRead
and edx, CAS_LATENCY_CLR AND tRCD_CLR
or edx, CAS_LATENCY_SET3 OR tRCD_SET3
NOSTACK bx, CpuMemRegWrite ; Set CAS latency=3
PORT80 POST_MEM_SIZE ;post_75h
;
; Memory sizing
;
NOSTACK bx, csSDRAMAutoSize ; Value for MC_BANK in ebp
mov edx, ebp
mov ax, CPU_MC_BANK_CFG
NOSTACK bx, CpuMemRegWrite
cmp ebp, 00700070h
jne sizeDone
PORT80 POST_MEM_SETUP_FAIL ; post_7fh
; this routine just toggles all of the address & data lines in memory for
; diagnostic purposes - you can put a scope on each line make sure they're toggling;
begintoggle:
mov ax, 0
mov ds, ax
mov si, ax
mov al, 01
mov cx, 0ffffh
nextaddr:
mov ds:[si], al
rol al, 1
inc si
loop nextaddr
jmp begintoggle
sizeDone:
PORT80 POST_MEM_ENABLE ;post_76h
NOSTACK bx, csGeodeGetMmrBase ; Base is in edi destroys eax
DO_REFRESH ; If do this with no mem, will lock up here
NOSTACK si, CpuEnableDimm ; Enable the DIMM
NOSTACK bx, CpumPostRamAutosize
PORT80 POST_MEM_SETUP_GOOD ; post_7eh
mov bx, fs ; Restore POST task pointer
jmp bx
memSetup ENDP
;**************************************************************************
;*
;* CpumPostRamAutosize
;*
;* Set the CMOS value if ConfigFailed and set CPU_BC_DRAM_TOP and
;* CPU_MC_GBASE_ADD
;*
;* Entry:
;* None
;*
;* Exit:
;* None
;*
;* Destroys:
;* Upper EBX, EBP, ECX, EAX, ESI, EDX
;* All other registers preserved.
;*
;**************************************************************************
CpumPostRamAutosize PROC NEAR PUBLIC
mov ebp, ebx
mov ax, CPU_MC_BANK_CFG ; Put address in eax
NOSTACK bx, CpuMemRegRead ; Read DIMM info
mov esi, edx
shr edx, 4 ; Save page size of DIMM0
mov ax, dx
and ax, 7
mov edx, esi
shr edx, 8 ; Save DIMM0 size
mov ax, dx
and ax, 7
mov edx, esi ; Save page size of DIMM1
shr edx, 20
mov ax, dx
and ax, 7
mov edx, esi ; Save DIMM1 size
shr edx, 24
mov ax, dx
and ax, 7
mov ax, CPU_MC_SYNC_TIM1 ; Put address in eax
NOSTACK bx, CpuMemRegRead
xchg esi, edx ; Restore edx
shr esi, 28 ; Save CAS latency
mov ax, si
and ax, 7
postRamDone:
mov ax, CPU_MC_BANK_CFG ; Get DIMM info
NOSTACK bx, CpuMemRegRead ; Read bank
xor eax, eax
xor esi, esi
mov ebx, edx ; Determine if any mem in Dimm0
shr ebx, 4 ; by looking at Page field
and ebx, 7
cmp bl, 7
je noDimm0
mov eax, 400000h ; Start at 4MB since this is min
mov ecx, edx
shr ecx, 8
and cl, 7
shl eax, cl ; Multiply 4MB by [10:8] value
mov esi, eax ; ESI holds total mem size
noDimm0:
mov ebx, edx ; Determine if any mem in Dimm1
shr ebx, 20 ; by looking at Page field
and ebx, 7
cmp bl, 7
je setDramTop
mov eax, 400000h ; Start at 4MB
mov ecx, edx
shr ecx, 24
and cl, 7
shl eax, cl ; Multiply 4MB by [10:8] value
add esi, eax ; ESI holds total mem size
setDramTop:
dec esi
mov edx, esi
mov ax, CPU_BC_DRAM_TOP
NOSTACK bx, CpuMemRegWrite
inc esi ; Set GBASE_ADD while here
mov ax, CPU_MC_GBASE_ADD
NOSTACK bx, CpuMemRegRead
and edx, 0FFFFF000h
shr esi, 19
or edx, esi
NOSTACK bx, CpuMemRegWrite
mov ebx, ebp
jmp bx
CpumPostRamAutosize ENDP
;**************************************************************************
;*
;* CpuEnableDimm
;*
;* Enable and program the DIMM interface.
;*
;* Entry:
;* BX[31:16] - Standard POST task
;* SI - Return Address
;*
;* Exit:
;* BX[31:16] - Standard POST task
;* SI - Return Address
;*
;* Destroys:
;* AX, BX, CX, EDX, EDI
;*
;**************************************************************************
CpuEnableDimm PROC NEAR PUBLIC
shl esi, 16 ; Save return address
;
; Start the SDCLK's
;
mov ax, CPU_MC_MEM_CNTRL1 ; Start SDRAM clock
NOSTACK bx, CpuMemRegRead
and edx, SDCLK_START_CLR
NOSTACK bx, CpuMemRegWrite
or edx, SDCLK_START_SET
NOSTACK bx, CpuMemRegWrite
;
; Unmask the SDCLK's - may want to unumask only clocks used for pwr savings
;
mov ax, CPU_MC_MEM_CNTRL2 ; Unmask the clock
NOSTACK bx, CpuMemRegRead
and edx, SDCLK_MASK_CLR AND SDCLKOUT_MASK_CLR
NOSTACK bx, CpuMemRegWrite
;
; Wait for clocks to unmask
;
mov cx, ENABLEDIMMWAIT1
delaySome:
IOPAUSE
loop delaySome
;
; Perform 8 Refreshes
;
mov ax, CPU_MC_MEM_CNTRL1 ; Read the control register
NOSTACK bx, CpuMemRegRead
mov cx, NUM_REFRESH
or edx, TEST_REF_SET
refLoop1:
NOSTACK bx, CpuMemRegWrite ; Perform a test refresh cycle
loop refLoop1
and edx, TEST_REF_CLR
;
; Perform the Mode Set Register command
;
and edx, PROGRAM_SDRAM_CLR
NOSTACK bx, CpuMemRegWrite
or edx, PROGRAM_SDRAM_SET OR 00002000h ; Set refresh timing
NOSTACK bx, CpuMemRegWrite ; Program the SDRAM
and edx, PROGRAM_SDRAM_CLR
NOSTACK bx, CpuMemRegWrite
;
; Perform 8 Refreshes after doing MRS
;
mov cx, NUM_REFRESH
or edx, TEST_REF_SET
refLoop2:
NOSTACK bx, CpuMemRegWrite ; Perform a test refresh cycle
loop refLoop2
and edx, TEST_REF_CLR
NOSTACK bx, CpuMemRegWrite ; Clear the test refresh
mov cx, ENABLEDIMMWAIT2
delaySome2:
IOPAUSE
loop delaySome2
shr esi, 16 ; Restore return address
jmp si
CpuEnableDimm ENDP
;**************************************************************************
;*
;* csSdramAutoSize
;*
;* Autosize both DIMMS (STACKLESS)
;*
;* Entry:
;* BX - Return address
;* ES - Points to flat 4GB space
;*
;* Exit:
;* Upon success:
;* EBP = value to put in CPU_MC_BANK_CFG
;* Carry Clear
;* No Dimms:
;* EBP = 00700070h
;* Carry Set
;*
;* Destroys:
;* GS, EAX, BX, ECX, EDX, ESI, EDI, EBP
;* All other registers preserved.
;*
;**************************************************************************
csSdramAutoSize PROC NEAR PUBLIC
mov gs, bx ; Save return address
NOSTACK bx, csGeodeGetMmrBase ; Base is in edi
;
; Dimm under test set to Module Bank=1, Comp Bank=4, Page=16KB, Size=512MB
;
mov edx, 57405740h ; Make it the largest for MRS purposes
mov di, CPU_MC_BANK_CFG
mov es:[edi], edx ; Write the new value to MC
NOSTACK si, CpuEnableDimm ; Program the DIMM's
mov edx, 00705740h ; Set up DIMM0
mov ebp, 00700070h ; Default to no DIMMs installed
mov cx, 0 ; This is the Dimm Shift Value
NOSTACK bx, csGeodeGetMmrBase ; Base is in edi
;
; Test Dimm0 first then Dimm1
; Check mem location 0 to see if a mem module is installed
;
testForDimm:
cmp cx, 32
je doneSizing
mov di, CPU_MC_BANK_CFG
mov es:[edi], edx ; Write the new value to MC
DO_REFRESH ; Destroys eax,di
mov DWORD PTR es:[0], TEST_DATA1 ; Write data to location 0
mov DWORD PTR es:[100h], 0 ; Clear the bus since has keepers
mov eax, DWORD PTR es:[0] ; Read data from location 0
mov DWORD PTR es:[0], 0 ; Clear the bus since has keepers
testVerify:
cmp eax, TEST_DATA1
je startSizing ; There is a DIMM so size it
tryDimm1:
add cx, 16
mov edx, 57400070h ; BANK_CFG for DIMM1 check
jmp testForDimm
;
; Page Size 4=16KB 3=8KB 2=4KB 1=2KB 0=1KB
; Default for Dimm under test = 4
; Default for Dimm not under test = 7 (not installed)
; How it works: Start with a page size of 16KB which is represented if the
; value in ebx were placed in the BANK_CFG register for Dimm0. So the first
; address to test = 8KB, which is the 1st byte of the 2nd half of the the 16KB
; page. If there is a wrap then the page size is wrong so go from 16KB to
; 8KB and halve the test address. When a wrap is not seen then bx will hold
; the value indicating page size. The bit field in MC_BANK_CFG to write is
; determined by using the value in ebx and the DSV
; (Dimm Shift Value - 0 for Dimm0 and 16 for Dimm1)
;
startSizing:
mov ebx, 0040h ; Represents 16KB page if in low word of BANK_CFG
mov esi, 2000h ; First test at 8KB boundary
pageSizeLoop:
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
mov DWORD PTR es:[ 0], 0 ; Clear location 0
pageVerify:
cmp eax,TEST_DATA1 ; If TOP/2 data then wrap occured
je pageSizeFound
mov di, CPU_MC_BANK_CFG
mov edx, es:[edi] ; BANK_CFG setting in edx
mov eax, DIMM0_PAGE_CLR
rol eax, cl
and edx, eax ; Clear page field
dec ebx
cmp bl, 0FFh
je failedID ; Went thru 4,3,2,1,0
and ebx, 70h ; Must be {0..7}
shl ebx, cl ; Move to Dimm word in reg
or edx, ebx
shr ebx, cl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -