context.S 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. /*
  2. * Copyright 2007-2009 Analog Devices Inc.
  3. *
  4. * Licensed under the GPL-2 or later.
  5. */
  6. /*
  7. * NOTE! The single-stepping code assumes that all interrupt handlers
  8. * start by saving SYSCFG on the stack with their first instruction.
  9. */
  10. /*
  11. * Code to save processor context.
  12. * We even save the register which are preserved by a function call
  13. * - r4, r5, r6, r7, p3, p4, p5
  14. */
  15. .macro save_context_with_interrupts
  16. [--sp] = SYSCFG;
  17. [--sp] = P0; /*orig_p0*/
  18. [--sp] = R0; /*orig_r0*/
  19. [--sp] = ( R7:0, P5:0 );
  20. [--sp] = fp;
  21. [--sp] = usp;
  22. [--sp] = i0;
  23. [--sp] = i1;
  24. [--sp] = i2;
  25. [--sp] = i3;
  26. [--sp] = m0;
  27. [--sp] = m1;
  28. [--sp] = m2;
  29. [--sp] = m3;
  30. [--sp] = l0;
  31. [--sp] = l1;
  32. [--sp] = l2;
  33. [--sp] = l3;
  34. [--sp] = b0;
  35. [--sp] = b1;
  36. [--sp] = b2;
  37. [--sp] = b3;
  38. [--sp] = a0.x;
  39. [--sp] = a0.w;
  40. [--sp] = a1.x;
  41. [--sp] = a1.w;
  42. [--sp] = LC0;
  43. [--sp] = LC1;
  44. [--sp] = LT0;
  45. [--sp] = LT1;
  46. [--sp] = LB0;
  47. [--sp] = LB1;
  48. [--sp] = ASTAT;
  49. [--sp] = r0; /* Skip reserved */
  50. [--sp] = RETS;
  51. r0 = RETI;
  52. [--sp] = r0;
  53. [--sp] = RETX;
  54. [--sp] = RETN;
  55. [--sp] = RETE;
  56. [--sp] = SEQSTAT;
  57. [--sp] = r0; /* Skip IPEND as well. */
  58. /* Switch to other method of keeping interrupts disabled. */
  59. #ifdef CONFIG_DEBUG_HWERR
  60. r0 = 0x3f;
  61. sti r0;
  62. #else
  63. cli r0;
  64. #endif
  65. [--sp] = RETI; /*orig_pc*/
  66. /* Clear all L registers. */
  67. r0 = 0 (x);
  68. l0 = r0;
  69. l1 = r0;
  70. l2 = r0;
  71. l3 = r0;
  72. .endm
  73. .macro save_context_syscall
  74. [--sp] = SYSCFG;
  75. [--sp] = P0; /*orig_p0*/
  76. [--sp] = R0; /*orig_r0*/
  77. [--sp] = ( R7:0, P5:0 );
  78. [--sp] = fp;
  79. [--sp] = usp;
  80. [--sp] = i0;
  81. [--sp] = i1;
  82. [--sp] = i2;
  83. [--sp] = i3;
  84. [--sp] = m0;
  85. [--sp] = m1;
  86. [--sp] = m2;
  87. [--sp] = m3;
  88. [--sp] = l0;
  89. [--sp] = l1;
  90. [--sp] = l2;
  91. [--sp] = l3;
  92. [--sp] = b0;
  93. [--sp] = b1;
  94. [--sp] = b2;
  95. [--sp] = b3;
  96. [--sp] = a0.x;
  97. [--sp] = a0.w;
  98. [--sp] = a1.x;
  99. [--sp] = a1.w;
  100. [--sp] = LC0;
  101. [--sp] = LC1;
  102. [--sp] = LT0;
  103. [--sp] = LT1;
  104. [--sp] = LB0;
  105. [--sp] = LB1;
  106. [--sp] = ASTAT;
  107. [--sp] = r0; /* Skip reserved */
  108. [--sp] = RETS;
  109. r0 = RETI;
  110. [--sp] = r0;
  111. [--sp] = RETX;
  112. [--sp] = RETN;
  113. [--sp] = RETE;
  114. [--sp] = SEQSTAT;
  115. [--sp] = r0; /* Skip IPEND as well. */
  116. [--sp] = RETI; /*orig_pc*/
  117. /* Clear all L registers. */
  118. r0 = 0 (x);
  119. l0 = r0;
  120. l1 = r0;
  121. l2 = r0;
  122. l3 = r0;
  123. .endm
  124. .macro save_context_no_interrupts
  125. [--sp] = SYSCFG;
  126. [--sp] = P0; /* orig_p0 */
  127. [--sp] = R0; /* orig_r0 */
  128. [--sp] = ( R7:0, P5:0 );
  129. [--sp] = fp;
  130. [--sp] = usp;
  131. [--sp] = i0;
  132. [--sp] = i1;
  133. [--sp] = i2;
  134. [--sp] = i3;
  135. [--sp] = m0;
  136. [--sp] = m1;
  137. [--sp] = m2;
  138. [--sp] = m3;
  139. [--sp] = l0;
  140. [--sp] = l1;
  141. [--sp] = l2;
  142. [--sp] = l3;
  143. [--sp] = b0;
  144. [--sp] = b1;
  145. [--sp] = b2;
  146. [--sp] = b3;
  147. [--sp] = a0.x;
  148. [--sp] = a0.w;
  149. [--sp] = a1.x;
  150. [--sp] = a1.w;
  151. [--sp] = LC0;
  152. [--sp] = LC1;
  153. [--sp] = LT0;
  154. [--sp] = LT1;
  155. [--sp] = LB0;
  156. [--sp] = LB1;
  157. [--sp] = ASTAT;
  158. #ifdef CONFIG_KGDB
  159. fp = 0(Z);
  160. r1 = sp;
  161. r1 += 60;
  162. r1 += 60;
  163. r1 += 60;
  164. [--sp] = r1;
  165. #else
  166. [--sp] = r0; /* Skip reserved */
  167. #endif
  168. [--sp] = RETS;
  169. r0 = RETI;
  170. [--sp] = r0;
  171. [--sp] = RETX;
  172. [--sp] = RETN;
  173. [--sp] = RETE;
  174. [--sp] = SEQSTAT;
  175. #ifdef CONFIG_DEBUG_KERNEL
  176. p1.l = lo(IPEND);
  177. p1.h = hi(IPEND);
  178. r1 = [p1];
  179. [--sp] = r1;
  180. #else
  181. [--sp] = r0; /* Skip IPEND as well. */
  182. #endif
  183. [--sp] = r0; /*orig_pc*/
  184. /* Clear all L registers. */
  185. r0 = 0 (x);
  186. l0 = r0;
  187. l1 = r0;
  188. l2 = r0;
  189. l3 = r0;
  190. .endm
  191. .macro restore_context_no_interrupts
  192. sp += 4; /* Skip orig_pc */
  193. sp += 4; /* Skip IPEND */
  194. SEQSTAT = [sp++];
  195. RETE = [sp++];
  196. RETN = [sp++];
  197. RETX = [sp++];
  198. r0 = [sp++];
  199. RETI = r0; /* Restore RETI indirectly when in exception */
  200. RETS = [sp++];
  201. sp += 4; /* Skip Reserved */
  202. ASTAT = [sp++];
  203. LB1 = [sp++];
  204. LB0 = [sp++];
  205. LT1 = [sp++];
  206. LT0 = [sp++];
  207. LC1 = [sp++];
  208. LC0 = [sp++];
  209. a1.w = [sp++];
  210. a1.x = [sp++];
  211. a0.w = [sp++];
  212. a0.x = [sp++];
  213. b3 = [sp++];
  214. b2 = [sp++];
  215. b1 = [sp++];
  216. b0 = [sp++];
  217. l3 = [sp++];
  218. l2 = [sp++];
  219. l1 = [sp++];
  220. l0 = [sp++];
  221. m3 = [sp++];
  222. m2 = [sp++];
  223. m1 = [sp++];
  224. m0 = [sp++];
  225. i3 = [sp++];
  226. i2 = [sp++];
  227. i1 = [sp++];
  228. i0 = [sp++];
  229. sp += 4;
  230. fp = [sp++];
  231. ( R7 : 0, P5 : 0) = [ SP ++ ];
  232. sp += 8; /* Skip orig_r0/orig_p0 */
  233. SYSCFG = [sp++];
  234. .endm
  235. .macro restore_context_with_interrupts
  236. sp += 4; /* Skip orig_pc */
  237. sp += 4; /* Skip IPEND */
  238. SEQSTAT = [sp++];
  239. RETE = [sp++];
  240. RETN = [sp++];
  241. RETX = [sp++];
  242. RETI = [sp++];
  243. RETS = [sp++];
  244. #ifdef CONFIG_SMP
  245. GET_PDA(p0, r0);
  246. r0 = [p0 + PDA_IRQFLAGS];
  247. #else
  248. p0.h = _bfin_irq_flags;
  249. p0.l = _bfin_irq_flags;
  250. r0 = [p0];
  251. #endif
  252. sti r0;
  253. sp += 4; /* Skip Reserved */
  254. ASTAT = [sp++];
  255. LB1 = [sp++];
  256. LB0 = [sp++];
  257. LT1 = [sp++];
  258. LT0 = [sp++];
  259. LC1 = [sp++];
  260. LC0 = [sp++];
  261. a1.w = [sp++];
  262. a1.x = [sp++];
  263. a0.w = [sp++];
  264. a0.x = [sp++];
  265. b3 = [sp++];
  266. b2 = [sp++];
  267. b1 = [sp++];
  268. b0 = [sp++];
  269. l3 = [sp++];
  270. l2 = [sp++];
  271. l1 = [sp++];
  272. l0 = [sp++];
  273. m3 = [sp++];
  274. m2 = [sp++];
  275. m1 = [sp++];
  276. m0 = [sp++];
  277. i3 = [sp++];
  278. i2 = [sp++];
  279. i1 = [sp++];
  280. i0 = [sp++];
  281. sp += 4;
  282. fp = [sp++];
  283. ( R7 : 0, P5 : 0) = [ SP ++ ];
  284. sp += 8; /* Skip orig_r0/orig_p0 */
  285. csync;
  286. SYSCFG = [sp++];
  287. csync;
  288. .endm
  289. .macro save_context_cplb
  290. [--sp] = (R7:0, P5:0);
  291. [--sp] = fp;
  292. [--sp] = a0.x;
  293. [--sp] = a0.w;
  294. [--sp] = a1.x;
  295. [--sp] = a1.w;
  296. [--sp] = LC0;
  297. [--sp] = LC1;
  298. [--sp] = LT0;
  299. [--sp] = LT1;
  300. [--sp] = LB0;
  301. [--sp] = LB1;
  302. [--sp] = RETS;
  303. .endm
  304. .macro restore_context_cplb
  305. RETS = [sp++];
  306. LB1 = [sp++];
  307. LB0 = [sp++];
  308. LT1 = [sp++];
  309. LT0 = [sp++];
  310. LC1 = [sp++];
  311. LC0 = [sp++];
  312. a1.w = [sp++];
  313. a1.x = [sp++];
  314. a0.w = [sp++];
  315. a0.x = [sp++];
  316. fp = [sp++];
  317. (R7:0, P5:0) = [SP++];
  318. .endm