secondary.S 3.8 KB

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