entry.S 49 KB

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