secondary.S 3.9 KB

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