1/* 2 * Common Blackfin startup code 3 * 4 * Copyright 2004-2008 Analog Devices Inc. 5 * 6 * Licensed under the GPL-2 or later. 7 */ 8 9#include <linux/linkage.h> 10#include <linux/init.h> 11#include <asm/blackfin.h> 12#include <asm/thread_info.h> 13#include <asm/trace.h> 14#include <asm/asm-offsets.h> 15 16__INIT 17 18ENTRY(__init_clear_bss) 19 r2 = r2 - r1; 20 cc = r2 == 0; 21 if cc jump .L_bss_done; 22 r2 >>= 2; 23 p1 = r1; 24 p2 = r2; 25 lsetup (1f, 1f) lc0 = p2; 261: [p1++] = r0; 27.L_bss_done: 28 rts; 29ENDPROC(__init_clear_bss) 30 31ENTRY(__start) 32 /* R0: argument of command line string, passed from uboot, save it */ 33 R7 = R0; 34 /* Enable Cycle Counter and Nesting Of Interrupts */ 35#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES 36 R0 = SYSCFG_SNEN; 37#else 38 R0 = SYSCFG_SNEN | SYSCFG_CCEN; 39#endif 40 SYSCFG = R0; 41 R0 = 0; 42 43 /* Clear Out All the data and pointer Registers */ 44 R1 = R0; 45 R2 = R0; 46 R3 = R0; 47 R4 = R0; 48 R5 = R0; 49 R6 = R0; 50 51 P0 = R0; 52 P1 = R0; 53 P2 = R0; 54 P3 = R0; 55 P4 = R0; 56 P5 = R0; 57 58 LC0 = r0; 59 LC1 = r0; 60 L0 = r0; 61 L1 = r0; 62 L2 = r0; 63 L3 = r0; 64 65 /* Clear Out All the DAG Registers */ 66 B0 = r0; 67 B1 = r0; 68 B2 = r0; 69 B3 = r0; 70 71 I0 = r0; 72 I1 = r0; 73 I2 = r0; 74 I3 = r0; 75 76 M0 = r0; 77 M1 = r0; 78 M2 = r0; 79 M3 = r0; 80 81 /* 82 * Clear ITEST_COMMAND and DTEST_COMMAND registers, 83 * Leaving these as non-zero can confuse the emulator 84 */ 85 p0.L = LO(DTEST_COMMAND); 86 p0.H = HI(DTEST_COMMAND); 87 [p0] = R0; 88 [p0 + (ITEST_COMMAND - DTEST_COMMAND)] = R0; 89 CSYNC; 90 91 trace_buffer_init(p0,r0); 92 P0 = R1; 93 R0 = R1; 94 95 /* Turn off the icache */ 96 p0.l = LO(IMEM_CONTROL); 97 p0.h = HI(IMEM_CONTROL); 98 R1 = [p0]; 99 R0 = ~ENICPLB; 100 R0 = R0 & R1; 101 [p0] = R0; 102 SSYNC; 103 104 /* Turn off the dcache */ 105 p0.l = LO(DMEM_CONTROL); 106 p0.h = HI(DMEM_CONTROL); 107 R1 = [p0]; 108 R0 = ~ENDCPLB; 109 R0 = R0 & R1; 110 [p0] = R0; 111 SSYNC; 112 113 /* in case of double faults, save a few things */ 114 p0.l = _init_retx; 115 p0.h = _init_retx; 116 R0 = RETX; 117 [P0] = R0; 118 119#ifdef CONFIG_DEBUG_DOUBLEFAULT 120 /* Only save these if we are storing them, 121 * This happens here, since L1 gets clobbered 122 * below 123 */ 124 GET_PDA(p0, r0); 125 r6 = [p0 + PDA_DF_RETX]; 126 p1.l = _init_saved_retx; 127 p1.h = _init_saved_retx; 128 [p1] = r6; 129 130 r6 = [p0 + PDA_DF_DCPLB]; 131 p1.l = _init_saved_dcplb_fault_addr; 132 p1.h = _init_saved_dcplb_fault_addr; 133 [p1] = r6; 134 135 r6 = [p0 + PDA_DF_ICPLB]; 136 p1.l = _init_saved_icplb_fault_addr; 137 p1.h = _init_saved_icplb_fault_addr; 138 [p1] = r6; 139 140 r6 = [p0 + PDA_DF_SEQSTAT]; 141 p1.l = _init_saved_seqstat; 142 p1.h = _init_saved_seqstat; 143 [p1] = r6; 144#endif 145 146 /* Initialize stack pointer */ 147 sp.l = _init_thread_union + THREAD_SIZE; 148 sp.h = _init_thread_union + THREAD_SIZE; 149 fp = sp; 150 usp = sp; 151 152#ifdef CONFIG_EARLY_PRINTK 153 call _init_early_exception_vectors; 154 r0 = (EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU); 155 sti r0; 156#endif 157 158 r0 = 0 (x); 159 /* Zero out all of the fun bss regions */ 160#if L1_DATA_A_LENGTH > 0 161 r1.l = __sbss_l1; 162 r1.h = __sbss_l1; 163 r2.l = __ebss_l1; 164 r2.h = __ebss_l1; 165 call __init_clear_bss 166#endif 167#if L1_DATA_B_LENGTH > 0 168 r1.l = __sbss_b_l1; 169 r1.h = __sbss_b_l1; 170 r2.l = __ebss_b_l1; 171 r2.h = __ebss_b_l1; 172 call __init_clear_bss 173#endif 174#if L2_LENGTH > 0 175 r1.l = __sbss_l2; 176 r1.h = __sbss_l2; 177 r2.l = __ebss_l2; 178 r2.h = __ebss_l2; 179 call __init_clear_bss 180#endif 181 r1.l = ___bss_start; 182 r1.h = ___bss_start; 183 r2.l = ___bss_stop; 184 r2.h = ___bss_stop; 185 call __init_clear_bss 186 187 /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ 188 call _bfin_relocate_l1_mem; 189 190#ifdef CONFIG_ROMKERNEL 191 call _bfin_relocate_xip_data; 192#endif 193 194#ifdef CONFIG_BFIN_KERNEL_CLOCK 195 /* Only use on-chip scratch space for stack when absolutely required 196 * to avoid Anomaly 05000227 ... we know the init_clocks() func only 197 * uses L1 text and stack space and no other memory region. 198 */ 199# define KERNEL_CLOCK_STACK (L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12) 200 sp.l = lo(KERNEL_CLOCK_STACK); 201 sp.h = hi(KERNEL_CLOCK_STACK); 202 call _init_clocks; 203 sp = usp; /* usp hasnt been touched, so restore from there */ 204#endif 205 206 /* This section keeps the processor in supervisor mode 207 * during kernel boot. Switches to user mode at end of boot. 208 * See page 3-9 of Hardware Reference manual for documentation. 209 */ 210 211 /* EVT15 = _real_start */ 212 213 p0.l = lo(EVT15); 214 p0.h = hi(EVT15); 215 p1.l = _real_start; 216 p1.h = _real_start; 217 [p0] = p1; 218 csync; 219 220#ifdef CONFIG_EARLY_PRINTK 221 r0 = (EVT_IVG15 | EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU) (z); 222#else 223 r0 = EVT_IVG15 (z); 224#endif 225 sti r0; 226 227 raise 15; 228#ifdef CONFIG_EARLY_PRINTK 229 p0.l = _early_trap; 230 p0.h = _early_trap; 231#else 232 p0.l = .LWAIT_HERE; 233 p0.h = .LWAIT_HERE; 234#endif 235 reti = p0; 236#if ANOMALY_05000281 237 nop; nop; nop; 238#endif 239 rti; 240 241.LWAIT_HERE: 242 jump .LWAIT_HERE; 243ENDPROC(__start) 244 245/* A little BF561 glue ... */ 246#ifndef WDOG_CTL 247# define WDOG_CTL WDOGA_CTL 248#endif 249 250ENTRY(_real_start) 251 /* Enable nested interrupts */ 252 [--sp] = reti; 253 254 /* watchdog off for now */ 255 p0.l = lo(WDOG_CTL); 256 p0.h = hi(WDOG_CTL); 257 r0 = 0xAD6(z); 258 w[p0] = r0; 259 ssync; 260 261 /* Pass the u-boot arguments to the global value command line */ 262 R0 = R7; 263 call _cmdline_init; 264 265 sp += -12 + 4; /* +4 is for reti loading above */ 266 call _init_pda 267 sp += 12; 268 jump.l _start_kernel; 269ENDPROC(_real_start) 270 271__FINIT 272