1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | /* * BF561 coreB bootstrap file * * Copyright 2007-2009 Analog Devices Inc. * Philippe Gerum <rpm@xenomai.org> * * Licensed under the GPL-2 or later. */ #include <linux/linkage.h> #include <linux/init.h> #include <asm/blackfin.h> #include <asm/asm-offsets.h> #include <asm/trace.h> /* * This code must come first as CoreB is hardcoded (in hardware) * to start at the beginning of its L1 instruction memory. */ .section .l1.text.head /* Lay the initial stack into the L1 scratch area of Core B */ #define INITIAL_STACK (COREB_L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12) ENTRY(_coreb_trampoline_start) /* Enable Cycle Counter and Nesting Of Interrupts */ #ifdef [31mCONFIG_BFIN_SCRATCH_REG_CYCLES[0m R0 = SYSCFG_SNEN; #else R0 = SYSCFG_SNEN | SYSCFG_CCEN; #endif SYSCFG = R0; /* Optimization register tricks: keep a base value in the * reserved P registers so we use the load/store with an * offset syntax. R0 = [P5 + <constant>]; * P5 - core MMR base * R6 - 0 */ r6 = 0; p5.l = 0; p5.h = hi(COREMMR_BASE); /* Zero out registers required by Blackfin ABI */ /* Disable circular buffers */ L0 = r6; L1 = r6; L2 = r6; L3 = r6; /* Disable hardware loops in case we were started by 'go' */ LC0 = r6; LC1 = r6; /* * Clear ITEST_COMMAND and DTEST_COMMAND registers, * Leaving these as non-zero can confuse the emulator */ [p5 + (DTEST_COMMAND - COREMMR_BASE)] = r6; [p5 + (ITEST_COMMAND - COREMMR_BASE)] = r6; CSYNC; trace_buffer_init(p0,r0); /* Turn off the icache */ r1 = [p5 + (IMEM_CONTROL - COREMMR_BASE)]; BITCLR (r1, ENICPLB_P); [p5 + (IMEM_CONTROL - COREMMR_BASE)] = r1; SSYNC; /* Turn off the dcache */ r1 = [p5 + (DMEM_CONTROL - COREMMR_BASE)]; BITCLR (r1, ENDCPLB_P); [p5 + (DMEM_CONTROL - COREMMR_BASE)] = r1; SSYNC; /* in case of double faults, save a few things */ p1.l = _initial_pda_coreb; p1.h = _initial_pda_coreb; r4 = RETX; #ifdef [31mCONFIG_DEBUG_DOUBLEFAULT[0m /* Only save these if we are storing them, * This happens here, since L1 gets clobbered * below */ GET_PDA(p0, r0); r0 = [p0 + PDA_DF_RETX]; r1 = [p0 + PDA_DF_DCPLB]; r2 = [p0 + PDA_DF_ICPLB]; r3 = [p0 + PDA_DF_SEQSTAT]; [p1 + PDA_INIT_DF_RETX] = r0; [p1 + PDA_INIT_DF_DCPLB] = r1; [p1 + PDA_INIT_DF_ICPLB] = r2; [p1 + PDA_INIT_DF_SEQSTAT] = r3; #endif [p1 + PDA_INIT_RETX] = r4; /* Initialize stack pointer */ sp.l = lo(INITIAL_STACK); sp.h = hi(INITIAL_STACK); fp = sp; usp = sp; /* This section keeps the processor in supervisor mode * during core B startup. Branches to the idle task. */ /* EVT15 = _real_start */ p1.l = _coreb_start; p1.h = _coreb_start; [p5 + (EVT15 - COREMMR_BASE)] = p1; csync; r0 = EVT_IVG15 (z); sti r0; raise 15; p0.l = .LWAIT_HERE; p0.h = .LWAIT_HERE; reti = p0; #if defined(ANOMALY_05000281) nop; nop; nop; #endif rti; .LWAIT_HERE: jump .LWAIT_HERE; ENDPROC(_coreb_trampoline_start) #ifdef [31mCONFIG_HOTPLUG_CPU[0m .section ".text" ENTRY(_coreb_die) sp.l = lo(INITIAL_STACK); sp.h = hi(INITIAL_STACK); fp = sp; usp = sp; CLI R2; SSYNC; IDLE; STI R2; R0 = IWR_DISABLE_ALL; P0.H = hi(SYSMMR_BASE); P0.L = lo(SYSMMR_BASE); [P0 + (SICB_IWR0 - SYSMMR_BASE)] = R0; [P0 + (SICB_IWR1 - SYSMMR_BASE)] = R0; SSYNC; p0.h = hi(COREB_L1_CODE_START); p0.l = lo(COREB_L1_CODE_START); jump (p0); ENDPROC(_coreb_die) #endif __INIT ENTRY(_coreb_start) [--sp] = reti; p0.l = lo(WDOGB_CTL); p0.h = hi(WDOGB_CTL); r0 = 0xAD6(z); w[p0] = r0; /* Clear the watchdog. */ ssync; /* * switch to IDLE stack. */ p0.l = _secondary_stack; p0.h = _secondary_stack; sp = [p0]; usp = sp; fp = sp; #ifdef [31mCONFIG_HOTPLUG_CPU[0m p0.l = _hotplug_coreb; p0.h = _hotplug_coreb; r0 = [p0]; cc = BITTST(r0, 0); if cc jump 3f; #endif sp += -12; call _init_pda sp += 12; #ifdef [31mCONFIG_HOTPLUG_CPU[0m 3: #endif call _secondary_start_kernel; .L_exit: jump.s .L_exit; ENDPROC(_coreb_start) |