OPT 2 INCLUDE kxarm.h INCLUDE option.inc INCLUDE s2440addr.inc INCLUDE memcfg.inc OPT 1 OPT 128 ; Pre-defined constants. ; USERMODE EQU 0x10 FIQMODE EQU 0x11 IRQMODE EQU 0x12 SVCMODE EQU 0x13 ABORTMODE EQU 0x17 UNDEFMODE EQU 0x1b MODEMASK EQU 0x1f NOINT EQU 0xc0 ; Stack locations. ; SVCStack EQU (_STACK_BASEADDRESS-0x2800) ; 0x33ff5800 ~ UserStack EQU (_STACK_BASEADDRESS-0x3800) ; 0x33ff4800 ~ UndefStack EQU (_STACK_BASEADDRESS-0x2400) ; 0x33ff5c00 ~ AbortStack EQU (_STACK_BASEADDRESS-0x2000) ; 0x33ff6000 ~ IRQStack EQU (_STACK_BASEADDRESS-0x1000) ; 0x33ff7000 ~ FIQStack EQU (_STACK_BASEADDRESS-0x0) ; 0x33ff8000 ~ ;------------------------------------------------------------------------------ ; Sleep state constants ; ; Location of sleep data ; BUGBUG - this needs to be declared as a local var. SLEEPDATA_BASE_PHYSICAL EQU 0x30028000 WORD_SIZE EQU 0x4 ; Sleep State memory locations SleepState_Data_Start EQU (0) SleepState_WakeAddr EQU (SleepState_Data_Start + 0) SleepState_MMUCTL EQU (SleepState_WakeAddr + WORD_SIZE) SleepState_MMUTTB EQU (SleepState_MMUCTL + WORD_SIZE) SleepState_MMUDOMAIN EQU (SleepState_MMUTTB + WORD_SIZE) SleepState_SVC_SP EQU (SleepState_MMUDOMAIN + WORD_SIZE) SleepState_SVC_SPSR EQU (SleepState_SVC_SP + WORD_SIZE) SleepState_FIQ_SPSR EQU (SleepState_SVC_SPSR + WORD_SIZE) SleepState_FIQ_R8 EQU (SleepState_FIQ_SPSR + WORD_SIZE) SleepState_FIQ_R9 EQU (SleepState_FIQ_R8 + WORD_SIZE) SleepState_FIQ_R10 EQU (SleepState_FIQ_R9 + WORD_SIZE) SleepState_FIQ_R11 EQU (SleepState_FIQ_R10 + WORD_SIZE) SleepState_FIQ_R12 EQU (SleepState_FIQ_R11 + WORD_SIZE) SleepState_FIQ_SP EQU (SleepState_FIQ_R12 + WORD_SIZE) SleepState_FIQ_LR EQU (SleepState_FIQ_SP + WORD_SIZE) SleepState_ABT_SPSR EQU (SleepState_FIQ_LR + WORD_SIZE) SleepState_ABT_SP EQU (SleepState_ABT_SPSR + WORD_SIZE) SleepState_ABT_LR EQU (SleepState_ABT_SP + WORD_SIZE) SleepState_IRQ_SPSR EQU (SleepState_ABT_LR + WORD_SIZE) SleepState_IRQ_SP EQU (SleepState_IRQ_SPSR + WORD_SIZE) SleepState_IRQ_LR EQU (SleepState_IRQ_SP + WORD_SIZE) SleepState_UND_SPSR EQU (SleepState_IRQ_LR + WORD_SIZE) SleepState_UND_SP EQU (SleepState_UND_SPSR + WORD_SIZE) SleepState_UND_LR EQU (SleepState_UND_SP + WORD_SIZE) SleepState_SYS_SP EQU (SleepState_UND_LR + WORD_SIZE) SleepState_SYS_LR EQU (SleepState_SYS_SP + WORD_SIZE) SleepState_Data_End EQU (SleepState_SYS_LR + WORD_SIZE) SLEEPDATA_SIZE EQU (SleepState_Data_End - SleepState_Data_Start) / 4 ; for S3C2440 v0.19 board ; 300MHz -> 1.1 +- 0.05 Volt ; 400MHz -> 1.2 +- 0.05 Volt ; 533MHz -> 1.35 +- 0.05 Volt ; ///////////////////////////////////////// ; // D4 D3 D2 D1 D0 ; // 0 0 1 1 1 // 1.40V/ ; // 0 1 0 0 0 // 1.35V/ ; // 0 1 0 0 1 // 1.30V ; // 0 1 0 1 0 // 1.25V ; // 0 1 0 1 1 // 1.20V ; // 0 1 1 0 0 // 1.15V ; // 0 1 1 0 1 // 1.10V ; // 0 1 1 1 0 // 1.05V ; // 0 1 1 1 1 // 1.00V ; // 1 0 0 0 1 // 0.95V ; // 1 0 0 1 1 // 0.90V ; // 1 0 1 0 1 // 0.85V ; // 1 0 1 1 1 // 0.80V GBLA CLKVAL ;CLKVAL SETA 266 ;CLKVAL SETA 296 CLKVAL SETA 399 ;CLKVAL SETA 315 ;CLKVAL SETA 399 ;CLKVAL SETA 406 ;CLKVAL SETA 530 [ CLKVAL = 406 FCLK EQU (406) PLLVAL EQU (((64 << 12) + (4 << 4) + 0)) CLKDIVVAL EQU 7 ; 0x0 = 1:1:1, 0x1 = 1:1:2, 0x2 = 1:2:2, 0x3 = 1:2:4, 0x4 = 1:4:4, 0x5 = 1:4:8, 0x6 = 1:3:3, 0x7 = 1:3:6 D4VAL EQU 0 ; 1.2 V D3VAL EQU 1 D2VAL EQU 0 D1VAL EQU 1 D0VAL EQU 1 ] [ CLKVAL = 296 FCLK EQU (296) PLLVAL EQU (((97 << 12) + (1 << 4) + 2)) CLKDIVVAL EQU 7 ; 0x0 = 1:1:1, 0x1 = 1:1:2, 0x2 = 1:2:2, 0x3 = 1:2:4, 0x4 = 1:4:4, 0x5 = 1:4:8, 0x6 = 1:3:3, 0x7 = 1:3:6 D4VAL EQU 0 ; 1.35 V D3VAL EQU 1 D2VAL EQU 0 D1VAL EQU 0 D0VAL EQU 0 ] [ CLKVAL = 299 FCLK EQU (299) PLLVAL EQU (((116 << 12) + (5 << 4) + 1)) CLKDIVVAL EQU 7 ; 0x0 = 1:1:1, 0x1 = 1:1:2, 0x2 = 1:2:2, 0x3 = 1:2:4, 0x4 = 1:4:4, 0x5 = 1:4:8, 0x6 = 1:3:3, 0x7 = 1:3:6 D4VAL EQU 0 ; 1.35 V D3VAL EQU 1 D2VAL EQU 0 D1VAL EQU 0 D0VAL EQU 0 ] [ CLKVAL = 266 FCLK EQU (266) PLLVAL EQU (((118 << 12) + (2 << 4) + 2)) CLKDIVVAL EQU 3 ; 0x0 = 1:1:1, 0x1 = 1:1:2, 0x2 = 1:2:2, 0x3 = 1:2:4, 0x4 = 1:4:4, 0x5 = 1:4:8, 0x6 = 1:3:3, 0x7 = 1:3:6 D4VAL EQU 0 ; 1.05 V D3VAL EQU 1 D2VAL EQU 0 D1VAL EQU 0 D0VAL EQU 0 ] [ CLKVAL = 315 FCLK EQU (315) PLLVAL EQU (((85 << 12) + (3 << 4) + 1)) CLKDIVVAL EQU 7 ; 0x0 = 1:1:1, 0x1 = 1:1:2, 0x2 = 1:2:2, 0x3 = 1:2:4, 0x4 = 1:4:4, 0x5 = 1:4:8, 0x6 = 1:3:3, 0x7 = 1:3:6 D4VAL EQU 0 ; 1.05 V D3VAL EQU 1 D2VAL EQU 1 D1VAL EQU 1 D0VAL EQU 0 ] [ CLKVAL = 399 FCLK EQU (399) PLLVAL EQU (((110 << 12) + (3 << 4) + 1)) CLKDIVVAL EQU 7 ; 0x0 = 1:1:1, 0x1 = 1:1:2, 0x2 = 1:2:2, 0x3 = 1:2:4, 0x4 = 1:4:4, 0x5 = 1:4:8, 0x6 = 1:3:3, 0x7 = 1:3:6 D4VAL EQU 0 ; 1.3V D3VAL EQU 1 D2VAL EQU 0 D1VAL EQU 0 D0VAL EQU 1 ] [ CLKVAL = 530 FCLK EQU (530) PLLVAL EQU (((86 << 12) + (1 << 4) + 1)) CLKDIVVAL EQU 5 ; 0x0 = 1:1:1, 0x1 = 1:1:2, 0x2 = 1:2:2, 0x3 = 1:2:4, 0x4 = 1:4:4, 0x5 = 1:4:8, 0x6 = 1:3:3, 0x7 = 1:3:6 D4VAL EQU 0 ; 1.35 V D3VAL EQU 1 D2VAL EQU 0 D1VAL EQU 0 D0VAL EQU 0 ] UPLLVAL EQU (((60 << 12) + (0x4 << 4) + 0x2)) ;48MHz ;--------------------------------------------------------------------------- ; Voltage Change function ; The LEDs are located below AMD Flash ROM MACRO VOLTAGECHANGE ldr r8, = GPBDAT ; D4 ldr r9, [r8] ldr r10, = 0x77f and r9, r9, r10 ldr r10, = (D4VAL<<7) orr r9, r9, r10 str r9, [r8] ldr r8, = GPFDAT ; D3~0 ldr r9, [r8] ldr r10, = 0x0f and r9, r9, r10 ldr r10, = ((D3VAL<<7)+(D2VAL<<6)+(D1VAL<<5)+(D0VAL<<4)) orr r9, r9, r10 str r9, [r8] ldr r8, = GPBCON ; GPB7: Output ldr r9, [r8] ldr r10, = 0x3f3fff and r9, r9, r10 ldr r10, = (1<<14) orr r9, r9, r10 str r9, [r8] ldr r8, = GPFCON ; GPF4~7: Output ldr r9, [r8] ldr r10, = 0x00ff and r9, r9, r10 ldr r10, = 0x5500 orr r9, r9, r10 str r9, [r8] ldr r8, = GPBDAT ; Latch enable ldr r9, [r8] ldr r10, = ~(0<<8) and r9, r9, r10 str r9, [r8] ldr r8, = GPBCON ; GPB8: Output ldr r9, [r8] ldr r10, = 0x3cffff and r9, r9, r10 ldr r10, = (1<<16) orr r9, r9, r10 str r9, [r8] ldr r8, = GPBDAT ; Output enable ldr r9, [r8] ldr r10, = (1<<10) orr r9, r9, r10 str r9, [r8] ldr r8, = GPBCON ; GPB10: Output ldr r9, [r8] ldr r10, = 0x0fffff and r9, r9, r10 ldr r10, = (1<<20) orr r9, r9, r10 str r9, [r8] ldr r8, = GPBDAT ; Latch disable ldr r9, [r8] ldr r10, = (1<<8) orr r9, r9, r10 str r9, [r8] MEND ;--------------------------------------------------------------------------- IMPORT main ; C entrypoint for Steppingstone loader. EXPORT MMU_EnableICache EXPORT MMU_SetAsyncBusMode STARTUPTEXT LEAF_ENTRY StartUp b ResetHandler b . b . b . b . b . b . b . PowerOffCPU str r1, [r0] ; Enable SDRAM self-refresh str r3, [r2] ; MISCCR Setting str r5, [r4] ; Power Off !! b . ; Resume handler code. ; WAKEUP_POWER_OFF ; Release SCLKn after wake-up from the POWER_OFF mode. ldr r1, =MISCCR ldr r0, [r1] bic r0, r0, #(7<<17) ; SCLK0:0->SCLK, SCLK1:0->SCLK, SCKE:L->H. str r0, [r1] ; Set up the memory control registers. ; add r0, pc, #SMRDATA - (. + 8) ldr r1, =BWSCON ; BWSCON Address. add r2, r0, #52 ; End address of SMRDATA. 3 ldr r3, [r0], #4 str r3, [r1], #4 cmp r2, r0 bne %B3 mov r0, #0x2000 4 subs r0, r0, #1 bne %B4 ;------------------------------------------------------------------------------ ; Recover Process : Starting Point ; ; 1. Checksum Calculation saved Data ldr r5, =SLEEPDATA_BASE_PHYSICAL ; pointer to physical address of reserved Sleep mode info data structure mov r3, r5 ; pointer for checksum calculation ldr r2, =0x0 ldr r0, =(SLEEPDATA_SIZE-1) ; get size of data structure to do checksum on 50 ldr r1, [r3], #4 ; pointer to SLEEPDATA and r1, r1, #0x1 mov r1, r1, ROR #31 add r2, r2, r1 subs r0, r0, #1 ; dec the count bne %b50 ; loop till done ldr r0,=GSTATUS3 ldr r3, [r0] ; get the Sleep data checksum from the Power Manager Scratch pad register cmp r2, r3 ; compare to what we saved before going to sleep bne BringUpWinCE ; bad news - do a cold boot ; 2. MMU Enable ldr r10, [r5, #SleepState_MMUDOMAIN] ; load the MMU domain access info ldr r9, [r5, #SleepState_MMUTTB] ; load the MMU TTB info ldr r8, [r5, #SleepState_MMUCTL] ; load the MMU control info ldr r7, [r5, #SleepState_WakeAddr ] ; load the LR address nop nop nop nop nop ; if software reset mov r1, #0 teq r1, r7 bne %f60 b BringUpWinCE ; wakeup routine 60 mcr p15, 0, r10, c3, c0, 0 ; setup access to domain 0 mcr p15, 0, r9, c2, c0, 0 ; PT address mcr p15, 0, r0, c8, c7, 0 ; flush I+D TLBs mcr p15, 0, r8, c1, c0, 0 ; restore MMU control ; 3. Jump to Kernel Image's fw.s (Awake_address) mov pc, r7 ; jump to new VA (back up Power management stack) nop BringUpWinCE ; bad news, data lose, bring up wince again mov r0, #2 ldr r1, =GSTATUS2 str r0, [r1] LTORG ;----------------------------------- ; Steppingstone loader entry point. ;----------------------------------- ResetHandler VOLTAGECHANGE ldr r0, = GPFCON ldr r1, = 0x55aa str r1, [r0] ldr r0, =WTCON ; disable the watchdog timer. ldr r1, =0x0 str r1, [r0] ldr r0, =INTMSK ; mask all first-level interrupts. ldr r1, =0xffffffff str r1, [r0] ldr r0, =INTSUBMSK ; mask all second-level interrupts. ldr r1, =0x7fff str r1, [r0] ; CLKDIVN ldr r0,=CLKDIVN ldr r1,=0x7 ; 0x0 = 1:1:1 , 0x1 = 1:1:2 , 0x2 = 1:2:2 , 0x3 = 1:2:4, 0x4 = 1:4:4, 0x5 = 1:4:8, 0x6 = 1:3:3, 0x7 = 1:3:6 str r1,[r0] ; BATT_FLT ldr r1, =MISCCR ldr r0, [r1] bic r0, r0, #(7<<20) orr r0, r0, #(4<<20) str r0, [r1] ; MMU_SetAsyncBusMode FCLK:HCLK= 1:2 ands r1, r1, #0x2 beq %F5 bl MMU_SetAsyncBusMode 5 ; TODO: to reduce PLL lock time, adjust the LOCKTIME register. ldr r0, =LOCKTIME ldr r1, =0xffffff str r1, [r0] ; Configure the clock PLL. ; [ PLL_ON_START ldr r0, =UPLLCON ldr r1, =UPLLVAL ; Fin=16.9344MHz, Fout=48MHz. str r1, [r0] nop nop nop nop nop nop nop nop ldr r0, =MPLLCON ldr r1, =PLLVAL str r1, [r0] mov r0, #0x2000 10 subs r0, r0, #1 bne %B10 ] ; Are we waking up from a suspended state? ; ldr r1, =GSTATUS2 ldr r0, [r1] tst r0, #0x2 ; Yes? Then go to the resume handler code... bne WAKEUP_POWER_OFF ; Set up the memory control registers. ; add r0, pc, #SMRDATA - (. + 8) ldr r1, =BWSCON ; BWSCON Address. add r2, r0, #52 ; End address of SMRDATA. 15 ldr r3, [r0], #4 str r3, [r1], #4 cmp r2, r0 bne %B15 ; Turn on all LEDs. ; ldr r0, =GPFCON ldr r1, =0x55aa str r1, [r0] ldr r0, =GPFUP ldr r1, =0xff str r1, [r0] ldr r0, =GPFDAT ldr r1, =0x0 str r1, [r0] ; If this is a cold boot or a warm reset, clear RAM because the RAM filesystem may be ; bad. If this is a software reboot (triggered by the watchdog timer), don't clear RAM. ; ldr r1, =GSTATUS2 ; Determine why we're in the startup code. ldr r10, [r1] ; str r10, [r1] ; Clear GPSTATUS2. tst r10, #0x4 ; Watchdog (software) reboot? Skip code that clears RAM. bne %F40 ; Clear RAM. ; mov r1,#0 mov r2,#0 mov r3,#0 mov r4,#0 mov r5,#0 mov r6,#0 mov r7,#0 mov r8,#0 ldr r0,=0x30000000 ; Start address (physical 0x3000.0000). ldr r9,=0x04000000 ; 64MB of RAM. 20 stmia r0!, {r1-r8} subs r9, r9, #32 bne %B20 ; Initialize stacks. ; 30 mrs r0, cpsr bic r0, r0, #MODEMASK|NOINT orr r1, r0, #SVCMODE msr cpsr_cxsf, r1 ; SVCMode. ldr sp, =SVCStack ; Jump to main C routine. ; bl main ;;; 20060404 for s/w reset 40 ; ldr r4, =0x22B784 ldr r4, =0x200000 add r4, r4, #0x30000000 mov pc, r4 b . ; b led_loop ; for debugging ; for debugging led_loop ldr r0, =GPFCON ldr r1, =0x55aa str r1, [r0] ldr r0, =GPFDAT ldr r1, =0xF0 str r1, [r0] ldr r0, =0x100000 100 subs r0, r0, #1 bne %B100 ldr r0, =GPFDAT ldr r1, =0x00 str r1, [r0] ldr r0, =0x100000 200 subs r0, r0, #1 bne %B200 b led_loop LTORG SMRDATA DATA ; Memory configuration should be optimized for best performance . ; The following parameter is not optimized. ; Memory access cycle parameter strategy ; 1) The memory settings is safe parameters even at HCLK=75Mhz. ; 2) SDRAM refresh period is for HCLK=75Mhz. ; DCD (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28)) DCD ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) ;GCS0 DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) ;GCS1 DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) ;GCS2 DCD ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) ;GCS3 DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) ;GCS4 DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) ;GCS5 DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) ;GCS6 DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) ;GCS7 DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT) DCD (0x32|0x80) ; SCLK power saving mode, BANKSIZE 128M/128M, 4-burst. DCD 0x20 ; MRSR6 CL=3clk. DCD 0x20 ; MRSR7. ;------------------------------------ ; MMU Cache/TLB/etc on/off functions ;------------------------------------ R1_I EQU (1<<12) R1_C EQU (1<<2) R1_A EQU (1<<1) R1_M EQU (1) R1_iA EQU (1<<31) R1_nF EQU (1<<30) ; void MMU_EnableICache(void); ; LEAF_ENTRY MMU_EnableICache mrc p15, 0, r0, c1, c0, 0 orr r0, r0, #R1_I mcr p15, 0, r0, c1, c0, 0 mov pc, lr ; void MMU_SetAsyncBusMode(void); ; FCLK:HCLK= 1:2 ; LEAF_ENTRY MMU_SetAsyncBusMode mrc p15, 0, r0, c1, c0, 0 orr r0, r0, #R1_nF:OR:R1_iA mcr p15, 0, r0, c1, c0, 0 mov pc, lr ; NAND code... ; A410_BASE_ADDR EQU 0x2000000 ;;; MACRO ;;; LDR4STR1 $src,$tmp1,$tmp2 ;;; ldrb $tmp1,[$src] ;;; ldrb $tmp2,[$src] ;;; orr $tmp1,$tmp1,$tmp2,LSL #8 ;;; ldrb $tmp2,[$src] ;;; orr $tmp1,$tmp1,$tmp2,LSL #16 ;;; ldrb $tmp2,[$src] ;;; orr $tmp1,$tmp1,$tmp2,LSL #24 ;;; MEND EXPORT __RdPage512 __RdPage512 ;input:a1(r0)=pPage stmfd sp!,{r1-r11} ldr r1,=0x4e000010 ;NFDATA mov r2,#0x200 10 ldr r4,[r1] ldr r5,[r1] ldr r6,[r1] ldr r7,[r1] ldr r8,[r1] ldr r9,[r1] ldr r10,[r1] ldr r11,[r1] stmia r0!,{r4-r11} subs r2,r2,#32 bne %B10 ldmfd sp!,{r1-r11} mov pc,lr END