head.S 40 KB

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