1/* 2 * Platform-specific assembly head 3 * intended to perform whatever fixup is needed 4 * adter the boot loader. 5 * Also includes the secondary entry point for SMP. 6 */ 7 8 9#include <linux/linkage.h> 10#include <linux/init.h> 11 12#include <asm/assembler.h> 13#include <asm/system.h> 14#include <asm/memory.h> 15#include <asm/mach-types.h> 16#include <plat/plat-bcm5301x.h> 17#include <armca9_core.h> 18 19#ifndef CONFIG_DEBUG_LL 20ENTRY(printch) 21 mov pc,lr 22ENDPROC(printch) 23 24ENTRY(printhex8) 25 mov pc,lr 26ENDPROC(printhex8) 27#endif 28 29/* 30 * This is called from head.S at the beginning. 31 * If the boot monitor provides corect r1, r2 values 32 * then these need to be preserved. 33 * 34 * On return, the requirements are: 35 * MMU = off, D-cache = off, I-cache = dont care, 36 * r0 = 0, r1 = machine nr, r2 = atags pointer, or 0. 37 */ 38 __HEAD 39ENTRY(__mach_head_fixup) 40 mov r12,lr @ save return address 41 @ Disable d-chace and MMU for UART to work for sure 42 mrc p15, 0, r0, c1, c0, 0 @ Read SCTLR 43 bic r0, #CR_C|CR_M 44 mcr p15, 0, r0, c1, c0, 0 @ Write SCTLR 45 /* Clean up any residule in caches */ 46 bl v7_all_dcache_invalidate 47 mov r0, #'.' 48 bl printch 49 mov r0,#0 50 ldr r3, =L2CC_BASE_PA @ L2 cache controller, control reg 51 str r0, [r3, #0x100] @ Disable L2 cache 52 ldr r0, =0xffff 53 str r0, [r3, #0x77c] @ Invalidate by all Ways 54 nop 55 mov r0, #'.' 56 bl printch 57 /* fixup MaskROM LUT holding pen */ 58 ldr r1, =SOC_ROM_BASE_PA 59 ldr r0, =0xffff002c 60 str r0, [r1, #SOC_ROM_LUT_OFF] 61 nop 62 63 /* disable CCU clock gating */ 64 ldr r0,=IHOST_PROC_CLK_CORE0_CLKGATE 65 ldr r1,=0x00010303 66 str r1,[r0] 67 ldr r0,=IHOST_PROC_CLK_CORE1_CLKGATE 68 ldr r2,=0x00000303 69 str r2,[r0] 70 ldr r0,=IHOST_PROC_CLK_ARM_SWITCH_CLKGATE 71 str r1,[r0] 72 ldr r0,=IHOST_PROC_CLK_ARM_PERIPH_CLKGATE 73 str r1,[r0] 74 ldr r0,=IHOST_PROC_CLK_APB0_CLKGATE 75 str r1,[r0] 76 77 78#ifndef CONFIG_XIP_KERNEL 79 /* Copy ourselves to RAM if loaded in wrong address */ 80 mov r0, #0xff000000 81 orr r0, #0x00ff0000 82 mov r8, pc 83 and r8, r8, r0 84 ldr r9, =ddr_phys_offset_va 85 ldr r10, =PAGE_OFFSET 86 sub r9, r9, r10 87 ldr r10, =CONFIG_DRAM_BASE 88 add r9, r9, r10 89 ldr r9, [r9, #0x0] 90 and r9, r9, r0 91 cmp r8, r9 92 beq 5f 93 ldr r12, =TEXT_OFFSET 94 add r9, r9, r12 95 mov r12, r9 @ start again in RAM 96 /* The __bss_start is located at < 128MB address */ 97 ldr r10, =__bss_start 98 ldr r3, =PAGE_OFFSET 99 sub r10, r10, r3 @ get offset 100 ldr r3, =ddr_phys_offset_va 101 ldr r2, =PAGE_OFFSET 102 sub r3, r3, r2 103 ldr r2, =CONFIG_DRAM_BASE 104 add r3, r3, r2 105 ldr r3, [r3, #0x0] @ get real PHYS_OFFSET value 106 add r10, r10, r3 107 108 mov r0, #'X' 109 bl printch 110 mov r0, r8 111 bl printhex8 112 mov r0, #':' 113 bl printch 114 mov r0, r9 115 bl printhex8 116 mov r0, #'-' 117 bl printch 118 mov r0, r10 119 bl printhex8 120 nop 121 1222: 123 ldmia r8!, { r0 - r7 } 124 stmia r9!, { r0 - r7 } 125 mov r0, r9 126 mov r1, #0xff 127 orr r1, r1, #0xff00 128 tst r0, r1 129 bne 2b 130 mov r0, #'.' 131 bl printch 132 cmp r9, r10 133 blo 2b 134 135 mov r0, #'!' 136 bl printch 137 mov r0, r9 138 bl printhex8 139 nop 1405: 141 mov r0, #'.' 142 bl printch 143 nop 144#endif /* !CONFIG_XIP_KERNEL */ 145 146szmem: 147 ldr r3,=0x80000000 148 ldr r2,=0xaa55beef 149 ldr r1,=0x00000000 150 ldr r6,[r3,#0x3c] /* Save the value in r6 */ 151 str r1,[r3,#0x3c] 152 ldr r0,=(1 << 20) 153 ldr r5,=(1 << 30) 1541: 155 ldr r4,=0x80000000 156 add r4,r4,r0 157 ldr r7,[r4,#0x3c] /* Save the value in r7 */ 158 str r2,[r4,#0x3c] 159 ldr r1,[r4,#0x3c] /* Read back to ensure completion */ 160 ldr r1,[r3,#0x3c] 161 str r7,[r4,#0x3c] /* Restore the value from r7 */ 162 cmp r1,r2 163 beq 2f 164 165 lsl r0,r0,#1 166 cmp r0,r5 167 bne 1b 168 169 /* Didn't find an alias, must be 128MB */ 1702: 171 str r6,[r3,#0x3c] /* Restore the value from r6 */ 172 adr r7,__mach_head_fixup 173 ldr r8,=__mach_head_fixup 174 sub r7,r7,r8 175 ldr r8,=_memsize 176 add r7,r8,r7 177 str r0,[r7] 178 179 @ Override machine type and atags pointers 180 ldr r1, =(machine_arch_type) 181 mov r0, #0 182 mov r2, r0 183 mov pc, r12 @ return 184 nop 185ENDPROC(__mach_head_fixup) 186 .ltorg 187 188 .global _memsize 189 .type _memsize, %object 190 .size _memsize, 4 191 .align 2 192_memsize: 193 .word 0 194 195#ifdef CONFIG_SMP 196/* 197 * Platform specific entry point for secondary CPUs. This 198 * provides a "holding pen" into which all secondary cores are held 199 * until we're ready for them to initialise. 200 */ 201 __CPUINIT 202ENTRY(platform_secondary_startup) 203 /* 204 * Get hardware CPU id of ours 205 */ 206 mrc p15, 0, r0, c0, c0, 5 207 and r0, r0, #15 208 /* 209 * Wait on <pen_release> variable by physical address 210 * to contain our hardware CPU id 211 */ 212 /* The pen_release is located at < 128MB address */ 213 ldr r6, =pen_release 214 ldr r3, =PAGE_OFFSET 215 sub r6, r6, r3 @ get offset 216 ldr r3, =ddr_phys_offset_va 217 ldr r2, =PAGE_OFFSET 218 sub r3, r3, r2 219 ldr r2, =CONFIG_DRAM_BASE 220 add r3, r3, r2 221 ldr r3, [r3, #0x0] @ get real PHYS_OFFSET value 222 add r6, r6, r3 223 224pen: ldr r7, [r6] 225 cmp r7, r0 226 bne pen 227 nop 228 /* 229 * In case L1 cache has unpredictable contents at power-up 230 * clean its contents without flushing. 231 */ 232 bl v7_l1_cache_invalidate 233 nop 234 /* 235 * we've been released from the holding pen: secondary_stack 236 * should now contain the SVC stack for this core 237 */ 238 b secondary_startup 239 240ENDPROC(platform_secondary_startup) 241 .ltorg 242#endif /* CONFIG_SMP */ 243