head_8xx.S 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064
  1. /*
  2. * PowerPC version
  3. * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  4. * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
  5. * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
  6. * Low-level exception handlers and MMU support
  7. * rewritten by Paul Mackerras.
  8. * Copyright (C) 1996 Paul Mackerras.
  9. * MPC8xx modifications by Dan Malek
  10. * Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
  11. *
  12. * This file contains low-level support and setup for PowerPC 8xx
  13. * embedded processors, including trap and interrupt dispatch.
  14. *
  15. * This program is free software; you can redistribute it and/or
  16. * modify it under the terms of the GNU General Public License
  17. * as published by the Free Software Foundation; either version
  18. * 2 of the License, or (at your option) any later version.
  19. *
  20. */
  21. #include <linux/init.h>
  22. #include <asm/processor.h>
  23. #include <asm/page.h>
  24. #include <asm/mmu.h>
  25. #include <asm/cache.h>
  26. #include <asm/pgtable.h>
  27. #include <asm/cputable.h>
  28. #include <asm/thread_info.h>
  29. #include <asm/ppc_asm.h>
  30. #include <asm/asm-offsets.h>
  31. #include <asm/ptrace.h>
  32. #include <asm/fixmap.h>
  33. #include <asm/export.h>
  34. #if CONFIG_TASK_SIZE <= 0x80000000 && CONFIG_PAGE_OFFSET >= 0x80000000
  35. /* By simply checking Address >= 0x80000000, we know if its a kernel address */
  36. #define SIMPLE_KERNEL_ADDRESS 1
  37. #endif
  38. /*
  39. * We need an ITLB miss handler for kernel addresses if:
  40. * - Either we have modules
  41. * - Or we have not pinned the first 8M
  42. */
  43. #if defined(CONFIG_MODULES) || !defined(CONFIG_PIN_TLB_TEXT) || \
  44. defined(CONFIG_DEBUG_PAGEALLOC)
  45. #define ITLB_MISS_KERNEL 1
  46. #endif
  47. /*
  48. * Value for the bits that have fixed value in RPN entries.
  49. * Also used for tagging DAR for DTLBerror.
  50. */
  51. #define RPN_PATTERN 0x00f0
  52. #define PAGE_SHIFT_512K 19
  53. #define PAGE_SHIFT_8M 23
  54. __HEAD
  55. _ENTRY(_stext);
  56. _ENTRY(_start);
  57. /* MPC8xx
  58. * This port was done on an MBX board with an 860. Right now I only
  59. * support an ELF compressed (zImage) boot from EPPC-Bug because the
  60. * code there loads up some registers before calling us:
  61. * r3: ptr to board info data
  62. * r4: initrd_start or if no initrd then 0
  63. * r5: initrd_end - unused if r4 is 0
  64. * r6: Start of command line string
  65. * r7: End of command line string
  66. *
  67. * I decided to use conditional compilation instead of checking PVR and
  68. * adding more processor specific branches around code I don't need.
  69. * Since this is an embedded processor, I also appreciate any memory
  70. * savings I can get.
  71. *
  72. * The MPC8xx does not have any BATs, but it supports large page sizes.
  73. * We first initialize the MMU to support 8M byte pages, then load one
  74. * entry into each of the instruction and data TLBs to map the first
  75. * 8M 1:1. I also mapped an additional I/O space 1:1 so we can get to
  76. * the "internal" processor registers before MMU_init is called.
  77. *
  78. * -- Dan
  79. */
  80. .globl __start
  81. __start:
  82. mr r31,r3 /* save device tree ptr */
  83. /* We have to turn on the MMU right away so we get cache modes
  84. * set correctly.
  85. */
  86. bl initial_mmu
  87. /* We now have the lower 8 Meg mapped into TLB entries, and the caches
  88. * ready to work.
  89. */
  90. turn_on_mmu:
  91. mfmsr r0
  92. ori r0,r0,MSR_DR|MSR_IR
  93. mtspr SPRN_SRR1,r0
  94. lis r0,start_here@h
  95. ori r0,r0,start_here@l
  96. mtspr SPRN_SRR0,r0
  97. rfi /* enables MMU */
  98. /*
  99. * Exception entry code. This code runs with address translation
  100. * turned off, i.e. using physical addresses.
  101. * We assume sprg3 has the physical address of the current
  102. * task's thread_struct.
  103. */
  104. #define EXCEPTION_PROLOG \
  105. mtspr SPRN_SPRG_SCRATCH0, r10; \
  106. mtspr SPRN_SPRG_SCRATCH1, r11; \
  107. mfcr r10; \
  108. EXCEPTION_PROLOG_1; \
  109. EXCEPTION_PROLOG_2
  110. #define EXCEPTION_PROLOG_1 \
  111. mfspr r11,SPRN_SRR1; /* check whether user or kernel */ \
  112. andi. r11,r11,MSR_PR; \
  113. tophys(r11,r1); /* use tophys(r1) if kernel */ \
  114. beq 1f; \
  115. mfspr r11,SPRN_SPRG_THREAD; \
  116. lwz r11,THREAD_INFO-THREAD(r11); \
  117. addi r11,r11,THREAD_SIZE; \
  118. tophys(r11,r11); \
  119. 1: subi r11,r11,INT_FRAME_SIZE /* alloc exc. frame */
  120. #define EXCEPTION_PROLOG_2 \
  121. stw r10,_CCR(r11); /* save registers */ \
  122. stw r12,GPR12(r11); \
  123. stw r9,GPR9(r11); \
  124. mfspr r10,SPRN_SPRG_SCRATCH0; \
  125. stw r10,GPR10(r11); \
  126. mfspr r12,SPRN_SPRG_SCRATCH1; \
  127. stw r12,GPR11(r11); \
  128. mflr r10; \
  129. stw r10,_LINK(r11); \
  130. mfspr r12,SPRN_SRR0; \
  131. mfspr r9,SPRN_SRR1; \
  132. stw r1,GPR1(r11); \
  133. stw r1,0(r11); \
  134. tovirt(r1,r11); /* set new kernel sp */ \
  135. li r10,MSR_KERNEL & ~(MSR_IR|MSR_DR); /* can take exceptions */ \
  136. mtmsr r10; \
  137. stw r0,GPR0(r11); \
  138. SAVE_4GPRS(3, r11); \
  139. SAVE_2GPRS(7, r11)
  140. /*
  141. * Note: code which follows this uses cr0.eq (set if from kernel),
  142. * r11, r12 (SRR0), and r9 (SRR1).
  143. *
  144. * Note2: once we have set r1 we are in a position to take exceptions
  145. * again, and we could thus set MSR:RI at that point.
  146. */
  147. /*
  148. * Exception vectors.
  149. */
  150. #define EXCEPTION(n, label, hdlr, xfer) \
  151. . = n; \
  152. label: \
  153. EXCEPTION_PROLOG; \
  154. addi r3,r1,STACK_FRAME_OVERHEAD; \
  155. xfer(n, hdlr)
  156. #define EXC_XFER_TEMPLATE(n, hdlr, trap, copyee, tfer, ret) \
  157. li r10,trap; \
  158. stw r10,_TRAP(r11); \
  159. li r10,MSR_KERNEL; \
  160. copyee(r10, r9); \
  161. bl tfer; \
  162. i##n: \
  163. .long hdlr; \
  164. .long ret
  165. #define COPY_EE(d, s) rlwimi d,s,0,16,16
  166. #define NOCOPY(d, s)
  167. #define EXC_XFER_STD(n, hdlr) \
  168. EXC_XFER_TEMPLATE(n, hdlr, n, NOCOPY, transfer_to_handler_full, \
  169. ret_from_except_full)
  170. #define EXC_XFER_LITE(n, hdlr) \
  171. EXC_XFER_TEMPLATE(n, hdlr, n+1, NOCOPY, transfer_to_handler, \
  172. ret_from_except)
  173. #define EXC_XFER_EE(n, hdlr) \
  174. EXC_XFER_TEMPLATE(n, hdlr, n, COPY_EE, transfer_to_handler_full, \
  175. ret_from_except_full)
  176. #define EXC_XFER_EE_LITE(n, hdlr) \
  177. EXC_XFER_TEMPLATE(n, hdlr, n+1, COPY_EE, transfer_to_handler, \
  178. ret_from_except)
  179. /* System reset */
  180. EXCEPTION(0x100, Reset, system_reset_exception, EXC_XFER_STD)
  181. /* Machine check */
  182. . = 0x200
  183. MachineCheck:
  184. EXCEPTION_PROLOG
  185. mfspr r4,SPRN_DAR
  186. stw r4,_DAR(r11)
  187. li r5,RPN_PATTERN
  188. mtspr SPRN_DAR,r5 /* Tag DAR, to be used in DTLB Error */
  189. mfspr r5,SPRN_DSISR
  190. stw r5,_DSISR(r11)
  191. addi r3,r1,STACK_FRAME_OVERHEAD
  192. EXC_XFER_STD(0x200, machine_check_exception)
  193. /* Data access exception.
  194. * This is "never generated" by the MPC8xx.
  195. */
  196. . = 0x300
  197. DataAccess:
  198. /* Instruction access exception.
  199. * This is "never generated" by the MPC8xx.
  200. */
  201. . = 0x400
  202. InstructionAccess:
  203. /* External interrupt */
  204. EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
  205. /* Alignment exception */
  206. . = 0x600
  207. Alignment:
  208. EXCEPTION_PROLOG
  209. mfspr r4,SPRN_DAR
  210. stw r4,_DAR(r11)
  211. li r5,RPN_PATTERN
  212. mtspr SPRN_DAR,r5 /* Tag DAR, to be used in DTLB Error */
  213. mfspr r5,SPRN_DSISR
  214. stw r5,_DSISR(r11)
  215. addi r3,r1,STACK_FRAME_OVERHEAD
  216. EXC_XFER_EE(0x600, alignment_exception)
  217. /* Program check exception */
  218. EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
  219. /* No FPU on MPC8xx. This exception is not supposed to happen.
  220. */
  221. EXCEPTION(0x800, FPUnavailable, unknown_exception, EXC_XFER_STD)
  222. /* Decrementer */
  223. EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
  224. EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_EE)
  225. EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_EE)
  226. /* System call */
  227. . = 0xc00
  228. SystemCall:
  229. EXCEPTION_PROLOG
  230. EXC_XFER_EE_LITE(0xc00, DoSyscall)
  231. /* Single step - not used on 601 */
  232. EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD)
  233. EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_EE)
  234. EXCEPTION(0xf00, Trap_0f, unknown_exception, EXC_XFER_EE)
  235. /* On the MPC8xx, this is a software emulation interrupt. It occurs
  236. * for all unimplemented and illegal instructions.
  237. */
  238. EXCEPTION(0x1000, SoftEmu, program_check_exception, EXC_XFER_STD)
  239. . = 0x1100
  240. /*
  241. * For the MPC8xx, this is a software tablewalk to load the instruction
  242. * TLB. The task switch loads the M_TW register with the pointer to the first
  243. * level table.
  244. * If we discover there is no second level table (value is zero) or if there
  245. * is an invalid pte, we load that into the TLB, which causes another fault
  246. * into the TLB Error interrupt where we can handle such problems.
  247. * We have to use the MD_xxx registers for the tablewalk because the
  248. * equivalent MI_xxx registers only perform the attribute functions.
  249. */
  250. #ifdef CONFIG_8xx_CPU15
  251. #define INVALIDATE_ADJACENT_PAGES_CPU15(tmp, addr) \
  252. addi tmp, addr, PAGE_SIZE; \
  253. tlbie tmp; \
  254. addi tmp, addr, -PAGE_SIZE; \
  255. tlbie tmp
  256. #else
  257. #define INVALIDATE_ADJACENT_PAGES_CPU15(tmp, addr)
  258. #endif
  259. InstructionTLBMiss:
  260. mtspr SPRN_SPRG_SCRATCH0, r10
  261. mtspr SPRN_SPRG_SCRATCH1, r11
  262. #if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE)
  263. mtspr SPRN_SPRG_SCRATCH2, r12
  264. #endif
  265. /* If we are faulting a kernel address, we have to use the
  266. * kernel page tables.
  267. */
  268. mfspr r10, SPRN_SRR0 /* Get effective address of fault */
  269. INVALIDATE_ADJACENT_PAGES_CPU15(r11, r10)
  270. /* Only modules will cause ITLB Misses as we always
  271. * pin the first 8MB of kernel memory */
  272. #if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE)
  273. mfcr r12
  274. #endif
  275. #ifdef ITLB_MISS_KERNEL
  276. #if defined(SIMPLE_KERNEL_ADDRESS) && defined(CONFIG_PIN_TLB_TEXT)
  277. andis. r11, r10, 0x8000 /* Address >= 0x80000000 */
  278. #else
  279. rlwinm r11, r10, 16, 0xfff8
  280. cmpli cr0, r11, PAGE_OFFSET@h
  281. #ifndef CONFIG_PIN_TLB_TEXT
  282. /* It is assumed that kernel code fits into the first 8M page */
  283. _ENTRY(ITLBMiss_cmp)
  284. cmpli cr7, r11, (PAGE_OFFSET + 0x0800000)@h
  285. #endif
  286. #endif
  287. #endif
  288. mfspr r11, SPRN_M_TW /* Get level 1 table */
  289. #ifdef ITLB_MISS_KERNEL
  290. #if defined(SIMPLE_KERNEL_ADDRESS) && defined(CONFIG_PIN_TLB_TEXT)
  291. beq+ 3f
  292. #else
  293. blt+ 3f
  294. #endif
  295. #ifndef CONFIG_PIN_TLB_TEXT
  296. blt cr7, ITLBMissLinear
  297. #endif
  298. lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha
  299. 3:
  300. #endif
  301. /* Insert level 1 index */
  302. rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
  303. lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */
  304. /* Extract level 2 index */
  305. rlwinm r10, r10, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29
  306. #ifdef CONFIG_HUGETLB_PAGE
  307. mtcr r11
  308. bt- 28, 10f /* bit 28 = Large page (8M) */
  309. bt- 29, 20f /* bit 29 = Large page (8M or 512k) */
  310. #endif
  311. rlwimi r10, r11, 0, 0, 32 - PAGE_SHIFT - 1 /* Add level 2 base */
  312. lwz r10, 0(r10) /* Get the pte */
  313. 4:
  314. #if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE)
  315. mtcr r12
  316. #endif
  317. #ifdef CONFIG_SWAP
  318. rlwinm r11, r10, 31, _PAGE_ACCESSED >> 1
  319. #endif
  320. /* Load the MI_TWC with the attributes for this "segment." */
  321. mtspr SPRN_MI_TWC, r11 /* Set segment attributes */
  322. li r11, RPN_PATTERN | 0x200
  323. /* The Linux PTE won't go exactly into the MMU TLB.
  324. * Software indicator bits 20 and 23 must be clear.
  325. * Software indicator bits 22, 24, 25, 26, and 27 must be
  326. * set. All other Linux PTE bits control the behavior
  327. * of the MMU.
  328. */
  329. rlwimi r11, r10, 4, 0x0400 /* Copy _PAGE_EXEC into bit 21 */
  330. rlwimi r10, r11, 0, 0x0ff0 /* Set 22, 24-27, clear 20,23 */
  331. mtspr SPRN_MI_RPN, r10 /* Update TLB entry */
  332. /* Restore registers */
  333. _ENTRY(itlb_miss_exit_1)
  334. mfspr r10, SPRN_SPRG_SCRATCH0
  335. mfspr r11, SPRN_SPRG_SCRATCH1
  336. #if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE)
  337. mfspr r12, SPRN_SPRG_SCRATCH2
  338. #endif
  339. rfi
  340. #ifdef CONFIG_PERF_EVENTS
  341. _ENTRY(itlb_miss_perf)
  342. lis r10, (itlb_miss_counter - PAGE_OFFSET)@ha
  343. lwz r11, (itlb_miss_counter - PAGE_OFFSET)@l(r10)
  344. addi r11, r11, 1
  345. stw r11, (itlb_miss_counter - PAGE_OFFSET)@l(r10)
  346. #endif
  347. mfspr r10, SPRN_SPRG_SCRATCH0
  348. mfspr r11, SPRN_SPRG_SCRATCH1
  349. #if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE)
  350. mfspr r12, SPRN_SPRG_SCRATCH2
  351. #endif
  352. rfi
  353. #ifdef CONFIG_HUGETLB_PAGE
  354. 10: /* 8M pages */
  355. #ifdef CONFIG_PPC_16K_PAGES
  356. /* Extract level 2 index */
  357. rlwinm r10, r10, 32 - (PAGE_SHIFT_8M - PAGE_SHIFT), 32 + PAGE_SHIFT_8M - (PAGE_SHIFT << 1), 29
  358. /* Add level 2 base */
  359. rlwimi r10, r11, 0, 0, 32 + PAGE_SHIFT_8M - (PAGE_SHIFT << 1) - 1
  360. #else
  361. /* Level 2 base */
  362. rlwinm r10, r11, 0, ~HUGEPD_SHIFT_MASK
  363. #endif
  364. lwz r10, 0(r10) /* Get the pte */
  365. b 4b
  366. 20: /* 512k pages */
  367. /* Extract level 2 index */
  368. rlwinm r10, r10, 32 - (PAGE_SHIFT_512K - PAGE_SHIFT), 32 + PAGE_SHIFT_512K - (PAGE_SHIFT << 1), 29
  369. /* Add level 2 base */
  370. rlwimi r10, r11, 0, 0, 32 + PAGE_SHIFT_512K - (PAGE_SHIFT << 1) - 1
  371. lwz r10, 0(r10) /* Get the pte */
  372. b 4b
  373. #endif
  374. . = 0x1200
  375. DataStoreTLBMiss:
  376. mtspr SPRN_SPRG_SCRATCH0, r10
  377. mtspr SPRN_SPRG_SCRATCH1, r11
  378. mtspr SPRN_SPRG_SCRATCH2, r12
  379. mfcr r12
  380. /* If we are faulting a kernel address, we have to use the
  381. * kernel page tables.
  382. */
  383. mfspr r10, SPRN_MD_EPN
  384. rlwinm r11, r10, 16, 0xfff8
  385. cmpli cr0, r11, PAGE_OFFSET@h
  386. mfspr r11, SPRN_M_TW /* Get level 1 table */
  387. blt+ 3f
  388. rlwinm r11, r10, 16, 0xfff8
  389. #ifndef CONFIG_PIN_TLB_IMMR
  390. cmpli cr0, r11, VIRT_IMMR_BASE@h
  391. #endif
  392. _ENTRY(DTLBMiss_cmp)
  393. cmpli cr7, r11, (PAGE_OFFSET + 0x1800000)@h
  394. #ifndef CONFIG_PIN_TLB_IMMR
  395. _ENTRY(DTLBMiss_jmp)
  396. beq- DTLBMissIMMR
  397. #endif
  398. blt cr7, DTLBMissLinear
  399. lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha
  400. 3:
  401. /* Insert level 1 index */
  402. rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
  403. lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */
  404. /* We have a pte table, so load fetch the pte from the table.
  405. */
  406. /* Extract level 2 index */
  407. rlwinm r10, r10, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29
  408. #ifdef CONFIG_HUGETLB_PAGE
  409. mtcr r11
  410. bt- 28, 10f /* bit 28 = Large page (8M) */
  411. bt- 29, 20f /* bit 29 = Large page (8M or 512k) */
  412. #endif
  413. rlwimi r10, r11, 0, 0, 32 - PAGE_SHIFT - 1 /* Add level 2 base */
  414. lwz r10, 0(r10) /* Get the pte */
  415. 4:
  416. mtcr r12
  417. /* Insert the Guarded flag into the TWC from the Linux PTE.
  418. * It is bit 27 of both the Linux PTE and the TWC (at least
  419. * I got that right :-). It will be better when we can put
  420. * this into the Linux pgd/pmd and load it in the operation
  421. * above.
  422. */
  423. rlwimi r11, r10, 0, _PAGE_GUARDED
  424. #ifdef CONFIG_SWAP
  425. /* _PAGE_ACCESSED has to be set. We use second APG bit for that, 0
  426. * on that bit will represent a Non Access group
  427. */
  428. rlwinm r11, r10, 31, _PAGE_ACCESSED >> 1
  429. #endif
  430. mtspr SPRN_MD_TWC, r11
  431. /* The Linux PTE won't go exactly into the MMU TLB.
  432. * Software indicator bits 24, 25, 26, and 27 must be
  433. * set. All other Linux PTE bits control the behavior
  434. * of the MMU.
  435. */
  436. li r11, RPN_PATTERN
  437. rlwimi r10, r11, 0, 24, 27 /* Set 24-27 */
  438. mtspr SPRN_MD_RPN, r10 /* Update TLB entry */
  439. /* Restore registers */
  440. mtspr SPRN_DAR, r11 /* Tag DAR */
  441. _ENTRY(dtlb_miss_exit_1)
  442. mfspr r10, SPRN_SPRG_SCRATCH0
  443. mfspr r11, SPRN_SPRG_SCRATCH1
  444. mfspr r12, SPRN_SPRG_SCRATCH2
  445. rfi
  446. #ifdef CONFIG_PERF_EVENTS
  447. _ENTRY(dtlb_miss_perf)
  448. lis r10, (dtlb_miss_counter - PAGE_OFFSET)@ha
  449. lwz r11, (dtlb_miss_counter - PAGE_OFFSET)@l(r10)
  450. addi r11, r11, 1
  451. stw r11, (dtlb_miss_counter - PAGE_OFFSET)@l(r10)
  452. #endif
  453. mfspr r10, SPRN_SPRG_SCRATCH0
  454. mfspr r11, SPRN_SPRG_SCRATCH1
  455. mfspr r12, SPRN_SPRG_SCRATCH2
  456. rfi
  457. #ifdef CONFIG_HUGETLB_PAGE
  458. 10: /* 8M pages */
  459. /* Extract level 2 index */
  460. #ifdef CONFIG_PPC_16K_PAGES
  461. rlwinm r10, r10, 32 - (PAGE_SHIFT_8M - PAGE_SHIFT), 32 + PAGE_SHIFT_8M - (PAGE_SHIFT << 1), 29
  462. /* Add level 2 base */
  463. rlwimi r10, r11, 0, 0, 32 + PAGE_SHIFT_8M - (PAGE_SHIFT << 1) - 1
  464. #else
  465. /* Level 2 base */
  466. rlwinm r10, r11, 0, ~HUGEPD_SHIFT_MASK
  467. #endif
  468. lwz r10, 0(r10) /* Get the pte */
  469. b 4b
  470. 20: /* 512k pages */
  471. /* Extract level 2 index */
  472. rlwinm r10, r10, 32 - (PAGE_SHIFT_512K - PAGE_SHIFT), 32 + PAGE_SHIFT_512K - (PAGE_SHIFT << 1), 29
  473. /* Add level 2 base */
  474. rlwimi r10, r11, 0, 0, 32 + PAGE_SHIFT_512K - (PAGE_SHIFT << 1) - 1
  475. lwz r10, 0(r10) /* Get the pte */
  476. b 4b
  477. #endif
  478. /* This is an instruction TLB error on the MPC8xx. This could be due
  479. * to many reasons, such as executing guarded memory or illegal instruction
  480. * addresses. There is nothing to do but handle a big time error fault.
  481. */
  482. . = 0x1300
  483. InstructionTLBError:
  484. EXCEPTION_PROLOG
  485. mr r4,r12
  486. andis. r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */
  487. andis. r10,r9,SRR1_ISI_NOPT@h
  488. beq+ 1f
  489. tlbie r4
  490. itlbie:
  491. /* 0x400 is InstructionAccess exception, needed by bad_page_fault() */
  492. 1: EXC_XFER_LITE(0x400, handle_page_fault)
  493. /* This is the data TLB error on the MPC8xx. This could be due to
  494. * many reasons, including a dirty update to a pte. We bail out to
  495. * a higher level function that can handle it.
  496. */
  497. . = 0x1400
  498. DataTLBError:
  499. mtspr SPRN_SPRG_SCRATCH0, r10
  500. mtspr SPRN_SPRG_SCRATCH1, r11
  501. mfcr r10
  502. mfspr r11, SPRN_DAR
  503. cmpwi cr0, r11, RPN_PATTERN
  504. beq- FixupDAR /* must be a buggy dcbX, icbi insn. */
  505. DARFixed:/* Return from dcbx instruction bug workaround */
  506. EXCEPTION_PROLOG_1
  507. EXCEPTION_PROLOG_2
  508. mfspr r5,SPRN_DSISR
  509. stw r5,_DSISR(r11)
  510. mfspr r4,SPRN_DAR
  511. andis. r10,r5,DSISR_NOHPTE@h
  512. beq+ 1f
  513. tlbie r4
  514. dtlbie:
  515. 1: li r10,RPN_PATTERN
  516. mtspr SPRN_DAR,r10 /* Tag DAR, to be used in DTLB Error */
  517. /* 0x300 is DataAccess exception, needed by bad_page_fault() */
  518. EXC_XFER_LITE(0x300, handle_page_fault)
  519. EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_EE)
  520. EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_EE)
  521. EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_EE)
  522. EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_EE)
  523. EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_EE)
  524. EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_EE)
  525. EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_EE)
  526. /* On the MPC8xx, these next four traps are used for development
  527. * support of breakpoints and such. Someday I will get around to
  528. * using them.
  529. */
  530. . = 0x1c00
  531. DataBreakpoint:
  532. mtspr SPRN_SPRG_SCRATCH0, r10
  533. mtspr SPRN_SPRG_SCRATCH1, r11
  534. mfcr r10
  535. mfspr r11, SPRN_SRR0
  536. cmplwi cr0, r11, (dtlbie - PAGE_OFFSET)@l
  537. cmplwi cr7, r11, (itlbie - PAGE_OFFSET)@l
  538. beq- cr0, 11f
  539. beq- cr7, 11f
  540. EXCEPTION_PROLOG_1
  541. EXCEPTION_PROLOG_2
  542. addi r3,r1,STACK_FRAME_OVERHEAD
  543. mfspr r4,SPRN_BAR
  544. stw r4,_DAR(r11)
  545. mfspr r5,SPRN_DSISR
  546. EXC_XFER_EE(0x1c00, do_break)
  547. 11:
  548. mtcr r10
  549. mfspr r10, SPRN_SPRG_SCRATCH0
  550. mfspr r11, SPRN_SPRG_SCRATCH1
  551. rfi
  552. #ifdef CONFIG_PERF_EVENTS
  553. . = 0x1d00
  554. InstructionBreakpoint:
  555. mtspr SPRN_SPRG_SCRATCH0, r10
  556. mtspr SPRN_SPRG_SCRATCH1, r11
  557. lis r10, (instruction_counter - PAGE_OFFSET)@ha
  558. lwz r11, (instruction_counter - PAGE_OFFSET)@l(r10)
  559. addi r11, r11, -1
  560. stw r11, (instruction_counter - PAGE_OFFSET)@l(r10)
  561. lis r10, 0xffff
  562. ori r10, r10, 0x01
  563. mtspr SPRN_COUNTA, r10
  564. mfspr r10, SPRN_SPRG_SCRATCH0
  565. mfspr r11, SPRN_SPRG_SCRATCH1
  566. rfi
  567. #else
  568. EXCEPTION(0x1d00, Trap_1d, unknown_exception, EXC_XFER_EE)
  569. #endif
  570. EXCEPTION(0x1e00, Trap_1e, unknown_exception, EXC_XFER_EE)
  571. EXCEPTION(0x1f00, Trap_1f, unknown_exception, EXC_XFER_EE)
  572. . = 0x2000
  573. /*
  574. * Bottom part of DataStoreTLBMiss handlers for IMMR area and linear RAM.
  575. * not enough space in the DataStoreTLBMiss area.
  576. */
  577. DTLBMissIMMR:
  578. mtcr r12
  579. /* Set 512k byte guarded page and mark it valid and accessed */
  580. li r10, MD_PS512K | MD_GUARDED | MD_SVALID | M_APG2
  581. mtspr SPRN_MD_TWC, r10
  582. mfspr r10, SPRN_IMMR /* Get current IMMR */
  583. rlwinm r10, r10, 0, 0xfff80000 /* Get 512 kbytes boundary */
  584. ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_PRIVILEGED | _PAGE_DIRTY | \
  585. _PAGE_PRESENT | _PAGE_NO_CACHE
  586. mtspr SPRN_MD_RPN, r10 /* Update TLB entry */
  587. li r11, RPN_PATTERN
  588. mtspr SPRN_DAR, r11 /* Tag DAR */
  589. _ENTRY(dtlb_miss_exit_2)
  590. mfspr r10, SPRN_SPRG_SCRATCH0
  591. mfspr r11, SPRN_SPRG_SCRATCH1
  592. mfspr r12, SPRN_SPRG_SCRATCH2
  593. rfi
  594. DTLBMissLinear:
  595. mtcr r12
  596. /* Set 8M byte page and mark it valid and accessed */
  597. li r11, MD_PS8MEG | MD_SVALID | M_APG2
  598. mtspr SPRN_MD_TWC, r11
  599. rlwinm r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */
  600. ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_PRIVILEGED | _PAGE_DIRTY | \
  601. _PAGE_PRESENT
  602. mtspr SPRN_MD_RPN, r10 /* Update TLB entry */
  603. li r11, RPN_PATTERN
  604. mtspr SPRN_DAR, r11 /* Tag DAR */
  605. _ENTRY(dtlb_miss_exit_3)
  606. mfspr r10, SPRN_SPRG_SCRATCH0
  607. mfspr r11, SPRN_SPRG_SCRATCH1
  608. mfspr r12, SPRN_SPRG_SCRATCH2
  609. rfi
  610. #ifndef CONFIG_PIN_TLB_TEXT
  611. ITLBMissLinear:
  612. mtcr r12
  613. /* Set 8M byte page and mark it valid,accessed */
  614. li r11, MI_PS8MEG | MI_SVALID | M_APG2
  615. mtspr SPRN_MI_TWC, r11
  616. rlwinm r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */
  617. ori r10, r10, 0xf0 | MI_SPS16K | _PAGE_PRIVILEGED | _PAGE_DIRTY | \
  618. _PAGE_PRESENT
  619. mtspr SPRN_MI_RPN, r10 /* Update TLB entry */
  620. _ENTRY(itlb_miss_exit_2)
  621. mfspr r10, SPRN_SPRG_SCRATCH0
  622. mfspr r11, SPRN_SPRG_SCRATCH1
  623. mfspr r12, SPRN_SPRG_SCRATCH2
  624. rfi
  625. #endif
  626. /* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions
  627. * by decoding the registers used by the dcbx instruction and adding them.
  628. * DAR is set to the calculated address.
  629. */
  630. /* define if you don't want to use self modifying code */
  631. #define NO_SELF_MODIFYING_CODE
  632. FixupDAR:/* Entry point for dcbx workaround. */
  633. mtspr SPRN_SPRG_SCRATCH2, r10
  634. /* fetch instruction from memory. */
  635. mfspr r10, SPRN_SRR0
  636. rlwinm r11, r10, 16, 0xfff8
  637. cmpli cr0, r11, PAGE_OFFSET@h
  638. mfspr r11, SPRN_M_TW /* Get level 1 table */
  639. blt+ 3f
  640. rlwinm r11, r10, 16, 0xfff8
  641. _ENTRY(FixupDAR_cmp)
  642. cmpli cr7, r11, (PAGE_OFFSET + 0x1800000)@h
  643. /* create physical page address from effective address */
  644. tophys(r11, r10)
  645. blt- cr7, 201f
  646. lis r11, (swapper_pg_dir-PAGE_OFFSET)@ha
  647. /* Insert level 1 index */
  648. 3: rlwimi r11, r10, 32 - ((PAGE_SHIFT - 2) << 1), (PAGE_SHIFT - 2) << 1, 29
  649. lwz r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11) /* Get the level 1 entry */
  650. mtcr r11
  651. bt 28,200f /* bit 28 = Large page (8M) */
  652. bt 29,202f /* bit 29 = Large page (8M or 512K) */
  653. rlwinm r11, r11,0,0,19 /* Extract page descriptor page address */
  654. /* Insert level 2 index */
  655. rlwimi r11, r10, 32 - (PAGE_SHIFT - 2), 32 - PAGE_SHIFT, 29
  656. lwz r11, 0(r11) /* Get the pte */
  657. /* concat physical page address(r11) and page offset(r10) */
  658. rlwimi r11, r10, 0, 32 - PAGE_SHIFT, 31
  659. 201: lwz r11,0(r11)
  660. /* Check if it really is a dcbx instruction. */
  661. /* dcbt and dcbtst does not generate DTLB Misses/Errors,
  662. * no need to include them here */
  663. xoris r10, r11, 0x7c00 /* check if major OP code is 31 */
  664. rlwinm r10, r10, 0, 21, 5
  665. cmpwi cr0, r10, 2028 /* Is dcbz? */
  666. beq+ 142f
  667. cmpwi cr0, r10, 940 /* Is dcbi? */
  668. beq+ 142f
  669. cmpwi cr0, r10, 108 /* Is dcbst? */
  670. beq+ 144f /* Fix up store bit! */
  671. cmpwi cr0, r10, 172 /* Is dcbf? */
  672. beq+ 142f
  673. cmpwi cr0, r10, 1964 /* Is icbi? */
  674. beq+ 142f
  675. 141: mfspr r10,SPRN_SPRG_SCRATCH2
  676. b DARFixed /* Nope, go back to normal TLB processing */
  677. /* concat physical page address(r11) and page offset(r10) */
  678. 200:
  679. #ifdef CONFIG_PPC_16K_PAGES
  680. rlwinm r11, r11, 0, 0, 32 + PAGE_SHIFT_8M - (PAGE_SHIFT << 1) - 1
  681. rlwimi r11, r10, 32 - (PAGE_SHIFT_8M - 2), 32 + PAGE_SHIFT_8M - (PAGE_SHIFT << 1), 29
  682. #else
  683. rlwinm r11, r10, 0, ~HUGEPD_SHIFT_MASK
  684. #endif
  685. lwz r11, 0(r11) /* Get the pte */
  686. /* concat physical page address(r11) and page offset(r10) */
  687. rlwimi r11, r10, 0, 32 - PAGE_SHIFT_8M, 31
  688. b 201b
  689. 202:
  690. rlwinm r11, r11, 0, 0, 32 + PAGE_SHIFT_512K - (PAGE_SHIFT << 1) - 1
  691. rlwimi r11, r10, 32 - (PAGE_SHIFT_512K - 2), 32 + PAGE_SHIFT_512K - (PAGE_SHIFT << 1), 29
  692. lwz r11, 0(r11) /* Get the pte */
  693. /* concat physical page address(r11) and page offset(r10) */
  694. rlwimi r11, r10, 0, 32 - PAGE_SHIFT_512K, 31
  695. b 201b
  696. 144: mfspr r10, SPRN_DSISR
  697. rlwinm r10, r10,0,7,5 /* Clear store bit for buggy dcbst insn */
  698. mtspr SPRN_DSISR, r10
  699. 142: /* continue, it was a dcbx, dcbi instruction. */
  700. #ifndef NO_SELF_MODIFYING_CODE
  701. andis. r10,r11,0x1f /* test if reg RA is r0 */
  702. li r10,modified_instr@l
  703. dcbtst r0,r10 /* touch for store */
  704. rlwinm r11,r11,0,0,20 /* Zero lower 10 bits */
  705. oris r11,r11,640 /* Transform instr. to a "add r10,RA,RB" */
  706. ori r11,r11,532
  707. stw r11,0(r10) /* store add/and instruction */
  708. dcbf 0,r10 /* flush new instr. to memory. */
  709. icbi 0,r10 /* invalidate instr. cache line */
  710. mfspr r11, SPRN_SPRG_SCRATCH1 /* restore r11 */
  711. mfspr r10, SPRN_SPRG_SCRATCH0 /* restore r10 */
  712. isync /* Wait until new instr is loaded from memory */
  713. modified_instr:
  714. .space 4 /* this is where the add instr. is stored */
  715. bne+ 143f
  716. subf r10,r0,r10 /* r10=r10-r0, only if reg RA is r0 */
  717. 143: mtdar r10 /* store faulting EA in DAR */
  718. mfspr r10,SPRN_SPRG_SCRATCH2
  719. b DARFixed /* Go back to normal TLB handling */
  720. #else
  721. mfctr r10
  722. mtdar r10 /* save ctr reg in DAR */
  723. rlwinm r10, r11, 24, 24, 28 /* offset into jump table for reg RB */
  724. addi r10, r10, 150f@l /* add start of table */
  725. mtctr r10 /* load ctr with jump address */
  726. xor r10, r10, r10 /* sum starts at zero */
  727. bctr /* jump into table */
  728. 150:
  729. add r10, r10, r0 ;b 151f
  730. add r10, r10, r1 ;b 151f
  731. add r10, r10, r2 ;b 151f
  732. add r10, r10, r3 ;b 151f
  733. add r10, r10, r4 ;b 151f
  734. add r10, r10, r5 ;b 151f
  735. add r10, r10, r6 ;b 151f
  736. add r10, r10, r7 ;b 151f
  737. add r10, r10, r8 ;b 151f
  738. add r10, r10, r9 ;b 151f
  739. mtctr r11 ;b 154f /* r10 needs special handling */
  740. mtctr r11 ;b 153f /* r11 needs special handling */
  741. add r10, r10, r12 ;b 151f
  742. add r10, r10, r13 ;b 151f
  743. add r10, r10, r14 ;b 151f
  744. add r10, r10, r15 ;b 151f
  745. add r10, r10, r16 ;b 151f
  746. add r10, r10, r17 ;b 151f
  747. add r10, r10, r18 ;b 151f
  748. add r10, r10, r19 ;b 151f
  749. add r10, r10, r20 ;b 151f
  750. add r10, r10, r21 ;b 151f
  751. add r10, r10, r22 ;b 151f
  752. add r10, r10, r23 ;b 151f
  753. add r10, r10, r24 ;b 151f
  754. add r10, r10, r25 ;b 151f
  755. add r10, r10, r26 ;b 151f
  756. add r10, r10, r27 ;b 151f
  757. add r10, r10, r28 ;b 151f
  758. add r10, r10, r29 ;b 151f
  759. add r10, r10, r30 ;b 151f
  760. add r10, r10, r31
  761. 151:
  762. rlwinm. r11,r11,19,24,28 /* offset into jump table for reg RA */
  763. beq 152f /* if reg RA is zero, don't add it */
  764. addi r11, r11, 150b@l /* add start of table */
  765. mtctr r11 /* load ctr with jump address */
  766. rlwinm r11,r11,0,16,10 /* make sure we don't execute this more than once */
  767. bctr /* jump into table */
  768. 152:
  769. mfdar r11
  770. mtctr r11 /* restore ctr reg from DAR */
  771. mtdar r10 /* save fault EA to DAR */
  772. mfspr r10,SPRN_SPRG_SCRATCH2
  773. b DARFixed /* Go back to normal TLB handling */
  774. /* special handling for r10,r11 since these are modified already */
  775. 153: mfspr r11, SPRN_SPRG_SCRATCH1 /* load r11 from SPRN_SPRG_SCRATCH1 */
  776. add r10, r10, r11 /* add it */
  777. mfctr r11 /* restore r11 */
  778. b 151b
  779. 154: mfspr r11, SPRN_SPRG_SCRATCH0 /* load r10 from SPRN_SPRG_SCRATCH0 */
  780. add r10, r10, r11 /* add it */
  781. mfctr r11 /* restore r11 */
  782. b 151b
  783. #endif
  784. /*
  785. * This is where the main kernel code starts.
  786. */
  787. start_here:
  788. /* ptr to current */
  789. lis r2,init_task@h
  790. ori r2,r2,init_task@l
  791. /* ptr to phys current thread */
  792. tophys(r4,r2)
  793. addi r4,r4,THREAD /* init task's THREAD */
  794. mtspr SPRN_SPRG_THREAD,r4
  795. /* stack */
  796. lis r1,init_thread_union@ha
  797. addi r1,r1,init_thread_union@l
  798. li r0,0
  799. stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
  800. bl early_init /* We have to do this with MMU on */
  801. /*
  802. * Decide what sort of machine this is and initialize the MMU.
  803. */
  804. li r3,0
  805. mr r4,r31
  806. bl machine_init
  807. bl MMU_init
  808. /*
  809. * Go back to running unmapped so we can load up new values
  810. * and change to using our exception vectors.
  811. * On the 8xx, all we have to do is invalidate the TLB to clear
  812. * the old 8M byte TLB mappings and load the page table base register.
  813. */
  814. /* The right way to do this would be to track it down through
  815. * init's THREAD like the context switch code does, but this is
  816. * easier......until someone changes init's static structures.
  817. */
  818. lis r6, swapper_pg_dir@ha
  819. tophys(r6,r6)
  820. mtspr SPRN_M_TW, r6
  821. lis r4,2f@h
  822. ori r4,r4,2f@l
  823. tophys(r4,r4)
  824. li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
  825. mtspr SPRN_SRR0,r4
  826. mtspr SPRN_SRR1,r3
  827. rfi
  828. /* Load up the kernel context */
  829. 2:
  830. tlbia /* Clear all TLB entries */
  831. sync /* wait for tlbia/tlbie to finish */
  832. /* set up the PTE pointers for the Abatron bdiGDB.
  833. */
  834. tovirt(r6,r6)
  835. lis r5, abatron_pteptrs@h
  836. ori r5, r5, abatron_pteptrs@l
  837. stw r5, 0xf0(0) /* Must match your Abatron config file */
  838. tophys(r5,r5)
  839. stw r6, 0(r5)
  840. /* Now turn on the MMU for real! */
  841. li r4,MSR_KERNEL
  842. lis r3,start_kernel@h
  843. ori r3,r3,start_kernel@l
  844. mtspr SPRN_SRR0,r3
  845. mtspr SPRN_SRR1,r4
  846. rfi /* enable MMU and jump to start_kernel */
  847. /* Set up the initial MMU state so we can do the first level of
  848. * kernel initialization. This maps the first 8 MBytes of memory 1:1
  849. * virtual to physical. Also, set the cache mode since that is defined
  850. * by TLB entries and perform any additional mapping (like of the IMMR).
  851. * If configured to pin some TLBs, we pin the first 8 Mbytes of kernel,
  852. * 24 Mbytes of data, and the 512k IMMR space. Anything not covered by
  853. * these mappings is mapped by page tables.
  854. */
  855. initial_mmu:
  856. li r8, 0
  857. mtspr SPRN_MI_CTR, r8 /* remove PINNED ITLB entries */
  858. lis r10, MD_RESETVAL@h
  859. #ifndef CONFIG_8xx_COPYBACK
  860. oris r10, r10, MD_WTDEF@h
  861. #endif
  862. mtspr SPRN_MD_CTR, r10 /* remove PINNED DTLB entries */
  863. tlbia /* Invalidate all TLB entries */
  864. #ifdef CONFIG_PIN_TLB_TEXT
  865. lis r8, MI_RSV4I@h
  866. ori r8, r8, 0x1c00
  867. mtspr SPRN_MI_CTR, r8 /* Set instruction MMU control */
  868. #endif
  869. #ifdef CONFIG_PIN_TLB_DATA
  870. oris r10, r10, MD_RSV4I@h
  871. mtspr SPRN_MD_CTR, r10 /* Set data TLB control */
  872. #endif
  873. /* Now map the lower 8 Meg into the ITLB. */
  874. lis r8, KERNELBASE@h /* Create vaddr for TLB */
  875. ori r8, r8, MI_EVALID /* Mark it valid */
  876. mtspr SPRN_MI_EPN, r8
  877. li r8, MI_PS8MEG /* Set 8M byte page */
  878. ori r8, r8, MI_SVALID | M_APG2 /* Make it valid, APG 2 */
  879. mtspr SPRN_MI_TWC, r8
  880. li r8, MI_BOOTINIT /* Create RPN for address 0 */
  881. mtspr SPRN_MI_RPN, r8 /* Store TLB entry */
  882. lis r8, MI_APG_INIT@h /* Set protection modes */
  883. ori r8, r8, MI_APG_INIT@l
  884. mtspr SPRN_MI_AP, r8
  885. lis r8, MD_APG_INIT@h
  886. ori r8, r8, MD_APG_INIT@l
  887. mtspr SPRN_MD_AP, r8
  888. /* Map a 512k page for the IMMR to get the processor
  889. * internal registers (among other things).
  890. */
  891. #ifdef CONFIG_PIN_TLB_IMMR
  892. oris r10, r10, MD_RSV4I@h
  893. ori r10, r10, 0x1c00
  894. mtspr SPRN_MD_CTR, r10
  895. mfspr r9, 638 /* Get current IMMR */
  896. andis. r9, r9, 0xfff8 /* Get 512 kbytes boundary */
  897. lis r8, VIRT_IMMR_BASE@h /* Create vaddr for TLB */
  898. ori r8, r8, MD_EVALID /* Mark it valid */
  899. mtspr SPRN_MD_EPN, r8
  900. li r8, MD_PS512K | MD_GUARDED /* Set 512k byte page */
  901. ori r8, r8, MD_SVALID | M_APG2 /* Make it valid and accessed */
  902. mtspr SPRN_MD_TWC, r8
  903. mr r8, r9 /* Create paddr for TLB */
  904. ori r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */
  905. mtspr SPRN_MD_RPN, r8
  906. #endif
  907. /* Since the cache is enabled according to the information we
  908. * just loaded into the TLB, invalidate and enable the caches here.
  909. * We should probably check/set other modes....later.
  910. */
  911. lis r8, IDC_INVALL@h
  912. mtspr SPRN_IC_CST, r8
  913. mtspr SPRN_DC_CST, r8
  914. lis r8, IDC_ENABLE@h
  915. mtspr SPRN_IC_CST, r8
  916. #ifdef CONFIG_8xx_COPYBACK
  917. mtspr SPRN_DC_CST, r8
  918. #else
  919. /* For a debug option, I left this here to easily enable
  920. * the write through cache mode
  921. */
  922. lis r8, DC_SFWT@h
  923. mtspr SPRN_DC_CST, r8
  924. lis r8, IDC_ENABLE@h
  925. mtspr SPRN_DC_CST, r8
  926. #endif
  927. /* Disable debug mode entry on breakpoints */
  928. mfspr r8, SPRN_DER
  929. #ifdef CONFIG_PERF_EVENTS
  930. rlwinm r8, r8, 0, ~0xc
  931. #else
  932. rlwinm r8, r8, 0, ~0x8
  933. #endif
  934. mtspr SPRN_DER, r8
  935. blr
  936. /*
  937. * We put a few things here that have to be page-aligned.
  938. * This stuff goes at the beginning of the data segment,
  939. * which is page-aligned.
  940. */
  941. .data
  942. .globl sdata
  943. sdata:
  944. .globl empty_zero_page
  945. .align PAGE_SHIFT
  946. empty_zero_page:
  947. .space PAGE_SIZE
  948. EXPORT_SYMBOL(empty_zero_page)
  949. .globl swapper_pg_dir
  950. swapper_pg_dir:
  951. .space PGD_TABLE_SIZE
  952. /* Room for two PTE table poiners, usually the kernel and current user
  953. * pointer to their respective root page table (pgdir).
  954. */
  955. abatron_pteptrs:
  956. .space 8
  957. #ifdef CONFIG_PERF_EVENTS
  958. .globl itlb_miss_counter
  959. itlb_miss_counter:
  960. .space 4
  961. .globl dtlb_miss_counter
  962. dtlb_miss_counter:
  963. .space 4
  964. .globl instruction_counter
  965. instruction_counter:
  966. .space 4
  967. #endif