123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- /*
- * 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 CONFIG_BFIN_SCRATCH_REG_CYCLES
- 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 CONFIG_DEBUG_DOUBLEFAULT
- /* 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 CONFIG_HOTPLUG_CPU
- .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 CONFIG_HOTPLUG_CPU
- 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 CONFIG_HOTPLUG_CPU
- 3:
- #endif
- call _secondary_start_kernel;
- .L_exit:
- jump.s .L_exit;
- ENDPROC(_coreb_start)
|