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 35 /* Enable Cycle Counter and Nesting Of Interrupts */ 36#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES 37 R0 = SYSCFG_SNEN; 38#else 39 R0 = SYSCFG_SNEN | SYSCFG_CCEN; 40#endif 41 SYSCFG = R0; 42 43 /* Optimization register tricks: keep a base value in the 44 * reserved P registers so we use the load/store with an 45 * offset syntax. R0 = [P5 + <constant>]; 46 * P5 - core MMR base 47 * R6 - 0 48 */ 49 r6 = 0; 50 p5.l = 0; 51 p5.h = hi(COREMMR_BASE); 52 53 /* Zero out registers required by Blackfin ABI */ 54 55 /* Disable circular buffers */ 56 L0 = r6; 57 L1 = r6; 58 L2 = r6; 59 L3 = r6; 60 61 /* Disable hardware loops in case we were started by 'go' */ 62 LC0 = r6; 63 LC1 = r6; 64 65 /* 66 * Clear ITEST_COMMAND and DTEST_COMMAND registers, 67 * Leaving these as non-zero can confuse the emulator 68 */ 69 [p5 + (DTEST_COMMAND - COREMMR_BASE)] = r6; 70 [p5 + (ITEST_COMMAND - COREMMR_BASE)] = r6; 71 CSYNC; 72 73 trace_buffer_init(p0,r0); 74 75 /* Turn off the icache */ 76 r1 = [p5 + (IMEM_CONTROL - COREMMR_BASE)]; 77 BITCLR (r1, ENICPLB_P); 78 [p5 + (IMEM_CONTROL - COREMMR_BASE)] = r1; 79 SSYNC; 80 81 /* Turn off the dcache */ 82 r1 = [p5 + (DMEM_CONTROL - COREMMR_BASE)]; 83 BITCLR (r1, ENDCPLB_P); 84 [p5 + (DMEM_CONTROL - COREMMR_BASE)] = r1; 85 SSYNC; 86 87 /* in case of double faults, save a few things */ 88 p1.l = _initial_pda; 89 p1.h = _initial_pda; 90 r4 = RETX; 91#ifdef CONFIG_DEBUG_DOUBLEFAULT 92 /* Only save these if we are storing them, 93 * This happens here, since L1 gets clobbered 94 * below 95 */ 96 GET_PDA(p0, r0); 97 r0 = [p0 + PDA_DF_RETX]; 98 r1 = [p0 + PDA_DF_DCPLB]; 99 r2 = [p0 + PDA_DF_ICPLB]; 100 r3 = [p0 + PDA_DF_SEQSTAT]; 101 [p1 + PDA_INIT_DF_RETX] = r0; 102 [p1 + PDA_INIT_DF_DCPLB] = r1; 103 [p1 + PDA_INIT_DF_ICPLB] = r2; 104 [p1 + PDA_INIT_DF_SEQSTAT] = r3; 105#endif 106 [p1 + PDA_INIT_RETX] = r4; 107 108 /* Initialize stack pointer */ 109 sp.l = _init_thread_union + THREAD_SIZE; 110 sp.h = _init_thread_union + THREAD_SIZE; 111 fp = sp; 112 usp = sp; 113 114#ifdef CONFIG_EARLY_PRINTK 115 call _init_early_exception_vectors; 116 r0 = (EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU); 117 sti r0; 118#endif 119 120 r0 = r6; 121 /* Zero out all of the fun bss regions */ 122#if L1_DATA_A_LENGTH > 0 123 r1.l = __sbss_l1; 124 r1.h = __sbss_l1; 125 r2.l = __ebss_l1; 126 r2.h = __ebss_l1; 127 call __init_clear_bss 128#endif 129#if L1_DATA_B_LENGTH > 0 130 r1.l = __sbss_b_l1; 131 r1.h = __sbss_b_l1; 132 r2.l = __ebss_b_l1; 133 r2.h = __ebss_b_l1; 134 call __init_clear_bss 135#endif 136#if L2_LENGTH > 0 137 r1.l = __sbss_l2; 138 r1.h = __sbss_l2; 139 r2.l = __ebss_l2; 140 r2.h = __ebss_l2; 141 call __init_clear_bss 142#endif 143 r1.l = ___bss_start; 144 r1.h = ___bss_start; 145 r2.l = ___bss_stop; 146 r2.h = ___bss_stop; 147 call __init_clear_bss 148 149 /* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */ 150 call _bfin_relocate_l1_mem; 151 152#ifdef CONFIG_ROMKERNEL 153 call _bfin_relocate_xip_data; 154#endif 155 156#ifdef CONFIG_BFIN_KERNEL_CLOCK 157 /* Only use on-chip scratch space for stack when absolutely required 158 * to avoid Anomaly 05000227 ... we know the init_clocks() func only 159 * uses L1 text and stack space and no other memory region. 160 */ 161# define KERNEL_CLOCK_STACK (L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12) 162 sp.l = lo(KERNEL_CLOCK_STACK); 163 sp.h = hi(KERNEL_CLOCK_STACK); 164 call _init_clocks; 165 sp = usp; /* usp hasn't been touched, so restore from there */ 166#endif 167 168 /* This section keeps the processor in supervisor mode 169 * during kernel boot. Switches to user mode at end of boot. 170 * See page 3-9 of Hardware Reference manual for documentation. 171 */ 172 173 /* EVT15 = _real_start */ 174 175 p1.l = _real_start; 176 p1.h = _real_start; 177 [p5 + (EVT15 - COREMMR_BASE)] = p1; 178 csync; 179 180#ifdef CONFIG_EARLY_PRINTK 181 r0 = (EVT_IVG15 | EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU) (z); 182#else 183 r0 = EVT_IVG15 (z); 184#endif 185 sti r0; 186 187 raise 15; 188#ifdef CONFIG_EARLY_PRINTK 189 p0.l = _early_trap; 190 p0.h = _early_trap; 191#else 192 p0.l = .LWAIT_HERE; 193 p0.h = .LWAIT_HERE; 194#endif 195 reti = p0; 196#if ANOMALY_05000281 197 nop; nop; nop; 198#endif 199 rti; 200 201.LWAIT_HERE: 202 jump .LWAIT_HERE; 203ENDPROC(__start) 204 205/* A little BF561 glue ... */ 206#ifndef WDOG_CTL 207# define WDOG_CTL WDOGA_CTL 208#endif 209 210ENTRY(_real_start) 211 /* Enable nested interrupts */ 212 [--sp] = reti; 213 /* watchdog off for now */ 214 p0.l = lo(WDOG_CTL); 215 p0.h = hi(WDOG_CTL); 216 r0 = 0xAD6(z); 217 w[p0] = r0; 218 ssync; 219 /* Pass the u-boot arguments to the global value command line */ 220 R0 = R7; 221 call _cmdline_init; 222 223 sp += -12 + 4; /* +4 is for reti loading above */ 224 call _init_pda 225 sp += 12; 226 jump.l _start_kernel; 227ENDPROC(_real_start) 228 229__FINIT 230