relocate_kernel.S 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /*
  2. * arch/ia64/kernel/relocate_kernel.S
  3. *
  4. * Relocate kexec'able kernel and start it
  5. *
  6. * Copyright (C) 2005 Hewlett-Packard Development Company, L.P.
  7. * Copyright (C) 2005 Khalid Aziz <khalid.aziz@hp.com>
  8. * Copyright (C) 2005 Intel Corp, Zou Nan hai <nanhai.zou@intel.com>
  9. *
  10. * This source code is licensed under the GNU General Public License,
  11. * Version 2. See the file COPYING for more details.
  12. */
  13. #include <asm/asmmacro.h>
  14. #include <asm/kregs.h>
  15. #include <asm/page.h>
  16. #include <asm/pgtable.h>
  17. #include <asm/mca_asm.h>
  18. /* Must be relocatable PIC code callable as a C function
  19. */
  20. GLOBAL_ENTRY(relocate_new_kernel)
  21. .prologue
  22. alloc r31=ar.pfs,4,0,0,0
  23. .body
  24. .reloc_entry:
  25. {
  26. rsm psr.i| psr.ic
  27. mov r2=ip
  28. }
  29. ;;
  30. {
  31. flushrs // must be first insn in group
  32. srlz.i
  33. }
  34. ;;
  35. dep r2=0,r2,61,3 //to physical address
  36. ;;
  37. //first switch to physical mode
  38. add r3=1f-.reloc_entry, r2
  39. movl r16 = IA64_PSR_AC|IA64_PSR_BN|IA64_PSR_IC
  40. mov ar.rsc=0 // put RSE in enforced lazy mode
  41. ;;
  42. add sp=(memory_stack_end - 16 - .reloc_entry),r2
  43. add r8=(register_stack - .reloc_entry),r2
  44. ;;
  45. mov r18=ar.rnat
  46. mov ar.bspstore=r8
  47. ;;
  48. mov cr.ipsr=r16
  49. mov cr.iip=r3
  50. mov cr.ifs=r0
  51. srlz.i
  52. ;;
  53. mov ar.rnat=r18
  54. rfi
  55. ;;
  56. 1:
  57. //physical mode code begin
  58. mov b6=in1
  59. dep r28=0,in2,61,3 //to physical address
  60. // purge all TC entries
  61. #define O(member) IA64_CPUINFO_##member##_OFFSET
  62. GET_THIS_PADDR(r2, cpu_info) // load phys addr of cpu_info into r2
  63. ;;
  64. addl r17=O(PTCE_STRIDE),r2
  65. addl r2=O(PTCE_BASE),r2
  66. ;;
  67. ld8 r18=[r2],(O(PTCE_COUNT)-O(PTCE_BASE));; // r18=ptce_base
  68. ld4 r19=[r2],4 // r19=ptce_count[0]
  69. ld4 r21=[r17],4 // r21=ptce_stride[0]
  70. ;;
  71. ld4 r20=[r2] // r20=ptce_count[1]
  72. ld4 r22=[r17] // r22=ptce_stride[1]
  73. mov r24=r0
  74. ;;
  75. adds r20=-1,r20
  76. ;;
  77. #undef O
  78. 2:
  79. cmp.ltu p6,p7=r24,r19
  80. (p7) br.cond.dpnt.few 4f
  81. mov ar.lc=r20
  82. 3:
  83. ptc.e r18
  84. ;;
  85. add r18=r22,r18
  86. br.cloop.sptk.few 3b
  87. ;;
  88. add r18=r21,r18
  89. add r24=1,r24
  90. ;;
  91. br.sptk.few 2b
  92. 4:
  93. srlz.i
  94. ;;
  95. //purge TR entry for kernel text and data
  96. movl r16=KERNEL_START
  97. mov r18=KERNEL_TR_PAGE_SHIFT<<2
  98. ;;
  99. ptr.i r16, r18
  100. ptr.d r16, r18
  101. ;;
  102. srlz.i
  103. ;;
  104. // purge TR entry for percpu data
  105. movl r16=PERCPU_ADDR
  106. mov r18=PERCPU_PAGE_SHIFT<<2
  107. ;;
  108. ptr.d r16,r18
  109. ;;
  110. srlz.d
  111. ;;
  112. // purge TR entry for pal code
  113. mov r16=in3
  114. mov r18=IA64_GRANULE_SHIFT<<2
  115. ;;
  116. ptr.i r16,r18
  117. ;;
  118. srlz.i
  119. ;;
  120. // purge TR entry for stack
  121. mov r16=IA64_KR(CURRENT_STACK)
  122. ;;
  123. shl r16=r16,IA64_GRANULE_SHIFT
  124. movl r19=PAGE_OFFSET
  125. ;;
  126. add r16=r19,r16
  127. mov r18=IA64_GRANULE_SHIFT<<2
  128. ;;
  129. ptr.d r16,r18
  130. ;;
  131. srlz.i
  132. ;;
  133. //copy segments
  134. movl r16=PAGE_MASK
  135. mov r30=in0 // in0 is page_list
  136. br.sptk.few .dest_page
  137. ;;
  138. .loop:
  139. ld8 r30=[in0], 8;;
  140. .dest_page:
  141. tbit.z p0, p6=r30, 0;; // 0x1 dest page
  142. (p6) and r17=r30, r16
  143. (p6) br.cond.sptk.few .loop;;
  144. tbit.z p0, p6=r30, 1;; // 0x2 indirect page
  145. (p6) and in0=r30, r16
  146. (p6) br.cond.sptk.few .loop;;
  147. tbit.z p0, p6=r30, 2;; // 0x4 end flag
  148. (p6) br.cond.sptk.few .end_loop;;
  149. tbit.z p6, p0=r30, 3;; // 0x8 source page
  150. (p6) br.cond.sptk.few .loop
  151. and r18=r30, r16
  152. // simple copy page, may optimize later
  153. movl r14=PAGE_SIZE/8 - 1;;
  154. mov ar.lc=r14;;
  155. 1:
  156. ld8 r14=[r18], 8;;
  157. st8 [r17]=r14;;
  158. fc.i r17
  159. add r17=8, r17
  160. br.ctop.sptk.few 1b
  161. br.sptk.few .loop
  162. ;;
  163. .end_loop:
  164. sync.i // for fc.i
  165. ;;
  166. srlz.i
  167. ;;
  168. srlz.d
  169. ;;
  170. br.call.sptk.many b0=b6;;
  171. .align 32
  172. memory_stack:
  173. .fill 8192, 1, 0
  174. memory_stack_end:
  175. register_stack:
  176. .fill 8192, 1, 0
  177. register_stack_end:
  178. relocate_new_kernel_end:
  179. END(relocate_new_kernel)
  180. .global relocate_new_kernel_size
  181. relocate_new_kernel_size:
  182. data8 relocate_new_kernel_end - relocate_new_kernel
  183. GLOBAL_ENTRY(ia64_dump_cpu_regs)
  184. .prologue
  185. alloc loc0=ar.pfs,1,2,0,0
  186. .body
  187. mov ar.rsc=0 // put RSE in enforced lazy mode
  188. add loc1=4*8, in0 // save r4 and r5 first
  189. ;;
  190. {
  191. flushrs // flush dirty regs to backing store
  192. srlz.i
  193. }
  194. st8 [loc1]=r4, 8
  195. ;;
  196. st8 [loc1]=r5, 8
  197. ;;
  198. add loc1=32*8, in0
  199. mov r4=ar.rnat
  200. ;;
  201. st8 [in0]=r0, 8 // r0
  202. st8 [loc1]=r4, 8 // rnat
  203. mov r5=pr
  204. ;;
  205. st8 [in0]=r1, 8 // r1
  206. st8 [loc1]=r5, 8 // pr
  207. mov r4=b0
  208. ;;
  209. st8 [in0]=r2, 8 // r2
  210. st8 [loc1]=r4, 8 // b0
  211. mov r5=b1;
  212. ;;
  213. st8 [in0]=r3, 24 // r3
  214. st8 [loc1]=r5, 8 // b1
  215. mov r4=b2
  216. ;;
  217. st8 [in0]=r6, 8 // r6
  218. st8 [loc1]=r4, 8 // b2
  219. mov r5=b3
  220. ;;
  221. st8 [in0]=r7, 8 // r7
  222. st8 [loc1]=r5, 8 // b3
  223. mov r4=b4
  224. ;;
  225. st8 [in0]=r8, 8 // r8
  226. st8 [loc1]=r4, 8 // b4
  227. mov r5=b5
  228. ;;
  229. st8 [in0]=r9, 8 // r9
  230. st8 [loc1]=r5, 8 // b5
  231. mov r4=b6
  232. ;;
  233. st8 [in0]=r10, 8 // r10
  234. st8 [loc1]=r5, 8 // b6
  235. mov r5=b7
  236. ;;
  237. st8 [in0]=r11, 8 // r11
  238. st8 [loc1]=r5, 8 // b7
  239. mov r4=b0
  240. ;;
  241. st8 [in0]=r12, 8 // r12
  242. st8 [loc1]=r4, 8 // ip
  243. mov r5=loc0
  244. ;;
  245. st8 [in0]=r13, 8 // r13
  246. extr.u r5=r5, 0, 38 // ar.pfs.pfm
  247. mov r4=r0 // user mask
  248. ;;
  249. st8 [in0]=r14, 8 // r14
  250. st8 [loc1]=r5, 8 // cfm
  251. ;;
  252. st8 [in0]=r15, 8 // r15
  253. st8 [loc1]=r4, 8 // user mask
  254. mov r5=ar.rsc
  255. ;;
  256. st8 [in0]=r16, 8 // r16
  257. st8 [loc1]=r5, 8 // ar.rsc
  258. mov r4=ar.bsp
  259. ;;
  260. st8 [in0]=r17, 8 // r17
  261. st8 [loc1]=r4, 8 // ar.bsp
  262. mov r5=ar.bspstore
  263. ;;
  264. st8 [in0]=r18, 8 // r18
  265. st8 [loc1]=r5, 8 // ar.bspstore
  266. mov r4=ar.rnat
  267. ;;
  268. st8 [in0]=r19, 8 // r19
  269. st8 [loc1]=r4, 8 // ar.rnat
  270. mov r5=ar.ccv
  271. ;;
  272. st8 [in0]=r20, 8 // r20
  273. st8 [loc1]=r5, 8 // ar.ccv
  274. mov r4=ar.unat
  275. ;;
  276. st8 [in0]=r21, 8 // r21
  277. st8 [loc1]=r4, 8 // ar.unat
  278. mov r5 = ar.fpsr
  279. ;;
  280. st8 [in0]=r22, 8 // r22
  281. st8 [loc1]=r5, 8 // ar.fpsr
  282. mov r4 = ar.unat
  283. ;;
  284. st8 [in0]=r23, 8 // r23
  285. st8 [loc1]=r4, 8 // unat
  286. mov r5 = ar.fpsr
  287. ;;
  288. st8 [in0]=r24, 8 // r24
  289. st8 [loc1]=r5, 8 // fpsr
  290. mov r4 = ar.pfs
  291. ;;
  292. st8 [in0]=r25, 8 // r25
  293. st8 [loc1]=r4, 8 // ar.pfs
  294. mov r5 = ar.lc
  295. ;;
  296. st8 [in0]=r26, 8 // r26
  297. st8 [loc1]=r5, 8 // ar.lc
  298. mov r4 = ar.ec
  299. ;;
  300. st8 [in0]=r27, 8 // r27
  301. st8 [loc1]=r4, 8 // ar.ec
  302. mov r5 = ar.csd
  303. ;;
  304. st8 [in0]=r28, 8 // r28
  305. st8 [loc1]=r5, 8 // ar.csd
  306. mov r4 = ar.ssd
  307. ;;
  308. st8 [in0]=r29, 8 // r29
  309. st8 [loc1]=r4, 8 // ar.ssd
  310. ;;
  311. st8 [in0]=r30, 8 // r30
  312. ;;
  313. st8 [in0]=r31, 8 // r31
  314. mov ar.pfs=loc0
  315. ;;
  316. br.ret.sptk.many rp
  317. END(ia64_dump_cpu_regs)