head.S 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * OpenRISC head.S
  4. *
  5. * Linux architectural port borrowing liberally from similar works of
  6. * others. All original copyrights apply as per the original source
  7. * declaration.
  8. *
  9. * Modifications for the OpenRISC architecture:
  10. * Copyright (C) 2003 Matjaz Breskvar <[email protected]>
  11. * Copyright (C) 2010-2011 Jonas Bonn <[email protected]>
  12. */
  13. #include <linux/linkage.h>
  14. #include <linux/threads.h>
  15. #include <linux/errno.h>
  16. #include <linux/init.h>
  17. #include <linux/serial_reg.h>
  18. #include <linux/pgtable.h>
  19. #include <asm/processor.h>
  20. #include <asm/page.h>
  21. #include <asm/mmu.h>
  22. #include <asm/thread_info.h>
  23. #include <asm/cache.h>
  24. #include <asm/spr_defs.h>
  25. #include <asm/asm-offsets.h>
  26. #include <linux/of_fdt.h>
  27. #define tophys(rd,rs) \
  28. l.movhi rd,hi(-KERNELBASE) ;\
  29. l.add rd,rd,rs
  30. #define CLEAR_GPR(gpr) \
  31. l.movhi gpr,0x0
  32. #define LOAD_SYMBOL_2_GPR(gpr,symbol) \
  33. l.movhi gpr,hi(symbol) ;\
  34. l.ori gpr,gpr,lo(symbol)
  35. #define UART_BASE_ADD 0x90000000
  36. #define EXCEPTION_SR (SPR_SR_DME | SPR_SR_IME | SPR_SR_DCE | SPR_SR_ICE | SPR_SR_SM)
  37. #define SYSCALL_SR (SPR_SR_DME | SPR_SR_IME | SPR_SR_DCE | SPR_SR_ICE | SPR_SR_IEE | SPR_SR_TEE | SPR_SR_SM)
  38. /* ============================================[ tmp store locations ]=== */
  39. #define SPR_SHADOW_GPR(x) ((x) + SPR_GPR_BASE + 32)
  40. /*
  41. * emergency_print temporary stores
  42. */
  43. #ifdef CONFIG_OPENRISC_HAVE_SHADOW_GPRS
  44. #define EMERGENCY_PRINT_STORE_GPR4 l.mtspr r0,r4,SPR_SHADOW_GPR(14)
  45. #define EMERGENCY_PRINT_LOAD_GPR4 l.mfspr r4,r0,SPR_SHADOW_GPR(14)
  46. #define EMERGENCY_PRINT_STORE_GPR5 l.mtspr r0,r5,SPR_SHADOW_GPR(15)
  47. #define EMERGENCY_PRINT_LOAD_GPR5 l.mfspr r5,r0,SPR_SHADOW_GPR(15)
  48. #define EMERGENCY_PRINT_STORE_GPR6 l.mtspr r0,r6,SPR_SHADOW_GPR(16)
  49. #define EMERGENCY_PRINT_LOAD_GPR6 l.mfspr r6,r0,SPR_SHADOW_GPR(16)
  50. #define EMERGENCY_PRINT_STORE_GPR7 l.mtspr r0,r7,SPR_SHADOW_GPR(7)
  51. #define EMERGENCY_PRINT_LOAD_GPR7 l.mfspr r7,r0,SPR_SHADOW_GPR(7)
  52. #define EMERGENCY_PRINT_STORE_GPR8 l.mtspr r0,r8,SPR_SHADOW_GPR(8)
  53. #define EMERGENCY_PRINT_LOAD_GPR8 l.mfspr r8,r0,SPR_SHADOW_GPR(8)
  54. #define EMERGENCY_PRINT_STORE_GPR9 l.mtspr r0,r9,SPR_SHADOW_GPR(9)
  55. #define EMERGENCY_PRINT_LOAD_GPR9 l.mfspr r9,r0,SPR_SHADOW_GPR(9)
  56. #else /* !CONFIG_OPENRISC_HAVE_SHADOW_GPRS */
  57. #define EMERGENCY_PRINT_STORE_GPR4 l.sw 0x20(r0),r4
  58. #define EMERGENCY_PRINT_LOAD_GPR4 l.lwz r4,0x20(r0)
  59. #define EMERGENCY_PRINT_STORE_GPR5 l.sw 0x24(r0),r5
  60. #define EMERGENCY_PRINT_LOAD_GPR5 l.lwz r5,0x24(r0)
  61. #define EMERGENCY_PRINT_STORE_GPR6 l.sw 0x28(r0),r6
  62. #define EMERGENCY_PRINT_LOAD_GPR6 l.lwz r6,0x28(r0)
  63. #define EMERGENCY_PRINT_STORE_GPR7 l.sw 0x2c(r0),r7
  64. #define EMERGENCY_PRINT_LOAD_GPR7 l.lwz r7,0x2c(r0)
  65. #define EMERGENCY_PRINT_STORE_GPR8 l.sw 0x30(r0),r8
  66. #define EMERGENCY_PRINT_LOAD_GPR8 l.lwz r8,0x30(r0)
  67. #define EMERGENCY_PRINT_STORE_GPR9 l.sw 0x34(r0),r9
  68. #define EMERGENCY_PRINT_LOAD_GPR9 l.lwz r9,0x34(r0)
  69. #endif
  70. /*
  71. * TLB miss handlers temorary stores
  72. */
  73. #ifdef CONFIG_OPENRISC_HAVE_SHADOW_GPRS
  74. #define EXCEPTION_STORE_GPR2 l.mtspr r0,r2,SPR_SHADOW_GPR(2)
  75. #define EXCEPTION_LOAD_GPR2 l.mfspr r2,r0,SPR_SHADOW_GPR(2)
  76. #define EXCEPTION_STORE_GPR3 l.mtspr r0,r3,SPR_SHADOW_GPR(3)
  77. #define EXCEPTION_LOAD_GPR3 l.mfspr r3,r0,SPR_SHADOW_GPR(3)
  78. #define EXCEPTION_STORE_GPR4 l.mtspr r0,r4,SPR_SHADOW_GPR(4)
  79. #define EXCEPTION_LOAD_GPR4 l.mfspr r4,r0,SPR_SHADOW_GPR(4)
  80. #define EXCEPTION_STORE_GPR5 l.mtspr r0,r5,SPR_SHADOW_GPR(5)
  81. #define EXCEPTION_LOAD_GPR5 l.mfspr r5,r0,SPR_SHADOW_GPR(5)
  82. #define EXCEPTION_STORE_GPR6 l.mtspr r0,r6,SPR_SHADOW_GPR(6)
  83. #define EXCEPTION_LOAD_GPR6 l.mfspr r6,r0,SPR_SHADOW_GPR(6)
  84. #else /* !CONFIG_OPENRISC_HAVE_SHADOW_GPRS */
  85. #define EXCEPTION_STORE_GPR2 l.sw 0x64(r0),r2
  86. #define EXCEPTION_LOAD_GPR2 l.lwz r2,0x64(r0)
  87. #define EXCEPTION_STORE_GPR3 l.sw 0x68(r0),r3
  88. #define EXCEPTION_LOAD_GPR3 l.lwz r3,0x68(r0)
  89. #define EXCEPTION_STORE_GPR4 l.sw 0x6c(r0),r4
  90. #define EXCEPTION_LOAD_GPR4 l.lwz r4,0x6c(r0)
  91. #define EXCEPTION_STORE_GPR5 l.sw 0x70(r0),r5
  92. #define EXCEPTION_LOAD_GPR5 l.lwz r5,0x70(r0)
  93. #define EXCEPTION_STORE_GPR6 l.sw 0x74(r0),r6
  94. #define EXCEPTION_LOAD_GPR6 l.lwz r6,0x74(r0)
  95. #endif
  96. /*
  97. * EXCEPTION_HANDLE temporary stores
  98. */
  99. #ifdef CONFIG_OPENRISC_HAVE_SHADOW_GPRS
  100. #define EXCEPTION_T_STORE_GPR30 l.mtspr r0,r30,SPR_SHADOW_GPR(30)
  101. #define EXCEPTION_T_LOAD_GPR30(reg) l.mfspr reg,r0,SPR_SHADOW_GPR(30)
  102. #define EXCEPTION_T_STORE_GPR10 l.mtspr r0,r10,SPR_SHADOW_GPR(10)
  103. #define EXCEPTION_T_LOAD_GPR10(reg) l.mfspr reg,r0,SPR_SHADOW_GPR(10)
  104. #define EXCEPTION_T_STORE_SP l.mtspr r0,r1,SPR_SHADOW_GPR(1)
  105. #define EXCEPTION_T_LOAD_SP(reg) l.mfspr reg,r0,SPR_SHADOW_GPR(1)
  106. #else /* !CONFIG_OPENRISC_HAVE_SHADOW_GPRS */
  107. #define EXCEPTION_T_STORE_GPR30 l.sw 0x78(r0),r30
  108. #define EXCEPTION_T_LOAD_GPR30(reg) l.lwz reg,0x78(r0)
  109. #define EXCEPTION_T_STORE_GPR10 l.sw 0x7c(r0),r10
  110. #define EXCEPTION_T_LOAD_GPR10(reg) l.lwz reg,0x7c(r0)
  111. #define EXCEPTION_T_STORE_SP l.sw 0x80(r0),r1
  112. #define EXCEPTION_T_LOAD_SP(reg) l.lwz reg,0x80(r0)
  113. #endif
  114. /* =========================================================[ macros ]=== */
  115. #ifdef CONFIG_SMP
  116. #define GET_CURRENT_PGD(reg,t1) \
  117. LOAD_SYMBOL_2_GPR(reg,current_pgd) ;\
  118. l.mfspr t1,r0,SPR_COREID ;\
  119. l.slli t1,t1,2 ;\
  120. l.add reg,reg,t1 ;\
  121. tophys (t1,reg) ;\
  122. l.lwz reg,0(t1)
  123. #else
  124. #define GET_CURRENT_PGD(reg,t1) \
  125. LOAD_SYMBOL_2_GPR(reg,current_pgd) ;\
  126. tophys (t1,reg) ;\
  127. l.lwz reg,0(t1)
  128. #endif
  129. /* Load r10 from current_thread_info_set - clobbers r1 and r30 */
  130. #ifdef CONFIG_SMP
  131. #define GET_CURRENT_THREAD_INFO \
  132. LOAD_SYMBOL_2_GPR(r1,current_thread_info_set) ;\
  133. tophys (r30,r1) ;\
  134. l.mfspr r10,r0,SPR_COREID ;\
  135. l.slli r10,r10,2 ;\
  136. l.add r30,r30,r10 ;\
  137. /* r10: current_thread_info */ ;\
  138. l.lwz r10,0(r30)
  139. #else
  140. #define GET_CURRENT_THREAD_INFO \
  141. LOAD_SYMBOL_2_GPR(r1,current_thread_info_set) ;\
  142. tophys (r30,r1) ;\
  143. /* r10: current_thread_info */ ;\
  144. l.lwz r10,0(r30)
  145. #endif
  146. /*
  147. * DSCR: this is a common hook for handling exceptions. it will save
  148. * the needed registers, set up stack and pointer to current
  149. * then jump to the handler while enabling MMU
  150. *
  151. * PRMS: handler - a function to jump to. it has to save the
  152. * remaining registers to kernel stack, call
  153. * appropriate arch-independant exception handler
  154. * and finaly jump to ret_from_except
  155. *
  156. * PREQ: unchanged state from the time exception happened
  157. *
  158. * POST: SAVED the following registers original value
  159. * to the new created exception frame pointed to by r1
  160. *
  161. * r1 - ksp pointing to the new (exception) frame
  162. * r4 - EEAR exception EA
  163. * r10 - current pointing to current_thread_info struct
  164. * r12 - syscall 0, since we didn't come from syscall
  165. * r30 - handler address of the handler we'll jump to
  166. *
  167. * handler has to save remaining registers to the exception
  168. * ksp frame *before* tainting them!
  169. *
  170. * NOTE: this function is not reentrant per se. reentrancy is guaranteed
  171. * by processor disabling all exceptions/interrupts when exception
  172. * accours.
  173. *
  174. * OPTM: no need to make it so wasteful to extract ksp when in user mode
  175. */
  176. #define EXCEPTION_HANDLE(handler) \
  177. EXCEPTION_T_STORE_GPR30 ;\
  178. l.mfspr r30,r0,SPR_ESR_BASE ;\
  179. l.andi r30,r30,SPR_SR_SM ;\
  180. l.sfeqi r30,0 ;\
  181. EXCEPTION_T_STORE_GPR10 ;\
  182. l.bnf 2f /* kernel_mode */ ;\
  183. EXCEPTION_T_STORE_SP /* delay slot */ ;\
  184. 1: /* user_mode: */ ;\
  185. GET_CURRENT_THREAD_INFO ;\
  186. tophys (r30,r10) ;\
  187. l.lwz r1,(TI_KSP)(r30) ;\
  188. /* fall through */ ;\
  189. 2: /* kernel_mode: */ ;\
  190. /* create new stack frame, save only needed gprs */ ;\
  191. /* r1: KSP, r10: current, r4: EEAR, r31: __pa(KSP) */ ;\
  192. /* r12: temp, syscall indicator */ ;\
  193. l.addi r1,r1,-(INT_FRAME_SIZE) ;\
  194. /* r1 is KSP, r30 is __pa(KSP) */ ;\
  195. tophys (r30,r1) ;\
  196. l.sw PT_GPR12(r30),r12 ;\
  197. /* r4 use for tmp before EA */ ;\
  198. l.mfspr r12,r0,SPR_EPCR_BASE ;\
  199. l.sw PT_PC(r30),r12 ;\
  200. l.mfspr r12,r0,SPR_ESR_BASE ;\
  201. l.sw PT_SR(r30),r12 ;\
  202. /* save r30 */ ;\
  203. EXCEPTION_T_LOAD_GPR30(r12) ;\
  204. l.sw PT_GPR30(r30),r12 ;\
  205. /* save r10 as was prior to exception */ ;\
  206. EXCEPTION_T_LOAD_GPR10(r12) ;\
  207. l.sw PT_GPR10(r30),r12 ;\
  208. /* save PT_SP as was prior to exception */ ;\
  209. EXCEPTION_T_LOAD_SP(r12) ;\
  210. l.sw PT_SP(r30),r12 ;\
  211. /* save exception r4, set r4 = EA */ ;\
  212. l.sw PT_GPR4(r30),r4 ;\
  213. l.mfspr r4,r0,SPR_EEAR_BASE ;\
  214. /* r12 == 1 if we come from syscall */ ;\
  215. CLEAR_GPR(r12) ;\
  216. /* ----- turn on MMU ----- */ ;\
  217. /* Carry DSX into exception SR */ ;\
  218. l.mfspr r30,r0,SPR_SR ;\
  219. l.andi r30,r30,SPR_SR_DSX ;\
  220. l.ori r30,r30,(EXCEPTION_SR) ;\
  221. l.mtspr r0,r30,SPR_ESR_BASE ;\
  222. /* r30: EA address of handler */ ;\
  223. LOAD_SYMBOL_2_GPR(r30,handler) ;\
  224. l.mtspr r0,r30,SPR_EPCR_BASE ;\
  225. l.rfe
  226. /*
  227. * this doesn't work
  228. *
  229. *
  230. * #ifdef CONFIG_JUMP_UPON_UNHANDLED_EXCEPTION
  231. * #define UNHANDLED_EXCEPTION(handler) \
  232. * l.ori r3,r0,0x1 ;\
  233. * l.mtspr r0,r3,SPR_SR ;\
  234. * l.movhi r3,hi(0xf0000100) ;\
  235. * l.ori r3,r3,lo(0xf0000100) ;\
  236. * l.jr r3 ;\
  237. * l.nop 1
  238. *
  239. * #endif
  240. */
  241. /* DSCR: this is the same as EXCEPTION_HANDLE(), we are just
  242. * a bit more carefull (if we have a PT_SP or current pointer
  243. * corruption) and set them up from 'current_set'
  244. *
  245. */
  246. #define UNHANDLED_EXCEPTION(handler) \
  247. EXCEPTION_T_STORE_GPR30 ;\
  248. EXCEPTION_T_STORE_GPR10 ;\
  249. EXCEPTION_T_STORE_SP ;\
  250. /* temporary store r3, r9 into r1, r10 */ ;\
  251. l.addi r1,r3,0x0 ;\
  252. l.addi r10,r9,0x0 ;\
  253. LOAD_SYMBOL_2_GPR(r9,_string_unhandled_exception) ;\
  254. tophys (r3,r9) ;\
  255. l.jal _emergency_print ;\
  256. l.nop ;\
  257. l.mfspr r3,r0,SPR_NPC ;\
  258. l.jal _emergency_print_nr ;\
  259. l.andi r3,r3,0x1f00 ;\
  260. LOAD_SYMBOL_2_GPR(r9,_string_epc_prefix) ;\
  261. tophys (r3,r9) ;\
  262. l.jal _emergency_print ;\
  263. l.nop ;\
  264. l.jal _emergency_print_nr ;\
  265. l.mfspr r3,r0,SPR_EPCR_BASE ;\
  266. LOAD_SYMBOL_2_GPR(r9,_string_nl) ;\
  267. tophys (r3,r9) ;\
  268. l.jal _emergency_print ;\
  269. l.nop ;\
  270. /* end of printing */ ;\
  271. l.addi r3,r1,0x0 ;\
  272. l.addi r9,r10,0x0 ;\
  273. /* extract current, ksp from current_set */ ;\
  274. LOAD_SYMBOL_2_GPR(r1,_unhandled_stack_top) ;\
  275. LOAD_SYMBOL_2_GPR(r10,init_thread_union) ;\
  276. /* create new stack frame, save only needed gprs */ ;\
  277. /* r1: KSP, r10: current, r31: __pa(KSP) */ ;\
  278. /* r12: temp, syscall indicator, r13 temp */ ;\
  279. l.addi r1,r1,-(INT_FRAME_SIZE) ;\
  280. /* r1 is KSP, r30 is __pa(KSP) */ ;\
  281. tophys (r30,r1) ;\
  282. l.sw PT_GPR12(r30),r12 ;\
  283. l.mfspr r12,r0,SPR_EPCR_BASE ;\
  284. l.sw PT_PC(r30),r12 ;\
  285. l.mfspr r12,r0,SPR_ESR_BASE ;\
  286. l.sw PT_SR(r30),r12 ;\
  287. /* save r31 */ ;\
  288. EXCEPTION_T_LOAD_GPR30(r12) ;\
  289. l.sw PT_GPR30(r30),r12 ;\
  290. /* save r10 as was prior to exception */ ;\
  291. EXCEPTION_T_LOAD_GPR10(r12) ;\
  292. l.sw PT_GPR10(r30),r12 ;\
  293. /* save PT_SP as was prior to exception */ ;\
  294. EXCEPTION_T_LOAD_SP(r12) ;\
  295. l.sw PT_SP(r30),r12 ;\
  296. l.sw PT_GPR13(r30),r13 ;\
  297. /* --> */ ;\
  298. /* save exception r4, set r4 = EA */ ;\
  299. l.sw PT_GPR4(r30),r4 ;\
  300. l.mfspr r4,r0,SPR_EEAR_BASE ;\
  301. /* r12 == 1 if we come from syscall */ ;\
  302. CLEAR_GPR(r12) ;\
  303. /* ----- play a MMU trick ----- */ ;\
  304. l.ori r30,r0,(EXCEPTION_SR) ;\
  305. l.mtspr r0,r30,SPR_ESR_BASE ;\
  306. /* r31: EA address of handler */ ;\
  307. LOAD_SYMBOL_2_GPR(r30,handler) ;\
  308. l.mtspr r0,r30,SPR_EPCR_BASE ;\
  309. l.rfe
  310. /* =====================================================[ exceptions] === */
  311. /* ---[ 0x100: RESET exception ]----------------------------------------- */
  312. .org 0x100
  313. /* Jump to .init code at _start which lives in the .head section
  314. * and will be discarded after boot.
  315. */
  316. LOAD_SYMBOL_2_GPR(r15, _start)
  317. tophys (r13,r15) /* MMU disabled */
  318. l.jr r13
  319. l.nop
  320. /* ---[ 0x200: BUS exception ]------------------------------------------- */
  321. .org 0x200
  322. _dispatch_bus_fault:
  323. EXCEPTION_HANDLE(_bus_fault_handler)
  324. /* ---[ 0x300: Data Page Fault exception ]------------------------------- */
  325. .org 0x300
  326. _dispatch_do_dpage_fault:
  327. // totaly disable timer interrupt
  328. // l.mtspr r0,r0,SPR_TTMR
  329. // DEBUG_TLB_PROBE(0x300)
  330. // EXCEPTION_DEBUG_VALUE_ER_ENABLED(0x300)
  331. EXCEPTION_HANDLE(_data_page_fault_handler)
  332. /* ---[ 0x400: Insn Page Fault exception ]------------------------------- */
  333. .org 0x400
  334. _dispatch_do_ipage_fault:
  335. // totaly disable timer interrupt
  336. // l.mtspr r0,r0,SPR_TTMR
  337. // DEBUG_TLB_PROBE(0x400)
  338. // EXCEPTION_DEBUG_VALUE_ER_ENABLED(0x400)
  339. EXCEPTION_HANDLE(_insn_page_fault_handler)
  340. /* ---[ 0x500: Timer exception ]----------------------------------------- */
  341. .org 0x500
  342. EXCEPTION_HANDLE(_timer_handler)
  343. /* ---[ 0x600: Alignment exception ]-------------------------------------- */
  344. .org 0x600
  345. EXCEPTION_HANDLE(_alignment_handler)
  346. /* ---[ 0x700: Illegal insn exception ]---------------------------------- */
  347. .org 0x700
  348. EXCEPTION_HANDLE(_illegal_instruction_handler)
  349. /* ---[ 0x800: External interrupt exception ]---------------------------- */
  350. .org 0x800
  351. EXCEPTION_HANDLE(_external_irq_handler)
  352. /* ---[ 0x900: DTLB miss exception ]------------------------------------- */
  353. .org 0x900
  354. l.j boot_dtlb_miss_handler
  355. l.nop
  356. /* ---[ 0xa00: ITLB miss exception ]------------------------------------- */
  357. .org 0xa00
  358. l.j boot_itlb_miss_handler
  359. l.nop
  360. /* ---[ 0xb00: Range exception ]----------------------------------------- */
  361. .org 0xb00
  362. UNHANDLED_EXCEPTION(_vector_0xb00)
  363. /* ---[ 0xc00: Syscall exception ]--------------------------------------- */
  364. .org 0xc00
  365. EXCEPTION_HANDLE(_sys_call_handler)
  366. /* ---[ 0xd00: Trap exception ]------------------------------------------ */
  367. .org 0xd00
  368. UNHANDLED_EXCEPTION(_vector_0xd00)
  369. /* ---[ 0xe00: Trap exception ]------------------------------------------ */
  370. .org 0xe00
  371. // UNHANDLED_EXCEPTION(_vector_0xe00)
  372. EXCEPTION_HANDLE(_trap_handler)
  373. /* ---[ 0xf00: Reserved exception ]-------------------------------------- */
  374. .org 0xf00
  375. UNHANDLED_EXCEPTION(_vector_0xf00)
  376. /* ---[ 0x1000: Reserved exception ]------------------------------------- */
  377. .org 0x1000
  378. UNHANDLED_EXCEPTION(_vector_0x1000)
  379. /* ---[ 0x1100: Reserved exception ]------------------------------------- */
  380. .org 0x1100
  381. UNHANDLED_EXCEPTION(_vector_0x1100)
  382. /* ---[ 0x1200: Reserved exception ]------------------------------------- */
  383. .org 0x1200
  384. UNHANDLED_EXCEPTION(_vector_0x1200)
  385. /* ---[ 0x1300: Reserved exception ]------------------------------------- */
  386. .org 0x1300
  387. UNHANDLED_EXCEPTION(_vector_0x1300)
  388. /* ---[ 0x1400: Reserved exception ]------------------------------------- */
  389. .org 0x1400
  390. UNHANDLED_EXCEPTION(_vector_0x1400)
  391. /* ---[ 0x1500: Reserved exception ]------------------------------------- */
  392. .org 0x1500
  393. UNHANDLED_EXCEPTION(_vector_0x1500)
  394. /* ---[ 0x1600: Reserved exception ]------------------------------------- */
  395. .org 0x1600
  396. UNHANDLED_EXCEPTION(_vector_0x1600)
  397. /* ---[ 0x1700: Reserved exception ]------------------------------------- */
  398. .org 0x1700
  399. UNHANDLED_EXCEPTION(_vector_0x1700)
  400. /* ---[ 0x1800: Reserved exception ]------------------------------------- */
  401. .org 0x1800
  402. UNHANDLED_EXCEPTION(_vector_0x1800)
  403. /* ---[ 0x1900: Reserved exception ]------------------------------------- */
  404. .org 0x1900
  405. UNHANDLED_EXCEPTION(_vector_0x1900)
  406. /* ---[ 0x1a00: Reserved exception ]------------------------------------- */
  407. .org 0x1a00
  408. UNHANDLED_EXCEPTION(_vector_0x1a00)
  409. /* ---[ 0x1b00: Reserved exception ]------------------------------------- */
  410. .org 0x1b00
  411. UNHANDLED_EXCEPTION(_vector_0x1b00)
  412. /* ---[ 0x1c00: Reserved exception ]------------------------------------- */
  413. .org 0x1c00
  414. UNHANDLED_EXCEPTION(_vector_0x1c00)
  415. /* ---[ 0x1d00: Reserved exception ]------------------------------------- */
  416. .org 0x1d00
  417. UNHANDLED_EXCEPTION(_vector_0x1d00)
  418. /* ---[ 0x1e00: Reserved exception ]------------------------------------- */
  419. .org 0x1e00
  420. UNHANDLED_EXCEPTION(_vector_0x1e00)
  421. /* ---[ 0x1f00: Reserved exception ]------------------------------------- */
  422. .org 0x1f00
  423. UNHANDLED_EXCEPTION(_vector_0x1f00)
  424. .org 0x2000
  425. /* ===================================================[ kernel start ]=== */
  426. /* .text*/
  427. /* This early stuff belongs in HEAD, but some of the functions below definitely
  428. * don't... */
  429. __HEAD
  430. .global _start
  431. _start:
  432. /* Init r0 to zero as per spec */
  433. CLEAR_GPR(r0)
  434. /* save kernel parameters */
  435. l.or r25,r0,r3 /* pointer to fdt */
  436. /*
  437. * ensure a deterministic start
  438. */
  439. l.ori r3,r0,0x1
  440. l.mtspr r0,r3,SPR_SR
  441. /*
  442. * Start the TTCR as early as possible, so that the RNG can make use of
  443. * measurements of boot time from the earliest opportunity. Especially
  444. * important is that the TTCR does not return zero by the time we reach
  445. * random_init().
  446. */
  447. l.movhi r3,hi(SPR_TTMR_CR)
  448. l.mtspr r0,r3,SPR_TTMR
  449. CLEAR_GPR(r1)
  450. CLEAR_GPR(r2)
  451. CLEAR_GPR(r3)
  452. CLEAR_GPR(r4)
  453. CLEAR_GPR(r5)
  454. CLEAR_GPR(r6)
  455. CLEAR_GPR(r7)
  456. CLEAR_GPR(r8)
  457. CLEAR_GPR(r9)
  458. CLEAR_GPR(r10)
  459. CLEAR_GPR(r11)
  460. CLEAR_GPR(r12)
  461. CLEAR_GPR(r13)
  462. CLEAR_GPR(r14)
  463. CLEAR_GPR(r15)
  464. CLEAR_GPR(r16)
  465. CLEAR_GPR(r17)
  466. CLEAR_GPR(r18)
  467. CLEAR_GPR(r19)
  468. CLEAR_GPR(r20)
  469. CLEAR_GPR(r21)
  470. CLEAR_GPR(r22)
  471. CLEAR_GPR(r23)
  472. CLEAR_GPR(r24)
  473. CLEAR_GPR(r26)
  474. CLEAR_GPR(r27)
  475. CLEAR_GPR(r28)
  476. CLEAR_GPR(r29)
  477. CLEAR_GPR(r30)
  478. CLEAR_GPR(r31)
  479. #ifdef CONFIG_SMP
  480. l.mfspr r26,r0,SPR_COREID
  481. l.sfeq r26,r0
  482. l.bnf secondary_wait
  483. l.nop
  484. #endif
  485. /*
  486. * set up initial ksp and current
  487. */
  488. /* setup kernel stack */
  489. LOAD_SYMBOL_2_GPR(r1,init_thread_union + THREAD_SIZE)
  490. LOAD_SYMBOL_2_GPR(r10,init_thread_union) // setup current
  491. tophys (r31,r10)
  492. l.sw TI_KSP(r31), r1
  493. l.ori r4,r0,0x0
  494. /*
  495. * .data contains initialized data,
  496. * .bss contains uninitialized data - clear it up
  497. */
  498. clear_bss:
  499. LOAD_SYMBOL_2_GPR(r24, __bss_start)
  500. LOAD_SYMBOL_2_GPR(r26, _end)
  501. tophys(r28,r24)
  502. tophys(r30,r26)
  503. CLEAR_GPR(r24)
  504. CLEAR_GPR(r26)
  505. 1:
  506. l.sw (0)(r28),r0
  507. l.sfltu r28,r30
  508. l.bf 1b
  509. l.addi r28,r28,4
  510. enable_ic:
  511. l.jal _ic_enable
  512. l.nop
  513. enable_dc:
  514. l.jal _dc_enable
  515. l.nop
  516. flush_tlb:
  517. l.jal _flush_tlb
  518. l.nop
  519. /* The MMU needs to be enabled before or1k_early_setup is called */
  520. enable_mmu:
  521. /*
  522. * enable dmmu & immu
  523. * SR[5] = 0, SR[6] = 0, 6th and 7th bit of SR set to 0
  524. */
  525. l.mfspr r30,r0,SPR_SR
  526. l.movhi r28,hi(SPR_SR_DME | SPR_SR_IME)
  527. l.ori r28,r28,lo(SPR_SR_DME | SPR_SR_IME)
  528. l.or r30,r30,r28
  529. l.mtspr r0,r30,SPR_SR
  530. l.nop
  531. l.nop
  532. l.nop
  533. l.nop
  534. l.nop
  535. l.nop
  536. l.nop
  537. l.nop
  538. l.nop
  539. l.nop
  540. l.nop
  541. l.nop
  542. l.nop
  543. l.nop
  544. l.nop
  545. l.nop
  546. // reset the simulation counters
  547. l.nop 5
  548. /* check fdt header magic word */
  549. l.lwz r3,0(r25) /* load magic from fdt into r3 */
  550. l.movhi r4,hi(OF_DT_HEADER)
  551. l.ori r4,r4,lo(OF_DT_HEADER)
  552. l.sfeq r3,r4
  553. l.bf _fdt_found
  554. l.nop
  555. /* magic number mismatch, set fdt pointer to null */
  556. l.or r25,r0,r0
  557. _fdt_found:
  558. /* pass fdt pointer to or1k_early_setup in r3 */
  559. l.or r3,r0,r25
  560. LOAD_SYMBOL_2_GPR(r24, or1k_early_setup)
  561. l.jalr r24
  562. l.nop
  563. clear_regs:
  564. /*
  565. * clear all GPRS to increase determinism
  566. */
  567. CLEAR_GPR(r2)
  568. CLEAR_GPR(r3)
  569. CLEAR_GPR(r4)
  570. CLEAR_GPR(r5)
  571. CLEAR_GPR(r6)
  572. CLEAR_GPR(r7)
  573. CLEAR_GPR(r8)
  574. CLEAR_GPR(r9)
  575. CLEAR_GPR(r11)
  576. CLEAR_GPR(r12)
  577. CLEAR_GPR(r13)
  578. CLEAR_GPR(r14)
  579. CLEAR_GPR(r15)
  580. CLEAR_GPR(r16)
  581. CLEAR_GPR(r17)
  582. CLEAR_GPR(r18)
  583. CLEAR_GPR(r19)
  584. CLEAR_GPR(r20)
  585. CLEAR_GPR(r21)
  586. CLEAR_GPR(r22)
  587. CLEAR_GPR(r23)
  588. CLEAR_GPR(r24)
  589. CLEAR_GPR(r25)
  590. CLEAR_GPR(r26)
  591. CLEAR_GPR(r27)
  592. CLEAR_GPR(r28)
  593. CLEAR_GPR(r29)
  594. CLEAR_GPR(r30)
  595. CLEAR_GPR(r31)
  596. jump_start_kernel:
  597. /*
  598. * jump to kernel entry (start_kernel)
  599. */
  600. LOAD_SYMBOL_2_GPR(r30, start_kernel)
  601. l.jr r30
  602. l.nop
  603. _flush_tlb:
  604. /*
  605. * I N V A L I D A T E T L B e n t r i e s
  606. */
  607. LOAD_SYMBOL_2_GPR(r5,SPR_DTLBMR_BASE(0))
  608. LOAD_SYMBOL_2_GPR(r6,SPR_ITLBMR_BASE(0))
  609. l.addi r7,r0,128 /* Maximum number of sets */
  610. 1:
  611. l.mtspr r5,r0,0x0
  612. l.mtspr r6,r0,0x0
  613. l.addi r5,r5,1
  614. l.addi r6,r6,1
  615. l.sfeq r7,r0
  616. l.bnf 1b
  617. l.addi r7,r7,-1
  618. l.jr r9
  619. l.nop
  620. #ifdef CONFIG_SMP
  621. secondary_wait:
  622. /* Doze the cpu until we are asked to run */
  623. /* If we dont have power management skip doze */
  624. l.mfspr r25,r0,SPR_UPR
  625. l.andi r25,r25,SPR_UPR_PMP
  626. l.sfeq r25,r0
  627. l.bf secondary_check_release
  628. l.nop
  629. /* Setup special secondary exception handler */
  630. LOAD_SYMBOL_2_GPR(r3, _secondary_evbar)
  631. tophys(r25,r3)
  632. l.mtspr r0,r25,SPR_EVBAR
  633. /* Enable Interrupts */
  634. l.mfspr r25,r0,SPR_SR
  635. l.ori r25,r25,SPR_SR_IEE
  636. l.mtspr r0,r25,SPR_SR
  637. /* Unmask interrupts interrupts */
  638. l.mfspr r25,r0,SPR_PICMR
  639. l.ori r25,r25,0xffff
  640. l.mtspr r0,r25,SPR_PICMR
  641. /* Doze */
  642. l.mfspr r25,r0,SPR_PMR
  643. LOAD_SYMBOL_2_GPR(r3, SPR_PMR_DME)
  644. l.or r25,r25,r3
  645. l.mtspr r0,r25,SPR_PMR
  646. /* Wakeup - Restore exception handler */
  647. l.mtspr r0,r0,SPR_EVBAR
  648. secondary_check_release:
  649. /*
  650. * Check if we actually got the release signal, if not go-back to
  651. * sleep.
  652. */
  653. l.mfspr r25,r0,SPR_COREID
  654. LOAD_SYMBOL_2_GPR(r3, secondary_release)
  655. tophys(r4, r3)
  656. l.lwz r3,0(r4)
  657. l.sfeq r25,r3
  658. l.bnf secondary_wait
  659. l.nop
  660. /* fall through to secondary_init */
  661. secondary_init:
  662. /*
  663. * set up initial ksp and current
  664. */
  665. LOAD_SYMBOL_2_GPR(r10, secondary_thread_info)
  666. tophys (r30,r10)
  667. l.lwz r10,0(r30)
  668. l.addi r1,r10,THREAD_SIZE
  669. tophys (r30,r10)
  670. l.sw TI_KSP(r30),r1
  671. l.jal _ic_enable
  672. l.nop
  673. l.jal _dc_enable
  674. l.nop
  675. l.jal _flush_tlb
  676. l.nop
  677. /*
  678. * enable dmmu & immu
  679. */
  680. l.mfspr r30,r0,SPR_SR
  681. l.movhi r28,hi(SPR_SR_DME | SPR_SR_IME)
  682. l.ori r28,r28,lo(SPR_SR_DME | SPR_SR_IME)
  683. l.or r30,r30,r28
  684. /*
  685. * This is a bit tricky, we need to switch over from physical addresses
  686. * to virtual addresses on the fly.
  687. * To do that, we first set up ESR with the IME and DME bits set.
  688. * Then EPCR is set to secondary_start and then a l.rfe is issued to
  689. * "jump" to that.
  690. */
  691. l.mtspr r0,r30,SPR_ESR_BASE
  692. LOAD_SYMBOL_2_GPR(r30, secondary_start)
  693. l.mtspr r0,r30,SPR_EPCR_BASE
  694. l.rfe
  695. secondary_start:
  696. LOAD_SYMBOL_2_GPR(r30, secondary_start_kernel)
  697. l.jr r30
  698. l.nop
  699. #endif
  700. /* ========================================[ cache ]=== */
  701. /* alignment here so we don't change memory offsets with
  702. * memory controller defined
  703. */
  704. .align 0x2000
  705. _ic_enable:
  706. /* Check if IC present and skip enabling otherwise */
  707. l.mfspr r24,r0,SPR_UPR
  708. l.andi r26,r24,SPR_UPR_ICP
  709. l.sfeq r26,r0
  710. l.bf 9f
  711. l.nop
  712. /* Disable IC */
  713. l.mfspr r6,r0,SPR_SR
  714. l.addi r5,r0,-1
  715. l.xori r5,r5,SPR_SR_ICE
  716. l.and r5,r6,r5
  717. l.mtspr r0,r5,SPR_SR
  718. /* Establish cache block size
  719. If BS=0, 16;
  720. If BS=1, 32;
  721. r14 contain block size
  722. */
  723. l.mfspr r24,r0,SPR_ICCFGR
  724. l.andi r26,r24,SPR_ICCFGR_CBS
  725. l.srli r28,r26,7
  726. l.ori r30,r0,16
  727. l.sll r14,r30,r28
  728. /* Establish number of cache sets
  729. r16 contains number of cache sets
  730. r28 contains log(# of cache sets)
  731. */
  732. l.andi r26,r24,SPR_ICCFGR_NCS
  733. l.srli r28,r26,3
  734. l.ori r30,r0,1
  735. l.sll r16,r30,r28
  736. /* Invalidate IC */
  737. l.addi r6,r0,0
  738. l.sll r5,r14,r28
  739. // l.mul r5,r14,r16
  740. // l.trap 1
  741. // l.addi r5,r0,IC_SIZE
  742. 1:
  743. l.mtspr r0,r6,SPR_ICBIR
  744. l.sfne r6,r5
  745. l.bf 1b
  746. l.add r6,r6,r14
  747. // l.addi r6,r6,IC_LINE
  748. /* Enable IC */
  749. l.mfspr r6,r0,SPR_SR
  750. l.ori r6,r6,SPR_SR_ICE
  751. l.mtspr r0,r6,SPR_SR
  752. l.nop
  753. l.nop
  754. l.nop
  755. l.nop
  756. l.nop
  757. l.nop
  758. l.nop
  759. l.nop
  760. l.nop
  761. l.nop
  762. 9:
  763. l.jr r9
  764. l.nop
  765. _dc_enable:
  766. /* Check if DC present and skip enabling otherwise */
  767. l.mfspr r24,r0,SPR_UPR
  768. l.andi r26,r24,SPR_UPR_DCP
  769. l.sfeq r26,r0
  770. l.bf 9f
  771. l.nop
  772. /* Disable DC */
  773. l.mfspr r6,r0,SPR_SR
  774. l.addi r5,r0,-1
  775. l.xori r5,r5,SPR_SR_DCE
  776. l.and r5,r6,r5
  777. l.mtspr r0,r5,SPR_SR
  778. /* Establish cache block size
  779. If BS=0, 16;
  780. If BS=1, 32;
  781. r14 contain block size
  782. */
  783. l.mfspr r24,r0,SPR_DCCFGR
  784. l.andi r26,r24,SPR_DCCFGR_CBS
  785. l.srli r28,r26,7
  786. l.ori r30,r0,16
  787. l.sll r14,r30,r28
  788. /* Establish number of cache sets
  789. r16 contains number of cache sets
  790. r28 contains log(# of cache sets)
  791. */
  792. l.andi r26,r24,SPR_DCCFGR_NCS
  793. l.srli r28,r26,3
  794. l.ori r30,r0,1
  795. l.sll r16,r30,r28
  796. /* Invalidate DC */
  797. l.addi r6,r0,0
  798. l.sll r5,r14,r28
  799. 1:
  800. l.mtspr r0,r6,SPR_DCBIR
  801. l.sfne r6,r5
  802. l.bf 1b
  803. l.add r6,r6,r14
  804. /* Enable DC */
  805. l.mfspr r6,r0,SPR_SR
  806. l.ori r6,r6,SPR_SR_DCE
  807. l.mtspr r0,r6,SPR_SR
  808. 9:
  809. l.jr r9
  810. l.nop
  811. /* ===============================================[ page table masks ]=== */
  812. #define DTLB_UP_CONVERT_MASK 0x3fa
  813. #define ITLB_UP_CONVERT_MASK 0x3a
  814. /* for SMP we'd have (this is a bit subtle, CC must be always set
  815. * for SMP, but since we have _PAGE_PRESENT bit always defined
  816. * we can just modify the mask)
  817. */
  818. #define DTLB_SMP_CONVERT_MASK 0x3fb
  819. #define ITLB_SMP_CONVERT_MASK 0x3b
  820. /* ---[ boot dtlb miss handler ]----------------------------------------- */
  821. boot_dtlb_miss_handler:
  822. /* mask for DTLB_MR register: - (0) sets V (valid) bit,
  823. * - (31-12) sets bits belonging to VPN (31-12)
  824. */
  825. #define DTLB_MR_MASK 0xfffff001
  826. /* mask for DTLB_TR register: - (2) sets CI (cache inhibit) bit,
  827. * - (4) sets A (access) bit,
  828. * - (5) sets D (dirty) bit,
  829. * - (8) sets SRE (superuser read) bit
  830. * - (9) sets SWE (superuser write) bit
  831. * - (31-12) sets bits belonging to VPN (31-12)
  832. */
  833. #define DTLB_TR_MASK 0xfffff332
  834. /* These are for masking out the VPN/PPN value from the MR/TR registers...
  835. * it's not the same as the PFN */
  836. #define VPN_MASK 0xfffff000
  837. #define PPN_MASK 0xfffff000
  838. EXCEPTION_STORE_GPR6
  839. #if 0
  840. l.mfspr r6,r0,SPR_ESR_BASE //
  841. l.andi r6,r6,SPR_SR_SM // are we in kernel mode ?
  842. l.sfeqi r6,0 // r6 == 0x1 --> SM
  843. l.bf exit_with_no_dtranslation //
  844. l.nop
  845. #endif
  846. /* this could be optimized by moving storing of
  847. * non r6 registers here, and jumping r6 restore
  848. * if not in supervisor mode
  849. */
  850. EXCEPTION_STORE_GPR2
  851. EXCEPTION_STORE_GPR3
  852. EXCEPTION_STORE_GPR4
  853. EXCEPTION_STORE_GPR5
  854. l.mfspr r4,r0,SPR_EEAR_BASE // get the offending EA
  855. immediate_translation:
  856. CLEAR_GPR(r6)
  857. l.srli r3,r4,0xd // r3 <- r4 / 8192 (sets are relative to page size (8Kb) NOT VPN size (4Kb)
  858. l.mfspr r6, r0, SPR_DMMUCFGR
  859. l.andi r6, r6, SPR_DMMUCFGR_NTS
  860. l.srli r6, r6, SPR_DMMUCFGR_NTS_OFF
  861. l.ori r5, r0, 0x1
  862. l.sll r5, r5, r6 // r5 = number DMMU sets
  863. l.addi r6, r5, -1 // r6 = nsets mask
  864. l.and r2, r3, r6 // r2 <- r3 % NSETS_MASK
  865. l.or r6,r6,r4 // r6 <- r4
  866. l.ori r6,r6,~(VPN_MASK) // r6 <- VPN :VPN .xfff - clear up lo(r6) to 0x**** *fff
  867. l.movhi r5,hi(DTLB_MR_MASK) // r5 <- ffff:0000.x000
  868. l.ori r5,r5,lo(DTLB_MR_MASK) // r5 <- ffff:1111.x001 - apply DTLB_MR_MASK
  869. l.and r5,r5,r6 // r5 <- VPN :VPN .x001 - we have DTLBMR entry
  870. l.mtspr r2,r5,SPR_DTLBMR_BASE(0) // set DTLBMR
  871. /* set up DTLB with no translation for EA <= 0xbfffffff */
  872. LOAD_SYMBOL_2_GPR(r6,0xbfffffff)
  873. l.sfgeu r6,r4 // flag if r6 >= r4 (if 0xbfffffff >= EA)
  874. l.bf 1f // goto out
  875. l.and r3,r4,r4 // delay slot :: 24 <- r4 (if flag==1)
  876. tophys(r3,r4) // r3 <- PA
  877. 1:
  878. l.ori r3,r3,~(PPN_MASK) // r3 <- PPN :PPN .xfff - clear up lo(r6) to 0x**** *fff
  879. l.movhi r5,hi(DTLB_TR_MASK) // r5 <- ffff:0000.x000
  880. l.ori r5,r5,lo(DTLB_TR_MASK) // r5 <- ffff:1111.x330 - apply DTLB_MR_MASK
  881. l.and r5,r5,r3 // r5 <- PPN :PPN .x330 - we have DTLBTR entry
  882. l.mtspr r2,r5,SPR_DTLBTR_BASE(0) // set DTLBTR
  883. EXCEPTION_LOAD_GPR6
  884. EXCEPTION_LOAD_GPR5
  885. EXCEPTION_LOAD_GPR4
  886. EXCEPTION_LOAD_GPR3
  887. EXCEPTION_LOAD_GPR2
  888. l.rfe // SR <- ESR, PC <- EPC
  889. exit_with_no_dtranslation:
  890. /* EA out of memory or not in supervisor mode */
  891. EXCEPTION_LOAD_GPR6
  892. EXCEPTION_LOAD_GPR4
  893. l.j _dispatch_bus_fault
  894. /* ---[ boot itlb miss handler ]----------------------------------------- */
  895. boot_itlb_miss_handler:
  896. /* mask for ITLB_MR register: - sets V (valid) bit,
  897. * - sets bits belonging to VPN (15-12)
  898. */
  899. #define ITLB_MR_MASK 0xfffff001
  900. /* mask for ITLB_TR register: - sets A (access) bit,
  901. * - sets SXE (superuser execute) bit
  902. * - sets bits belonging to VPN (15-12)
  903. */
  904. #define ITLB_TR_MASK 0xfffff050
  905. /*
  906. #define VPN_MASK 0xffffe000
  907. #define PPN_MASK 0xffffe000
  908. */
  909. EXCEPTION_STORE_GPR2
  910. EXCEPTION_STORE_GPR3
  911. EXCEPTION_STORE_GPR4
  912. EXCEPTION_STORE_GPR5
  913. EXCEPTION_STORE_GPR6
  914. #if 0
  915. l.mfspr r6,r0,SPR_ESR_BASE //
  916. l.andi r6,r6,SPR_SR_SM // are we in kernel mode ?
  917. l.sfeqi r6,0 // r6 == 0x1 --> SM
  918. l.bf exit_with_no_itranslation
  919. l.nop
  920. #endif
  921. l.mfspr r4,r0,SPR_EEAR_BASE // get the offending EA
  922. earlyearly:
  923. CLEAR_GPR(r6)
  924. l.srli r3,r4,0xd // r3 <- r4 / 8192 (sets are relative to page size (8Kb) NOT VPN size (4Kb)
  925. l.mfspr r6, r0, SPR_IMMUCFGR
  926. l.andi r6, r6, SPR_IMMUCFGR_NTS
  927. l.srli r6, r6, SPR_IMMUCFGR_NTS_OFF
  928. l.ori r5, r0, 0x1
  929. l.sll r5, r5, r6 // r5 = number IMMU sets from IMMUCFGR
  930. l.addi r6, r5, -1 // r6 = nsets mask
  931. l.and r2, r3, r6 // r2 <- r3 % NSETS_MASK
  932. l.or r6,r6,r4 // r6 <- r4
  933. l.ori r6,r6,~(VPN_MASK) // r6 <- VPN :VPN .xfff - clear up lo(r6) to 0x**** *fff
  934. l.movhi r5,hi(ITLB_MR_MASK) // r5 <- ffff:0000.x000
  935. l.ori r5,r5,lo(ITLB_MR_MASK) // r5 <- ffff:1111.x001 - apply ITLB_MR_MASK
  936. l.and r5,r5,r6 // r5 <- VPN :VPN .x001 - we have ITLBMR entry
  937. l.mtspr r2,r5,SPR_ITLBMR_BASE(0) // set ITLBMR
  938. /*
  939. * set up ITLB with no translation for EA <= 0x0fffffff
  940. *
  941. * we need this for head.S mapping (EA = PA). if we move all functions
  942. * which run with mmu enabled into entry.S, we might be able to eliminate this.
  943. *
  944. */
  945. LOAD_SYMBOL_2_GPR(r6,0x0fffffff)
  946. l.sfgeu r6,r4 // flag if r6 >= r4 (if 0xb0ffffff >= EA)
  947. l.bf 1f // goto out
  948. l.and r3,r4,r4 // delay slot :: 24 <- r4 (if flag==1)
  949. tophys(r3,r4) // r3 <- PA
  950. 1:
  951. l.ori r3,r3,~(PPN_MASK) // r3 <- PPN :PPN .xfff - clear up lo(r6) to 0x**** *fff
  952. l.movhi r5,hi(ITLB_TR_MASK) // r5 <- ffff:0000.x000
  953. l.ori r5,r5,lo(ITLB_TR_MASK) // r5 <- ffff:1111.x050 - apply ITLB_MR_MASK
  954. l.and r5,r5,r3 // r5 <- PPN :PPN .x050 - we have ITLBTR entry
  955. l.mtspr r2,r5,SPR_ITLBTR_BASE(0) // set ITLBTR
  956. EXCEPTION_LOAD_GPR6
  957. EXCEPTION_LOAD_GPR5
  958. EXCEPTION_LOAD_GPR4
  959. EXCEPTION_LOAD_GPR3
  960. EXCEPTION_LOAD_GPR2
  961. l.rfe // SR <- ESR, PC <- EPC
  962. exit_with_no_itranslation:
  963. EXCEPTION_LOAD_GPR4
  964. EXCEPTION_LOAD_GPR6
  965. l.j _dispatch_bus_fault
  966. l.nop
  967. /* ====================================================================== */
  968. /*
  969. * Stuff below here shouldn't go into .head section... maybe this stuff
  970. * can be moved to entry.S ???
  971. */
  972. /* ==============================================[ DTLB miss handler ]=== */
  973. /*
  974. * Comments:
  975. * Exception handlers are entered with MMU off so the following handler
  976. * needs to use physical addressing
  977. *
  978. */
  979. .text
  980. ENTRY(dtlb_miss_handler)
  981. EXCEPTION_STORE_GPR2
  982. EXCEPTION_STORE_GPR3
  983. EXCEPTION_STORE_GPR4
  984. /*
  985. * get EA of the miss
  986. */
  987. l.mfspr r2,r0,SPR_EEAR_BASE
  988. /*
  989. * pmd = (pmd_t *)(current_pgd + pgd_index(daddr));
  990. */
  991. GET_CURRENT_PGD(r3,r4) // r3 is current_pgd, r4 is temp
  992. l.srli r4,r2,0x18 // >> PAGE_SHIFT + (PAGE_SHIFT - 2)
  993. l.slli r4,r4,0x2 // to get address << 2
  994. l.add r3,r4,r3 // r4 is pgd_index(daddr)
  995. /*
  996. * if (pmd_none(*pmd))
  997. * goto pmd_none:
  998. */
  999. tophys (r4,r3)
  1000. l.lwz r3,0x0(r4) // get *pmd value
  1001. l.sfne r3,r0
  1002. l.bnf d_pmd_none
  1003. l.addi r3,r0,0xffffe000 // PAGE_MASK
  1004. d_pmd_good:
  1005. /*
  1006. * pte = *pte_offset(pmd, daddr);
  1007. */
  1008. l.lwz r4,0x0(r4) // get **pmd value
  1009. l.and r4,r4,r3 // & PAGE_MASK
  1010. l.srli r2,r2,0xd // >> PAGE_SHIFT, r2 == EEAR
  1011. l.andi r3,r2,0x7ff // (1UL << PAGE_SHIFT - 2) - 1
  1012. l.slli r3,r3,0x2 // to get address << 2
  1013. l.add r3,r3,r4
  1014. l.lwz r3,0x0(r3) // this is pte at last
  1015. /*
  1016. * if (!pte_present(pte))
  1017. */
  1018. l.andi r4,r3,0x1
  1019. l.sfne r4,r0 // is pte present
  1020. l.bnf d_pte_not_present
  1021. l.addi r4,r0,0xffffe3fa // PAGE_MASK | DTLB_UP_CONVERT_MASK
  1022. /*
  1023. * fill DTLB TR register
  1024. */
  1025. l.and r4,r3,r4 // apply the mask
  1026. // Determine number of DMMU sets
  1027. l.mfspr r2, r0, SPR_DMMUCFGR
  1028. l.andi r2, r2, SPR_DMMUCFGR_NTS
  1029. l.srli r2, r2, SPR_DMMUCFGR_NTS_OFF
  1030. l.ori r3, r0, 0x1
  1031. l.sll r3, r3, r2 // r3 = number DMMU sets DMMUCFGR
  1032. l.addi r2, r3, -1 // r2 = nsets mask
  1033. l.mfspr r3, r0, SPR_EEAR_BASE
  1034. l.srli r3, r3, 0xd // >> PAGE_SHIFT
  1035. l.and r2, r3, r2 // calc offset: & (NUM_TLB_ENTRIES-1)
  1036. //NUM_TLB_ENTRIES
  1037. l.mtspr r2,r4,SPR_DTLBTR_BASE(0)
  1038. /*
  1039. * fill DTLB MR register
  1040. */
  1041. l.slli r3, r3, 0xd /* << PAGE_SHIFT => EA & PAGE_MASK */
  1042. l.ori r4,r3,0x1 // set hardware valid bit: DTBL_MR entry
  1043. l.mtspr r2,r4,SPR_DTLBMR_BASE(0)
  1044. EXCEPTION_LOAD_GPR2
  1045. EXCEPTION_LOAD_GPR3
  1046. EXCEPTION_LOAD_GPR4
  1047. l.rfe
  1048. d_pmd_none:
  1049. d_pte_not_present:
  1050. EXCEPTION_LOAD_GPR2
  1051. EXCEPTION_LOAD_GPR3
  1052. EXCEPTION_LOAD_GPR4
  1053. EXCEPTION_HANDLE(_dtlb_miss_page_fault_handler)
  1054. /* ==============================================[ ITLB miss handler ]=== */
  1055. ENTRY(itlb_miss_handler)
  1056. EXCEPTION_STORE_GPR2
  1057. EXCEPTION_STORE_GPR3
  1058. EXCEPTION_STORE_GPR4
  1059. /*
  1060. * get EA of the miss
  1061. */
  1062. l.mfspr r2,r0,SPR_EEAR_BASE
  1063. /*
  1064. * pmd = (pmd_t *)(current_pgd + pgd_index(daddr));
  1065. *
  1066. */
  1067. GET_CURRENT_PGD(r3,r4) // r3 is current_pgd, r5 is temp
  1068. l.srli r4,r2,0x18 // >> PAGE_SHIFT + (PAGE_SHIFT - 2)
  1069. l.slli r4,r4,0x2 // to get address << 2
  1070. l.add r3,r4,r3 // r4 is pgd_index(daddr)
  1071. /*
  1072. * if (pmd_none(*pmd))
  1073. * goto pmd_none:
  1074. */
  1075. tophys (r4,r3)
  1076. l.lwz r3,0x0(r4) // get *pmd value
  1077. l.sfne r3,r0
  1078. l.bnf i_pmd_none
  1079. l.addi r3,r0,0xffffe000 // PAGE_MASK
  1080. i_pmd_good:
  1081. /*
  1082. * pte = *pte_offset(pmd, iaddr);
  1083. *
  1084. */
  1085. l.lwz r4,0x0(r4) // get **pmd value
  1086. l.and r4,r4,r3 // & PAGE_MASK
  1087. l.srli r2,r2,0xd // >> PAGE_SHIFT, r2 == EEAR
  1088. l.andi r3,r2,0x7ff // (1UL << PAGE_SHIFT - 2) - 1
  1089. l.slli r3,r3,0x2 // to get address << 2
  1090. l.add r3,r3,r4
  1091. l.lwz r3,0x0(r3) // this is pte at last
  1092. /*
  1093. * if (!pte_present(pte))
  1094. *
  1095. */
  1096. l.andi r4,r3,0x1
  1097. l.sfne r4,r0 // is pte present
  1098. l.bnf i_pte_not_present
  1099. l.addi r4,r0,0xffffe03a // PAGE_MASK | ITLB_UP_CONVERT_MASK
  1100. /*
  1101. * fill ITLB TR register
  1102. */
  1103. l.and r4,r3,r4 // apply the mask
  1104. l.andi r3,r3,0x7c0 // _PAGE_EXEC | _PAGE_SRE | _PAGE_SWE | _PAGE_URE | _PAGE_UWE
  1105. l.sfeq r3,r0
  1106. l.bf itlb_tr_fill //_workaround
  1107. // Determine number of IMMU sets
  1108. l.mfspr r2, r0, SPR_IMMUCFGR
  1109. l.andi r2, r2, SPR_IMMUCFGR_NTS
  1110. l.srli r2, r2, SPR_IMMUCFGR_NTS_OFF
  1111. l.ori r3, r0, 0x1
  1112. l.sll r3, r3, r2 // r3 = number IMMU sets IMMUCFGR
  1113. l.addi r2, r3, -1 // r2 = nsets mask
  1114. l.mfspr r3, r0, SPR_EEAR_BASE
  1115. l.srli r3, r3, 0xd // >> PAGE_SHIFT
  1116. l.and r2, r3, r2 // calc offset: & (NUM_TLB_ENTRIES-1)
  1117. /*
  1118. * __PHX__ :: fixme
  1119. * we should not just blindly set executable flags,
  1120. * but it does help with ping. the clean way would be to find out
  1121. * (and fix it) why stack doesn't have execution permissions
  1122. */
  1123. itlb_tr_fill_workaround:
  1124. l.ori r4,r4,0xc0 // | (SPR_ITLBTR_UXE | ITLBTR_SXE)
  1125. itlb_tr_fill:
  1126. l.mtspr r2,r4,SPR_ITLBTR_BASE(0)
  1127. /*
  1128. * fill DTLB MR register
  1129. */
  1130. l.slli r3, r3, 0xd /* << PAGE_SHIFT => EA & PAGE_MASK */
  1131. l.ori r4,r3,0x1 // set hardware valid bit: ITBL_MR entry
  1132. l.mtspr r2,r4,SPR_ITLBMR_BASE(0)
  1133. EXCEPTION_LOAD_GPR2
  1134. EXCEPTION_LOAD_GPR3
  1135. EXCEPTION_LOAD_GPR4
  1136. l.rfe
  1137. i_pmd_none:
  1138. i_pte_not_present:
  1139. EXCEPTION_LOAD_GPR2
  1140. EXCEPTION_LOAD_GPR3
  1141. EXCEPTION_LOAD_GPR4
  1142. EXCEPTION_HANDLE(_itlb_miss_page_fault_handler)
  1143. /* ==============================================[ boot tlb handlers ]=== */
  1144. /* =================================================[ debugging aids ]=== */
  1145. /*
  1146. * DESC: Prints ASCII character stored in r7
  1147. *
  1148. * PRMS: r7 - a 32-bit value with an ASCII character in the first byte
  1149. * position.
  1150. *
  1151. * PREQ: The UART at UART_BASE_ADD has to be initialized
  1152. *
  1153. * POST: internally used but restores:
  1154. * r4 - to store UART_BASE_ADD
  1155. * r5 - for loading OFF_TXFULL / THRE,TEMT
  1156. * r6 - for storing bitmask (SERIAL_8250)
  1157. */
  1158. ENTRY(_emergency_putc)
  1159. EMERGENCY_PRINT_STORE_GPR4
  1160. EMERGENCY_PRINT_STORE_GPR5
  1161. EMERGENCY_PRINT_STORE_GPR6
  1162. l.movhi r4,hi(UART_BASE_ADD)
  1163. l.ori r4,r4,lo(UART_BASE_ADD)
  1164. #if defined(CONFIG_SERIAL_LITEUART)
  1165. /* Check OFF_TXFULL status */
  1166. 1: l.lwz r5,4(r4)
  1167. l.andi r5,r5,0xff
  1168. l.sfnei r5,0
  1169. l.bf 1b
  1170. l.nop
  1171. /* Write character */
  1172. l.andi r7,r7,0xff
  1173. l.sw 0(r4),r7
  1174. #elif defined(CONFIG_SERIAL_8250)
  1175. /* Check UART LSR THRE (hold) bit */
  1176. l.addi r6,r0,0x20
  1177. 1: l.lbz r5,5(r4)
  1178. l.andi r5,r5,0x20
  1179. l.sfeq r5,r6
  1180. l.bnf 1b
  1181. l.nop
  1182. /* Write character */
  1183. l.sb 0(r4),r7
  1184. /* Check UART LSR THRE|TEMT (hold, empty) bits */
  1185. l.addi r6,r0,0x60
  1186. 1: l.lbz r5,5(r4)
  1187. l.andi r5,r5,0x60
  1188. l.sfeq r5,r6
  1189. l.bnf 1b
  1190. l.nop
  1191. #endif
  1192. EMERGENCY_PRINT_LOAD_GPR6
  1193. EMERGENCY_PRINT_LOAD_GPR5
  1194. EMERGENCY_PRINT_LOAD_GPR4
  1195. l.jr r9
  1196. l.nop
  1197. /*
  1198. * DSCR: prints a string referenced by r3.
  1199. *
  1200. * PRMS: r3 - address of the first character of null
  1201. * terminated string to be printed
  1202. *
  1203. * PREQ: UART at UART_BASE_ADD has to be initialized
  1204. *
  1205. * POST: caller should be aware that r3, r9 are changed
  1206. */
  1207. ENTRY(_emergency_print)
  1208. EMERGENCY_PRINT_STORE_GPR7
  1209. EMERGENCY_PRINT_STORE_GPR9
  1210. /* Load character to r7, check for null terminator */
  1211. 2: l.lbz r7,0(r3)
  1212. l.sfeqi r7,0x0
  1213. l.bf 9f
  1214. l.nop
  1215. l.jal _emergency_putc
  1216. l.nop
  1217. /* next character */
  1218. l.j 2b
  1219. l.addi r3,r3,0x1
  1220. 9:
  1221. EMERGENCY_PRINT_LOAD_GPR9
  1222. EMERGENCY_PRINT_LOAD_GPR7
  1223. l.jr r9
  1224. l.nop
  1225. /*
  1226. * DSCR: prints a number in r3 in hex.
  1227. *
  1228. * PRMS: r3 - a 32-bit unsigned integer
  1229. *
  1230. * PREQ: UART at UART_BASE_ADD has to be initialized
  1231. *
  1232. * POST: caller should be aware that r3, r9 are changed
  1233. */
  1234. ENTRY(_emergency_print_nr)
  1235. EMERGENCY_PRINT_STORE_GPR7
  1236. EMERGENCY_PRINT_STORE_GPR8
  1237. EMERGENCY_PRINT_STORE_GPR9
  1238. l.addi r8,r0,32 // shift register
  1239. 1: /* remove leading zeros */
  1240. l.addi r8,r8,-0x4
  1241. l.srl r7,r3,r8
  1242. l.andi r7,r7,0xf
  1243. /* don't skip the last zero if number == 0x0 */
  1244. l.sfeqi r8,0x4
  1245. l.bf 2f
  1246. l.nop
  1247. l.sfeq r7,r0
  1248. l.bf 1b
  1249. l.nop
  1250. 2:
  1251. l.srl r7,r3,r8
  1252. l.andi r7,r7,0xf
  1253. l.sflts r8,r0
  1254. l.bf 9f
  1255. /* Numbers greater than 9 translate to a-f */
  1256. l.sfgtui r7,0x9
  1257. l.bnf 8f
  1258. l.nop
  1259. l.addi r7,r7,0x27
  1260. /* Convert to ascii and output character */
  1261. 8: l.jal _emergency_putc
  1262. l.addi r7,r7,0x30
  1263. /* next character */
  1264. l.j 2b
  1265. l.addi r8,r8,-0x4
  1266. 9:
  1267. EMERGENCY_PRINT_LOAD_GPR9
  1268. EMERGENCY_PRINT_LOAD_GPR8
  1269. EMERGENCY_PRINT_LOAD_GPR7
  1270. l.jr r9
  1271. l.nop
  1272. /*
  1273. * This should be used for debugging only.
  1274. * It messes up the Linux early serial output
  1275. * somehow, so use it sparingly and essentially
  1276. * only if you need to debug something that goes wrong
  1277. * before Linux gets the early serial going.
  1278. *
  1279. * Furthermore, you'll have to make sure you set the
  1280. * UART_DEVISOR correctly according to the system
  1281. * clock rate.
  1282. *
  1283. *
  1284. */
  1285. #define SYS_CLK 20000000
  1286. //#define SYS_CLK 1843200
  1287. #define OR32_CONSOLE_BAUD 115200
  1288. #define UART_DIVISOR SYS_CLK/(16*OR32_CONSOLE_BAUD)
  1289. ENTRY(_early_uart_init)
  1290. l.movhi r3,hi(UART_BASE_ADD)
  1291. l.ori r3,r3,lo(UART_BASE_ADD)
  1292. #if defined(CONFIG_SERIAL_8250)
  1293. l.addi r4,r0,0x7
  1294. l.sb 0x2(r3),r4
  1295. l.addi r4,r0,0x0
  1296. l.sb 0x1(r3),r4
  1297. l.addi r4,r0,0x3
  1298. l.sb 0x3(r3),r4
  1299. l.lbz r5,3(r3)
  1300. l.ori r4,r5,0x80
  1301. l.sb 0x3(r3),r4
  1302. l.addi r4,r0,((UART_DIVISOR>>8) & 0x000000ff)
  1303. l.sb UART_DLM(r3),r4
  1304. l.addi r4,r0,((UART_DIVISOR) & 0x000000ff)
  1305. l.sb UART_DLL(r3),r4
  1306. l.sb 0x3(r3),r5
  1307. #endif
  1308. l.jr r9
  1309. l.nop
  1310. .align 0x1000
  1311. .global _secondary_evbar
  1312. _secondary_evbar:
  1313. .space 0x800
  1314. /* Just disable interrupts and Return */
  1315. l.ori r3,r0,SPR_SR_SM
  1316. l.mtspr r0,r3,SPR_ESR_BASE
  1317. l.rfe
  1318. .section .rodata
  1319. _string_unhandled_exception:
  1320. .string "\r\nRunarunaround: Unhandled exception 0x\0"
  1321. _string_epc_prefix:
  1322. .string ": EPC=0x\0"
  1323. _string_nl:
  1324. .string "\r\n\0"
  1325. /* ========================================[ page aligned structures ]=== */
  1326. /*
  1327. * .data section should be page aligned
  1328. * (look into arch/openrisc/kernel/vmlinux.lds.S)
  1329. */
  1330. .section .data,"aw"
  1331. .align 8192
  1332. .global empty_zero_page
  1333. empty_zero_page:
  1334. .space 8192
  1335. .global swapper_pg_dir
  1336. swapper_pg_dir:
  1337. .space 8192
  1338. .global _unhandled_stack
  1339. _unhandled_stack:
  1340. .space 8192
  1341. _unhandled_stack_top:
  1342. /* ============================================================[ EOF ]=== */