📄 sdramopt.asm
字号:
;**************************************************************************
;*
;* SDRAMOPT.ASM
;*
;* Copyright (c) 1999 National Semiconductor Corporation.
;* All Rights Reserved.
;*
;* Function:
;* Optimization for the memory controller.
;*
;* $Revision:: 1 $
;*
;**************************************************************************
.386
INCLUDE DEF.INC
INCLUDE MACROS.INC
INCLUDE PORT80.INC
INCLUDE CPU.INC
INCLUDE NSSIO.INC
INCLUDE OPTIONS.INC
INCLUDE MPC.INC
INCLUDE NVRAMTOK.INC
INCLUDE BDCFG.INC
_TEXT SEGMENT PUBLIC use16 'CODE'
EXTERN CpuMemRegReadStack:NEAR
EXTERN CpuMemRegWriteStack:NEAR
EXTERN csGetSPDByte:NEAR
EXTERN csInitI2CStack:NEAR
EXTERN CpumSDRAMReadSpd:NEAR
EXTERN CpuEnableDimm:NEAR
EXTERN GetCPUSpeed:NEAR
EXTERN GetNVRAMValue:NEAR
INCLUDE MEMTIMES.INC
EXTERN GetHRTimerSpeed:NEAR
INSTALL_NSSIO SC1x00
;**************************************************************************
;*
;* memRAMoptimize
;*
;* Set Cpu SDRAM Timing
;*
;* Entry:
;* None
;*
;* Exit:
;* None
;*
;* Destroys:
;*
;**************************************************************************
memRAMoptimize PROC NEAR PUBLIC
push bx
;
; Figure out which SDRAMOPT table to use.
;
mov cx,TOKEN_MEM_OPTIMIZE
call GetNVRAMValue
cmp al,TVALUE_MEM_OPT_CONSERVATIVE ; conservative means force pc66 timings...
; for now auto, agressive & manual select auto
je notPC100
call ckPC133
cmp al, 075h
jne notPC133
mov si, OFFSET SDRAMTimingTablePC133
jmp setupCPUspeed
notPC133:
call pc66orPc100
cmp al, 064h
;out 80h, al
jne notPC100
mov si, OFFSET SDRAMTimingTablePC100
jmp short setupCPUspeed
notPC100:
mov si, OFFSET SDRAMTimingTable
setupCPUspeed:
mov al, 056h ; Start TIMER 1
out 043h, al
mov al, 012h
out 041h, al
push si
call GetCPUSpeed ; AX = Cpu Speed Calculated uses si
pop si
xor bx, bx ; Start at beginning of table
;
; Walk the SDRAM table
;
findCpuSpeedLoop:
cmp ax, WORD PTR cs:[si] ; compare cpu speed to current dram table entry
jbe setMCRegs ; if cpu speed less than or equal to current table entry then we found correct entry
add si, SDRAMTimingEntrySize ; else go to next entry
cmp WORD PTR CS:[si],0ffffh ; if we are at the end of the table
jne findCpuSpeedLoop ; just fall thru
setMCRegs:
mov eax, CPU_MC_MEM_CNTRL1 ; must transistion start sdclk for
call CpuMemRegReadStack ; new values to take effect
and edx, SDCLK_START_CLR ; clean te bit we will toggle
call CpuMemRegWriteStack
; Set up the SDCLK shift value in MC_MEM_CNTRL2
mov eax, CPU_MC_MEM_CNTRL2
call CpuMemRegReadStack
and edx, SDCLK_SHIFT_CLR ; clear the shift value
mov ecx, DWORD PTR cs:[si+4]
or edx, ecx
call CpuMemRegWriteStack ; write new shift value
mov eax, CPU_MC_SYNC_TIM1
call CpuMemRegReadStack
mov ecx, DWORD PTR cs:[si+8]
AND edx, 0F000000Fh
OR edx, ecx
call CpuMemRegWriteStack ; write new shift value
; Set up the SDCLK ratio and the Refresh Interval in MC_MEM_CNTRL1
mov eax, CPU_MC_MEM_CNTRL1
call CpuMemRegReadStack
and edx, SDCLK_START_CLR ; set SDCLK low
call CpuMemRegWriteStack
or edx, TEST_REF_SET ; set test refresh bit
call CpuMemRegWriteStack ; run a refresh cycle
and edx, SDCLK_RATIO_CLR AND REF_INTERVAL_CLR AND TEST_REF_CLR AND XBUS_RR_CLR
mov ecx, DWORD PTR cs:[si+12]
or edx, ecx
call CpuMemRegWriteStack ; set refresh and SDRAM clk ratio
mov eax, CPU_MC_MEM_CNTRL1 ; must transistion start sdclk for
call CpuMemRegReadStack ; new values to take effect
and edx, SDCLK_START_CLR
call CpuMemRegWriteStack
or edx, SDCLK_START_SET
call CpuMemRegWriteStack
;
; See if it is possible to change the CAS Latency from the default of 3
; There is a state kept in DL which indicates if the CAS latency can be
; modified. IF (Dimm0 present & EEPROM present & Dimm1 NOT present)
; || (Dimm1 present & EEPROM present & Dimm0 NOT present)
; || (Dimm0 present & EEPROM present & Dimm1 present & EEPROM present)
; then CAS latency can be changed if the CAS latency value(s) do not conflict
; IF THE CAS LATENCY IS MODIFIED THEN AN INIT SEQUENCE MUST BE RUN
;
;
; 1st see if CAS=2 is allowed for this speed
;
test WORD PTR cs:[si+2],1 ; ok for this speed?
jz exitTiming ; nope - just exit
test WORD PTR cs:[si+2],2 ; Forced for this speed?
jz checkCas ; nope - check to see if it's allowed
mov cl,00000010b
jmp setCASLatency
checkCas:
call csInitI2CStack ; set direction of GPIO clk
xor dx, dx
xor cx, cx
push cx
push dx
mov eax, CPU_MC_BANK_CFG
call CpuMemRegReadStack
mov ax, dx
pop dx
pop cx
and ax, 070h
cmp ax, 070h
or dl, 01h
cmp BYTE PTR cs:OnBoardSDRAM[0],01h ; if 1(TRUE) then onboard
jne checkForDimm0EE
or dl, 02h
mov cl, BYTE PTR cs:OnBoardSDRAMCAS[0]
jmp checkForDimm1
checkForDimm0EE:
push cx
push dx
mov bx, 0
mov bl, cs:DimmEEPROMAddr[bx] ; array of EEPROM address
shl bl, 1
or bl, 0A0h
mov cx, 18
call csGetSPDByte ; read value is in bx
pop dx
pop cx
jc checkForDimm1
or dl, 02h
mov cl, bl ; save Dimm0 CAS latency
checkForDimm1:
push cx
push dx
mov eax, CPU_MC_BANK_CFG
call CpuMemRegReadStack
shr edx, 16
mov ax, dx
pop dx
pop cx
and ax, 070h
cmp ax, 070h
je verifyCASChange
or dl, 04h
push cx
push dx
mov bx, 1
mov bl, cs:DimmEEPROMAddr[bx] ; array of EEPROM address
shl bl, 1
or bl, 0A0h
mov cx, 18
call csGetSPDByte ; read value is in bx
pop dx
pop cx
jc verifyCASChange
or dl, 08h
mov ch, bl ; Save Dimm1 CAS latency
verifyCASChange:
and dl, 0Fh
cmp dl, 03h ; Dimm0 with EEPROM / no Dimm1
je setCASLatency
cmp dl, 0Ch ; no Dimm0 / Dimm1 with EEPROM
jne checkBoth
mov cl, ch ; checked in setCASLatench
je setCASLatency
checkBoth:
cmp dl, 0Fh ; Dimm0 with EEPROM/ Dimm1 with EEPROM
jne restartSDCLK ; just restart SDCLK
and cl, ch ; and Dimm0 and Dimm1 CAS values
setCASLatency:
test cl, 00000010b ; cas 2 supported?
jz restartSDCLK ; no!
mov eax, CPU_MC_MEM_CNTRL1
call CpuMemRegReadStack
push edx ; save mem_cntrl1 value as enabledimm trashes bit 13
mov ax, CPU_MC_SYNC_TIM1
call CpuMemRegReadStack
and edx, CAS_LATENCY_CLR AND tRCD_CLR
or edx, CAS_LATENCY_SET2 OR tRCD_SET2
call CpuMemRegWriteStack ; set CAS latency=2
NOSTACK si, CpuEnableDimm ; enable the DIMM
pop edx ; get saved mem_cntrl1 value
mov eax, CPU_MC_MEM_CNTRL1
call CpuMemRegWriteStack ; restore it
restartSDCLK:
mov eax, CPU_MC_MEM_CNTRL1
call CpuMemRegReadStack
or edx, SDCLK_START_SET ; start SDCLK
call CpuMemRegWriteStack
exitTiming:
;
; see if manual override
mov cx,TOKEN_MEM_OPTIMIZE
call GetNVRAMValue
cmp al,TVALUE_MEM_OPT_MANUAL
jne exit_manual
;************************************************************
; do manual override of timings
;************************************************************
mov eax, CPU_MC_MEM_CNTRL1 ; must transistion start sdclk for
call CpuMemRegReadStack ; new values to take effect
and edx, SDCLK_START_CLR ; clean te bit we will toggle
call CpuMemRegWriteStack
; edx has mem_ctrl1 value
; clear all bits we will change
and edx,00000000011000111111111111010111b
;MDHDCTL
mov cx,TOKEN_SDRAM_MDHDCTL
call GetNVRAMValue
and eax,0111b ; insure only bits we need
shl eax,29 ; shift to proper position
or edx,eax ; or in to saved value
;MABAHDCTL
mov cx,TOKEN_SDRAM_MABAHDCTL
call GetNVRAMValue
and eax,0111b ; insure only bits we need
shl eax,26 ; shift to proper position
or edx,eax ; or in to saved value
;MEMHDCTL
mov cx,TOKEN_SDRAM_MEMHDCTL
call GetNVRAMValue
and eax,0111b ; insure only bits we need
shl eax,23 ; shift to proper position
or edx,eax ; or in to saved value
;SDCLKRATE
mov cx,TOKEN_SDRAM_CLOCK_RATIO
call GetNVRAMValue
and eax,0111b ; insure only bits we need
shl eax,18 ; shift to proper position
or edx,eax ; or in to saved value
;2CLKADDR
mov cx,TOKEN_SDRAM_2CLKADDR
call GetNVRAMValue
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -