/* ***************** reset.s ****************************************/ /* SBC-DBG crt0 for ARMCortex-A9. /* /* /* (c) OJSC ELVEES, multicore.ru /* /* *******************************************************************/ /*================================================================== /* BootROM Program (c) Elvees 2013 /*================================================================== */ .text .code 32 .global _start .global _end .global _get_cpu_id .global _invalidate_l1_it_cache .global _invalidate_l1_data_cache .global _enable_I_cache .global _enable_cache .global _disable_cache /************Defines***************************************************/ .equ PMCTR_BASE, 0x38095000 .equ WARM_RST_EN, 0x02c .equ WARM_RST_STATUS, 0x044 .equ PDM_RST_STATUS, 0x048 .equ ALWAYS_MISC0, 0x070 .equ DDR_PIN_RET, 0x024 .equ DDR_INIT_END, 0x028 .equ CORE_PWR_UP, 0x080 .equ GATE_CORE_CTR, 0x38094048 .equ GATE_SYS_CTR, 0x3809404c .equ SEL_APLL, 0x38094100 .equ POINTER_DDR0, 0x20000020 .equ DDR_REMAP, 0x3809600c /**********************************************************************/ .func _start /*=================================================================== /* Entry point /*=================================================================== */ _start: B _reset LDR pc, =0x20000004 LDR pc, =0x20000008 LDR pc, =0x2000000c LDR pc, =0x20000010 LDR pc, =0x20000014 LDR pc, =0x20000018 LDR pc, =0x2000001c .align 4 /* re-align to the word boundary */ _reset: /*choose at which type of reset we are*/ LDR r3, =PMCTR_BASE LDR r0, =0x1 STR r0, [r3, #CORE_PWR_UP] LDR r4, =GATE_CORE_CTR LDR r0, [r4] ORR r0, r0, #0x1 /*Enable L0_CLK*/ STR r0, [r4] LDR r4, =GATE_SYS_CTR LDR r0, [r4] ORR r0, r0, #0x1 /*Enable SYS_CLK*/ STR r0, [r4] _cold_reset: /*================================================================== /* Disable caches, MMU and branch prediction /*==================================================================*/ /* Read CP15 System Control register */ MRC p15, 0, r0, c1, c0, 0 /* Clear I bit 12 to disable I Cache*/ /* Clear C bit 2 to disable D Cache*/ /* Clear M bit 0 to disable MMU*/ /* Clear Z bit 11 to disable branch prediction*/ LDR r1, =0x1805 BIC r0, r1 MCR p15, 0, r0, c1, c0, 0 /* Write value back to CP15 System Control register*/ /* Init stacks */ BL set_cpu_stack /* Enable NEON */ MRC p15,0,r0,c1,c0,2 // Read CP Access register ORR r0,r0,#0x00f00000 // Enable full access to NEON/VFP (Coprocessors 10 and 11) MCR p15,0,r0,c1,c0,2 // Write CP Access register ISB MOV r0,#0x40000000 // Switch on the VFP and NEON hardware VMSR FPEXC,r0 // Set EN bit in FPEXC go_to_main: LDR r12, =main BX r12 .endfunc .func _get_cpu_id /*=================================================================== /* Get number of core /*=================================================================== */ _get_cpu_id: MRC p15, 0, r0, c0, c0, 5 /* Read CPU ID register*/ ANDS r0, r0, #0x03 /* Mask off, leaving the CPU ID field*/ MOV pc, lr .endfunc .func set_cpu_stack /*=================================================================== /* Init cpu0, cpu1 stacks /*=================================================================== */ set_cpu_stack: MOV r12, r14 MRC p15, 0, r0, c0, c0, 5 /* Read CPU ID register*/ ANDS r0, r0, #0x03 /* Mask off, leaving the CPU ID field*/ BEQ set_cpu0_stack set_cpu1_stack: MSR CPSR_c, 0x12 /* IRQ Mode */ LDR sp, =__irq_stack1_top__ /* IRQ Stack*/ MSR CPSR_c, 0xD3 /* Supervisor Mode*/ LDR sp, =__svc_stack1_top__ /* SVC Stack*/ MOV pc, r12 set_cpu0_stack: MSR CPSR_c, 0x12 /* IRQ Mode */ LDR sp, =__irq_stack0_top__ /* IRQ Stack*/ MSR CPSR_c, 0xD3 /* Supervisor Mode*/ LDR sp, =__svc_stack0_top__ /* SVC Stack*/ MOV pc, r12 .endfunc .func _invalidate_l1_it_cache /*=================================================================== /* Invalidate L1 instruction cache /*=================================================================== */ _invalidate_l1_it_cache: STMFD sp!,{r0, r14} MOV r0, #0 /* SBZ*/ MCR p15, 0, r0, c7, c5, 0 /* ICIALLU - Invalidate instruction cache and flush branch target cache*/ LDMFD sp!,{r0, pc} .endfunc .func _invalidate_l1_data_cache /*=================================================================== /* Invalidate L1 data cache /*=================================================================== */ _invalidate_l1_data_cache: STMFD sp!,{r0-r11, r14} /*================================================================== /* Cache Invalidation code for Cortex-A9 /*================================================================== */ /* Invalidate Data/Unified Caches*/ DMB MRC p15, 1, r0, c0, c0, 1 /* Read CLIDR*/ ANDS r3, r0, #0x07000000 /* Extract coherency level*/ MOV r3, r3, LSR #23 /* Total cache levels << 1*/ BEQ Finished /* If 0, no need to clean*/ MOV r10, #0 /* R10 holds current cache level << 1*/ Loop1: ADD r2, r10, r10, LSR #1 /* R2 holds cache "Set" position */ MOV r1, r0, LSR r2 /* Bottom 3 bits are the Cache-type for this level*/ AND r1, r1, #7 /* Isolate those lower 3 bits*/ CMP r1, #2 BLT Skip /* No cache or only instruction cache at this level*/ MCR p15, 2, r10, c0, c0, 0 /* Write the Cache Size selection register*/ ISB /* ISB to sync the change to the CacheSizeID reg*/ MRC p15, 1, r1, c0, c0, 0 /* Reads current Cache Size ID register*/ AND r2, r1, #7 /* Extract the line length field*/ ADD r2, r2, #4 /* Add 4 for the line length offset (log2 16 bytes)*/ LDR r4, =0x3FF ANDS r4, r4, r1, LSR #3 /* R4 is the max number on the way size (right aligned)*/ CLZ r5, r4 /* R5 is the bit position of the way size increment*/ LDR r7, =0x7FFF ANDS r7, r7, r1, LSR #13 /* R7 is the max number of the index size (right aligned)*/ Loop2: MOV r9, r4 /* R9 working copy of the max way size (right aligned)*/ Loop3: ORR r11, r10, r9, LSL r5 /* Factor in the Way number and cache number into R11*/ ORR r11, r11, r7, LSL r2 /* Factor in the Set number*/ MCR p15, 0, r11, c7, c6, 2 /* Invalidate by Set/Way*/ SUBS r9, r9, #1 /* Decrement the Way number*/ BGE Loop3 SUBS r7, r7, #1 /* Decrement the Set number*/ BGE Loop2 Skip: ADD r10, r10, #2 /* increment the cache number*/ CMP r3, r10 BGT Loop1 Finished: /*MOV r10, #0 /* swith back to cache level 0 */ /*MCR p15, 2, r10, c0, c0, 0 /* select current cache level in cssr */ DSB ISB LDMFD sp!,{r0-r11, pc} .endfunc .func _enable_cache /*=================================================================== /* Enable all caches /*=================================================================== */ _enable_cache: STMFD sp!,{r0, r14} /* Invalidate the cache */ /* BL _invalidate_l1_it_cache */ /*================================================================== /* Enable I cache and branch prediction /*================================================================== */ MRC p15, 0, r0, c1, c0, 0 /* Read System Control Register*/ ORR r0, r0, #(0x1 << 12) /* Set I bit 12 to enable I Cache*/ ORR r0, r0, #(0x1 << 11) /* Set Z bit 11 to enable branch prediction*/ MCR p15, 0, r0, c1, c0, 0 /* Write System Control Register*/ /*BL _invalidate_l1_data_cache*/ /*BL _invalidate_l1_data_cache_example */ /*================================================================== /* Enable D cache /*================================================================== */ MRC p15, 0, r0, c1, c0, 0 /* Read System Control Register*/ ORR r0, r0, #(0x1 << 2) /* Set C bit 2 to enable D Cache*/ MCR p15, 0, r0, c1, c0, 0 /* Write System Control Register*/ DSB ISB LDMFD sp!,{r0, pc} .endfunc .func _enable_I_cache /*================================================================== /* Enable I cache and branch prediction /*================================================================== */ _enable_I_cache: STMFD sp!,{r0, r14} /* Invalidate the cache */ /* BL _invalidate_l1_it_cache */ MRC p15, 0, r0, c1, c0, 0 /* Read System Control Register*/ /* Set I bit 12 to enable I Cache*/ /* Set Z bit 11 to enable branch prediction*/ ORR r0, r0, #0x1800 MCR p15, 0, r0, c1, c0, 0 /* Write System Control Register*/ /*BL _invalidate_l1_data_cache*/ /*BL _invalidate_l1_data_cache_example */ DSB ISB LDMFD sp!,{r0, pc} .endfunc .func _disable_cache /*=================================================================== /* Disable all caches /*=================================================================== */ _disable_cache: STMFD sp!,{r1, r14} MRC p15, 0, r1, c1, c0, 0 /* Read System Control Register configuration data */ /* instruction cache disable */ BIC r1, r1, #0x1000 /* data cache disable */ BIC r1, r1, #0x4 MCR p15, 0, r1, c1, c0, 0 /* disabled cache RAMs */ LDMFD sp!,{r1, pc} .endfunc _end: .end