secondary.S 3.8 KB
Newer Older
1
/*
2
 * BF561 coreB bootstrap file
3
 *
4 5
 * Copyright 2007-2009 Analog Devices Inc.
 *               Philippe Gerum <rpm@xenomai.org>
6
 *
7
 * Licensed under the GPL-2 or later.
8 9 10 11 12 13
 */

#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/blackfin.h>
#include <asm/asm-offsets.h>
14
#include <asm/trace.h>
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

__INIT

/* 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)
	/* Set the SYSCFG register */
	R0 = 0x36;
	SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
	R0 = 0;

	/*Clear Out All the data and pointer  Registers*/
	R1 = R0;
	R2 = R0;
	R3 = R0;
	R4 = R0;
	R5 = R0;
	R6 = R0;
	R7 = R0;

	P0 = R0;
	P1 = R0;
	P2 = R0;
	P3 = R0;
	P4 = R0;
	P5 = R0;

	LC0 = r0;
	LC1 = r0;
	L0 = r0;
	L1 = r0;
	L2 = r0;
	L3 = r0;

	/* Clear Out All the DAG Registers*/
	B0 = r0;
	B1 = r0;
	B2 = r0;
	B3 = r0;

	I0 = r0;
	I1 = r0;
	I2 = r0;
	I3 = r0;

	M0 = r0;
	M1 = r0;
	M2 = r0;
	M3 = r0;

66 67
	trace_buffer_init(p0,r0);

68 69 70 71 72 73 74
	/* Turn off the icache */
	p0.l = LO(IMEM_CONTROL);
	p0.h = HI(IMEM_CONTROL);
	R1 = [p0];
	R0 = ~ENICPLB;
	R0 = R0 & R1;

75 76
	/* Disabling of CPLBs should be proceeded by a CSYNC */
	CSYNC;
77 78 79 80 81 82 83 84 85 86
	[p0] = R0;
	SSYNC;

	/* Turn off the dcache */
	p0.l = LO(DMEM_CONTROL);
	p0.h = HI(DMEM_CONTROL);
	R1 = [p0];
	R0 = ~ENDCPLB;
	R0 = R0 & R1;

87 88
	/* Disabling of CPLBs should be proceeded by a CSYNC */
	CSYNC;
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
	[p0] = R0;
	SSYNC;

	/* in case of double faults, save a few things */
	p0.l = _init_retx_coreb;
	p0.h = _init_retx_coreb;
	R0 = RETX;
	[P0] = R0;

#ifdef CONFIG_DEBUG_DOUBLEFAULT
	/* Only save these if we are storing them,
	 * This happens here, since L1 gets clobbered
	 * below
	 */
	GET_PDA(p0, r0);
104
	r7 = [p0 + PDA_DF_RETX];
105 106 107 108
	p1.l = _init_saved_retx_coreb;
	p1.h = _init_saved_retx_coreb;
	[p1] = r7;

109
	r7 = [p0 + PDA_DF_DCPLB];
110 111 112 113
	p1.l = _init_saved_dcplb_fault_addr_coreb;
	p1.h = _init_saved_dcplb_fault_addr_coreb;
	[p1] = r7;

114
	r7 = [p0 + PDA_DF_ICPLB];
115 116 117 118
	p1.l = _init_saved_icplb_fault_addr_coreb;
	p1.h = _init_saved_icplb_fault_addr_coreb;
	[p1] = r7;

119
	r7 = [p0 + PDA_DF_SEQSTAT];
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
	p1.l = _init_saved_seqstat_coreb;
	p1.h = _init_saved_seqstat_coreb;
	[p1] = r7;
#endif

	/* 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 */

	p0.l = lo(EVT15);
	p0.h = hi(EVT15);
	p1.l = _coreb_start;
	p1.h = _coreb_start;
	[p0] = p1;
	csync;

	p0.l = lo(IMASK);
	p0.h = hi(IMASK);
	p1.l = IMASK_IVG15;
	p1.h = 0x0;
	[p0] = p1;
	csync;

	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)
ENTRY(_coreb_trampoline_end)

165
#ifdef CONFIG_HOTPLUG_CPU
166
.section ".text"
167
ENTRY(_coreb_die)
168 169 170 171 172 173 174 175 176 177 178
	sp.l = lo(INITIAL_STACK);
	sp.h = hi(INITIAL_STACK);
	fp = sp;
	usp = sp;

	CLI R2;
	SSYNC;
	IDLE;
	STI R2;

	R0 = IWR_DISABLE_ALL;
179 180 181 182 183
	P0.H = hi(SYSMMR_BASE);
	P0.L = lo(SYSMMR_BASE);
	[P0 + (SICB_IWR0 - SYSMMR_BASE)] = R0;
	[P0 + (SICB_IWR1 - SYSMMR_BASE)] = R0;
	SSYNC;
184 185 186 187

	p0.h = hi(COREB_L1_CODE_START);
	p0.l = lo(COREB_L1_CODE_START);
	jump (p0);
188 189
ENDPROC(_coreb_die)
#endif
190

191
__INIT
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
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;
209 210 211 212 213 214 215
#ifdef CONFIG_HOTPLUG_CPU
	p0.l = _hotplug_coreb;
	p0.h = _hotplug_coreb;
	r0 = [p0];
	cc = BITTST(r0, 0);
	if cc jump 3f;
#endif
216 217 218
	sp += -12;
	call _init_pda
	sp += 12;
219 220 221
#ifdef CONFIG_HOTPLUG_CPU
3:
#endif
222 223 224 225
	call _secondary_start_kernel;
.L_exit:
	jump.s	.L_exit;
ENDPROC(_coreb_start)