📄 memsetup-pxa.s
字号:
@ ****************************************************************************
@ Step 5
@
@ pause for 200 uSecs
@
ldr r3, =OSCR_BASE @reset the OS Timer Count to zero
mov r2, #0
str r2, [r3]
ldr r4, =0x300 @really 0x2E1 is about 200usec, so 0x300 should be plenty
1:
ldr r2, [r3]
cmp r4, r2
bgt 1b
@****************************************************************************
@ Step 6
@
mov r0, #0x78 @turn everything off
mcr p15, 0, r0, c1, c0, 0 @(caches off, MMU off, etc.)
@ ****************************************************************************
@ Step 7
@
@ Access memory *not yet enabled* for CBR refresh cycles (8)
@ - CBR is generated for all banks
ldr r2, =SDRAM_BASE
str r2, [r2]
str r2, [r2]
str r2, [r2]
str r2, [r2]
str r2, [r2]
str r2, [r2]
str r2, [r2]
str r2, [r2]
@ ****************************************************************************
@ Step 8: NOP (enable dcache if you wanna... we dont)
@
@ ****************************************************************************
@ Step 9
@
@get memory controller base address
@
ldr r1, =MEMC_BASE
@fetch current mdcnfg value
@
ldr r3, [r1, #MDCNFG_OFFSET]
@enable sdram bank 0 if installed (must do for any populated bank)
@
orr r3, r3, #MDCNFG_DE0
@write back mdcnfg, enabling the sdram bank(s)
@
str r3, [r1, #MDCNFG_OFFSET]
@****************************************************************************
@ Step 10
@
@ write mdmrs
@
ldr r2, =MDMRS_VAL
str r2, [r1, #MDMRS_OFFSET]
@****************************************************************************
@ Step 11: Final Step
@
#ifndef A0_COTULLA
@!!! errata: don't enable auto power-down for A0
@get current value of mdrefr
@
@ldr r3, [r1, #MDREFR_OFFSET]
@enable auto-power down
@
@orr r3, r3, #MDREFR_APD
@write back mdrefr
@
@str r3, [r1, #MDREFR_OFFSET]
#endif
@ Check to see if we're coming out of sleep reset.
@ If so, jump to the resume code
ldr r0, =RCSR
ldr r1, [r0]
tst r1, #4
ldrne r0, =PSPR
ldrne r1, [r0]
movne pc, r1
@INITINTC
@********************************************************************
@ Disable (mask) all interrupts at the interrupt controller
@
@ clear the interrupt level register (use IRQ, not FIQ)
@
mov r1, #0
ldr r2, =ICLR
str r1, [r2]
@ mask all interrupts at the controller
@
ldr r2, =ICMR
str r1, [r2]
@INITCLKS
@ Turn Off ALL on-chip peripheral clocks for re-configuration
@
ldr r1, =CKEN
mov r2, #0
str r2, [r1]
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ Lubbock: Allow the user to select the {T/R/M} with predetermined
@ SDCLK. Based on Table 3-1 in PXA250 and PXA210 Dev Man.
@
@ * = Must set MDREFR.K1DB2 to halve the MemClk for desired SDCLK[1]
@
@ S25, S26 used to provide all 400 MHz BIN values for Cotulla (0,0 - 1,3)
@ S25, S26 used to provide all 200 MHz BIN values for Sabinal
@
@ S23: Force the halving of MemClk when deriving SDCLK[1]
@ DOT: no override !DOT: halve (if not already forced half)
@ *For certain MemClks, SDCLK's derivation is forced to be halved
@
@ S24: Run/Turbo.
@ DOT: Run mode !DOT: Turbo mode
@
ldr r2, =FPGA_REGS_BASE
bl GET_S25 @r0, r3 @ get the value of S25 in R0, i put the base adx of fpga in r2
bl GET_S26 @r1, r3 @ get the value of S26 in R3, i put the base adx of fpga in r2
orr r0, r0, r3 @ concatenate S25 & S26 vals
and r0, r0, #0xFF
@
@ With this info, let's set up the CCCR {T/R/M/SD} accordingly
@ *SDCLK = MEMClk/2 forced eariler
@
@ default value in case no valid rotary switch setting is found
ldr r2, =(CCCR_L27 | CCCR_M2 | CCCR_N10) @ DEFAULT: {200/200/100}
cmp r0, #0x00 @ {100/100/100/100}
ldreq r2, =(CCCR_L27 | CCCR_M1 | CCCR_N10)
cmp r0, #0x01 @ {200/100/100/100}
ldreq r2, =(CCCR_L27 | CCCR_M1 | CCCR_N20)
cmp r0, #0x02 @ {300/100/100/100}
ldreq r2, =(CCCR_L27 | CCCR_M1 | CCCR_N30)
cmp r0, #0x03 @ {118/118/118/59} *
ldreq r2, =(CCCR_L32 | CCCR_M1 | CCCR_N10)
cmp r0, #0x04 @ {236/118/118/59} *
ldreq r2, =(CCCR_L32 | CCCR_M1 | CCCR_N20)
cmp r0, #0x05 @ {354/118/118/59} *
ldreq r2, =(CCCR_L32 | CCCR_M1 | CCCR_N30)
cmp r0, #0x06 @ {133/133/133/66} *
ldreq r2, =(CCCR_L36 | CCCR_M1 | CCCR_N10)
cmp r0, #0x07 @ {266/133/133/66} *
ldreq r2, =(CCCR_L36 | CCCR_M1 | CCCR_N20)
cmp r0, #0x08 @ {399/133/133/66} *
ldreq r2, =(CCCR_L36 | CCCR_M1 | CCCR_N30)
cmp r0, #0x09 @ {148/148/148/74} *
ldreq r2, =(CCCR_L40 | CCCR_M1 | CCCR_N10)
cmp r0, #0x0A @ {296/148/148/74} *
ldreq r2, =(CCCR_L40 | CCCR_M1 | CCCR_N20)
cmp r0, #0x0B @ {166/166/166/83} *
ldreq r2, =(CCCR_L45 | CCCR_M1 | CCCR_N10)
cmp r0, #0x0C @ {332/166/166/83} *
ldreq r2, =(CCCR_L45 | CCCR_M1 | CCCR_N20)
cmp r0, #0x0D @ {200/200/100/100}
ldreq r2, =(CCCR_L27 | CCCR_M2 | CCCR_N10)
cmp r0, #0x0E @ {300/200/100/100}
ldreq r2, =(CCCR_L27 | CCCR_M2 | CCCR_N15)
cmp r0, #0x0F @ {400/200/100/100}
ldreq r2, =(CCCR_L27 | CCCR_M2 | CCCR_N20)
cmp r0, #0x10 @ {236/236/118/59} *
ldreq r2, =(CCCR_L32 | CCCR_M2 | CCCR_N10)
cmp r0, #0x11 @ {266/266/133/66} *
ldreq r2, =(CCCR_L36 | CCCR_M2 | CCCR_N10)
cmp r0, #0x12 @ {295/295/148/74} *
ldreq r2, =(CCCR_L40 | CCCR_M2 | CCCR_N10)
cmp r0, #0x13 @ {332/332/166/83} *
ldreq r2, =(CCCR_L45 | CCCR_M2 | CCCR_N10)
cmp r0, #0x14 @ {398/398/100/100} C0/Dalhart permissable
ldreq r2, =(CCCR_L27 | CCCR_M4 | CCCR_N10)
@ @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@... and write the core clock config register
@
ldr r1, =CCCR
str r2, [r1]
@ enable the 32Khz oscillator for RTC and PowerManager
@
ldr r1, =OSCC
mov r2, #OSCC_OON
str r2, [r1]
@ NOTE: spin here until OSCC.OOK get set,
@ meaning the PLL has settled.
@
60:
ldr r2, [r1]
ands r2, r2, #1
beq 60b
@OSCC_OON_DONE
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ initiate the frequency change sequence
@
@ Lubbock: Allow the user to choose whether to run in Run Mode or Turbo Mode
@ via dip S24:
@
@ DOT: Run
@ noDOT: Turbo
@
mov r1, #2 @ frequency change bit
ldr r2, =FPGA_REGS_BASE
bl GET_S24 @ r0, r2 @ 1 = DOT (Run), 0 = !DOT(Turbo)
cmp r0, #0x0 @ S23 = !DOT?
moveq r1, #3 @ If !Dot@ Turbo and f change bits set simultaneously
mcr p14, 0, r1, c6, c0, 0 @ write CCLKCFG
@ @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@#ifdef A0_COTULLA
@****************************************************************************
@ !!! Take care of A0 Errata Sighting #4 --
@ after a frequency change, the memory controller must be restarted
@
@ get memory controller base address
ldr r1, =MEMC_BASE
@ get the current state of MDREFR
@
ldr r2, [r1, #MDREFR_OFFSET]
@ clear E0PIN, E1PIN
@
bic r3, r2, #(MDREFR_E0PIN | MDREFR_E1PIN)
@ write MDREFR with E0PIN, E1PIN cleared (disable sdclk[0,1])
@
str r3, [r1, #MDREFR_OFFSET]
@ then write MDREFR with E0PIN, E1PIN set (enable sdclk[0,1])
@
str r2, [r1, #MDREFR_OFFSET]
@ get the current state of MDCNFG
@
ldr r3, [r1, #MDCNFG_OFFSET]
@ disable all SDRAM banks
@
bic r3, r3, #(MDCNFG_DE0 | MDCNFG_DE1)
bic r3, r3, #(MDCNFG_DE2 | MDCNFG_DE3)
@ write back MDCNFG
@
ldr r3, [r1, #MDCNFG_OFFSET]
@ Access memory not yet enabled for CBR refresh cycles (8)
@ - CBR is generated for *all* banks
ldr r2, =SDRAM_BASE
str r2, [r2]
str r2, [r2]
str r2, [r2]
str r2, [r2]
str r2, [r2]
str r2, [r2]
str r2, [r2]
str r2, [r2]
@ fetch current mdcnfg value
@
ldr r3, [r1, #MDCNFG_OFFSET]
@ enable sdram bank 0 if installed
@
orr r3, r3, #MDCNFG_DE0
@ write back mdcnfg, enabling the sdram bank(s)
@
str r3, [r1, #MDCNFG_OFFSET]
@ write mdmrs
@
ldr r2, =MDMRS_VAL
str r2, [r1, #MDMRS_OFFSET]
@ errata: don't enable auto power-down
@ get current value of mdrefr
@ldr r3, [r1, #MDREFR_OFFSET]
@ enable auto-power down
@orr r3, r3, #MDREFR_APD
@write back mdrefr
@str r3, [r1, #MDREFR_OFFSET]
@#endif A0_Cotulla
@ ^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%
@ ^%^%^%^%^%^%^%^%^% above could be replaced by prememLLI ^%^%^%^%^%^%^%^%^%
@ ^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%^%
// scrub/init SDRAM if enabled/present
ldr r11, =0xa0000000 //RAM_BASE // base address of SDRAM
ldr r12, =0x04000000 // size of memory to scrub
mov r8,r12 // save DRAM size
mov r0, #0 // scrub with 0x0000:0000
mov r1, #0
mov r2, #0
mov r3, #0
mov r4, #0
mov r5, #0
mov r6, #0
mov r7, #0
10: // fastScrubLoop
subs r12, r12, #32 // 32 bytes/line
stmia r11!, {r0-r7}
beq 15f
b 10b
15:
/* Mask all interrupts */
ldr r0, =ICMR
mov r1, #0
str r1, [r0]
//Disable software and data breakpoints
mov r0, #0
mcr p15,0,r0,c14,c8,0 // ibcr0
mcr p15,0,r0,c14,c9,0 // ibcr1
mcr p15,0,r0,c14,c4,0 // dbcon
//Enable all debug functionality
mov r0,#0x80000000
mcr p14,0,r0,c10,c0,0 // dcsr
ret:
mov pc, r10
@ %%%%%%%%%%% Useful subroutines
GET_S23:
@ This macro will read S23 and return its value in r3
@ r2 contains the base address of the Lubbock user registers
ldr r2, =FPGA_REGS_BASE
@ read S23's value
ldr r3, [r2, #USER_SW_OFFSET]
@ mask out irrelevant bits
and r3, r3, #0x200
@ get bit into position 0
mov r3, r3, LSR #9
mov pc, lr
@ End GET_S23
GET_S24:
@ This macro will read S24 and return its value in r0
@ r2 contains the base address of the Lubbock user registers
ldr r2, =FPGA_REGS_BASE
@ read S24's value
ldr r0, [r2, #USER_SW_OFFSET]
@ mask out irrelevant bits
and r0, r0, #0x100
@ get bit into position 0
mov r0, r0, LSR #8
mov pc, lr
@ End GET_S23
GET_S25:
@ This macro will read rotary S25 and return its value in r0
@ r2 contains the base address of the Lubbock user registers
@ read the user switches register
ldr r0, [r2, #USER_SW_OFFSET]
@ mask out irrelevant bits
and r0, r0, #0xF0
mov pc, lr
@ End subroutine
GET_S26:
@ This macro will read rotary S26 and return its value in r3
@ r2 contains the base address of the Lubbock user registers
@ read the user switches register
ldr r3, [r2, #USER_SW_OFFSET]
@ mask out irrelevant bits
and r3, r3, #0x0F
mov pc, lr
@ End subroutine GET_S26
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -