linux/arch/blackfin/mach-bf561/secondary.S
<<
>>
Prefs
   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
  15__INIT
  16
  17/* Lay the initial stack into the L1 scratch area of Core B */
  18#define INITIAL_STACK   (COREB_L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12)
  19
  20ENTRY(_coreb_trampoline_start)
  21        /* Set the SYSCFG register */
  22        R0 = 0x36;
  23        SYSCFG = R0; /*Enable Cycle Counter and Nesting Of Interrupts(3rd Bit)*/
  24        R0 = 0;
  25
  26        /*Clear Out All the data and pointer  Registers*/
  27        R1 = R0;
  28        R2 = R0;
  29        R3 = R0;
  30        R4 = R0;
  31        R5 = R0;
  32        R6 = R0;
  33        R7 = R0;
  34
  35        P0 = R0;
  36        P1 = R0;
  37        P2 = R0;
  38        P3 = R0;
  39        P4 = R0;
  40        P5 = R0;
  41
  42        LC0 = r0;
  43        LC1 = r0;
  44        L0 = r0;
  45        L1 = r0;
  46        L2 = r0;
  47        L3 = r0;
  48
  49        /* Clear Out All the DAG Registers*/
  50        B0 = r0;
  51        B1 = r0;
  52        B2 = r0;
  53        B3 = r0;
  54
  55        I0 = r0;
  56        I1 = r0;
  57        I2 = r0;
  58        I3 = r0;
  59
  60        M0 = r0;
  61        M1 = r0;
  62        M2 = r0;
  63        M3 = r0;
  64
  65        /* Turn off the icache */
  66        p0.l = LO(IMEM_CONTROL);
  67        p0.h = HI(IMEM_CONTROL);
  68        R1 = [p0];
  69        R0 = ~ENICPLB;
  70        R0 = R0 & R1;
  71
  72        /* Disabling of CPLBs should be proceeded by a CSYNC */
  73        CSYNC;
  74        [p0] = R0;
  75        SSYNC;
  76
  77        /* Turn off the dcache */
  78        p0.l = LO(DMEM_CONTROL);
  79        p0.h = HI(DMEM_CONTROL);
  80        R1 = [p0];
  81        R0 = ~ENDCPLB;
  82        R0 = R0 & R1;
  83
  84        /* Disabling of CPLBs should be proceeded by a CSYNC */
  85        CSYNC;
  86        [p0] = R0;
  87        SSYNC;
  88
  89        /* in case of double faults, save a few things */
  90        p0.l = _init_retx_coreb;
  91        p0.h = _init_retx_coreb;
  92        R0 = RETX;
  93        [P0] = R0;
  94
  95#ifdef CONFIG_DEBUG_DOUBLEFAULT
  96        /* Only save these if we are storing them,
  97         * This happens here, since L1 gets clobbered
  98         * below
  99         */
 100        GET_PDA(p0, r0);
 101        r7 = [p0 + PDA_DF_RETX];
 102        p1.l = _init_saved_retx_coreb;
 103        p1.h = _init_saved_retx_coreb;
 104        [p1] = r7;
 105
 106        r7 = [p0 + PDA_DF_DCPLB];
 107        p1.l = _init_saved_dcplb_fault_addr_coreb;
 108        p1.h = _init_saved_dcplb_fault_addr_coreb;
 109        [p1] = r7;
 110
 111        r7 = [p0 + PDA_DF_ICPLB];
 112        p1.l = _init_saved_icplb_fault_addr_coreb;
 113        p1.h = _init_saved_icplb_fault_addr_coreb;
 114        [p1] = r7;
 115
 116        r7 = [p0 + PDA_DF_SEQSTAT];
 117        p1.l = _init_saved_seqstat_coreb;
 118        p1.h = _init_saved_seqstat_coreb;
 119        [p1] = r7;
 120#endif
 121
 122        /* Initialize stack pointer */
 123        sp.l = lo(INITIAL_STACK);
 124        sp.h = hi(INITIAL_STACK);
 125        fp = sp;
 126        usp = sp;
 127
 128        /* This section keeps the processor in supervisor mode
 129         * during core B startup.  Branches to the idle task.
 130         */
 131
 132        /* EVT15 = _real_start */
 133
 134        p0.l = lo(EVT15);
 135        p0.h = hi(EVT15);
 136        p1.l = _coreb_start;
 137        p1.h = _coreb_start;
 138        [p0] = p1;
 139        csync;
 140
 141        p0.l = lo(IMASK);
 142        p0.h = hi(IMASK);
 143        p1.l = IMASK_IVG15;
 144        p1.h = 0x0;
 145        [p0] = p1;
 146        csync;
 147
 148        raise 15;
 149        p0.l = .LWAIT_HERE;
 150        p0.h = .LWAIT_HERE;
 151        reti = p0;
 152#if defined(ANOMALY_05000281)
 153        nop; nop; nop;
 154#endif
 155        rti;
 156
 157.LWAIT_HERE:
 158        jump .LWAIT_HERE;
 159ENDPROC(_coreb_trampoline_start)
 160ENTRY(_coreb_trampoline_end)
 161
 162ENTRY(_coreb_start)
 163        [--sp] = reti;
 164
 165        p0.l = lo(WDOGB_CTL);
 166        p0.h = hi(WDOGB_CTL);
 167        r0 = 0xAD6(z);
 168        w[p0] = r0;     /* Clear the watchdog. */
 169        ssync;
 170
 171        /*
 172         * switch to IDLE stack.
 173         */
 174        p0.l = _secondary_stack;
 175        p0.h = _secondary_stack;
 176        sp = [p0];
 177        usp = sp;
 178        fp = sp;
 179        sp += -12;
 180        call _init_pda
 181        sp += 12;
 182        call _secondary_start_kernel;
 183.L_exit:
 184        jump.s  .L_exit;
 185ENDPROC(_coreb_start)
 186
 187__FINIT
 188