head_book3s_32.S 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * PowerPC version
  4. * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  5. *
  6. * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
  7. * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
  8. * Adapted for Power Macintosh by Paul Mackerras.
  9. * Low-level exception handlers and MMU support
  10. * rewritten by Paul Mackerras.
  11. * Copyright (C) 1996 Paul Mackerras.
  12. * MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
  13. *
  14. * This file contains the low-level support and setup for the
  15. * PowerPC platform, including trap and interrupt dispatch.
  16. * (The PPC 8xx embedded CPUs use head_8xx.S instead.)
  17. */
  18. #include <linux/init.h>
  19. #include <linux/pgtable.h>
  20. #include <linux/linkage.h>
  21. #include <asm/reg.h>
  22. #include <asm/page.h>
  23. #include <asm/mmu.h>
  24. #include <asm/cputable.h>
  25. #include <asm/cache.h>
  26. #include <asm/thread_info.h>
  27. #include <asm/ppc_asm.h>
  28. #include <asm/asm-offsets.h>
  29. #include <asm/ptrace.h>
  30. #include <asm/bug.h>
  31. #include <asm/kvm_book3s_asm.h>
  32. #include <asm/feature-fixups.h>
  33. #include <asm/interrupt.h>
  34. #include "head_32.h"
  35. #define LOAD_BAT(n, reg, RA, RB) \
  36. /* see the comment for clear_bats() -- Cort */ \
  37. li RA,0; \
  38. mtspr SPRN_IBAT##n##U,RA; \
  39. mtspr SPRN_DBAT##n##U,RA; \
  40. lwz RA,(n*16)+0(reg); \
  41. lwz RB,(n*16)+4(reg); \
  42. mtspr SPRN_IBAT##n##U,RA; \
  43. mtspr SPRN_IBAT##n##L,RB; \
  44. lwz RA,(n*16)+8(reg); \
  45. lwz RB,(n*16)+12(reg); \
  46. mtspr SPRN_DBAT##n##U,RA; \
  47. mtspr SPRN_DBAT##n##L,RB
  48. __HEAD
  49. _GLOBAL(_stext);
  50. /*
  51. * _start is defined this way because the XCOFF loader in the OpenFirmware
  52. * on the powermac expects the entry point to be a procedure descriptor.
  53. */
  54. _GLOBAL(_start);
  55. /*
  56. * These are here for legacy reasons, the kernel used to
  57. * need to look like a coff function entry for the pmac
  58. * but we're always started by some kind of bootloader now.
  59. * -- Cort
  60. */
  61. nop /* used by __secondary_hold on prep (mtx) and chrp smp */
  62. nop /* used by __secondary_hold on prep (mtx) and chrp smp */
  63. nop
  64. /* PMAC
  65. * Enter here with the kernel text, data and bss loaded starting at
  66. * 0, running with virtual == physical mapping.
  67. * r5 points to the prom entry point (the client interface handler
  68. * address). Address translation is turned on, with the prom
  69. * managing the hash table. Interrupts are disabled. The stack
  70. * pointer (r1) points to just below the end of the half-meg region
  71. * from 0x380000 - 0x400000, which is mapped in already.
  72. *
  73. * If we are booted from MacOS via BootX, we enter with the kernel
  74. * image loaded somewhere, and the following values in registers:
  75. * r3: 'BooX' (0x426f6f58)
  76. * r4: virtual address of boot_infos_t
  77. * r5: 0
  78. *
  79. * PREP
  80. * This is jumped to on prep systems right after the kernel is relocated
  81. * to its proper place in memory by the boot loader. The expected layout
  82. * of the regs is:
  83. * r3: ptr to residual data
  84. * r4: initrd_start or if no initrd then 0
  85. * r5: initrd_end - unused if r4 is 0
  86. * r6: Start of command line string
  87. * r7: End of command line string
  88. *
  89. * This just gets a minimal mmu environment setup so we can call
  90. * start_here() to do the real work.
  91. * -- Cort
  92. */
  93. .globl __start
  94. __start:
  95. /*
  96. * We have to do any OF calls before we map ourselves to KERNELBASE,
  97. * because OF may have I/O devices mapped into that area
  98. * (particularly on CHRP).
  99. */
  100. cmpwi 0,r5,0
  101. beq 1f
  102. #ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE
  103. /* find out where we are now */
  104. bcl 20,31,$+4
  105. 0: mflr r8 /* r8 = runtime addr here */
  106. addis r8,r8,(_stext - 0b)@ha
  107. addi r8,r8,(_stext - 0b)@l /* current runtime base addr */
  108. bl prom_init
  109. #endif /* CONFIG_PPC_OF_BOOT_TRAMPOLINE */
  110. /* We never return. We also hit that trap if trying to boot
  111. * from OF while CONFIG_PPC_OF_BOOT_TRAMPOLINE isn't selected */
  112. trap
  113. /*
  114. * Check for BootX signature when supporting PowerMac and branch to
  115. * appropriate trampoline if it's present
  116. */
  117. #ifdef CONFIG_PPC_PMAC
  118. 1: lis r31,0x426f
  119. ori r31,r31,0x6f58
  120. cmpw 0,r3,r31
  121. bne 1f
  122. bl bootx_init
  123. trap
  124. #endif /* CONFIG_PPC_PMAC */
  125. 1: mr r31,r3 /* save device tree ptr */
  126. li r24,0 /* cpu # */
  127. /*
  128. * early_init() does the early machine identification and does
  129. * the necessary low-level setup and clears the BSS
  130. * -- Cort <cort@fsmlabs.com>
  131. */
  132. bl early_init
  133. /* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains
  134. * the physical address we are running at, returned by early_init()
  135. */
  136. bl mmu_off
  137. __after_mmu_off:
  138. bl clear_bats
  139. bl flush_tlbs
  140. bl initial_bats
  141. bl load_segment_registers
  142. bl reloc_offset
  143. bl early_hash_table
  144. #if defined(CONFIG_BOOTX_TEXT)
  145. bl setup_disp_bat
  146. #endif
  147. #ifdef CONFIG_PPC_EARLY_DEBUG_CPM
  148. bl setup_cpm_bat
  149. #endif
  150. #ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO
  151. bl setup_usbgecko_bat
  152. #endif
  153. /*
  154. * Call setup_cpu for CPU 0 and initialize 6xx Idle
  155. */
  156. bl reloc_offset
  157. li r24,0 /* cpu# */
  158. bl call_setup_cpu /* Call setup_cpu for this CPU */
  159. bl reloc_offset
  160. bl init_idle_6xx
  161. /*
  162. * We need to run with _start at physical address 0.
  163. * On CHRP, we are loaded at 0x10000 since OF on CHRP uses
  164. * the exception vectors at 0 (and therefore this copy
  165. * overwrites OF's exception vectors with our own).
  166. * The MMU is off at this point.
  167. */
  168. bl reloc_offset
  169. mr r26,r3
  170. addis r4,r3,KERNELBASE@h /* current address of _start */
  171. lis r5,PHYSICAL_START@h
  172. cmplw 0,r4,r5 /* already running at PHYSICAL_START? */
  173. bne relocate_kernel
  174. /*
  175. * we now have the 1st 16M of ram mapped with the bats.
  176. * prep needs the mmu to be turned on here, but pmac already has it on.
  177. * this shouldn't bother the pmac since it just gets turned on again
  178. * as we jump to our code at KERNELBASE. -- Cort
  179. * Actually no, pmac doesn't have it on any more. BootX enters with MMU
  180. * off, and in other cases, we now turn it off before changing BATs above.
  181. */
  182. turn_on_mmu:
  183. mfmsr r0
  184. ori r0,r0,MSR_DR|MSR_IR|MSR_RI
  185. mtspr SPRN_SRR1,r0
  186. lis r0,start_here@h
  187. ori r0,r0,start_here@l
  188. mtspr SPRN_SRR0,r0
  189. rfi /* enables MMU */
  190. /*
  191. * We need __secondary_hold as a place to hold the other cpus on
  192. * an SMP machine, even when we are running a UP kernel.
  193. */
  194. . = 0xc0 /* for prep bootloader */
  195. li r3,1 /* MTX only has 1 cpu */
  196. .globl __secondary_hold
  197. __secondary_hold:
  198. /* tell the master we're here */
  199. stw r3,__secondary_hold_acknowledge@l(0)
  200. #ifdef CONFIG_SMP
  201. 100: lwz r4,0(0)
  202. /* wait until we're told to start */
  203. cmpw 0,r4,r3
  204. bne 100b
  205. /* our cpu # was at addr 0 - go */
  206. mr r24,r3 /* cpu # */
  207. b __secondary_start
  208. #else
  209. b .
  210. #endif /* CONFIG_SMP */
  211. .globl __secondary_hold_spinloop
  212. __secondary_hold_spinloop:
  213. .long 0
  214. .globl __secondary_hold_acknowledge
  215. __secondary_hold_acknowledge:
  216. .long -1
  217. /* System reset */
  218. /* core99 pmac starts the seconary here by changing the vector, and
  219. putting it back to what it was (unknown_async_exception) when done. */
  220. EXCEPTION(INTERRUPT_SYSTEM_RESET, Reset, unknown_async_exception)
  221. /* Machine check */
  222. /*
  223. * On CHRP, this is complicated by the fact that we could get a
  224. * machine check inside RTAS, and we have no guarantee that certain
  225. * critical registers will have the values we expect. The set of
  226. * registers that might have bad values includes all the GPRs
  227. * and all the BATs. We indicate that we are in RTAS by putting
  228. * a non-zero value, the address of the exception frame to use,
  229. * in thread.rtas_sp. The machine check handler checks thread.rtas_sp
  230. * and uses its value if it is non-zero.
  231. * (Other exception handlers assume that r1 is a valid kernel stack
  232. * pointer when we take an exception from supervisor mode.)
  233. * -- paulus.
  234. */
  235. START_EXCEPTION(INTERRUPT_MACHINE_CHECK, MachineCheck)
  236. EXCEPTION_PROLOG_0
  237. #ifdef CONFIG_PPC_CHRP
  238. mtspr SPRN_SPRG_SCRATCH2,r1
  239. mfspr r1, SPRN_SPRG_THREAD
  240. lwz r1, RTAS_SP(r1)
  241. cmpwi cr1, r1, 0
  242. bne cr1, 7f
  243. mfspr r1, SPRN_SPRG_SCRATCH2
  244. #endif /* CONFIG_PPC_CHRP */
  245. EXCEPTION_PROLOG_1
  246. 7: EXCEPTION_PROLOG_2 0x200 MachineCheck
  247. #ifdef CONFIG_PPC_CHRP
  248. beq cr1, 1f
  249. twi 31, 0, 0
  250. #endif
  251. 1: prepare_transfer_to_handler
  252. bl machine_check_exception
  253. b interrupt_return
  254. /* Data access exception. */
  255. START_EXCEPTION(INTERRUPT_DATA_STORAGE, DataAccess)
  256. #ifdef CONFIG_PPC_BOOK3S_604
  257. BEGIN_MMU_FTR_SECTION
  258. mtspr SPRN_SPRG_SCRATCH2,r10
  259. mfspr r10, SPRN_SPRG_THREAD
  260. stw r11, THR11(r10)
  261. mfspr r10, SPRN_DSISR
  262. mfcr r11
  263. andis. r10, r10, (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH)@h
  264. mfspr r10, SPRN_SPRG_THREAD
  265. beq hash_page_dsi
  266. .Lhash_page_dsi_cont:
  267. mtcr r11
  268. lwz r11, THR11(r10)
  269. mfspr r10, SPRN_SPRG_SCRATCH2
  270. MMU_FTR_SECTION_ELSE
  271. b 1f
  272. ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE)
  273. #endif
  274. 1: EXCEPTION_PROLOG_0 handle_dar_dsisr=1
  275. EXCEPTION_PROLOG_1
  276. EXCEPTION_PROLOG_2 INTERRUPT_DATA_STORAGE DataAccess handle_dar_dsisr=1
  277. prepare_transfer_to_handler
  278. lwz r5, _DSISR(r1)
  279. andis. r0, r5, DSISR_DABRMATCH@h
  280. bne- 1f
  281. bl do_page_fault
  282. b interrupt_return
  283. 1: bl do_break
  284. REST_NVGPRS(r1)
  285. b interrupt_return
  286. /* Instruction access exception. */
  287. START_EXCEPTION(INTERRUPT_INST_STORAGE, InstructionAccess)
  288. mtspr SPRN_SPRG_SCRATCH0,r10
  289. mtspr SPRN_SPRG_SCRATCH1,r11
  290. mfspr r10, SPRN_SPRG_THREAD
  291. mfspr r11, SPRN_SRR0
  292. stw r11, SRR0(r10)
  293. mfspr r11, SPRN_SRR1 /* check whether user or kernel */
  294. stw r11, SRR1(r10)
  295. mfcr r10
  296. #ifdef CONFIG_PPC_BOOK3S_604
  297. BEGIN_MMU_FTR_SECTION
  298. andis. r11, r11, SRR1_ISI_NOPT@h /* no pte found? */
  299. bne hash_page_isi
  300. .Lhash_page_isi_cont:
  301. mfspr r11, SPRN_SRR1 /* check whether user or kernel */
  302. END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
  303. #endif
  304. andi. r11, r11, MSR_PR
  305. EXCEPTION_PROLOG_1
  306. EXCEPTION_PROLOG_2 INTERRUPT_INST_STORAGE InstructionAccess
  307. andis. r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */
  308. stw r5, _DSISR(r11)
  309. stw r12, _DAR(r11)
  310. prepare_transfer_to_handler
  311. bl do_page_fault
  312. b interrupt_return
  313. /* External interrupt */
  314. EXCEPTION(INTERRUPT_EXTERNAL, HardwareInterrupt, do_IRQ)
  315. /* Alignment exception */
  316. START_EXCEPTION(INTERRUPT_ALIGNMENT, Alignment)
  317. EXCEPTION_PROLOG INTERRUPT_ALIGNMENT Alignment handle_dar_dsisr=1
  318. prepare_transfer_to_handler
  319. bl alignment_exception
  320. REST_NVGPRS(r1)
  321. b interrupt_return
  322. /* Program check exception */
  323. START_EXCEPTION(INTERRUPT_PROGRAM, ProgramCheck)
  324. EXCEPTION_PROLOG INTERRUPT_PROGRAM ProgramCheck
  325. prepare_transfer_to_handler
  326. bl program_check_exception
  327. REST_NVGPRS(r1)
  328. b interrupt_return
  329. /* Floating-point unavailable */
  330. START_EXCEPTION(0x800, FPUnavailable)
  331. #ifdef CONFIG_PPC_FPU
  332. BEGIN_FTR_SECTION
  333. /*
  334. * Certain Freescale cores don't have a FPU and treat fp instructions
  335. * as a FP Unavailable exception. Redirect to illegal/emulation handling.
  336. */
  337. b ProgramCheck
  338. END_FTR_SECTION_IFSET(CPU_FTR_FPU_UNAVAILABLE)
  339. EXCEPTION_PROLOG INTERRUPT_FP_UNAVAIL FPUnavailable
  340. beq 1f
  341. bl load_up_fpu /* if from user, just load it up */
  342. b fast_exception_return
  343. 1: prepare_transfer_to_handler
  344. bl kernel_fp_unavailable_exception
  345. b interrupt_return
  346. #else
  347. b ProgramCheck
  348. #endif
  349. /* Decrementer */
  350. EXCEPTION(INTERRUPT_DECREMENTER, Decrementer, timer_interrupt)
  351. EXCEPTION(0xa00, Trap_0a, unknown_exception)
  352. EXCEPTION(0xb00, Trap_0b, unknown_exception)
  353. /* System call */
  354. START_EXCEPTION(INTERRUPT_SYSCALL, SystemCall)
  355. SYSCALL_ENTRY INTERRUPT_SYSCALL
  356. EXCEPTION(INTERRUPT_TRACE, SingleStep, single_step_exception)
  357. EXCEPTION(0xe00, Trap_0e, unknown_exception)
  358. /*
  359. * The Altivec unavailable trap is at 0x0f20. Foo.
  360. * We effectively remap it to 0x3000.
  361. * We include an altivec unavailable exception vector even if
  362. * not configured for Altivec, so that you can't panic a
  363. * non-altivec kernel running on a machine with altivec just
  364. * by executing an altivec instruction.
  365. */
  366. START_EXCEPTION(INTERRUPT_PERFMON, PerformanceMonitorTrap)
  367. b PerformanceMonitor
  368. START_EXCEPTION(INTERRUPT_ALTIVEC_UNAVAIL, AltiVecUnavailableTrap)
  369. b AltiVecUnavailable
  370. __HEAD
  371. /*
  372. * Handle TLB miss for instruction on 603/603e.
  373. * Note: we get an alternate set of r0 - r3 to use automatically.
  374. */
  375. . = INTERRUPT_INST_TLB_MISS_603
  376. InstructionTLBMiss:
  377. /* Get PTE (linux-style) and check access */
  378. mfspr r0,SPRN_IMISS
  379. mfspr r2, SPRN_SDR1
  380. li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
  381. rlwinm r2, r2, 28, 0xfffff000
  382. rlwimi r2,r0,12,20,29 /* insert top 10 bits of address */
  383. lwz r2,0(r2) /* get pmd entry */
  384. #ifdef CONFIG_EXECMEM
  385. rlwinm r3, r0, 4, 0xf
  386. subi r3, r3, (TASK_SIZE >> 28) & 0xf
  387. #endif
  388. rlwinm. r2,r2,0,0,19 /* extract address of pte page */
  389. beq- InstructionAddressInvalid /* return if no mapping */
  390. rlwimi r2,r0,22,20,29 /* insert next 10 bits of address */
  391. lwz r2,0(r2) /* get linux-style pte */
  392. andc. r1,r1,r2 /* check access & ~permission */
  393. bne- InstructionAddressInvalid /* return if access not permitted */
  394. /* Convert linux-style PTE to low word of PPC-style PTE */
  395. #ifdef CONFIG_EXECMEM
  396. rlwimi r2, r3, 1, 31, 31 /* userspace ? -> PP lsb */
  397. #endif
  398. ori r1, r1, 0xe06 /* clear out reserved bits */
  399. andc r1, r2, r1 /* PP = user? 1 : 0 */
  400. BEGIN_FTR_SECTION
  401. rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */
  402. END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
  403. mtspr SPRN_RPA,r1
  404. tlbli r0
  405. mfspr r3,SPRN_SRR1 /* Need to restore CR0 */
  406. mtcrf 0x80,r3
  407. rfi
  408. InstructionAddressInvalid:
  409. mfspr r3,SPRN_SRR1
  410. rlwinm r1,r3,9,6,6 /* Get load/store bit */
  411. addis r1,r1,0x2000
  412. mtspr SPRN_DSISR,r1 /* (shouldn't be needed) */
  413. andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */
  414. or r2,r2,r1
  415. mtspr SPRN_SRR1,r2
  416. mfspr r1,SPRN_IMISS /* Get failing address */
  417. rlwinm. r2,r2,0,31,31 /* Check for little endian access */
  418. rlwimi r2,r2,1,30,30 /* change 1 -> 3 */
  419. xor r1,r1,r2
  420. mtspr SPRN_DAR,r1 /* Set fault address */
  421. mfmsr r0 /* Restore "normal" registers */
  422. xoris r0,r0,MSR_TGPR>>16
  423. mtcrf 0x80,r3 /* Restore CR0 */
  424. mtmsr r0
  425. b InstructionAccess
  426. /*
  427. * Handle TLB miss for DATA Load operation on 603/603e
  428. */
  429. . = INTERRUPT_DATA_LOAD_TLB_MISS_603
  430. DataLoadTLBMiss:
  431. /* Get PTE (linux-style) and check access */
  432. mfspr r0,SPRN_DMISS
  433. mfspr r2, SPRN_SDR1
  434. rlwinm r1, r2, 28, 0xfffff000
  435. rlwimi r1,r0,12,20,29 /* insert top 10 bits of address */
  436. lwz r2,0(r1) /* get pmd entry */
  437. rlwinm r3, r0, 4, 0xf
  438. rlwinm. r2,r2,0,0,19 /* extract address of pte page */
  439. subi r3, r3, (TASK_SIZE >> 28) & 0xf
  440. beq- 2f /* bail if no mapping */
  441. 1: rlwimi r2,r0,22,20,29 /* insert next 10 bits of address */
  442. lwz r2,0(r2) /* get linux-style pte */
  443. li r1, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_READ
  444. andc. r1,r1,r2 /* check access & ~permission */
  445. bne- DataAddressInvalid /* return if access not permitted */
  446. /* Convert linux-style PTE to low word of PPC-style PTE */
  447. rlwinm r1,r2,32-9,30,30 /* _PAGE_WRITE -> PP msb */
  448. rlwimi r2,r3,2,30,31 /* userspace ? -> PP */
  449. rlwimi r1,r2,32-3,24,24 /* _PAGE_WRITE -> _PAGE_DIRTY */
  450. xori r1,r1,_PAGE_DIRTY /* clear dirty when not rw */
  451. ori r1,r1,0xe04 /* clear out reserved bits */
  452. andc r1,r2,r1 /* PP = user? rw? 1: 3: 0 */
  453. BEGIN_FTR_SECTION
  454. rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */
  455. END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
  456. mtspr SPRN_RPA,r1
  457. BEGIN_MMU_FTR_SECTION
  458. li r3,1
  459. mfspr r1,SPRN_SPRG_603_LRU
  460. rlwinm r2,r0,20,27,31 /* Get Address bits 15:19 */
  461. slw r3,r3,r2
  462. xor r1,r3,r1
  463. srw r3,r1,r2
  464. mtspr SPRN_SPRG_603_LRU,r1
  465. mfspr r2,SPRN_SRR1
  466. rlwimi r2,r3,31-14,14,14
  467. mtspr SPRN_SRR1,r2
  468. mtcrf 0x80,r2
  469. tlbld r0
  470. rfi
  471. MMU_FTR_SECTION_ELSE
  472. mfspr r2,SPRN_SRR1 /* Need to restore CR0 */
  473. mtcrf 0x80,r2
  474. tlbld r0
  475. rfi
  476. ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
  477. 2: lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha
  478. addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
  479. rlwimi r2,r0,12,20,29 /* insert top 10 bits of address */
  480. lwz r2,0(r2) /* get pmd entry */
  481. cmpwi cr0,r2,0
  482. beq- DataAddressInvalid /* return if no mapping */
  483. stw r2,0(r1)
  484. rlwinm. r2,r2,0,0,19 /* extract address of pte page */
  485. b 1b
  486. DataAddressInvalid:
  487. mfspr r3,SPRN_SRR1
  488. rlwinm r1,r3,9,6,6 /* Get load/store bit */
  489. addis r1,r1,0x2000
  490. mtspr SPRN_DSISR,r1
  491. andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */
  492. mtspr SPRN_SRR1,r2
  493. mfspr r1,SPRN_DMISS /* Get failing address */
  494. rlwinm. r2,r2,0,31,31 /* Check for little endian access */
  495. beq 20f /* Jump if big endian */
  496. xori r1,r1,3
  497. 20: mtspr SPRN_DAR,r1 /* Set fault address */
  498. mfmsr r0 /* Restore "normal" registers */
  499. xoris r0,r0,MSR_TGPR>>16
  500. mtcrf 0x80,r3 /* Restore CR0 */
  501. mtmsr r0
  502. b DataAccess
  503. /*
  504. * Handle TLB miss for DATA Store on 603/603e
  505. */
  506. . = INTERRUPT_DATA_STORE_TLB_MISS_603
  507. DataStoreTLBMiss:
  508. /* Get PTE (linux-style) and check access */
  509. mfspr r0,SPRN_DMISS
  510. mfspr r2, SPRN_SDR1
  511. rlwinm r1, r2, 28, 0xfffff000
  512. rlwimi r1,r0,12,20,29 /* insert top 10 bits of address */
  513. lwz r2,0(r1) /* get pmd entry */
  514. rlwinm r3, r0, 4, 0xf
  515. rlwinm. r2,r2,0,0,19 /* extract address of pte page */
  516. subi r3, r3, (TASK_SIZE >> 28) & 0xf
  517. beq- 2f /* bail if no mapping */
  518. 1:
  519. rlwimi r2,r0,22,20,29 /* insert next 10 bits of address */
  520. lwz r2,0(r2) /* get linux-style pte */
  521. li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED
  522. andc. r1,r1,r2 /* check access & ~permission */
  523. bne- DataAddressInvalid /* return if access not permitted */
  524. /* Convert linux-style PTE to low word of PPC-style PTE */
  525. rlwimi r2,r3,1,31,31 /* userspace ? -> PP lsb */
  526. li r1,0xe06 /* clear out reserved bits & PP msb */
  527. andc r1,r2,r1 /* PP = user? 1: 0 */
  528. BEGIN_FTR_SECTION
  529. rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */
  530. END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
  531. mtspr SPRN_RPA,r1
  532. mfspr r2,SPRN_SRR1 /* Need to restore CR0 */
  533. mtcrf 0x80,r2
  534. BEGIN_MMU_FTR_SECTION
  535. li r3,1
  536. mfspr r1,SPRN_SPRG_603_LRU
  537. rlwinm r2,r0,20,27,31 /* Get Address bits 15:19 */
  538. slw r3,r3,r2
  539. xor r1,r3,r1
  540. srw r3,r1,r2
  541. mtspr SPRN_SPRG_603_LRU,r1
  542. mfspr r2,SPRN_SRR1
  543. rlwimi r2,r3,31-14,14,14
  544. mtspr SPRN_SRR1,r2
  545. mtcrf 0x80,r2
  546. tlbld r0
  547. rfi
  548. MMU_FTR_SECTION_ELSE
  549. mfspr r2,SPRN_SRR1 /* Need to restore CR0 */
  550. mtcrf 0x80,r2
  551. tlbld r0
  552. rfi
  553. ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
  554. 2: lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha
  555. addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */
  556. rlwimi r2,r0,12,20,29 /* insert top 10 bits of address */
  557. lwz r2,0(r2) /* get pmd entry */
  558. cmpwi cr0,r2,0
  559. beq- DataAddressInvalid /* return if no mapping */
  560. stw r2,0(r1)
  561. rlwinm r2,r2,0,0,19 /* extract address of pte page */
  562. b 1b
  563. #ifndef CONFIG_ALTIVEC
  564. #define altivec_assist_exception unknown_exception
  565. #endif
  566. #ifndef CONFIG_TAU_INT
  567. #define TAUException unknown_async_exception
  568. #endif
  569. EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception)
  570. EXCEPTION(0x1400, SMI, SMIException)
  571. EXCEPTION(0x1500, Trap_15, unknown_exception)
  572. EXCEPTION(0x1600, Trap_16, altivec_assist_exception)
  573. EXCEPTION(0x1700, Trap_17, TAUException)
  574. EXCEPTION(0x1800, Trap_18, unknown_exception)
  575. EXCEPTION(0x1900, Trap_19, unknown_exception)
  576. EXCEPTION(0x1a00, Trap_1a, unknown_exception)
  577. EXCEPTION(0x1b00, Trap_1b, unknown_exception)
  578. EXCEPTION(0x1c00, Trap_1c, unknown_exception)
  579. EXCEPTION(0x1d00, Trap_1d, unknown_exception)
  580. EXCEPTION(0x1e00, Trap_1e, unknown_exception)
  581. EXCEPTION(0x1f00, Trap_1f, unknown_exception)
  582. EXCEPTION(0x2000, RunMode, RunModeException)
  583. EXCEPTION(0x2100, Trap_21, unknown_exception)
  584. EXCEPTION(0x2200, Trap_22, unknown_exception)
  585. EXCEPTION(0x2300, Trap_23, unknown_exception)
  586. EXCEPTION(0x2400, Trap_24, unknown_exception)
  587. EXCEPTION(0x2500, Trap_25, unknown_exception)
  588. EXCEPTION(0x2600, Trap_26, unknown_exception)
  589. EXCEPTION(0x2700, Trap_27, unknown_exception)
  590. EXCEPTION(0x2800, Trap_28, unknown_exception)
  591. EXCEPTION(0x2900, Trap_29, unknown_exception)
  592. EXCEPTION(0x2a00, Trap_2a, unknown_exception)
  593. EXCEPTION(0x2b00, Trap_2b, unknown_exception)
  594. EXCEPTION(0x2c00, Trap_2c, unknown_exception)
  595. EXCEPTION(0x2d00, Trap_2d, unknown_exception)
  596. EXCEPTION(0x2e00, Trap_2e, unknown_exception)
  597. EXCEPTION(0x2f00, Trap_2f, unknown_exception)
  598. __HEAD
  599. . = 0x3000
  600. #ifdef CONFIG_PPC_BOOK3S_604
  601. .macro save_regs_thread thread
  602. stw r0, THR0(\thread)
  603. stw r3, THR3(\thread)
  604. stw r4, THR4(\thread)
  605. stw r5, THR5(\thread)
  606. stw r6, THR6(\thread)
  607. stw r8, THR8(\thread)
  608. stw r9, THR9(\thread)
  609. mflr r0
  610. stw r0, THLR(\thread)
  611. mfctr r0
  612. stw r0, THCTR(\thread)
  613. .endm
  614. .macro restore_regs_thread thread
  615. lwz r0, THLR(\thread)
  616. mtlr r0
  617. lwz r0, THCTR(\thread)
  618. mtctr r0
  619. lwz r0, THR0(\thread)
  620. lwz r3, THR3(\thread)
  621. lwz r4, THR4(\thread)
  622. lwz r5, THR5(\thread)
  623. lwz r6, THR6(\thread)
  624. lwz r8, THR8(\thread)
  625. lwz r9, THR9(\thread)
  626. .endm
  627. hash_page_dsi:
  628. save_regs_thread r10
  629. mfdsisr r3
  630. mfdar r4
  631. mfsrr0 r5
  632. mfsrr1 r9
  633. rlwinm r3, r3, 32 - 15, _PAGE_WRITE /* DSISR_STORE -> _PAGE_WRITE */
  634. ori r3, r3, _PAGE_PRESENT | _PAGE_READ
  635. bl hash_page
  636. mfspr r10, SPRN_SPRG_THREAD
  637. restore_regs_thread r10
  638. b .Lhash_page_dsi_cont
  639. hash_page_isi:
  640. mr r11, r10
  641. mfspr r10, SPRN_SPRG_THREAD
  642. save_regs_thread r10
  643. li r3, _PAGE_PRESENT | _PAGE_EXEC
  644. lwz r4, SRR0(r10)
  645. lwz r9, SRR1(r10)
  646. bl hash_page
  647. mfspr r10, SPRN_SPRG_THREAD
  648. restore_regs_thread r10
  649. mr r10, r11
  650. b .Lhash_page_isi_cont
  651. .globl fast_hash_page_return
  652. fast_hash_page_return:
  653. andis. r10, r9, SRR1_ISI_NOPT@h /* Set on ISI, cleared on DSI */
  654. mfspr r10, SPRN_SPRG_THREAD
  655. restore_regs_thread r10
  656. bne 1f
  657. /* DSI */
  658. mtcr r11
  659. lwz r11, THR11(r10)
  660. mfspr r10, SPRN_SPRG_SCRATCH2
  661. rfi
  662. 1: /* ISI */
  663. mtcr r11
  664. mfspr r11, SPRN_SPRG_SCRATCH1
  665. mfspr r10, SPRN_SPRG_SCRATCH0
  666. rfi
  667. #endif /* CONFIG_PPC_BOOK3S_604 */
  668. #ifdef CONFIG_VMAP_STACK
  669. vmap_stack_overflow_exception
  670. #endif
  671. __HEAD
  672. AltiVecUnavailable:
  673. EXCEPTION_PROLOG 0xf20 AltiVecUnavailable
  674. #ifdef CONFIG_ALTIVEC
  675. beq 1f
  676. bl load_up_altivec /* if from user, just load it up */
  677. b fast_exception_return
  678. #endif /* CONFIG_ALTIVEC */
  679. 1: prepare_transfer_to_handler
  680. bl altivec_unavailable_exception
  681. b interrupt_return
  682. __HEAD
  683. PerformanceMonitor:
  684. EXCEPTION_PROLOG 0xf00 PerformanceMonitor
  685. prepare_transfer_to_handler
  686. bl performance_monitor_exception
  687. b interrupt_return
  688. __HEAD
  689. /*
  690. * This code is jumped to from the startup code to copy
  691. * the kernel image to physical address PHYSICAL_START.
  692. */
  693. relocate_kernel:
  694. lis r3,PHYSICAL_START@h /* Destination base address */
  695. li r6,0 /* Destination offset */
  696. li r5,0x4000 /* # bytes of memory to copy */
  697. bl copy_and_flush /* copy the first 0x4000 bytes */
  698. addi r0,r3,4f@l /* jump to the address of 4f */
  699. mtctr r0 /* in copy and do the rest. */
  700. bctr /* jump to the copy */
  701. 4: lis r5,_end-KERNELBASE@h
  702. ori r5,r5,_end-KERNELBASE@l
  703. bl copy_and_flush /* copy the rest */
  704. b turn_on_mmu
  705. /*
  706. * Copy routine used to copy the kernel to start at physical address 0
  707. * and flush and invalidate the caches as needed.
  708. * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
  709. * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
  710. */
  711. _GLOBAL(copy_and_flush)
  712. addi r5,r5,-4
  713. addi r6,r6,-4
  714. 4: li r0,L1_CACHE_BYTES/4
  715. mtctr r0
  716. 3: addi r6,r6,4 /* copy a cache line */
  717. lwzx r0,r6,r4
  718. stwx r0,r6,r3
  719. bdnz 3b
  720. dcbst r6,r3 /* write it to memory */
  721. sync
  722. icbi r6,r3 /* flush the icache line */
  723. cmplw 0,r6,r5
  724. blt 4b
  725. sync /* additional sync needed on g4 */
  726. isync
  727. addi r5,r5,4
  728. addi r6,r6,4
  729. blr
  730. #ifdef CONFIG_SMP
  731. .globl __secondary_start_mpc86xx
  732. __secondary_start_mpc86xx:
  733. mfspr r3, SPRN_PIR
  734. stw r3, __secondary_hold_acknowledge@l(0)
  735. mr r24, r3 /* cpu # */
  736. b __secondary_start
  737. .globl __secondary_start_pmac_0
  738. __secondary_start_pmac_0:
  739. /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */
  740. li r24,0
  741. b 1f
  742. li r24,1
  743. b 1f
  744. li r24,2
  745. b 1f
  746. li r24,3
  747. 1:
  748. /* on powersurge, we come in here with IR=0 and DR=1, and DBAT 0
  749. set to map the 0xf0000000 - 0xffffffff region */
  750. mfmsr r0
  751. rlwinm r0,r0,0,28,26 /* clear DR (0x10) */
  752. mtmsr r0
  753. isync
  754. .globl __secondary_start
  755. __secondary_start:
  756. /* Copy some CPU settings from CPU 0 */
  757. bl __restore_cpu_setup
  758. lis r3,-KERNELBASE@h
  759. mr r4,r24
  760. bl call_setup_cpu /* Call setup_cpu for this CPU */
  761. lis r3,-KERNELBASE@h
  762. bl init_idle_6xx
  763. /* get current's stack and current */
  764. lis r2,secondary_current@ha
  765. tophys(r2,r2)
  766. lwz r2,secondary_current@l(r2)
  767. tophys(r1,r2)
  768. lwz r1,TASK_STACK(r1)
  769. /* stack */
  770. addi r1,r1,THREAD_SIZE-STACK_FRAME_MIN_SIZE
  771. li r0,0
  772. tophys(r3,r1)
  773. stw r0,0(r3)
  774. /* load up the MMU */
  775. bl load_segment_registers
  776. bl load_up_mmu
  777. /* ptr to phys current thread */
  778. tophys(r4,r2)
  779. addi r4,r4,THREAD /* phys address of our thread_struct */
  780. mtspr SPRN_SPRG_THREAD,r4
  781. BEGIN_MMU_FTR_SECTION
  782. lis r4, (swapper_pg_dir - PAGE_OFFSET)@h
  783. ori r4, r4, (swapper_pg_dir - PAGE_OFFSET)@l
  784. rlwinm r4, r4, 4, 0xffff01ff
  785. mtspr SPRN_SDR1, r4
  786. END_MMU_FTR_SECTION_IFCLR(MMU_FTR_HPTE_TABLE)
  787. /* enable MMU and jump to start_secondary */
  788. li r4,MSR_KERNEL
  789. lis r3,start_secondary@h
  790. ori r3,r3,start_secondary@l
  791. mtspr SPRN_SRR0,r3
  792. mtspr SPRN_SRR1,r4
  793. rfi
  794. #endif /* CONFIG_SMP */
  795. #ifdef CONFIG_KVM_BOOK3S_HANDLER
  796. #include "../kvm/book3s_rmhandlers.S"
  797. #endif
  798. /*
  799. * Load stuff into the MMU. Intended to be called with
  800. * IR=0 and DR=0.
  801. */
  802. SYM_FUNC_START_LOCAL(early_hash_table)
  803. sync /* Force all PTE updates to finish */
  804. isync
  805. tlbia /* Clear all TLB entries */
  806. sync /* wait for tlbia/tlbie to finish */
  807. TLBSYNC /* ... on all CPUs */
  808. /* Load the SDR1 register (hash table base & size) */
  809. lis r6, early_hash - PAGE_OFFSET@h
  810. ori r6, r6, 3 /* 256kB table */
  811. mtspr SPRN_SDR1, r6
  812. blr
  813. SYM_FUNC_END(early_hash_table)
  814. SYM_FUNC_START_LOCAL(load_up_mmu)
  815. sync /* Force all PTE updates to finish */
  816. isync
  817. tlbia /* Clear all TLB entries */
  818. sync /* wait for tlbia/tlbie to finish */
  819. TLBSYNC /* ... on all CPUs */
  820. BEGIN_MMU_FTR_SECTION
  821. /* Load the SDR1 register (hash table base & size) */
  822. lis r6,_SDR1@ha
  823. tophys(r6,r6)
  824. lwz r6,_SDR1@l(r6)
  825. mtspr SPRN_SDR1,r6
  826. END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
  827. /* Load the BAT registers with the values set up by MMU_init. */
  828. lis r3,BATS@ha
  829. addi r3,r3,BATS@l
  830. tophys(r3,r3)
  831. LOAD_BAT(0,r3,r4,r5)
  832. LOAD_BAT(1,r3,r4,r5)
  833. LOAD_BAT(2,r3,r4,r5)
  834. LOAD_BAT(3,r3,r4,r5)
  835. BEGIN_MMU_FTR_SECTION
  836. LOAD_BAT(4,r3,r4,r5)
  837. LOAD_BAT(5,r3,r4,r5)
  838. LOAD_BAT(6,r3,r4,r5)
  839. LOAD_BAT(7,r3,r4,r5)
  840. END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
  841. blr
  842. SYM_FUNC_END(load_up_mmu)
  843. _GLOBAL(load_segment_registers)
  844. li r0, NUM_USER_SEGMENTS /* load up user segment register values */
  845. mtctr r0 /* for context 0 */
  846. #ifdef CONFIG_PPC_KUEP
  847. lis r3, SR_NX@h /* Kp = 0, Ks = 0, VSID = 0 */
  848. #else
  849. li r3, 0 /* Kp = 0, Ks = 0, VSID = 0 */
  850. #endif
  851. li r4, 0
  852. 3: mtsrin r3, r4
  853. addi r3, r3, 0x111 /* increment VSID */
  854. addis r4, r4, 0x1000 /* address of next segment */
  855. bdnz 3b
  856. li r0, 16 - NUM_USER_SEGMENTS /* load up kernel segment registers */
  857. mtctr r0 /* for context 0 */
  858. rlwinm r3, r3, 0, ~SR_NX /* Nx = 0 */
  859. rlwinm r3, r3, 0, ~SR_KS /* Ks = 0 */
  860. oris r3, r3, SR_KP@h /* Kp = 1 */
  861. 3: mtsrin r3, r4
  862. addi r3, r3, 0x111 /* increment VSID */
  863. addis r4, r4, 0x1000 /* address of next segment */
  864. bdnz 3b
  865. blr
  866. /*
  867. * This is where the main kernel code starts.
  868. */
  869. start_here:
  870. /* ptr to current */
  871. lis r2,init_task@h
  872. ori r2,r2,init_task@l
  873. /* Set up for using our exception vectors */
  874. /* ptr to phys current thread */
  875. tophys(r4,r2)
  876. addi r4,r4,THREAD /* init task's THREAD */
  877. mtspr SPRN_SPRG_THREAD,r4
  878. BEGIN_MMU_FTR_SECTION
  879. lis r4, (swapper_pg_dir - PAGE_OFFSET)@h
  880. ori r4, r4, (swapper_pg_dir - PAGE_OFFSET)@l
  881. rlwinm r4, r4, 4, 0xffff01ff
  882. mtspr SPRN_SDR1, r4
  883. END_MMU_FTR_SECTION_IFCLR(MMU_FTR_HPTE_TABLE)
  884. /* stack */
  885. lis r1,init_thread_union@ha
  886. addi r1,r1,init_thread_union@l
  887. li r0,0
  888. stwu r0,THREAD_SIZE-STACK_FRAME_MIN_SIZE(r1)
  889. /*
  890. * Do early platform-specific initialization,
  891. * and set up the MMU.
  892. */
  893. #ifdef CONFIG_KASAN
  894. bl kasan_early_init
  895. #endif
  896. li r3,0
  897. mr r4,r31
  898. bl machine_init
  899. bl __save_cpu_setup
  900. bl MMU_init
  901. bl MMU_init_hw_patch
  902. /*
  903. * Go back to running unmapped so we can load up new values
  904. * for SDR1 (hash table pointer) and the segment registers
  905. * and change to using our exception vectors.
  906. */
  907. lis r4,2f@h
  908. ori r4,r4,2f@l
  909. tophys(r4,r4)
  910. li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
  911. .align 4
  912. mtspr SPRN_SRR0,r4
  913. mtspr SPRN_SRR1,r3
  914. rfi
  915. /* Load up the kernel context */
  916. 2: bl load_up_mmu
  917. #ifdef CONFIG_BDI_SWITCH
  918. /* Add helper information for the Abatron bdiGDB debugger.
  919. * We do this here because we know the mmu is disabled, and
  920. * will be enabled for real in just a few instructions.
  921. */
  922. lis r5, abatron_pteptrs@h
  923. ori r5, r5, abatron_pteptrs@l
  924. stw r5, 0xf0(0) /* This much match your Abatron config */
  925. lis r6, swapper_pg_dir@h
  926. ori r6, r6, swapper_pg_dir@l
  927. tophys(r5, r5)
  928. stw r6, 0(r5)
  929. #endif /* CONFIG_BDI_SWITCH */
  930. /* Now turn on the MMU for real! */
  931. li r4,MSR_KERNEL
  932. lis r3,start_kernel@h
  933. ori r3,r3,start_kernel@l
  934. mtspr SPRN_SRR0,r3
  935. mtspr SPRN_SRR1,r4
  936. rfi
  937. /*
  938. * An undocumented "feature" of 604e requires that the v bit
  939. * be cleared before changing BAT values.
  940. *
  941. * Also, newer IBM firmware does not clear bat3 and 4 so
  942. * this makes sure it's done.
  943. * -- Cort
  944. */
  945. SYM_FUNC_START_LOCAL(clear_bats)
  946. li r10,0
  947. mtspr SPRN_DBAT0U,r10
  948. mtspr SPRN_DBAT0L,r10
  949. mtspr SPRN_DBAT1U,r10
  950. mtspr SPRN_DBAT1L,r10
  951. mtspr SPRN_DBAT2U,r10
  952. mtspr SPRN_DBAT2L,r10
  953. mtspr SPRN_DBAT3U,r10
  954. mtspr SPRN_DBAT3L,r10
  955. mtspr SPRN_IBAT0U,r10
  956. mtspr SPRN_IBAT0L,r10
  957. mtspr SPRN_IBAT1U,r10
  958. mtspr SPRN_IBAT1L,r10
  959. mtspr SPRN_IBAT2U,r10
  960. mtspr SPRN_IBAT2L,r10
  961. mtspr SPRN_IBAT3U,r10
  962. mtspr SPRN_IBAT3L,r10
  963. BEGIN_MMU_FTR_SECTION
  964. /* Here's a tweak: at this point, CPU setup have
  965. * not been called yet, so HIGH_BAT_EN may not be
  966. * set in HID0 for the 745x processors. However, it
  967. * seems that doesn't affect our ability to actually
  968. * write to these SPRs.
  969. */
  970. mtspr SPRN_DBAT4U,r10
  971. mtspr SPRN_DBAT4L,r10
  972. mtspr SPRN_DBAT5U,r10
  973. mtspr SPRN_DBAT5L,r10
  974. mtspr SPRN_DBAT6U,r10
  975. mtspr SPRN_DBAT6L,r10
  976. mtspr SPRN_DBAT7U,r10
  977. mtspr SPRN_DBAT7L,r10
  978. mtspr SPRN_IBAT4U,r10
  979. mtspr SPRN_IBAT4L,r10
  980. mtspr SPRN_IBAT5U,r10
  981. mtspr SPRN_IBAT5L,r10
  982. mtspr SPRN_IBAT6U,r10
  983. mtspr SPRN_IBAT6L,r10
  984. mtspr SPRN_IBAT7U,r10
  985. mtspr SPRN_IBAT7L,r10
  986. END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
  987. blr
  988. SYM_FUNC_END(clear_bats)
  989. _GLOBAL(update_bats)
  990. lis r4, 1f@h
  991. ori r4, r4, 1f@l
  992. tophys(r4, r4)
  993. mfmsr r6
  994. mflr r7
  995. li r3, MSR_KERNEL & ~(MSR_IR | MSR_DR)
  996. rlwinm r0, r6, 0, ~MSR_RI
  997. rlwinm r0, r0, 0, ~MSR_EE
  998. mtmsr r0
  999. .align 4
  1000. mtspr SPRN_SRR0, r4
  1001. mtspr SPRN_SRR1, r3
  1002. rfi
  1003. 1: bl clear_bats
  1004. lis r3, BATS@ha
  1005. addi r3, r3, BATS@l
  1006. tophys(r3, r3)
  1007. LOAD_BAT(0, r3, r4, r5)
  1008. LOAD_BAT(1, r3, r4, r5)
  1009. LOAD_BAT(2, r3, r4, r5)
  1010. LOAD_BAT(3, r3, r4, r5)
  1011. BEGIN_MMU_FTR_SECTION
  1012. LOAD_BAT(4, r3, r4, r5)
  1013. LOAD_BAT(5, r3, r4, r5)
  1014. LOAD_BAT(6, r3, r4, r5)
  1015. LOAD_BAT(7, r3, r4, r5)
  1016. END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS)
  1017. li r3, MSR_KERNEL & ~(MSR_IR | MSR_DR | MSR_RI)
  1018. mtmsr r3
  1019. mtspr SPRN_SRR0, r7
  1020. mtspr SPRN_SRR1, r6
  1021. rfi
  1022. SYM_FUNC_START_LOCAL(flush_tlbs)
  1023. lis r10, 0x40
  1024. 1: addic. r10, r10, -0x1000
  1025. tlbie r10
  1026. bgt 1b
  1027. sync
  1028. blr
  1029. SYM_FUNC_END(flush_tlbs)
  1030. SYM_FUNC_START_LOCAL(mmu_off)
  1031. addi r4, r3, __after_mmu_off - _start
  1032. mfmsr r3
  1033. andi. r0,r3,MSR_DR|MSR_IR /* MMU enabled? */
  1034. beqlr
  1035. andc r3,r3,r0
  1036. .align 4
  1037. mtspr SPRN_SRR0,r4
  1038. mtspr SPRN_SRR1,r3
  1039. sync
  1040. rfi
  1041. SYM_FUNC_END(mmu_off)
  1042. /* We use one BAT to map up to 256M of RAM at _PAGE_OFFSET */
  1043. SYM_FUNC_START_LOCAL(initial_bats)
  1044. lis r11,PAGE_OFFSET@h
  1045. tophys(r8,r11)
  1046. #ifdef CONFIG_SMP
  1047. ori r8,r8,0x12 /* R/W access, M=1 */
  1048. #else
  1049. ori r8,r8,2 /* R/W access */
  1050. #endif /* CONFIG_SMP */
  1051. ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */
  1052. mtspr SPRN_DBAT0L,r8 /* N.B. 6xx have valid */
  1053. mtspr SPRN_DBAT0U,r11 /* bit in upper BAT register */
  1054. mtspr SPRN_IBAT0L,r8
  1055. mtspr SPRN_IBAT0U,r11
  1056. isync
  1057. blr
  1058. SYM_FUNC_END(initial_bats)
  1059. #ifdef CONFIG_BOOTX_TEXT
  1060. SYM_FUNC_START_LOCAL(setup_disp_bat)
  1061. /*
  1062. * setup the display bat prepared for us in prom.c
  1063. */
  1064. mflr r8
  1065. bl reloc_offset
  1066. mtlr r8
  1067. addis r8,r3,disp_BAT@ha
  1068. addi r8,r8,disp_BAT@l
  1069. cmpwi cr0,r8,0
  1070. beqlr
  1071. lwz r11,0(r8)
  1072. lwz r8,4(r8)
  1073. mtspr SPRN_DBAT3L,r8
  1074. mtspr SPRN_DBAT3U,r11
  1075. blr
  1076. SYM_FUNC_END(setup_disp_bat)
  1077. #endif /* CONFIG_BOOTX_TEXT */
  1078. #ifdef CONFIG_PPC_EARLY_DEBUG_CPM
  1079. SYM_FUNC_START_LOCAL(setup_cpm_bat)
  1080. lis r8, 0xf000
  1081. ori r8, r8, 0x002a
  1082. mtspr SPRN_DBAT1L, r8
  1083. lis r11, 0xf000
  1084. ori r11, r11, (BL_1M << 2) | 2
  1085. mtspr SPRN_DBAT1U, r11
  1086. blr
  1087. SYM_FUNC_END(setup_cpm_bat)
  1088. #endif
  1089. #ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO
  1090. SYM_FUNC_START_LOCAL(setup_usbgecko_bat)
  1091. /* prepare a BAT for early io */
  1092. #if defined(CONFIG_GAMECUBE)
  1093. lis r8, 0x0c00
  1094. #elif defined(CONFIG_WII)
  1095. lis r8, 0x0d00
  1096. #else
  1097. #error Invalid platform for USB Gecko based early debugging.
  1098. #endif
  1099. /*
  1100. * The virtual address used must match the virtual address
  1101. * associated to the fixmap entry FIX_EARLY_DEBUG_BASE.
  1102. */
  1103. lis r11, 0xfffe /* top 128K */
  1104. ori r8, r8, 0x002a /* uncached, guarded ,rw */
  1105. ori r11, r11, 0x2 /* 128K, Vs=1, Vp=0 */
  1106. mtspr SPRN_DBAT1L, r8
  1107. mtspr SPRN_DBAT1U, r11
  1108. blr
  1109. SYM_FUNC_END(setup_usbgecko_bat)
  1110. #endif
  1111. .data