entry.S 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003
  1. /*
  2. * arch/sh/kernel/cpu/sh5/entry.S
  3. *
  4. * Copyright (C) 2000, 2001 Paolo Alberelli
  5. * Copyright (C) 2004 - 2008 Paul Mundt
  6. * Copyright (C) 2003, 2004 Richard Curnow
  7. *
  8. * This file is subject to the terms and conditions of the GNU General Public
  9. * License. See the file "COPYING" in the main directory of this archive
  10. * for more details.
  11. */
  12. #include <linux/errno.h>
  13. #include <linux/init.h>
  14. #include <linux/sys.h>
  15. #include <cpu/registers.h>
  16. #include <asm/processor.h>
  17. #include <asm/unistd.h>
  18. #include <asm/thread_info.h>
  19. #include <asm/asm-offsets.h>
  20. /*
  21. * SR fields.
  22. */
  23. #define SR_ASID_MASK 0x00ff0000
  24. #define SR_FD_MASK 0x00008000
  25. #define SR_SS 0x08000000
  26. #define SR_BL 0x10000000
  27. #define SR_MD 0x40000000
  28. /*
  29. * Event code.
  30. */
  31. #define EVENT_INTERRUPT 0
  32. #define EVENT_FAULT_TLB 1
  33. #define EVENT_FAULT_NOT_TLB 2
  34. #define EVENT_DEBUG 3
  35. /* EXPEVT values */
  36. #define RESET_CAUSE 0x20
  37. #define DEBUGSS_CAUSE 0x980
  38. /*
  39. * Frame layout. Quad index.
  40. */
  41. #define FRAME_T(x) FRAME_TBASE+(x*8)
  42. #define FRAME_R(x) FRAME_RBASE+(x*8)
  43. #define FRAME_S(x) FRAME_SBASE+(x*8)
  44. #define FSPC 0
  45. #define FSSR 1
  46. #define FSYSCALL_ID 2
  47. /* Arrange the save frame to be a multiple of 32 bytes long */
  48. #define FRAME_SBASE 0
  49. #define FRAME_RBASE (FRAME_SBASE+(3*8)) /* SYSCALL_ID - SSR - SPC */
  50. #define FRAME_TBASE (FRAME_RBASE+(63*8)) /* r0 - r62 */
  51. #define FRAME_PBASE (FRAME_TBASE+(8*8)) /* tr0 -tr7 */
  52. #define FRAME_SIZE (FRAME_PBASE+(2*8)) /* pad0-pad1 */
  53. #define FP_FRAME_SIZE FP_FRAME_BASE+(33*8) /* dr0 - dr31 + fpscr */
  54. #define FP_FRAME_BASE 0
  55. #define SAVED_R2 0*8
  56. #define SAVED_R3 1*8
  57. #define SAVED_R4 2*8
  58. #define SAVED_R5 3*8
  59. #define SAVED_R18 4*8
  60. #define SAVED_R6 5*8
  61. #define SAVED_TR0 6*8
  62. /* These are the registers saved in the TLB path that aren't saved in the first
  63. level of the normal one. */
  64. #define TLB_SAVED_R25 7*8
  65. #define TLB_SAVED_TR1 8*8
  66. #define TLB_SAVED_TR2 9*8
  67. #define TLB_SAVED_TR3 10*8
  68. #define TLB_SAVED_TR4 11*8
  69. /* Save R0/R1 : PT-migrating compiler currently dishounours -ffixed-r0 and -ffixed-r1 causing
  70. breakage otherwise. */
  71. #define TLB_SAVED_R0 12*8
  72. #define TLB_SAVED_R1 13*8
  73. #define CLI() \
  74. getcon SR, r6; \
  75. ori r6, 0xf0, r6; \
  76. putcon r6, SR;
  77. #define STI() \
  78. getcon SR, r6; \
  79. andi r6, ~0xf0, r6; \
  80. putcon r6, SR;
  81. #ifdef CONFIG_PREEMPT
  82. # define preempt_stop() CLI()
  83. #else
  84. # define preempt_stop()
  85. # define resume_kernel restore_all
  86. #endif
  87. .section .data, "aw"
  88. #define FAST_TLBMISS_STACK_CACHELINES 4
  89. #define FAST_TLBMISS_STACK_QUADWORDS (4*FAST_TLBMISS_STACK_CACHELINES)
  90. /* Register back-up area for all exceptions */
  91. .balign 32
  92. /* Allow for 16 quadwords to be pushed by fast tlbmiss handling
  93. * register saves etc. */
  94. .fill FAST_TLBMISS_STACK_QUADWORDS, 8, 0x0
  95. /* This is 32 byte aligned by construction */
  96. /* Register back-up area for all exceptions */
  97. reg_save_area:
  98. .quad 0
  99. .quad 0
  100. .quad 0
  101. .quad 0
  102. .quad 0
  103. .quad 0
  104. .quad 0
  105. .quad 0
  106. .quad 0
  107. .quad 0
  108. .quad 0
  109. .quad 0
  110. .quad 0
  111. .quad 0
  112. /* Save area for RESVEC exceptions. We cannot use reg_save_area because of
  113. * reentrancy. Note this area may be accessed via physical address.
  114. * Align so this fits a whole single cache line, for ease of purging.
  115. */
  116. .balign 32,0,32
  117. resvec_save_area:
  118. .quad 0
  119. .quad 0
  120. .quad 0
  121. .quad 0
  122. .quad 0
  123. .balign 32,0,32
  124. /* Jump table of 3rd level handlers */
  125. trap_jtable:
  126. .long do_exception_error /* 0x000 */
  127. .long do_exception_error /* 0x020 */
  128. #ifdef CONFIG_MMU
  129. .long tlb_miss_load /* 0x040 */
  130. .long tlb_miss_store /* 0x060 */
  131. #else
  132. .long do_exception_error
  133. .long do_exception_error
  134. #endif
  135. ! ARTIFICIAL pseudo-EXPEVT setting
  136. .long do_debug_interrupt /* 0x080 */
  137. #ifdef CONFIG_MMU
  138. .long tlb_miss_load /* 0x0A0 */
  139. .long tlb_miss_store /* 0x0C0 */
  140. #else
  141. .long do_exception_error
  142. .long do_exception_error
  143. #endif
  144. .long do_address_error_load /* 0x0E0 */
  145. .long do_address_error_store /* 0x100 */
  146. #ifdef CONFIG_SH_FPU
  147. .long do_fpu_error /* 0x120 */
  148. #else
  149. .long do_exception_error /* 0x120 */
  150. #endif
  151. .long do_exception_error /* 0x140 */
  152. .long system_call /* 0x160 */
  153. .long do_reserved_inst /* 0x180 */
  154. .long do_illegal_slot_inst /* 0x1A0 */
  155. .long do_exception_error /* 0x1C0 - NMI */
  156. .long do_exception_error /* 0x1E0 */
  157. .rept 15
  158. .long do_IRQ /* 0x200 - 0x3C0 */
  159. .endr
  160. .long do_exception_error /* 0x3E0 */
  161. .rept 32
  162. .long do_IRQ /* 0x400 - 0x7E0 */
  163. .endr
  164. .long fpu_error_or_IRQA /* 0x800 */
  165. .long fpu_error_or_IRQB /* 0x820 */
  166. .long do_IRQ /* 0x840 */
  167. .long do_IRQ /* 0x860 */
  168. .rept 6
  169. .long do_exception_error /* 0x880 - 0x920 */
  170. .endr
  171. .long breakpoint_trap_handler /* 0x940 */
  172. .long do_exception_error /* 0x960 */
  173. .long do_single_step /* 0x980 */
  174. .rept 3
  175. .long do_exception_error /* 0x9A0 - 0x9E0 */
  176. .endr
  177. .long do_IRQ /* 0xA00 */
  178. .long do_IRQ /* 0xA20 */
  179. #ifdef CONFIG_MMU
  180. .long itlb_miss_or_IRQ /* 0xA40 */
  181. #else
  182. .long do_IRQ
  183. #endif
  184. .long do_IRQ /* 0xA60 */
  185. .long do_IRQ /* 0xA80 */
  186. #ifdef CONFIG_MMU
  187. .long itlb_miss_or_IRQ /* 0xAA0 */
  188. #else
  189. .long do_IRQ
  190. #endif
  191. .long do_exception_error /* 0xAC0 */
  192. .long do_address_error_exec /* 0xAE0 */
  193. .rept 8
  194. .long do_exception_error /* 0xB00 - 0xBE0 */
  195. .endr
  196. .rept 18
  197. .long do_IRQ /* 0xC00 - 0xE20 */
  198. .endr
  199. .section .text64, "ax"
  200. /*
  201. * --- Exception/Interrupt/Event Handling Section
  202. */
  203. /*
  204. * VBR and RESVEC blocks.
  205. *
  206. * First level handler for VBR-based exceptions.
  207. *
  208. * To avoid waste of space, align to the maximum text block size.
  209. * This is assumed to be at most 128 bytes or 32 instructions.
  210. * DO NOT EXCEED 32 instructions on the first level handlers !
  211. *
  212. * Also note that RESVEC is contained within the VBR block
  213. * where the room left (1KB - TEXT_SIZE) allows placing
  214. * the RESVEC block (at most 512B + TEXT_SIZE).
  215. *
  216. * So first (and only) level handler for RESVEC-based exceptions.
  217. *
  218. * Where the fault/interrupt is handled (not_a_tlb_miss, tlb_miss
  219. * and interrupt) we are a lot tight with register space until
  220. * saving onto the stack frame, which is done in handle_exception().
  221. *
  222. */
  223. #define TEXT_SIZE 128
  224. #define BLOCK_SIZE 1664 /* Dynamic check, 13*128 */
  225. .balign TEXT_SIZE
  226. LVBR_block:
  227. .space 256, 0 /* Power-on class handler, */
  228. /* not required here */
  229. not_a_tlb_miss:
  230. synco /* TAKum03020 (but probably a good idea anyway.) */
  231. /* Save original stack pointer into KCR1 */
  232. putcon SP, KCR1
  233. /* Save other original registers into reg_save_area */
  234. movi reg_save_area, SP
  235. st.q SP, SAVED_R2, r2
  236. st.q SP, SAVED_R3, r3
  237. st.q SP, SAVED_R4, r4
  238. st.q SP, SAVED_R5, r5
  239. st.q SP, SAVED_R6, r6
  240. st.q SP, SAVED_R18, r18
  241. gettr tr0, r3
  242. st.q SP, SAVED_TR0, r3
  243. /* Set args for Non-debug, Not a TLB miss class handler */
  244. getcon EXPEVT, r2
  245. movi ret_from_exception, r3
  246. ori r3, 1, r3
  247. movi EVENT_FAULT_NOT_TLB, r4
  248. or SP, ZERO, r5
  249. getcon KCR1, SP
  250. pta handle_exception, tr0
  251. blink tr0, ZERO
  252. .balign 256
  253. ! VBR+0x200
  254. nop
  255. .balign 256
  256. ! VBR+0x300
  257. nop
  258. .balign 256
  259. /*
  260. * Instead of the natural .balign 1024 place RESVEC here
  261. * respecting the final 1KB alignment.
  262. */
  263. .balign TEXT_SIZE
  264. /*
  265. * Instead of '.space 1024-TEXT_SIZE' place the RESVEC
  266. * block making sure the final alignment is correct.
  267. */
  268. #ifdef CONFIG_MMU
  269. tlb_miss:
  270. synco /* TAKum03020 (but probably a good idea anyway.) */
  271. putcon SP, KCR1
  272. movi reg_save_area, SP
  273. /* SP is guaranteed 32-byte aligned. */
  274. st.q SP, TLB_SAVED_R0 , r0
  275. st.q SP, TLB_SAVED_R1 , r1
  276. st.q SP, SAVED_R2 , r2
  277. st.q SP, SAVED_R3 , r3
  278. st.q SP, SAVED_R4 , r4
  279. st.q SP, SAVED_R5 , r5
  280. st.q SP, SAVED_R6 , r6
  281. st.q SP, SAVED_R18, r18
  282. /* Save R25 for safety; as/ld may want to use it to achieve the call to
  283. * the code in mm/tlbmiss.c */
  284. st.q SP, TLB_SAVED_R25, r25
  285. gettr tr0, r2
  286. gettr tr1, r3
  287. gettr tr2, r4
  288. gettr tr3, r5
  289. gettr tr4, r18
  290. st.q SP, SAVED_TR0 , r2
  291. st.q SP, TLB_SAVED_TR1 , r3
  292. st.q SP, TLB_SAVED_TR2 , r4
  293. st.q SP, TLB_SAVED_TR3 , r5
  294. st.q SP, TLB_SAVED_TR4 , r18
  295. pt do_fast_page_fault, tr0
  296. getcon SSR, r2
  297. getcon EXPEVT, r3
  298. getcon TEA, r4
  299. shlri r2, 30, r2
  300. andi r2, 1, r2 /* r2 = SSR.MD */
  301. blink tr0, LINK
  302. pt fixup_to_invoke_general_handler, tr1
  303. /* If the fast path handler fixed the fault, just drop through quickly
  304. to the restore code right away to return to the excepting context.
  305. */
  306. bnei/u r2, 0, tr1
  307. fast_tlb_miss_restore:
  308. ld.q SP, SAVED_TR0, r2
  309. ld.q SP, TLB_SAVED_TR1, r3
  310. ld.q SP, TLB_SAVED_TR2, r4
  311. ld.q SP, TLB_SAVED_TR3, r5
  312. ld.q SP, TLB_SAVED_TR4, r18
  313. ptabs r2, tr0
  314. ptabs r3, tr1
  315. ptabs r4, tr2
  316. ptabs r5, tr3
  317. ptabs r18, tr4
  318. ld.q SP, TLB_SAVED_R0, r0
  319. ld.q SP, TLB_SAVED_R1, r1
  320. ld.q SP, SAVED_R2, r2
  321. ld.q SP, SAVED_R3, r3
  322. ld.q SP, SAVED_R4, r4
  323. ld.q SP, SAVED_R5, r5
  324. ld.q SP, SAVED_R6, r6
  325. ld.q SP, SAVED_R18, r18
  326. ld.q SP, TLB_SAVED_R25, r25
  327. getcon KCR1, SP
  328. rte
  329. nop /* for safety, in case the code is run on sh5-101 cut1.x */
  330. fixup_to_invoke_general_handler:
  331. /* OK, new method. Restore stuff that's not expected to get saved into
  332. the 'first-level' reg save area, then just fall through to setting
  333. up the registers and calling the second-level handler. */
  334. /* 2nd level expects r2,3,4,5,6,18,tr0 to be saved. So we must restore
  335. r25,tr1-4 and save r6 to get into the right state. */
  336. ld.q SP, TLB_SAVED_TR1, r3
  337. ld.q SP, TLB_SAVED_TR2, r4
  338. ld.q SP, TLB_SAVED_TR3, r5
  339. ld.q SP, TLB_SAVED_TR4, r18
  340. ld.q SP, TLB_SAVED_R25, r25
  341. ld.q SP, TLB_SAVED_R0, r0
  342. ld.q SP, TLB_SAVED_R1, r1
  343. ptabs/u r3, tr1
  344. ptabs/u r4, tr2
  345. ptabs/u r5, tr3
  346. ptabs/u r18, tr4
  347. /* Set args for Non-debug, TLB miss class handler */
  348. getcon EXPEVT, r2
  349. movi ret_from_exception, r3
  350. ori r3, 1, r3
  351. movi EVENT_FAULT_TLB, r4
  352. or SP, ZERO, r5
  353. getcon KCR1, SP
  354. pta handle_exception, tr0
  355. blink tr0, ZERO
  356. #else /* CONFIG_MMU */
  357. .balign 256
  358. #endif
  359. /* NB TAKE GREAT CARE HERE TO ENSURE THAT THE INTERRUPT CODE
  360. DOES END UP AT VBR+0x600 */
  361. nop
  362. nop
  363. nop
  364. nop
  365. nop
  366. nop
  367. .balign 256
  368. /* VBR + 0x600 */
  369. interrupt:
  370. synco /* TAKum03020 (but probably a good idea anyway.) */
  371. /* Save original stack pointer into KCR1 */
  372. putcon SP, KCR1
  373. /* Save other original registers into reg_save_area */
  374. movi reg_save_area, SP
  375. st.q SP, SAVED_R2, r2
  376. st.q SP, SAVED_R3, r3
  377. st.q SP, SAVED_R4, r4
  378. st.q SP, SAVED_R5, r5
  379. st.q SP, SAVED_R6, r6
  380. st.q SP, SAVED_R18, r18
  381. gettr tr0, r3
  382. st.q SP, SAVED_TR0, r3
  383. /* Set args for interrupt class handler */
  384. getcon INTEVT, r2
  385. movi ret_from_irq, r3
  386. ori r3, 1, r3
  387. movi EVENT_INTERRUPT, r4
  388. or SP, ZERO, r5
  389. getcon KCR1, SP
  390. pta handle_exception, tr0
  391. blink tr0, ZERO
  392. .balign TEXT_SIZE /* let's waste the bare minimum */
  393. LVBR_block_end: /* Marker. Used for total checking */
  394. .balign 256
  395. LRESVEC_block:
  396. /* Panic handler. Called with MMU off. Possible causes/actions:
  397. * - Reset: Jump to program start.
  398. * - Single Step: Turn off Single Step & return.
  399. * - Others: Call panic handler, passing PC as arg.
  400. * (this may need to be extended...)
  401. */
  402. reset_or_panic:
  403. synco /* TAKum03020 (but probably a good idea anyway.) */
  404. putcon SP, DCR
  405. /* First save r0-1 and tr0, as we need to use these */
  406. movi resvec_save_area-CONFIG_PAGE_OFFSET, SP
  407. st.q SP, 0, r0
  408. st.q SP, 8, r1
  409. gettr tr0, r0
  410. st.q SP, 32, r0
  411. /* Check cause */
  412. getcon EXPEVT, r0
  413. movi RESET_CAUSE, r1
  414. sub r1, r0, r1 /* r1=0 if reset */
  415. movi _stext-CONFIG_PAGE_OFFSET, r0
  416. ori r0, 1, r0
  417. ptabs r0, tr0
  418. beqi r1, 0, tr0 /* Jump to start address if reset */
  419. getcon EXPEVT, r0
  420. movi DEBUGSS_CAUSE, r1
  421. sub r1, r0, r1 /* r1=0 if single step */
  422. pta single_step_panic, tr0
  423. beqi r1, 0, tr0 /* jump if single step */
  424. /* Now jump to where we save the registers. */
  425. movi panic_stash_regs-CONFIG_PAGE_OFFSET, r1
  426. ptabs r1, tr0
  427. blink tr0, r63
  428. single_step_panic:
  429. /* We are in a handler with Single Step set. We need to resume the
  430. * handler, by turning on MMU & turning off Single Step. */
  431. getcon SSR, r0
  432. movi SR_MMU, r1
  433. or r0, r1, r0
  434. movi ~SR_SS, r1
  435. and r0, r1, r0
  436. putcon r0, SSR
  437. /* Restore EXPEVT, as the rte won't do this */
  438. getcon PEXPEVT, r0
  439. putcon r0, EXPEVT
  440. /* Restore regs */
  441. ld.q SP, 32, r0
  442. ptabs r0, tr0
  443. ld.q SP, 0, r0
  444. ld.q SP, 8, r1
  445. getcon DCR, SP
  446. synco
  447. rte
  448. .balign 256
  449. debug_exception:
  450. synco /* TAKum03020 (but probably a good idea anyway.) */
  451. /*
  452. * Single step/software_break_point first level handler.
  453. * Called with MMU off, so the first thing we do is enable it
  454. * by doing an rte with appropriate SSR.
  455. */
  456. putcon SP, DCR
  457. /* Save SSR & SPC, together with R0 & R1, as we need to use 2 regs. */
  458. movi resvec_save_area-CONFIG_PAGE_OFFSET, SP
  459. /* With the MMU off, we are bypassing the cache, so purge any
  460. * data that will be made stale by the following stores.
  461. */
  462. ocbp SP, 0
  463. synco
  464. st.q SP, 0, r0
  465. st.q SP, 8, r1
  466. getcon SPC, r0
  467. st.q SP, 16, r0
  468. getcon SSR, r0
  469. st.q SP, 24, r0
  470. /* Enable MMU, block exceptions, set priv mode, disable single step */
  471. movi SR_MMU | SR_BL | SR_MD, r1
  472. or r0, r1, r0
  473. movi ~SR_SS, r1
  474. and r0, r1, r0
  475. putcon r0, SSR
  476. /* Force control to debug_exception_2 when rte is executed */
  477. movi debug_exeception_2, r0
  478. ori r0, 1, r0 /* force SHmedia, just in case */
  479. putcon r0, SPC
  480. getcon DCR, SP
  481. synco
  482. rte
  483. debug_exeception_2:
  484. /* Restore saved regs */
  485. putcon SP, KCR1
  486. movi resvec_save_area, SP
  487. ld.q SP, 24, r0
  488. putcon r0, SSR
  489. ld.q SP, 16, r0
  490. putcon r0, SPC
  491. ld.q SP, 0, r0
  492. ld.q SP, 8, r1
  493. /* Save other original registers into reg_save_area */
  494. movi reg_save_area, SP
  495. st.q SP, SAVED_R2, r2
  496. st.q SP, SAVED_R3, r3
  497. st.q SP, SAVED_R4, r4
  498. st.q SP, SAVED_R5, r5
  499. st.q SP, SAVED_R6, r6
  500. st.q SP, SAVED_R18, r18
  501. gettr tr0, r3
  502. st.q SP, SAVED_TR0, r3
  503. /* Set args for debug class handler */
  504. getcon EXPEVT, r2
  505. movi ret_from_exception, r3
  506. ori r3, 1, r3
  507. movi EVENT_DEBUG, r4
  508. or SP, ZERO, r5
  509. getcon KCR1, SP
  510. pta handle_exception, tr0
  511. blink tr0, ZERO
  512. .balign 256
  513. debug_interrupt:
  514. /* !!! WE COME HERE IN REAL MODE !!! */
  515. /* Hook-up debug interrupt to allow various debugging options to be
  516. * hooked into its handler. */
  517. /* Save original stack pointer into KCR1 */
  518. synco
  519. putcon SP, KCR1
  520. movi resvec_save_area-CONFIG_PAGE_OFFSET, SP
  521. ocbp SP, 0
  522. ocbp SP, 32
  523. synco
  524. /* Save other original registers into reg_save_area thru real addresses */
  525. st.q SP, SAVED_R2, r2
  526. st.q SP, SAVED_R3, r3
  527. st.q SP, SAVED_R4, r4
  528. st.q SP, SAVED_R5, r5
  529. st.q SP, SAVED_R6, r6
  530. st.q SP, SAVED_R18, r18
  531. gettr tr0, r3
  532. st.q SP, SAVED_TR0, r3
  533. /* move (spc,ssr)->(pspc,pssr). The rte will shift
  534. them back again, so that they look like the originals
  535. as far as the real handler code is concerned. */
  536. getcon spc, r6
  537. putcon r6, pspc
  538. getcon ssr, r6
  539. putcon r6, pssr
  540. ! construct useful SR for handle_exception
  541. movi 3, r6
  542. shlli r6, 30, r6
  543. getcon sr, r18
  544. or r18, r6, r6
  545. putcon r6, ssr
  546. ! SSR is now the current SR with the MD and MMU bits set
  547. ! i.e. the rte will switch back to priv mode and put
  548. ! the mmu back on
  549. ! construct spc
  550. movi handle_exception, r18
  551. ori r18, 1, r18 ! for safety (do we need this?)
  552. putcon r18, spc
  553. /* Set args for Non-debug, Not a TLB miss class handler */
  554. ! EXPEVT==0x80 is unused, so 'steal' this value to put the
  555. ! debug interrupt handler in the vectoring table
  556. movi 0x80, r2
  557. movi ret_from_exception, r3
  558. ori r3, 1, r3
  559. movi EVENT_FAULT_NOT_TLB, r4
  560. or SP, ZERO, r5
  561. movi CONFIG_PAGE_OFFSET, r6
  562. add r6, r5, r5
  563. getcon KCR1, SP
  564. synco ! for safety
  565. rte ! -> handle_exception, switch back to priv mode again
  566. LRESVEC_block_end: /* Marker. Unused. */
  567. .balign TEXT_SIZE
  568. /*
  569. * Second level handler for VBR-based exceptions. Pre-handler.
  570. * In common to all stack-frame sensitive handlers.
  571. *
  572. * Inputs:
  573. * (KCR0) Current [current task union]
  574. * (KCR1) Original SP
  575. * (r2) INTEVT/EXPEVT
  576. * (r3) appropriate return address
  577. * (r4) Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault, 3=debug)
  578. * (r5) Pointer to reg_save_area
  579. * (SP) Original SP
  580. *
  581. * Available registers:
  582. * (r6)
  583. * (r18)
  584. * (tr0)
  585. *
  586. */
  587. handle_exception:
  588. /* Common 2nd level handler. */
  589. /* First thing we need an appropriate stack pointer */
  590. getcon SSR, r6
  591. shlri r6, 30, r6
  592. andi r6, 1, r6
  593. pta stack_ok, tr0
  594. bne r6, ZERO, tr0 /* Original stack pointer is fine */
  595. /* Set stack pointer for user fault */
  596. getcon KCR0, SP
  597. movi THREAD_SIZE, r6 /* Point to the end */
  598. add SP, r6, SP
  599. stack_ok:
  600. /* DEBUG : check for underflow/overflow of the kernel stack */
  601. pta no_underflow, tr0
  602. getcon KCR0, r6
  603. movi 1024, r18
  604. add r6, r18, r6
  605. bge SP, r6, tr0 ! ? below 1k from bottom of stack : danger zone
  606. /* Just panic to cause a crash. */
  607. bad_sp:
  608. ld.b r63, 0, r6
  609. nop
  610. no_underflow:
  611. pta bad_sp, tr0
  612. getcon kcr0, r6
  613. movi THREAD_SIZE, r18
  614. add r18, r6, r6
  615. bgt SP, r6, tr0 ! sp above the stack
  616. /* Make some room for the BASIC frame. */
  617. movi -(FRAME_SIZE), r6
  618. add SP, r6, SP
  619. /* Could do this with no stalling if we had another spare register, but the
  620. code below will be OK. */
  621. ld.q r5, SAVED_R2, r6
  622. ld.q r5, SAVED_R3, r18
  623. st.q SP, FRAME_R(2), r6
  624. ld.q r5, SAVED_R4, r6
  625. st.q SP, FRAME_R(3), r18
  626. ld.q r5, SAVED_R5, r18
  627. st.q SP, FRAME_R(4), r6
  628. ld.q r5, SAVED_R6, r6
  629. st.q SP, FRAME_R(5), r18
  630. ld.q r5, SAVED_R18, r18
  631. st.q SP, FRAME_R(6), r6
  632. ld.q r5, SAVED_TR0, r6
  633. st.q SP, FRAME_R(18), r18
  634. st.q SP, FRAME_T(0), r6
  635. /* Keep old SP around */
  636. getcon KCR1, r6
  637. /* Save the rest of the general purpose registers */
  638. st.q SP, FRAME_R(0), r0
  639. st.q SP, FRAME_R(1), r1
  640. st.q SP, FRAME_R(7), r7
  641. st.q SP, FRAME_R(8), r8
  642. st.q SP, FRAME_R(9), r9
  643. st.q SP, FRAME_R(10), r10
  644. st.q SP, FRAME_R(11), r11
  645. st.q SP, FRAME_R(12), r12
  646. st.q SP, FRAME_R(13), r13
  647. st.q SP, FRAME_R(14), r14
  648. /* SP is somewhere else */
  649. st.q SP, FRAME_R(15), r6
  650. st.q SP, FRAME_R(16), r16
  651. st.q SP, FRAME_R(17), r17
  652. /* r18 is saved earlier. */
  653. st.q SP, FRAME_R(19), r19
  654. st.q SP, FRAME_R(20), r20
  655. st.q SP, FRAME_R(21), r21
  656. st.q SP, FRAME_R(22), r22
  657. st.q SP, FRAME_R(23), r23
  658. st.q SP, FRAME_R(24), r24
  659. st.q SP, FRAME_R(25), r25
  660. st.q SP, FRAME_R(26), r26
  661. st.q SP, FRAME_R(27), r27
  662. st.q SP, FRAME_R(28), r28
  663. st.q SP, FRAME_R(29), r29
  664. st.q SP, FRAME_R(30), r30
  665. st.q SP, FRAME_R(31), r31
  666. st.q SP, FRAME_R(32), r32
  667. st.q SP, FRAME_R(33), r33
  668. st.q SP, FRAME_R(34), r34
  669. st.q SP, FRAME_R(35), r35
  670. st.q SP, FRAME_R(36), r36
  671. st.q SP, FRAME_R(37), r37
  672. st.q SP, FRAME_R(38), r38
  673. st.q SP, FRAME_R(39), r39
  674. st.q SP, FRAME_R(40), r40
  675. st.q SP, FRAME_R(41), r41
  676. st.q SP, FRAME_R(42), r42
  677. st.q SP, FRAME_R(43), r43
  678. st.q SP, FRAME_R(44), r44
  679. st.q SP, FRAME_R(45), r45
  680. st.q SP, FRAME_R(46), r46
  681. st.q SP, FRAME_R(47), r47
  682. st.q SP, FRAME_R(48), r48
  683. st.q SP, FRAME_R(49), r49
  684. st.q SP, FRAME_R(50), r50
  685. st.q SP, FRAME_R(51), r51
  686. st.q SP, FRAME_R(52), r52
  687. st.q SP, FRAME_R(53), r53
  688. st.q SP, FRAME_R(54), r54
  689. st.q SP, FRAME_R(55), r55
  690. st.q SP, FRAME_R(56), r56
  691. st.q SP, FRAME_R(57), r57
  692. st.q SP, FRAME_R(58), r58
  693. st.q SP, FRAME_R(59), r59
  694. st.q SP, FRAME_R(60), r60
  695. st.q SP, FRAME_R(61), r61
  696. st.q SP, FRAME_R(62), r62
  697. /*
  698. * Save the S* registers.
  699. */
  700. getcon SSR, r61
  701. st.q SP, FRAME_S(FSSR), r61
  702. getcon SPC, r62
  703. st.q SP, FRAME_S(FSPC), r62
  704. movi -1, r62 /* Reset syscall_nr */
  705. st.q SP, FRAME_S(FSYSCALL_ID), r62
  706. /* Save the rest of the target registers */
  707. gettr tr1, r6
  708. st.q SP, FRAME_T(1), r6
  709. gettr tr2, r6
  710. st.q SP, FRAME_T(2), r6
  711. gettr tr3, r6
  712. st.q SP, FRAME_T(3), r6
  713. gettr tr4, r6
  714. st.q SP, FRAME_T(4), r6
  715. gettr tr5, r6
  716. st.q SP, FRAME_T(5), r6
  717. gettr tr6, r6
  718. st.q SP, FRAME_T(6), r6
  719. gettr tr7, r6
  720. st.q SP, FRAME_T(7), r6
  721. ! setup FP so that unwinder can wind back through nested kernel mode
  722. ! exceptions
  723. add SP, ZERO, r14
  724. /* For syscall and debug race condition, get TRA now */
  725. getcon TRA, r5
  726. /* We are in a safe position to turn SR.BL off, but set IMASK=0xf
  727. * Also set FD, to catch FPU usage in the kernel.
  728. *
  729. * benedict.gaster@superh.com 29/07/2002
  730. *
  731. * On all SH5-101 revisions it is unsafe to raise the IMASK and at the
  732. * same time change BL from 1->0, as any pending interrupt of a level
  733. * higher than he previous value of IMASK will leak through and be
  734. * taken unexpectedly.
  735. *
  736. * To avoid this we raise the IMASK and then issue another PUTCON to
  737. * enable interrupts.
  738. */
  739. getcon SR, r6
  740. movi SR_IMASK | SR_FD, r7
  741. or r6, r7, r6
  742. putcon r6, SR
  743. movi SR_UNBLOCK_EXC, r7
  744. and r6, r7, r6
  745. putcon r6, SR
  746. /* Now call the appropriate 3rd level handler */
  747. or r3, ZERO, LINK
  748. movi trap_jtable, r3
  749. shlri r2, 3, r2
  750. ldx.l r2, r3, r3
  751. shlri r2, 2, r2
  752. ptabs r3, tr0
  753. or SP, ZERO, r3
  754. blink tr0, ZERO
  755. /*
  756. * Second level handler for VBR-based exceptions. Post-handlers.
  757. *
  758. * Post-handlers for interrupts (ret_from_irq), exceptions
  759. * (ret_from_exception) and common reentrance doors (restore_all
  760. * to get back to the original context, ret_from_syscall loop to
  761. * check kernel exiting).
  762. *
  763. * ret_with_reschedule and work_notifysig are an inner lables of
  764. * the ret_from_syscall loop.
  765. *
  766. * In common to all stack-frame sensitive handlers.
  767. *
  768. * Inputs:
  769. * (SP) struct pt_regs *, original register's frame pointer (basic)
  770. *
  771. */
  772. .global ret_from_irq
  773. ret_from_irq:
  774. ld.q SP, FRAME_S(FSSR), r6
  775. shlri r6, 30, r6
  776. andi r6, 1, r6
  777. pta resume_kernel, tr0
  778. bne r6, ZERO, tr0 /* no further checks */
  779. STI()
  780. pta ret_with_reschedule, tr0
  781. blink tr0, ZERO /* Do not check softirqs */
  782. .global ret_from_exception
  783. ret_from_exception:
  784. preempt_stop()
  785. ld.q SP, FRAME_S(FSSR), r6
  786. shlri r6, 30, r6
  787. andi r6, 1, r6
  788. pta resume_kernel, tr0
  789. bne r6, ZERO, tr0 /* no further checks */
  790. /* Check softirqs */
  791. #ifdef CONFIG_PREEMPT
  792. pta ret_from_syscall, tr0
  793. blink tr0, ZERO
  794. resume_kernel:
  795. CLI()
  796. pta restore_all, tr0
  797. getcon KCR0, r6
  798. ld.l r6, TI_PRE_COUNT, r7
  799. beq/u r7, ZERO, tr0
  800. need_resched:
  801. ld.l r6, TI_FLAGS, r7
  802. movi (1 << TIF_NEED_RESCHED), r8
  803. and r8, r7, r8
  804. bne r8, ZERO, tr0
  805. getcon SR, r7
  806. andi r7, 0xf0, r7
  807. bne r7, ZERO, tr0
  808. movi preempt_schedule_irq, r7
  809. ori r7, 1, r7
  810. ptabs r7, tr1
  811. blink tr1, LINK
  812. pta need_resched, tr1
  813. blink tr1, ZERO
  814. #endif
  815. .global ret_from_syscall
  816. ret_from_syscall:
  817. ret_with_reschedule:
  818. getcon KCR0, r6 ! r6 contains current_thread_info
  819. ld.l r6, TI_FLAGS, r7 ! r7 contains current_thread_info->flags
  820. movi _TIF_NEED_RESCHED, r8
  821. and r8, r7, r8
  822. pta work_resched, tr0
  823. bne r8, ZERO, tr0
  824. pta restore_all, tr1
  825. movi (_TIF_SIGPENDING|_TIF_NOTIFY_RESUME), r8
  826. and r8, r7, r8
  827. pta work_notifysig, tr0
  828. bne r8, ZERO, tr0
  829. blink tr1, ZERO
  830. work_resched:
  831. pta ret_from_syscall, tr0
  832. gettr tr0, LINK
  833. movi schedule, r6
  834. ptabs r6, tr0
  835. blink tr0, ZERO /* Call schedule(), return on top */
  836. work_notifysig:
  837. gettr tr1, LINK
  838. movi do_notify_resume, r6
  839. ptabs r6, tr0
  840. or SP, ZERO, r2
  841. or r7, ZERO, r3
  842. blink tr0, LINK /* Call do_notify_resume(regs, current_thread_info->flags), return here */
  843. restore_all:
  844. /* Do prefetches */
  845. ld.q SP, FRAME_T(0), r6
  846. ld.q SP, FRAME_T(1), r7
  847. ld.q SP, FRAME_T(2), r8
  848. ld.q SP, FRAME_T(3), r9
  849. ptabs r6, tr0
  850. ptabs r7, tr1
  851. ptabs r8, tr2
  852. ptabs r9, tr3
  853. ld.q SP, FRAME_T(4), r6
  854. ld.q SP, FRAME_T(5), r7
  855. ld.q SP, FRAME_T(6), r8
  856. ld.q SP, FRAME_T(7), r9
  857. ptabs r6, tr4
  858. ptabs r7, tr5
  859. ptabs r8, tr6
  860. ptabs r9, tr7
  861. ld.q SP, FRAME_R(0), r0
  862. ld.q SP, FRAME_R(1), r1
  863. ld.q SP, FRAME_R(2), r2
  864. ld.q SP, FRAME_R(3), r3
  865. ld.q SP, FRAME_R(4), r4
  866. ld.q SP, FRAME_R(5), r5
  867. ld.q SP, FRAME_R(6), r6
  868. ld.q SP, FRAME_R(7), r7
  869. ld.q SP, FRAME_R(8), r8
  870. ld.q SP, FRAME_R(9), r9
  871. ld.q SP, FRAME_R(10), r10
  872. ld.q SP, FRAME_R(11), r11
  873. ld.q SP, FRAME_R(12), r12
  874. ld.q SP, FRAME_R(13), r13
  875. ld.q SP, FRAME_R(14), r14
  876. ld.q SP, FRAME_R(16), r16
  877. ld.q SP, FRAME_R(17), r17
  878. ld.q SP, FRAME_R(18), r18
  879. ld.q SP, FRAME_R(19), r19
  880. ld.q SP, FRAME_R(20), r20
  881. ld.q SP, FRAME_R(21), r21
  882. ld.q SP, FRAME_R(22), r22
  883. ld.q SP, FRAME_R(23), r23
  884. ld.q SP, FRAME_R(24), r24
  885. ld.q SP, FRAME_R(25), r25
  886. ld.q SP, FRAME_R(26), r26
  887. ld.q SP, FRAME_R(27), r27
  888. ld.q SP, FRAME_R(28), r28
  889. ld.q SP, FRAME_R(29), r29
  890. ld.q SP, FRAME_R(30), r30
  891. ld.q SP, FRAME_R(31), r31
  892. ld.q SP, FRAME_R(32), r32
  893. ld.q SP, FRAME_R(33), r33
  894. ld.q SP, FRAME_R(34), r34
  895. ld.q SP, FRAME_R(35), r35
  896. ld.q SP, FRAME_R(36), r36
  897. ld.q SP, FRAME_R(37), r37
  898. ld.q SP, FRAME_R(38), r38
  899. ld.q SP, FRAME_R(39), r39
  900. ld.q SP, FRAME_R(40), r40
  901. ld.q SP, FRAME_R(41), r41
  902. ld.q SP, FRAME_R(42), r42
  903. ld.q SP, FRAME_R(43), r43
  904. ld.q SP, FRAME_R(44), r44
  905. ld.q SP, FRAME_R(45), r45
  906. ld.q SP, FRAME_R(46), r46
  907. ld.q SP, FRAME_R(47), r47
  908. ld.q SP, FRAME_R(48), r48
  909. ld.q SP, FRAME_R(49), r49
  910. ld.q SP, FRAME_R(50), r50
  911. ld.q SP, FRAME_R(51), r51
  912. ld.q SP, FRAME_R(52), r52
  913. ld.q SP, FRAME_R(53), r53
  914. ld.q SP, FRAME_R(54), r54
  915. ld.q SP, FRAME_R(55), r55
  916. ld.q SP, FRAME_R(56), r56
  917. ld.q SP, FRAME_R(57), r57
  918. ld.q SP, FRAME_R(58), r58
  919. getcon SR, r59
  920. movi SR_BLOCK_EXC, r60
  921. or r59, r60, r59
  922. putcon r59, SR /* SR.BL = 1, keep nesting out */
  923. ld.q SP, FRAME_S(FSSR), r61
  924. ld.q SP, FRAME_S(FSPC), r62
  925. movi SR_ASID_MASK, r60
  926. and r59, r60, r59
  927. andc r61, r60, r61 /* Clear out older ASID */
  928. or r59, r61, r61 /* Retain current ASID */
  929. putcon r61, SSR
  930. putcon r62, SPC
  931. /* Ignore FSYSCALL_ID */
  932. ld.q SP, FRAME_R(59), r59
  933. ld.q SP, FRAME_R(60), r60
  934. ld.q SP, FRAME_R(61), r61
  935. ld.q SP, FRAME_R(62), r62
  936. /* Last touch */
  937. ld.q SP, FRAME_R(15), SP
  938. rte
  939. nop
  940. /*
  941. * Third level handlers for VBR-based exceptions. Adapting args to
  942. * and/or deflecting to fourth level handlers.
  943. *
  944. * Fourth level handlers interface.
  945. * Most are C-coded handlers directly pointed by the trap_jtable.
  946. * (Third = Fourth level)
  947. * Inputs:
  948. * (r2) fault/interrupt code, entry number (e.g. NMI = 14,
  949. * IRL0-3 (0000) = 16, RTLBMISS = 2, SYSCALL = 11, etc ...)
  950. * (r3) struct pt_regs *, original register's frame pointer
  951. * (r4) Event (0 = interrupt, 1 = TLB miss fault, 2 = Not TLB miss fault)
  952. * (r5) TRA control register (for syscall/debug benefit only)
  953. * (LINK) return address
  954. * (SP) = r3
  955. *
  956. * Kernel TLB fault handlers will get a slightly different interface.
  957. * (r2) struct pt_regs *, original register's frame pointer
  958. * (r3) page fault error code (see asm/thread_info.h)
  959. * (r4) Effective Address of fault
  960. * (LINK) return address
  961. * (SP) = r2
  962. *
  963. * fpu_error_or_IRQ? is a helper to deflect to the right cause.
  964. *
  965. */
  966. #ifdef CONFIG_MMU
  967. tlb_miss_load:
  968. or SP, ZERO, r2
  969. or ZERO, ZERO, r3 /* Read */
  970. getcon TEA, r4
  971. pta call_do_page_fault, tr0
  972. beq ZERO, ZERO, tr0
  973. tlb_miss_store:
  974. or SP, ZERO, r2
  975. movi FAULT_CODE_WRITE, r3 /* Write */
  976. getcon TEA, r4
  977. pta call_do_page_fault, tr0
  978. beq ZERO, ZERO, tr0
  979. itlb_miss_or_IRQ:
  980. pta its_IRQ, tr0
  981. beqi/u r4, EVENT_INTERRUPT, tr0
  982. /* ITLB miss */
  983. or SP, ZERO, r2
  984. movi FAULT_CODE_ITLB, r3
  985. getcon TEA, r4
  986. /* Fall through */
  987. call_do_page_fault:
  988. movi do_page_fault, r6
  989. ptabs r6, tr0
  990. blink tr0, ZERO
  991. #endif /* CONFIG_MMU */
  992. fpu_error_or_IRQA:
  993. pta its_IRQ, tr0
  994. beqi/l r4, EVENT_INTERRUPT, tr0
  995. #ifdef CONFIG_SH_FPU
  996. movi fpu_state_restore_trap_handler, r6
  997. #else
  998. movi do_exception_error, r6
  999. #endif
  1000. ptabs r6, tr0
  1001. blink tr0, ZERO
  1002. fpu_error_or_IRQB:
  1003. pta its_IRQ, tr0
  1004. beqi/l r4, EVENT_INTERRUPT, tr0
  1005. #ifdef CONFIG_SH_FPU
  1006. movi fpu_state_restore_trap_handler, r6
  1007. #else
  1008. movi do_exception_error, r6
  1009. #endif
  1010. ptabs r6, tr0
  1011. blink tr0, ZERO
  1012. its_IRQ:
  1013. movi do_IRQ, r6
  1014. ptabs r6, tr0
  1015. blink tr0, ZERO
  1016. /*
  1017. * system_call/unknown_trap third level handler:
  1018. *
  1019. * Inputs:
  1020. * (r2) fault/interrupt code, entry number (TRAP = 11)
  1021. * (r3) struct pt_regs *, original register's frame pointer
  1022. * (r4) Not used. Event (0=interrupt, 1=TLB miss fault, 2=Not TLB miss fault)
  1023. * (r5) TRA Control Reg (0x00xyzzzz: x=1 SYSCALL, y = #args, z=nr)
  1024. * (SP) = r3
  1025. * (LINK) return address: ret_from_exception
  1026. * (*r3) Syscall parms: SC#, arg0, arg1, ..., arg5 in order (Saved r2/r7)
  1027. *
  1028. * Outputs:
  1029. * (*r3) Syscall reply (Saved r2)
  1030. * (LINK) In case of syscall only it can be scrapped.
  1031. * Common second level post handler will be ret_from_syscall.
  1032. * Common (non-trace) exit point to that is syscall_ret (saving
  1033. * result to r2). Common bad exit point is syscall_bad (returning
  1034. * ENOSYS then saved to r2).
  1035. *
  1036. */
  1037. unknown_trap:
  1038. /* Unknown Trap or User Trace */
  1039. movi do_unknown_trapa, r6
  1040. ptabs r6, tr0
  1041. ld.q r3, FRAME_R(9), r2 /* r2 = #arg << 16 | syscall # */
  1042. andi r2, 0x1ff, r2 /* r2 = syscall # */
  1043. blink tr0, LINK
  1044. pta syscall_ret, tr0
  1045. blink tr0, ZERO
  1046. /* New syscall implementation*/
  1047. system_call:
  1048. pta unknown_trap, tr0
  1049. or r5, ZERO, r4 /* TRA (=r5) -> r4 */
  1050. shlri r4, 20, r4
  1051. bnei r4, 1, tr0 /* unknown_trap if not 0x1yzzzz */
  1052. /* It's a system call */
  1053. st.q r3, FRAME_S(FSYSCALL_ID), r5 /* ID (0x1yzzzz) -> stack */
  1054. andi r5, 0x1ff, r5 /* syscall # -> r5 */
  1055. STI()
  1056. pta syscall_allowed, tr0
  1057. movi NR_syscalls - 1, r4 /* Last valid */
  1058. bgeu/l r4, r5, tr0
  1059. syscall_bad:
  1060. /* Return ENOSYS ! */
  1061. movi -(ENOSYS), r2 /* Fall-through */
  1062. .global syscall_ret
  1063. syscall_ret:
  1064. st.q SP, FRAME_R(9), r2 /* Expecting SP back to BASIC frame */
  1065. ld.q SP, FRAME_S(FSPC), r2
  1066. addi r2, 4, r2 /* Move PC, being pre-execution event */
  1067. st.q SP, FRAME_S(FSPC), r2
  1068. pta ret_from_syscall, tr0
  1069. blink tr0, ZERO
  1070. /* A different return path for ret_from_fork, because we now need
  1071. * to call schedule_tail with the later kernels. Because prev is
  1072. * loaded into r2 by switch_to() means we can just call it straight away
  1073. */
  1074. .global ret_from_fork
  1075. ret_from_fork:
  1076. movi schedule_tail,r5
  1077. ori r5, 1, r5
  1078. ptabs r5, tr0
  1079. blink tr0, LINK
  1080. ld.q SP, FRAME_S(FSPC), r2
  1081. addi r2, 4, r2 /* Move PC, being pre-execution event */
  1082. st.q SP, FRAME_S(FSPC), r2
  1083. pta ret_from_syscall, tr0
  1084. blink tr0, ZERO
  1085. .global ret_from_kernel_thread
  1086. ret_from_kernel_thread:
  1087. movi schedule_tail,r5
  1088. ori r5, 1, r5
  1089. ptabs r5, tr0
  1090. blink tr0, LINK
  1091. ld.q SP, FRAME_R(2), r2
  1092. ld.q SP, FRAME_R(3), r3
  1093. ptabs r3, tr0
  1094. blink tr0, LINK
  1095. ld.q SP, FRAME_S(FSPC), r2
  1096. addi r2, 4, r2 /* Move PC, being pre-execution event */
  1097. st.q SP, FRAME_S(FSPC), r2
  1098. pta ret_from_syscall, tr0
  1099. blink tr0, ZERO
  1100. syscall_allowed:
  1101. /* Use LINK to deflect the exit point, default is syscall_ret */
  1102. pta syscall_ret, tr0
  1103. gettr tr0, LINK
  1104. pta syscall_notrace, tr0
  1105. getcon KCR0, r2
  1106. ld.l r2, TI_FLAGS, r4
  1107. movi _TIF_WORK_SYSCALL_MASK, r6
  1108. and r6, r4, r6
  1109. beq/l r6, ZERO, tr0
  1110. /* Trace it by calling syscall_trace before and after */
  1111. movi do_syscall_trace_enter, r4
  1112. or SP, ZERO, r2
  1113. ptabs r4, tr0
  1114. blink tr0, LINK
  1115. /* Save the retval */
  1116. st.q SP, FRAME_R(2), r2
  1117. /* Reload syscall number as r5 is trashed by do_syscall_trace_enter */
  1118. ld.q SP, FRAME_S(FSYSCALL_ID), r5
  1119. andi r5, 0x1ff, r5
  1120. pta syscall_ret_trace, tr0
  1121. gettr tr0, LINK
  1122. syscall_notrace:
  1123. /* Now point to the appropriate 4th level syscall handler */
  1124. movi sys_call_table, r4
  1125. shlli r5, 2, r5
  1126. ldx.l r4, r5, r5
  1127. ptabs r5, tr0
  1128. /* Prepare original args */
  1129. ld.q SP, FRAME_R(2), r2
  1130. ld.q SP, FRAME_R(3), r3
  1131. ld.q SP, FRAME_R(4), r4
  1132. ld.q SP, FRAME_R(5), r5
  1133. ld.q SP, FRAME_R(6), r6
  1134. ld.q SP, FRAME_R(7), r7
  1135. /* And now the trick for those syscalls requiring regs * ! */
  1136. or SP, ZERO, r8
  1137. /* Call it */
  1138. blink tr0, ZERO /* LINK is already properly set */
  1139. syscall_ret_trace:
  1140. /* We get back here only if under trace */
  1141. st.q SP, FRAME_R(9), r2 /* Save return value */
  1142. movi do_syscall_trace_leave, LINK
  1143. or SP, ZERO, r2
  1144. ptabs LINK, tr0
  1145. blink tr0, LINK
  1146. /* This needs to be done after any syscall tracing */
  1147. ld.q SP, FRAME_S(FSPC), r2
  1148. addi r2, 4, r2 /* Move PC, being pre-execution event */
  1149. st.q SP, FRAME_S(FSPC), r2
  1150. pta ret_from_syscall, tr0
  1151. blink tr0, ZERO /* Resume normal return sequence */
  1152. /*
  1153. * --- Switch to running under a particular ASID and return the previous ASID value
  1154. * --- The caller is assumed to have done a cli before calling this.
  1155. *
  1156. * Input r2 : new ASID
  1157. * Output r2 : old ASID
  1158. */
  1159. .global switch_and_save_asid
  1160. switch_and_save_asid:
  1161. getcon sr, r0
  1162. movi 255, r4
  1163. shlli r4, 16, r4 /* r4 = mask to select ASID */
  1164. and r0, r4, r3 /* r3 = shifted old ASID */
  1165. andi r2, 255, r2 /* mask down new ASID */
  1166. shlli r2, 16, r2 /* align new ASID against SR.ASID */
  1167. andc r0, r4, r0 /* efface old ASID from SR */
  1168. or r0, r2, r0 /* insert the new ASID */
  1169. putcon r0, ssr
  1170. movi 1f, r0
  1171. putcon r0, spc
  1172. rte
  1173. nop
  1174. 1:
  1175. ptabs LINK, tr0
  1176. shlri r3, 16, r2 /* r2 = old ASID */
  1177. blink tr0, r63
  1178. .global route_to_panic_handler
  1179. route_to_panic_handler:
  1180. /* Switch to real mode, goto panic_handler, don't return. Useful for
  1181. last-chance debugging, e.g. if no output wants to go to the console.
  1182. */
  1183. movi panic_handler - CONFIG_PAGE_OFFSET, r1
  1184. ptabs r1, tr0
  1185. pta 1f, tr1
  1186. gettr tr1, r0
  1187. putcon r0, spc
  1188. getcon sr, r0
  1189. movi 1, r1
  1190. shlli r1, 31, r1
  1191. andc r0, r1, r0
  1192. putcon r0, ssr
  1193. rte
  1194. nop
  1195. 1: /* Now in real mode */
  1196. blink tr0, r63
  1197. nop
  1198. .global peek_real_address_q
  1199. peek_real_address_q:
  1200. /* Two args:
  1201. r2 : real mode address to peek
  1202. r2(out) : result quadword
  1203. This is provided as a cheapskate way of manipulating device
  1204. registers for debugging (to avoid the need to ioremap the debug
  1205. module, and to avoid the need to ioremap the watchpoint
  1206. controller in a way that identity maps sufficient bits to avoid the
  1207. SH5-101 cut2 silicon defect).
  1208. This code is not performance critical
  1209. */
  1210. add.l r2, r63, r2 /* sign extend address */
  1211. getcon sr, r0 /* r0 = saved original SR */
  1212. movi 1, r1
  1213. shlli r1, 28, r1
  1214. or r0, r1, r1 /* r0 with block bit set */
  1215. putcon r1, sr /* now in critical section */
  1216. movi 1, r36
  1217. shlli r36, 31, r36
  1218. andc r1, r36, r1 /* turn sr.mmu off in real mode section */
  1219. putcon r1, ssr
  1220. movi .peek0 - CONFIG_PAGE_OFFSET, r36 /* real mode target address */
  1221. movi 1f, r37 /* virtual mode return addr */
  1222. putcon r36, spc
  1223. synco
  1224. rte
  1225. nop
  1226. .peek0: /* come here in real mode, don't touch caches!!
  1227. still in critical section (sr.bl==1) */
  1228. putcon r0, ssr
  1229. putcon r37, spc
  1230. /* Here's the actual peek. If the address is bad, all bets are now off
  1231. * what will happen (handlers invoked in real-mode = bad news) */
  1232. ld.q r2, 0, r2
  1233. synco
  1234. rte /* Back to virtual mode */
  1235. nop
  1236. 1:
  1237. ptabs LINK, tr0
  1238. blink tr0, r63
  1239. .global poke_real_address_q
  1240. poke_real_address_q:
  1241. /* Two args:
  1242. r2 : real mode address to poke
  1243. r3 : quadword value to write.
  1244. This is provided as a cheapskate way of manipulating device
  1245. registers for debugging (to avoid the need to ioremap the debug
  1246. module, and to avoid the need to ioremap the watchpoint
  1247. controller in a way that identity maps sufficient bits to avoid the
  1248. SH5-101 cut2 silicon defect).
  1249. This code is not performance critical
  1250. */
  1251. add.l r2, r63, r2 /* sign extend address */
  1252. getcon sr, r0 /* r0 = saved original SR */
  1253. movi 1, r1
  1254. shlli r1, 28, r1
  1255. or r0, r1, r1 /* r0 with block bit set */
  1256. putcon r1, sr /* now in critical section */
  1257. movi 1, r36
  1258. shlli r36, 31, r36
  1259. andc r1, r36, r1 /* turn sr.mmu off in real mode section */
  1260. putcon r1, ssr
  1261. movi .poke0-CONFIG_PAGE_OFFSET, r36 /* real mode target address */
  1262. movi 1f, r37 /* virtual mode return addr */
  1263. putcon r36, spc
  1264. synco
  1265. rte
  1266. nop
  1267. .poke0: /* come here in real mode, don't touch caches!!
  1268. still in critical section (sr.bl==1) */
  1269. putcon r0, ssr
  1270. putcon r37, spc
  1271. /* Here's the actual poke. If the address is bad, all bets are now off
  1272. * what will happen (handlers invoked in real-mode = bad news) */
  1273. st.q r2, 0, r3
  1274. synco
  1275. rte /* Back to virtual mode */
  1276. nop
  1277. 1:
  1278. ptabs LINK, tr0
  1279. blink tr0, r63
  1280. #ifdef CONFIG_MMU
  1281. /*
  1282. * --- User Access Handling Section
  1283. */
  1284. /*
  1285. * User Access support. It all moved to non inlined Assembler
  1286. * functions in here.
  1287. *
  1288. * __kernel_size_t __copy_user(void *__to, const void *__from,
  1289. * __kernel_size_t __n)
  1290. *
  1291. * Inputs:
  1292. * (r2) target address
  1293. * (r3) source address
  1294. * (r4) size in bytes
  1295. *
  1296. * Ouputs:
  1297. * (*r2) target data
  1298. * (r2) non-copied bytes
  1299. *
  1300. * If a fault occurs on the user pointer, bail out early and return the
  1301. * number of bytes not copied in r2.
  1302. * Strategy : for large blocks, call a real memcpy function which can
  1303. * move >1 byte at a time using unaligned ld/st instructions, and can
  1304. * manipulate the cache using prefetch + alloco to improve the speed
  1305. * further. If a fault occurs in that function, just revert to the
  1306. * byte-by-byte approach used for small blocks; this is rare so the
  1307. * performance hit for that case does not matter.
  1308. *
  1309. * For small blocks it's not worth the overhead of setting up and calling
  1310. * the memcpy routine; do the copy a byte at a time.
  1311. *
  1312. */
  1313. .global __copy_user
  1314. __copy_user:
  1315. pta __copy_user_byte_by_byte, tr1
  1316. movi 16, r0 ! this value is a best guess, should tune it by benchmarking
  1317. bge/u r0, r4, tr1
  1318. pta copy_user_memcpy, tr0
  1319. addi SP, -32, SP
  1320. /* Save arguments in case we have to fix-up unhandled page fault */
  1321. st.q SP, 0, r2
  1322. st.q SP, 8, r3
  1323. st.q SP, 16, r4
  1324. st.q SP, 24, r35 ! r35 is callee-save
  1325. /* Save LINK in a register to reduce RTS time later (otherwise
  1326. ld SP,*,LINK;ptabs LINK;trn;blink trn,r63 becomes a critical path) */
  1327. ori LINK, 0, r35
  1328. blink tr0, LINK
  1329. /* Copy completed normally if we get back here */
  1330. ptabs r35, tr0
  1331. ld.q SP, 24, r35
  1332. /* don't restore r2-r4, pointless */
  1333. /* set result=r2 to zero as the copy must have succeeded. */
  1334. or r63, r63, r2
  1335. addi SP, 32, SP
  1336. blink tr0, r63 ! RTS
  1337. .global __copy_user_fixup
  1338. __copy_user_fixup:
  1339. /* Restore stack frame */
  1340. ori r35, 0, LINK
  1341. ld.q SP, 24, r35
  1342. ld.q SP, 16, r4
  1343. ld.q SP, 8, r3
  1344. ld.q SP, 0, r2
  1345. addi SP, 32, SP
  1346. /* Fall through to original code, in the 'same' state we entered with */
  1347. /* The slow byte-by-byte method is used if the fast copy traps due to a bad
  1348. user address. In that rare case, the speed drop can be tolerated. */
  1349. __copy_user_byte_by_byte:
  1350. pta ___copy_user_exit, tr1
  1351. pta ___copy_user1, tr0
  1352. beq/u r4, r63, tr1 /* early exit for zero length copy */
  1353. sub r2, r3, r0
  1354. addi r0, -1, r0
  1355. ___copy_user1:
  1356. ld.b r3, 0, r5 /* Fault address 1 */
  1357. /* Could rewrite this to use just 1 add, but the second comes 'free'
  1358. due to load latency */
  1359. addi r3, 1, r3
  1360. addi r4, -1, r4 /* No real fixup required */
  1361. ___copy_user2:
  1362. stx.b r3, r0, r5 /* Fault address 2 */
  1363. bne r4, ZERO, tr0
  1364. ___copy_user_exit:
  1365. or r4, ZERO, r2
  1366. ptabs LINK, tr0
  1367. blink tr0, ZERO
  1368. /*
  1369. * __kernel_size_t __clear_user(void *addr, __kernel_size_t size)
  1370. *
  1371. * Inputs:
  1372. * (r2) target address
  1373. * (r3) size in bytes
  1374. *
  1375. * Ouputs:
  1376. * (*r2) zero-ed target data
  1377. * (r2) non-zero-ed bytes
  1378. */
  1379. .global __clear_user
  1380. __clear_user:
  1381. pta ___clear_user_exit, tr1
  1382. pta ___clear_user1, tr0
  1383. beq/u r3, r63, tr1
  1384. ___clear_user1:
  1385. st.b r2, 0, ZERO /* Fault address */
  1386. addi r2, 1, r2
  1387. addi r3, -1, r3 /* No real fixup required */
  1388. bne r3, ZERO, tr0
  1389. ___clear_user_exit:
  1390. or r3, ZERO, r2
  1391. ptabs LINK, tr0
  1392. blink tr0, ZERO
  1393. #endif /* CONFIG_MMU */
  1394. /*
  1395. * extern long __get_user_asm_?(void *val, long addr)
  1396. *
  1397. * Inputs:
  1398. * (r2) dest address
  1399. * (r3) source address (in User Space)
  1400. *
  1401. * Ouputs:
  1402. * (r2) -EFAULT (faulting)
  1403. * 0 (not faulting)
  1404. */
  1405. .global __get_user_asm_b
  1406. __get_user_asm_b:
  1407. or r2, ZERO, r4
  1408. movi -(EFAULT), r2 /* r2 = reply, no real fixup */
  1409. ___get_user_asm_b1:
  1410. ld.b r3, 0, r5 /* r5 = data */
  1411. st.b r4, 0, r5
  1412. or ZERO, ZERO, r2
  1413. ___get_user_asm_b_exit:
  1414. ptabs LINK, tr0
  1415. blink tr0, ZERO
  1416. .global __get_user_asm_w
  1417. __get_user_asm_w:
  1418. or r2, ZERO, r4
  1419. movi -(EFAULT), r2 /* r2 = reply, no real fixup */
  1420. ___get_user_asm_w1:
  1421. ld.w r3, 0, r5 /* r5 = data */
  1422. st.w r4, 0, r5
  1423. or ZERO, ZERO, r2
  1424. ___get_user_asm_w_exit:
  1425. ptabs LINK, tr0
  1426. blink tr0, ZERO
  1427. .global __get_user_asm_l
  1428. __get_user_asm_l:
  1429. or r2, ZERO, r4
  1430. movi -(EFAULT), r2 /* r2 = reply, no real fixup */
  1431. ___get_user_asm_l1:
  1432. ld.l r3, 0, r5 /* r5 = data */
  1433. st.l r4, 0, r5
  1434. or ZERO, ZERO, r2
  1435. ___get_user_asm_l_exit:
  1436. ptabs LINK, tr0
  1437. blink tr0, ZERO
  1438. .global __get_user_asm_q
  1439. __get_user_asm_q:
  1440. or r2, ZERO, r4
  1441. movi -(EFAULT), r2 /* r2 = reply, no real fixup */
  1442. ___get_user_asm_q1:
  1443. ld.q r3, 0, r5 /* r5 = data */
  1444. st.q r4, 0, r5
  1445. or ZERO, ZERO, r2
  1446. ___get_user_asm_q_exit:
  1447. ptabs LINK, tr0
  1448. blink tr0, ZERO
  1449. /*
  1450. * extern long __put_user_asm_?(void *pval, long addr)
  1451. *
  1452. * Inputs:
  1453. * (r2) kernel pointer to value
  1454. * (r3) dest address (in User Space)
  1455. *
  1456. * Ouputs:
  1457. * (r2) -EFAULT (faulting)
  1458. * 0 (not faulting)
  1459. */
  1460. .global __put_user_asm_b
  1461. __put_user_asm_b:
  1462. ld.b r2, 0, r4 /* r4 = data */
  1463. movi -(EFAULT), r2 /* r2 = reply, no real fixup */
  1464. ___put_user_asm_b1:
  1465. st.b r3, 0, r4
  1466. or ZERO, ZERO, r2
  1467. ___put_user_asm_b_exit:
  1468. ptabs LINK, tr0
  1469. blink tr0, ZERO
  1470. .global __put_user_asm_w
  1471. __put_user_asm_w:
  1472. ld.w r2, 0, r4 /* r4 = data */
  1473. movi -(EFAULT), r2 /* r2 = reply, no real fixup */
  1474. ___put_user_asm_w1:
  1475. st.w r3, 0, r4
  1476. or ZERO, ZERO, r2
  1477. ___put_user_asm_w_exit:
  1478. ptabs LINK, tr0
  1479. blink tr0, ZERO
  1480. .global __put_user_asm_l
  1481. __put_user_asm_l:
  1482. ld.l r2, 0, r4 /* r4 = data */
  1483. movi -(EFAULT), r2 /* r2 = reply, no real fixup */
  1484. ___put_user_asm_l1:
  1485. st.l r3, 0, r4
  1486. or ZERO, ZERO, r2
  1487. ___put_user_asm_l_exit:
  1488. ptabs LINK, tr0
  1489. blink tr0, ZERO
  1490. .global __put_user_asm_q
  1491. __put_user_asm_q:
  1492. ld.q r2, 0, r4 /* r4 = data */
  1493. movi -(EFAULT), r2 /* r2 = reply, no real fixup */
  1494. ___put_user_asm_q1:
  1495. st.q r3, 0, r4
  1496. or ZERO, ZERO, r2
  1497. ___put_user_asm_q_exit:
  1498. ptabs LINK, tr0
  1499. blink tr0, ZERO
  1500. panic_stash_regs:
  1501. /* The idea is : when we get an unhandled panic, we dump the registers
  1502. to a known memory location, the just sit in a tight loop.
  1503. This allows the human to look at the memory region through the GDB
  1504. session (assuming the debug module's SHwy initiator isn't locked up
  1505. or anything), to hopefully analyze the cause of the panic. */
  1506. /* On entry, former r15 (SP) is in DCR
  1507. former r0 is at resvec_saved_area + 0
  1508. former r1 is at resvec_saved_area + 8
  1509. former tr0 is at resvec_saved_area + 32
  1510. DCR is the only register whose value is lost altogether.
  1511. */
  1512. movi 0xffffffff80000000, r0 ! phy of dump area
  1513. ld.q SP, 0x000, r1 ! former r0
  1514. st.q r0, 0x000, r1
  1515. ld.q SP, 0x008, r1 ! former r1
  1516. st.q r0, 0x008, r1
  1517. st.q r0, 0x010, r2
  1518. st.q r0, 0x018, r3
  1519. st.q r0, 0x020, r4
  1520. st.q r0, 0x028, r5
  1521. st.q r0, 0x030, r6
  1522. st.q r0, 0x038, r7
  1523. st.q r0, 0x040, r8
  1524. st.q r0, 0x048, r9
  1525. st.q r0, 0x050, r10
  1526. st.q r0, 0x058, r11
  1527. st.q r0, 0x060, r12
  1528. st.q r0, 0x068, r13
  1529. st.q r0, 0x070, r14
  1530. getcon dcr, r14
  1531. st.q r0, 0x078, r14
  1532. st.q r0, 0x080, r16
  1533. st.q r0, 0x088, r17
  1534. st.q r0, 0x090, r18
  1535. st.q r0, 0x098, r19
  1536. st.q r0, 0x0a0, r20
  1537. st.q r0, 0x0a8, r21
  1538. st.q r0, 0x0b0, r22
  1539. st.q r0, 0x0b8, r23
  1540. st.q r0, 0x0c0, r24
  1541. st.q r0, 0x0c8, r25
  1542. st.q r0, 0x0d0, r26
  1543. st.q r0, 0x0d8, r27
  1544. st.q r0, 0x0e0, r28
  1545. st.q r0, 0x0e8, r29
  1546. st.q r0, 0x0f0, r30
  1547. st.q r0, 0x0f8, r31
  1548. st.q r0, 0x100, r32
  1549. st.q r0, 0x108, r33
  1550. st.q r0, 0x110, r34
  1551. st.q r0, 0x118, r35
  1552. st.q r0, 0x120, r36
  1553. st.q r0, 0x128, r37
  1554. st.q r0, 0x130, r38
  1555. st.q r0, 0x138, r39
  1556. st.q r0, 0x140, r40
  1557. st.q r0, 0x148, r41
  1558. st.q r0, 0x150, r42
  1559. st.q r0, 0x158, r43
  1560. st.q r0, 0x160, r44
  1561. st.q r0, 0x168, r45
  1562. st.q r0, 0x170, r46
  1563. st.q r0, 0x178, r47
  1564. st.q r0, 0x180, r48
  1565. st.q r0, 0x188, r49
  1566. st.q r0, 0x190, r50
  1567. st.q r0, 0x198, r51
  1568. st.q r0, 0x1a0, r52
  1569. st.q r0, 0x1a8, r53
  1570. st.q r0, 0x1b0, r54
  1571. st.q r0, 0x1b8, r55
  1572. st.q r0, 0x1c0, r56
  1573. st.q r0, 0x1c8, r57
  1574. st.q r0, 0x1d0, r58
  1575. st.q r0, 0x1d8, r59
  1576. st.q r0, 0x1e0, r60
  1577. st.q r0, 0x1e8, r61
  1578. st.q r0, 0x1f0, r62
  1579. st.q r0, 0x1f8, r63 ! bogus, but for consistency's sake...
  1580. ld.q SP, 0x020, r1 ! former tr0
  1581. st.q r0, 0x200, r1
  1582. gettr tr1, r1
  1583. st.q r0, 0x208, r1
  1584. gettr tr2, r1
  1585. st.q r0, 0x210, r1
  1586. gettr tr3, r1
  1587. st.q r0, 0x218, r1
  1588. gettr tr4, r1
  1589. st.q r0, 0x220, r1
  1590. gettr tr5, r1
  1591. st.q r0, 0x228, r1
  1592. gettr tr6, r1
  1593. st.q r0, 0x230, r1
  1594. gettr tr7, r1
  1595. st.q r0, 0x238, r1
  1596. getcon sr, r1
  1597. getcon ssr, r2
  1598. getcon pssr, r3
  1599. getcon spc, r4
  1600. getcon pspc, r5
  1601. getcon intevt, r6
  1602. getcon expevt, r7
  1603. getcon pexpevt, r8
  1604. getcon tra, r9
  1605. getcon tea, r10
  1606. getcon kcr0, r11
  1607. getcon kcr1, r12
  1608. getcon vbr, r13
  1609. getcon resvec, r14
  1610. st.q r0, 0x240, r1
  1611. st.q r0, 0x248, r2
  1612. st.q r0, 0x250, r3
  1613. st.q r0, 0x258, r4
  1614. st.q r0, 0x260, r5
  1615. st.q r0, 0x268, r6
  1616. st.q r0, 0x270, r7
  1617. st.q r0, 0x278, r8
  1618. st.q r0, 0x280, r9
  1619. st.q r0, 0x288, r10
  1620. st.q r0, 0x290, r11
  1621. st.q r0, 0x298, r12
  1622. st.q r0, 0x2a0, r13
  1623. st.q r0, 0x2a8, r14
  1624. getcon SPC,r2
  1625. getcon SSR,r3
  1626. getcon EXPEVT,r4
  1627. /* Prepare to jump to C - physical address */
  1628. movi panic_handler-CONFIG_PAGE_OFFSET, r1
  1629. ori r1, 1, r1
  1630. ptabs r1, tr0
  1631. getcon DCR, SP
  1632. blink tr0, ZERO
  1633. nop
  1634. nop
  1635. nop
  1636. nop
  1637. /*
  1638. * --- Signal Handling Section
  1639. */
  1640. /*
  1641. * extern long long _sa_default_rt_restorer
  1642. * extern long long _sa_default_restorer
  1643. *
  1644. * or, better,
  1645. *
  1646. * extern void _sa_default_rt_restorer(void)
  1647. * extern void _sa_default_restorer(void)
  1648. *
  1649. * Code prototypes to do a sys_rt_sigreturn() or sys_sysreturn()
  1650. * from user space. Copied into user space by signal management.
  1651. * Both must be quad aligned and 2 quad long (4 instructions).
  1652. *
  1653. */
  1654. .balign 8
  1655. .global sa_default_rt_restorer
  1656. sa_default_rt_restorer:
  1657. movi 0x10, r9
  1658. shori __NR_rt_sigreturn, r9
  1659. trapa r9
  1660. nop
  1661. .balign 8
  1662. .global sa_default_restorer
  1663. sa_default_restorer:
  1664. movi 0x10, r9
  1665. shori __NR_sigreturn, r9
  1666. trapa r9
  1667. nop
  1668. /*
  1669. * --- __ex_table Section
  1670. */
  1671. /*
  1672. * User Access Exception Table.
  1673. */
  1674. .section __ex_table, "a"
  1675. .global asm_uaccess_start /* Just a marker */
  1676. asm_uaccess_start:
  1677. #ifdef CONFIG_MMU
  1678. .long ___copy_user1, ___copy_user_exit
  1679. .long ___copy_user2, ___copy_user_exit
  1680. .long ___clear_user1, ___clear_user_exit
  1681. #endif
  1682. .long ___get_user_asm_b1, ___get_user_asm_b_exit
  1683. .long ___get_user_asm_w1, ___get_user_asm_w_exit
  1684. .long ___get_user_asm_l1, ___get_user_asm_l_exit
  1685. .long ___get_user_asm_q1, ___get_user_asm_q_exit
  1686. .long ___put_user_asm_b1, ___put_user_asm_b_exit
  1687. .long ___put_user_asm_w1, ___put_user_asm_w_exit
  1688. .long ___put_user_asm_l1, ___put_user_asm_l_exit
  1689. .long ___put_user_asm_q1, ___put_user_asm_q_exit
  1690. .global asm_uaccess_end /* Just a marker */
  1691. asm_uaccess_end:
  1692. /*
  1693. * --- .init.text Section
  1694. */
  1695. __INIT
  1696. /*
  1697. * void trap_init (void)
  1698. *
  1699. */
  1700. .global trap_init
  1701. trap_init:
  1702. addi SP, -24, SP /* Room to save r28/r29/r30 */
  1703. st.q SP, 0, r28
  1704. st.q SP, 8, r29
  1705. st.q SP, 16, r30
  1706. /* Set VBR and RESVEC */
  1707. movi LVBR_block, r19
  1708. andi r19, -4, r19 /* reset MMUOFF + reserved */
  1709. /* For RESVEC exceptions we force the MMU off, which means we need the
  1710. physical address. */
  1711. movi LRESVEC_block-CONFIG_PAGE_OFFSET, r20
  1712. andi r20, -4, r20 /* reset reserved */
  1713. ori r20, 1, r20 /* set MMUOFF */
  1714. putcon r19, VBR
  1715. putcon r20, RESVEC
  1716. /* Sanity check */
  1717. movi LVBR_block_end, r21
  1718. andi r21, -4, r21
  1719. movi BLOCK_SIZE, r29 /* r29 = expected size */
  1720. or r19, ZERO, r30
  1721. add r19, r29, r19
  1722. /*
  1723. * Ugly, but better loop forever now than crash afterwards.
  1724. * We should print a message, but if we touch LVBR or
  1725. * LRESVEC blocks we should not be surprised if we get stuck
  1726. * in trap_init().
  1727. */
  1728. pta trap_init_loop, tr1
  1729. gettr tr1, r28 /* r28 = trap_init_loop */
  1730. sub r21, r30, r30 /* r30 = actual size */
  1731. /*
  1732. * VBR/RESVEC handlers overlap by being bigger than
  1733. * allowed. Very bad. Just loop forever.
  1734. * (r28) panic/loop address
  1735. * (r29) expected size
  1736. * (r30) actual size
  1737. */
  1738. trap_init_loop:
  1739. bne r19, r21, tr1
  1740. /* Now that exception vectors are set up reset SR.BL */
  1741. getcon SR, r22
  1742. movi SR_UNBLOCK_EXC, r23
  1743. and r22, r23, r22
  1744. putcon r22, SR
  1745. addi SP, 24, SP
  1746. ptabs LINK, tr0
  1747. blink tr0, ZERO