diff options
-rw-r--r-- | arch/blackfin/mach-bf561/secondary.S | 132 |
1 files changed, 54 insertions, 78 deletions
diff --git a/arch/blackfin/mach-bf561/secondary.S b/arch/blackfin/mach-bf561/secondary.S index 4c462838f4e1..348c9191d19f 100644 --- a/arch/blackfin/mach-bf561/secondary.S +++ b/arch/blackfin/mach-bf561/secondary.S @@ -23,74 +23,56 @@ #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; + /* 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; - trace_buffer_init(p0,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); - /* Turn off the icache */ - p0.l = LO(IMEM_CONTROL); - p0.h = HI(IMEM_CONTROL); - R1 = [p0]; - R0 = ~ENICPLB; - R0 = R0 & R1; + /* Zero out registers required by Blackfin ABI */ - /* Disabling of CPLBs should be proceeded by a CSYNC */ + /* 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; - [p0] = R0; + + 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 */ - p0.l = LO(DMEM_CONTROL); - p0.h = HI(DMEM_CONTROL); - R1 = [p0]; - R0 = ~ENDCPLB; - R0 = R0 & R1; - - /* Disabling of CPLBs should be proceeded by a CSYNC */ - CSYNC; - [p0] = R0; + 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 */ @@ -105,25 +87,25 @@ ENTRY(_coreb_trampoline_start) * below */ GET_PDA(p0, r0); - r7 = [p0 + PDA_DF_RETX]; + r5 = [p0 + PDA_DF_RETX]; p1.l = _init_saved_retx_coreb; p1.h = _init_saved_retx_coreb; - [p1] = r7; + [p1] = r5; - r7 = [p0 + PDA_DF_DCPLB]; + r5 = [p0 + PDA_DF_DCPLB]; p1.l = _init_saved_dcplb_fault_addr_coreb; p1.h = _init_saved_dcplb_fault_addr_coreb; - [p1] = r7; + [p1] = r5; - r7 = [p0 + PDA_DF_ICPLB]; + r5 = [p0 + PDA_DF_ICPLB]; p1.l = _init_saved_icplb_fault_addr_coreb; p1.h = _init_saved_icplb_fault_addr_coreb; - [p1] = r7; + [p1] = r5; - r7 = [p0 + PDA_DF_SEQSTAT]; + r5 = [p0 + PDA_DF_SEQSTAT]; p1.l = _init_saved_seqstat_coreb; p1.h = _init_saved_seqstat_coreb; - [p1] = r7; + [p1] = r5; #endif /* Initialize stack pointer */ @@ -138,19 +120,13 @@ ENTRY(_coreb_trampoline_start) /* EVT15 = _real_start */ - p0.l = lo(EVT15); - p0.h = hi(EVT15); p1.l = _coreb_start; p1.h = _coreb_start; - [p0] = p1; + [p5 + (EVT15 - COREMMR_BASE)] = p1; csync; - p0.l = lo(IMASK); - p0.h = hi(IMASK); - p1.l = IMASK_IVG15; - p1.h = 0x0; - [p0] = p1; - csync; + r0 = EVT_IVG15 (z); + sti r0; raise 15; p0.l = .LWAIT_HERE; |