1/* 2 * BF561 coreB bootstrap file 3 * 4 * Copyright 2007-2009 Analog Devices Inc. 5 * Philippe Gerum <rpm@xenomai.org> 6 * 7 * Licensed under the GPL-2 or later. 8 */ 9 10#include <linux/linkage.h> 11#include <linux/init.h> 12#include <asm/blackfin.h> 13#include <asm/asm-offsets.h> 14#include <asm/trace.h> 15 16__INIT 17 18/* Lay the initial stack into the L1 scratch area of Core B */ 19#define INITIAL_STACK (COREB_L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12) 20 21ENTRY(_coreb_trampoline_start) 22 /* Set the SYSCFG register */ 23 R0 = 0x36; 24 SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/ 25 R0 = 0; 26 27 /*Clear Out All the data and pointer Registers*/ 28 R1 = R0; 29 R2 = R0; 30 R3 = R0; 31 R4 = R0; 32 R5 = R0; 33 R6 = R0; 34 R7 = R0; 35 36 P0 = R0; 37 P1 = R0; 38 P2 = R0; 39 P3 = R0; 40 P4 = R0; 41 P5 = R0; 42 43 LC0 = r0; 44 LC1 = r0; 45 L0 = r0; 46 L1 = r0; 47 L2 = r0; 48 L3 = r0; 49 50 /* Clear Out All the DAG Registers*/ 51 B0 = r0; 52 B1 = r0; 53 B2 = r0; 54 B3 = r0; 55 56 I0 = r0; 57 I1 = r0; 58 I2 = r0; 59 I3 = r0; 60 61 M0 = r0; 62 M1 = r0; 63 M2 = r0; 64 M3 = r0; 65 66 trace_buffer_init(p0,r0); 67 68 /* Turn off the icache */ 69 p0.l = LO(IMEM_CONTROL); 70 p0.h = HI(IMEM_CONTROL); 71 R1 = [p0]; 72 R0 = ~ENICPLB; 73 R0 = R0 & R1; 74 75 /* Disabling of CPLBs should be proceeded by a CSYNC */ 76 CSYNC; 77 [p0] = R0; 78 SSYNC; 79 80 /* Turn off the dcache */ 81 p0.l = LO(DMEM_CONTROL); 82 p0.h = HI(DMEM_CONTROL); 83 R1 = [p0]; 84 R0 = ~ENDCPLB; 85 R0 = R0 & R1; 86 87 /* Disabling of CPLBs should be proceeded by a CSYNC */ 88 CSYNC; 89 [p0] = R0; 90 SSYNC; 91 92 /* in case of double faults, save a few things */ 93 p0.l = _init_retx_coreb; 94 p0.h = _init_retx_coreb; 95 R0 = RETX; 96 [P0] = R0; 97 98#ifdef CONFIG_DEBUG_DOUBLEFAULT 99 /* Only save these if we are storing them, 100 * This happens here, since L1 gets clobbered 101 * below 102 */ 103 GET_PDA(p0, r0); 104 r7 = [p0 + PDA_DF_RETX]; 105 p1.l = _init_saved_retx_coreb; 106 p1.h = _init_saved_retx_coreb; 107 [p1] = r7; 108 109 r7 = [p0 + PDA_DF_DCPLB]; 110 p1.l = _init_saved_dcplb_fault_addr_coreb; 111 p1.h = _init_saved_dcplb_fault_addr_coreb; 112 [p1] = r7; 113 114 r7 = [p0 + PDA_DF_ICPLB]; 115 p1.l = _init_saved_icplb_fault_addr_coreb; 116 p1.h = _init_saved_icplb_fault_addr_coreb; 117 [p1] = r7; 118 119 r7 = [p0 + PDA_DF_SEQSTAT]; 120 p1.l = _init_saved_seqstat_coreb; 121 p1.h = _init_saved_seqstat_coreb; 122 [p1] = r7; 123#endif 124 125 /* Initialize stack pointer */ 126 sp.l = lo(INITIAL_STACK); 127 sp.h = hi(INITIAL_STACK); 128 fp = sp; 129 usp = sp; 130 131 /* This section keeps the processor in supervisor mode 132 * during core B startup. Branches to the idle task. 133 */ 134 135 /* EVT15 = _real_start */ 136 137 p0.l = lo(EVT15); 138 p0.h = hi(EVT15); 139 p1.l = _coreb_start; 140 p1.h = _coreb_start; 141 [p0] = p1; 142 csync; 143 144 p0.l = lo(IMASK); 145 p0.h = hi(IMASK); 146 p1.l = IMASK_IVG15; 147 p1.h = 0x0; 148 [p0] = p1; 149 csync; 150 151 raise 15; 152 p0.l = .LWAIT_HERE; 153 p0.h = .LWAIT_HERE; 154 reti = p0; 155#if defined(ANOMALY_05000281) 156 nop; nop; nop; 157#endif 158 rti; 159 160.LWAIT_HERE: 161 jump .LWAIT_HERE; 162ENDPROC(_coreb_trampoline_start) 163ENTRY(_coreb_trampoline_end) 164 165.section ".text" 166ENTRY(_set_sicb_iwr) 167 P0.H = hi(SICB_IWR0); 168 P0.L = lo(SICB_IWR0); 169 P1.H = hi(SICB_IWR1); 170 P1.L = lo(SICB_IWR1); 171 [P0] = R0; 172 [P1] = R1; 173 SSYNC; 174 RTS; 175ENDPROC(_set_sicb_iwr) 176 177ENTRY(_coreb_sleep) 178 sp.l = lo(INITIAL_STACK); 179 sp.h = hi(INITIAL_STACK); 180 fp = sp; 181 usp = sp; 182 183 call _set_sicb_iwr; 184 185 CLI R2; 186 SSYNC; 187 IDLE; 188 STI R2; 189 190 R0 = IWR_DISABLE_ALL; 191 R1 = IWR_DISABLE_ALL; 192 call _set_sicb_iwr; 193 194 p0.h = hi(COREB_L1_CODE_START); 195 p0.l = lo(COREB_L1_CODE_START); 196 jump (p0); 197ENDPROC(_coreb_sleep) 198 199__CPUINIT 200ENTRY(_coreb_start) 201 [--sp] = reti; 202 203 p0.l = lo(WDOGB_CTL); 204 p0.h = hi(WDOGB_CTL); 205 r0 = 0xAD6(z); 206 w[p0] = r0; /* Clear the watchdog. */ 207 ssync; 208 209 /* 210 * switch to IDLE stack. 211 */ 212 p0.l = _secondary_stack; 213 p0.h = _secondary_stack; 214 sp = [p0]; 215 usp = sp; 216 fp = sp; 217#ifdef CONFIG_HOTPLUG_CPU 218 p0.l = _hotplug_coreb; 219 p0.h = _hotplug_coreb; 220 r0 = [p0]; 221 cc = BITTST(r0, 0); 222 if cc jump 3f; 223#endif 224 sp += -12; 225 call _init_pda 226 sp += 12; 227#ifdef CONFIG_HOTPLUG_CPU 2283: 229#endif 230 call _secondary_start_kernel; 231.L_exit: 232 jump.s .L_exit; 233ENDPROC(_coreb_start) 234