head.S
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:47k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: %F% %I% %G% %U% %#%
  3.  */
  4. /*
  5.  *  PowerPC version 
  6.  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  7.  *
  8.  *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
  9.  *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
  10.  *  Adapted for Power Macintosh by Paul Mackerras.
  11.  *  Low-level exception handlers and MMU support
  12.  *  rewritten by Paul Mackerras.
  13.  *    Copyright (C) 1996 Paul Mackerras.
  14.  *  MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
  15.  *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
  16.  *
  17.  *  This file contains the low-level support and setup for the
  18.  *  PowerPC platform, including trap and interrupt dispatch.
  19.  *  (The PPC 8xx embedded CPUs use head_8xx.S instead.)
  20.  *
  21.  *  This program is free software; you can redistribute it and/or
  22.  *  modify it under the terms of the GNU General Public License
  23.  *  as published by the Free Software Foundation; either version
  24.  *  2 of the License, or (at your option) any later version.
  25.  *
  26.  */
  27. #include <linux/config.h>
  28. #include <linux/threads.h>
  29. #include <asm/processor.h>
  30. #include <asm/page.h>
  31. #include <asm/mmu.h>
  32. #include <asm/pgtable.h>
  33. #include <asm/cputable.h>
  34. #include <asm/cache.h>
  35. #include <asm/ppc_asm.h>
  36. #include "ppc_defs.h"
  37. #ifdef CONFIG_APUS
  38. #include <asm/amigappc.h>
  39. #endif
  40. #ifdef CONFIG_PPC64BRIDGE
  41. #define LOAD_BAT(n, reg, RA, RB)
  42. ld RA,(n*32)+0(reg);
  43. ld RB,(n*32)+8(reg);
  44. mtspr IBAT##n##U,RA;
  45. mtspr IBAT##n##L,RB;
  46. ld RA,(n*32)+16(reg);
  47. ld RB,(n*32)+24(reg);
  48. mtspr DBAT##n##U,RA;
  49. mtspr DBAT##n##L,RB;
  50. #else /* CONFIG_PPC64BRIDGE */
  51. /* 601 only have IBAT; cr0.eq is set on 601 when using this macro */
  52. #define LOAD_BAT(n, reg, RA, RB)
  53. /* see the comment for clear_bats() -- Cort */ 
  54. li RA,0;
  55. mtspr IBAT##n##U,RA;
  56. mtspr DBAT##n##U,RA;
  57. lwz RA,(n*16)+0(reg);
  58. lwz RB,(n*16)+4(reg);
  59. mtspr IBAT##n##U,RA;
  60. mtspr IBAT##n##L,RB;
  61. beq 1f;
  62. lwz RA,(n*16)+8(reg);
  63. lwz RB,(n*16)+12(reg);
  64. mtspr DBAT##n##U,RA;
  65. mtspr DBAT##n##L,RB;
  66. 1:
  67. #endif /* CONFIG_PPC64BRIDGE */  
  68. .text
  69. .globl _stext
  70. _stext:
  71. /*
  72.  * _start is defined this way because the XCOFF loader in the OpenFirmware
  73.  * on the powermac expects the entry point to be a procedure descriptor.
  74.  */
  75. .text
  76. .globl _start
  77. _start:
  78. /* 
  79.  * These are here for legacy reasons, the kernel used to
  80.  * need to look like a coff function entry for the pmac
  81.  * but we're always started by some kind of bootloader now.
  82.  *  -- Cort
  83.  */
  84. nop
  85. nop
  86. nop
  87. /* PMAC
  88.  * Enter here with the kernel text, data and bss loaded starting at
  89.  * 0, running with virtual == physical mapping.
  90.  * r5 points to the prom entry point (the client interface handler
  91.  * address).  Address translation is turned on, with the prom
  92.  * managing the hash table.  Interrupts are disabled.  The stack
  93.  * pointer (r1) points to just below the end of the half-meg region
  94.  * from 0x380000 - 0x400000, which is mapped in already.
  95.  *
  96.  * If we are booted from MacOS via BootX, we enter with the kernel
  97.  * image loaded somewhere, and the following values in registers:
  98.  *  r3: 'BooX' (0x426f6f58)
  99.  *  r4: virtual address of boot_infos_t
  100.  *  r5: 0
  101.  *
  102.  * APUS
  103.  *   r3: 'APUS'
  104.  *   r4: physical address of memory base
  105.  *   Linux/m68k style BootInfo structure at &_end.
  106.  *
  107.  * PREP
  108.  * This is jumped to on prep systems right after the kernel is relocated
  109.  * to its proper place in memory by the boot loader.  The expected layout
  110.  * of the regs is:
  111.  *   r3: ptr to residual data
  112.  *   r4: initrd_start or if no initrd then 0
  113.  *   r5: initrd_end - unused if r4 is 0
  114.  *   r6: Start of command line string
  115.  *   r7: End of command line string
  116.  *
  117.  * This just gets a minimal mmu environment setup so we can call
  118.  * start_here() to do the real work.
  119.  * -- Cort
  120.  */
  121. .globl __start
  122. __start:
  123. /*
  124.  * We have to do any OF calls before we map ourselves to KERNELBASE,
  125.  * because OF may have I/O devices mapped into that area
  126.  * (particularly on CHRP).
  127.  */
  128. mr r31,r3 /* save parameters */
  129. mr r30,r4
  130. mr r29,r5
  131. mr r28,r6
  132. mr r27,r7
  133. li r24,0 /* cpu # */
  134. /*
  135.  * early_init() does the early machine identification and does
  136.  * the necessary low-level setup and clears the BSS
  137.  *  -- Cort <cort@fsmlabs.com>
  138.  */ 
  139. bl early_init
  140. #ifdef CONFIG_APUS
  141. /* On APUS the __va/__pa constants need to be set to the correct 
  142.  * values before continuing. 
  143.  */
  144. mr r4,r30
  145. bl fix_mem_constants
  146. #endif /* CONFIG_APUS */
  147. #ifndef CONFIG_GEMINI
  148. /* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains
  149.  * the physical address we are running at, returned by early_init()
  150.  */
  151.   bl mmu_off
  152. __after_mmu_off:
  153. bl clear_bats
  154. bl flush_tlbs
  155. #endif
  156. #ifndef CONFIG_POWER4
  157. /* POWER4 doesn't have BATs */
  158. bl initial_bats
  159. #if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
  160. bl setup_disp_bat
  161. #endif
  162. #else /* CONFIG_POWER4 */
  163. /*
  164.  * Load up the SDR1 and segment register values now
  165.  * since we don't have the BATs.
  166.  */
  167. bl reloc_offset
  168. addis r4,r3,_SDR1@ha /* get the value from _SDR1 */
  169. lwz r4,_SDR1@l(r4) /* assume hash table below 4GB */
  170. mtspr SDR1,r4
  171. slbia
  172. lis r5,0x2000 /* set pseudo-segment reg 12 */
  173. ori r5,r5,0x0ccc
  174. mtsr 12,r5
  175. #endif /* CONFIG_POWER4 */
  176. /*
  177.  * Call setup_cpu for CPU 0
  178.  */
  179. bl reloc_offset
  180. li r24,0 /* cpu# */
  181. bl call_setup_cpu /* Call setup_cpu for this CPU */
  182. #ifdef CONFIG_6xx
  183. bl reloc_offset
  184. bl init_idle_6xx
  185. #endif /* CONFIG_6xx */
  186. #ifndef CONFIG_APUS
  187. /*
  188.  * We need to run with _start at physical address 0.
  189.  * On CHRP, we are loaded at 0x10000 since OF on CHRP uses
  190.  * the exception vectors at 0 (and therefore this copy
  191.  * overwrites OF's exception vectors with our own).
  192.  * If the MMU is already turned on, we copy stuff to KERNELBASE,
  193.  * otherwise we copy it to 0.
  194.  */
  195. bl reloc_offset
  196. mr r26,r3
  197. addis r4,r3,KERNELBASE@h /* current address of _start */
  198. cmpwi 0,r4,0 /* are we already running at 0? */
  199. bne relocate_kernel
  200. #endif /* CONFIG_APUS */
  201. /*
  202.  * we now have the 1st 16M of ram mapped with the bats.
  203.  * prep needs the mmu to be turned on here, but pmac already has it on.
  204.  * this shouldn't bother the pmac since it just gets turned on again
  205.  * as we jump to our code at KERNELBASE. -- Cort
  206.  * Actually no, pmac doesn't have it on any more. BootX enters with MMU
  207.  * off, and in other cases, we now turn it off before changing BATs above.
  208.  */
  209. turn_on_mmu:
  210. mfmsr r0
  211. ori r0,r0,MSR_DR|MSR_IR
  212. mtspr SRR1,r0
  213. lis r0,start_here@h
  214. ori r0,r0,start_here@l
  215. mtspr SRR0,r0
  216. SYNC
  217. RFI /* enables MMU */
  218. /*
  219.  * We need __secondary_hold as a place to hold the other cpus on
  220.  * an SMP machine, even when we are running a UP kernel.
  221.  */
  222. . = 0xc0 /* for prep bootloader */
  223. li r3,1 /* MTX only has 1 cpu */
  224. .globl __secondary_hold
  225. __secondary_hold:
  226. /* tell the master we're here */
  227. stw r3,4(0)
  228. #ifdef CONFIG_SMP
  229. 100: lwz r4,0(0)
  230. /* wait until we're told to start */
  231. cmpw 0,r4,r3
  232. bne 100b
  233. /* our cpu # was at addr 0 - go */
  234. mr r24,r3 /* cpu # */
  235. b __secondary_start
  236. #else
  237. b .
  238. #endif /* CONFIG_SMP */
  239. /*
  240.  * Exception entry code.  This code runs with address translation
  241.  * turned off, i.e. using physical addresses.
  242.  * We assume sprg3 has the physical address of the current
  243.  * task's thread_struct.
  244.  */
  245. #define EXCEPTION_PROLOG
  246. mtspr SPRG0,r20;
  247. mtspr SPRG1,r21;
  248. mfcr r20;
  249. mfspr r21,SPRG2; /* exception stack to use from */ 
  250. cmpwi 0,r21,0; /* user mode or RTAS */ 
  251. bne 1f;
  252. tophys(r21,r1); /* use tophys(kernel sp) otherwise */ 
  253. subi r21,r21,INT_FRAME_SIZE; /* alloc exc. frame */
  254. 1: CLR_TOP32(r21);
  255. stw r20,_CCR(r21); /* save registers */ 
  256. stw r22,GPR22(r21);
  257. stw r23,GPR23(r21);
  258. mfspr r20,SPRG0;
  259. stw r20,GPR20(r21);
  260. mfspr r22,SPRG1;
  261. stw r22,GPR21(r21);
  262. mflr r20;
  263. stw r20,_LINK(r21);
  264. mfctr r22;
  265. stw r22,_CTR(r21);
  266. mfspr r20,XER;
  267. stw r20,_XER(r21);
  268. mfspr r22,SRR0;
  269. mfspr r23,SRR1;
  270. stw r0,GPR0(r21);
  271. stw r1,GPR1(r21);
  272. stw r2,GPR2(r21);
  273. stw r1,0(r21);
  274. tovirt(r1,r21); /* set new kernel sp */
  275. SAVE_4GPRS(3, r21);
  276. SAVE_GPR(7, r21);
  277. /*
  278.  * Note: code which follows this uses cr0.eq (set if from kernel),
  279.  * r21, r22 (SRR0), and r23 (SRR1).
  280.  */
  281. /*
  282.  * Exception vectors.
  283.  */
  284. #define STD_EXCEPTION(n, label, hdlr)
  285. . = n;
  286. label:
  287. EXCEPTION_PROLOG;
  288. addi r3,r1,STACK_FRAME_OVERHEAD;
  289. li r20,MSR_KERNEL;
  290. bl transfer_to_handler; 
  291. i##n:
  292. .long hdlr;
  293. .long ret_from_except
  294. /* System reset */
  295. #ifdef CONFIG_SMP /* MVME/MTX and gemini start the secondary here */
  296. #ifdef CONFIG_GEMINI
  297. . = 0x100
  298. b __secondary_start_gemini
  299. #else /* CONFIG_GEMINI */
  300. STD_EXCEPTION(0x100, Reset, __secondary_start_psurge)
  301. #endif /* CONFIG_GEMINI */
  302. #else
  303. STD_EXCEPTION(0x100, Reset, UnknownException)
  304. #endif
  305. /* Machine check */
  306. BEGIN_FTR_SECTION
  307. DSSALL
  308. sync
  309. END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
  310. STD_EXCEPTION(0x200, MachineCheck, MachineCheckException)
  311. /* Data access exception. */
  312. . = 0x300
  313. #ifdef CONFIG_PPC64BRIDGE
  314. b DataAccess
  315. DataAccessCont:
  316. #else
  317. DataAccess:
  318. EXCEPTION_PROLOG
  319. #endif /* CONFIG_PPC64BRIDGE */
  320. mfspr r20,DSISR
  321. BEGIN_FTR_SECTION
  322. andis. r0,r20,0xa470 /* weird error? */
  323. bne 1f /* if not, try to put a PTE */
  324. mfspr r4,DAR /* into the hash table */
  325. rlwinm r3,r20,32-15,21,21 /* DSISR_STORE -> _PAGE_RW */
  326. bl hash_page
  327. END_FTR_SECTION_IFSET(CPU_FTR_HPTE_TABLE)
  328. 1: stw r20,_DSISR(r21)
  329. mr r5,r20
  330. mfspr r4,DAR
  331. stw r4,_DAR(r21)
  332. addi r3,r1,STACK_FRAME_OVERHEAD
  333. li r20,MSR_KERNEL
  334. rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
  335. bl transfer_to_handler
  336. i0x300:
  337. .long do_page_fault
  338. .long ret_from_except
  339. #ifdef CONFIG_PPC64BRIDGE
  340. /* SLB fault on data access. */
  341. . = 0x380
  342. b DataSegment
  343. DataSegmentCont:
  344. mfspr r4,DAR
  345. stw r4,_DAR(r21)
  346. addi r3,r1,STACK_FRAME_OVERHEAD
  347. li r20,MSR_KERNEL
  348. rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
  349. bl transfer_to_handler
  350. .long UnknownException
  351. .long ret_from_except
  352. #endif /* CONFIG_PPC64BRIDGE */
  353. /* Instruction access exception. */
  354. . = 0x400
  355. #ifdef CONFIG_PPC64BRIDGE
  356. b InstructionAccess
  357. InstructionAccessCont:
  358. #else
  359. InstructionAccess:
  360. EXCEPTION_PROLOG
  361. #endif /* CONFIG_PPC64BRIDGE */
  362. BEGIN_FTR_SECTION
  363. andis. r0,r23,0x4000 /* no pte found? */
  364. beq 1f /* if so, try to put a PTE */
  365. li r3,0 /* into the hash table */
  366. mr r4,r22 /* SRR0 is fault address */
  367. bl hash_page
  368. END_FTR_SECTION_IFSET(CPU_FTR_HPTE_TABLE)
  369. 1: addi r3,r1,STACK_FRAME_OVERHEAD
  370. mr r4,r22
  371. mr r5,r23
  372. li r20,MSR_KERNEL
  373. rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
  374. bl transfer_to_handler
  375. i0x400:
  376. .long do_page_fault
  377. .long ret_from_except
  378. #ifdef CONFIG_PPC64BRIDGE
  379. /* SLB fault on instruction access. */
  380. . = 0x480
  381. b InstructionSegment
  382. InstructionSegmentCont:
  383. addi r3,r1,STACK_FRAME_OVERHEAD
  384. li r20,MSR_KERNEL
  385. rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
  386. bl transfer_to_handler
  387. .long UnknownException
  388. .long ret_from_except
  389. #endif /* CONFIG_PPC64BRIDGE */
  390. /* External interrupt */
  391. . = 0x500;
  392. HardwareInterrupt:
  393. EXCEPTION_PROLOG;
  394. addi r3,r1,STACK_FRAME_OVERHEAD
  395. li r20,MSR_KERNEL
  396. li r4,0
  397. bl transfer_to_handler
  398. .globl do_IRQ_intercept
  399. do_IRQ_intercept:
  400. .long do_IRQ;
  401. .long ret_from_intercept
  402. /* Alignment exception */
  403. . = 0x600
  404. Alignment:
  405. EXCEPTION_PROLOG
  406. mfspr r4,DAR
  407. stw r4,_DAR(r21)
  408. mfspr r5,DSISR
  409. stw r5,_DSISR(r21)
  410. addi r3,r1,STACK_FRAME_OVERHEAD
  411. li r20,MSR_KERNEL
  412. rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
  413. bl transfer_to_handler
  414. i0x600:
  415. .long AlignmentException
  416. .long ret_from_except
  417. /* Program check exception */
  418. . = 0x700
  419. ProgramCheck:
  420. EXCEPTION_PROLOG
  421. addi r3,r1,STACK_FRAME_OVERHEAD
  422. li r20,MSR_KERNEL
  423. rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
  424. bl transfer_to_handler
  425. i0x700:
  426. .long ProgramCheckException
  427. .long ret_from_except
  428. /* Floating-point unavailable */
  429. . = 0x800
  430. FPUnavailable:
  431. EXCEPTION_PROLOG
  432. bne load_up_fpu /* if from user, just load it up */
  433. li r20,MSR_KERNEL
  434. bl transfer_to_handler /* if from kernel, take a trap */
  435. i0x800:
  436. .long KernelFP
  437. .long ret_from_except
  438. . = 0x900
  439. Decrementer:
  440. EXCEPTION_PROLOG
  441. addi r3,r1,STACK_FRAME_OVERHEAD
  442. li r20,MSR_KERNEL
  443. bl transfer_to_handler
  444. .globl timer_interrupt_intercept
  445. timer_interrupt_intercept:
  446. .long timer_interrupt
  447. .long ret_from_intercept
  448. STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
  449. STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
  450. /* System call */
  451. . = 0xc00
  452. SystemCall:
  453. EXCEPTION_PROLOG
  454. stw r3,ORIG_GPR3(r21)
  455. li r20,MSR_KERNEL
  456. rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
  457. bl transfer_to_handler
  458. .long DoSyscall
  459. .long ret_from_except
  460. /* Single step - not used on 601 */
  461. STD_EXCEPTION(0xd00, SingleStep, SingleStepException)
  462. STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
  463. /*
  464.  * The Altivec unavailable trap is at 0x0f20.  Foo.
  465.  * We effectively remap it to 0x3000.
  466.  */
  467. . = 0xf00
  468. b Trap_0f
  469. trap_0f_cont:
  470. addi r3,r1,STACK_FRAME_OVERHEAD
  471. li r20,MSR_KERNEL
  472. bl transfer_to_handler
  473. .long UnknownException
  474. .long ret_from_except
  475. . = 0xf20
  476. #ifdef CONFIG_ALTIVEC
  477. b AltiVecUnavailable
  478. #endif
  479. Trap_0f:
  480. EXCEPTION_PROLOG
  481. b trap_0f_cont
  482. /*
  483.  * Handle TLB miss for instruction on 603/603e.
  484.  * Note: we get an alternate set of r0 - r3 to use automatically.
  485.  */
  486. . = 0x1000
  487. InstructionTLBMiss:
  488. /*
  489.  * r0: stored ctr
  490.  * r1: linux style pte ( later becomes ppc hardware pte )
  491.  * r2: ptr to linux-style pte
  492.  * r3: scratch
  493.  */
  494. mfctr r0
  495. /* Get PTE (linux-style) and check access */
  496. mfspr r3,IMISS
  497. lis r1,KERNELBASE@h /* check if kernel address */
  498. cmplw 0,r3,r1
  499. mfspr r2,SPRG3
  500. li r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */
  501. lwz r2,PGDIR(r2)
  502. blt+ 112f
  503. lis r2,swapper_pg_dir@ha /* if kernel address, use */
  504. addi r2,r2,swapper_pg_dir@l /* kernel page table */
  505. mfspr r1,SRR1 /* and MSR_PR bit from SRR1 */
  506. rlwinm r1,r1,32-12,29,29 /* shift MSR_PR to _PAGE_USER posn */
  507. 112: tophys(r2,r2)
  508. rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
  509. lwz r2,0(r2) /* get pmd entry */
  510. rlwinm. r2,r2,0,0,19 /* extract address of pte page */
  511. beq- InstructionAddressInvalid /* return if no mapping */
  512. tophys(r2,r2)
  513. rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */
  514. lwz r3,0(r2) /* get linux-style pte */
  515. andc. r1,r1,r3 /* check access & ~permission */
  516. bne- InstructionAddressInvalid /* return if access not permitted */
  517. ori r3,r3,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */
  518. /*
  519.  * NOTE! We are assuming this is not an SMP system, otherwise
  520.  * we would need to update the pte atomically with lwarx/stwcx.
  521.  */
  522. stw r3,0(r2) /* update PTE (accessed bit) */
  523. /* Convert linux-style PTE to low word of PPC-style PTE */
  524. rlwinm r1,r3,32-10,31,31 /* _PAGE_RW -> PP lsb */
  525. rlwinm r2,r3,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */
  526. and r1,r1,r2 /* writable if _RW and _DIRTY */
  527. rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */
  528. rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */
  529. ori r1,r1,0xe14 /* clear out reserved bits and M */
  530. andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */
  531. mtspr RPA,r1
  532. mfspr r3,IMISS
  533. tlbli r3
  534. mfspr r3,SRR1 /* Need to restore CR0 */
  535. mtcrf 0x80,r3
  536. rfi
  537. InstructionAddressInvalid:
  538. mfspr r3,SRR1
  539. rlwinm r1,r3,9,6,6 /* Get load/store bit */
  540. addis r1,r1,0x2000
  541. mtspr DSISR,r1 /* (shouldn't be needed) */
  542. mtctr r0 /* Restore CTR */
  543. andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */
  544. or r2,r2,r1
  545. mtspr SRR1,r2
  546. mfspr r1,IMISS /* Get failing address */
  547. rlwinm. r2,r2,0,31,31 /* Check for little endian access */
  548. rlwimi r2,r2,1,30,30 /* change 1 -> 3 */
  549. xor r1,r1,r2
  550. mtspr DAR,r1 /* Set fault address */
  551. mfmsr r0 /* Restore "normal" registers */
  552. xoris r0,r0,MSR_TGPR>>16
  553. mtcrf 0x80,r3 /* Restore CR0 */
  554. mtmsr r0
  555. b InstructionAccess
  556. /*
  557.  * Handle TLB miss for DATA Load operation on 603/603e
  558.  */
  559. . = 0x1100
  560. DataLoadTLBMiss:
  561. /*
  562.  * r0: stored ctr
  563.  * r1: linux style pte ( later becomes ppc hardware pte )
  564.  * r2: ptr to linux-style pte
  565.  * r3: scratch
  566.  */
  567. mfctr r0
  568. /* Get PTE (linux-style) and check access */
  569. mfspr r3,DMISS
  570. lis r1,KERNELBASE@h /* check if kernel address */
  571. cmplw 0,r3,r1
  572. mfspr r2,SPRG3
  573. li r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */
  574. lwz r2,PGDIR(r2)
  575. blt+ 112f
  576. lis r2,swapper_pg_dir@ha /* if kernel address, use */
  577. addi r2,r2,swapper_pg_dir@l /* kernel page table */
  578. mfspr r1,SRR1 /* and MSR_PR bit from SRR1 */
  579. rlwinm r1,r1,32-12,29,29 /* shift MSR_PR to _PAGE_USER posn */
  580. 112: tophys(r2,r2)
  581. rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
  582. lwz r2,0(r2) /* get pmd entry */
  583. rlwinm. r2,r2,0,0,19 /* extract address of pte page */
  584. beq- DataAddressInvalid /* return if no mapping */
  585. tophys(r2,r2)
  586. rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */
  587. lwz r3,0(r2) /* get linux-style pte */
  588. andc. r1,r1,r3 /* check access & ~permission */
  589. bne- DataAddressInvalid /* return if access not permitted */
  590. ori r3,r3,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */
  591. /*
  592.  * NOTE! We are assuming this is not an SMP system, otherwise
  593.  * we would need to update the pte atomically with lwarx/stwcx.
  594.  */
  595. stw r3,0(r2) /* update PTE (accessed bit) */
  596. /* Convert linux-style PTE to low word of PPC-style PTE */
  597. rlwinm r1,r3,32-10,31,31 /* _PAGE_RW -> PP lsb */
  598. rlwinm r2,r3,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */
  599. and r1,r1,r2 /* writable if _RW and _DIRTY */
  600. rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */
  601. rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */
  602. ori r1,r1,0xe14 /* clear out reserved bits and M */
  603. andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */
  604. mtspr RPA,r1
  605. mfspr r3,DMISS
  606. tlbld r3
  607. mfspr r3,SRR1 /* Need to restore CR0 */
  608. mtcrf 0x80,r3
  609. rfi
  610. DataAddressInvalid:
  611. mfspr r3,SRR1
  612. rlwinm r1,r3,9,6,6 /* Get load/store bit */
  613. addis r1,r1,0x2000
  614. mtspr DSISR,r1
  615. mtctr r0 /* Restore CTR */
  616. andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */
  617. mtspr SRR1,r2
  618. mfspr r1,DMISS /* Get failing address */
  619. rlwinm. r2,r2,0,31,31 /* Check for little endian access */
  620. beq 20f /* Jump if big endian */
  621. xori r1,r1,3
  622. 20: mtspr DAR,r1 /* Set fault address */
  623. mfmsr r0 /* Restore "normal" registers */
  624. xoris r0,r0,MSR_TGPR>>16
  625. mtcrf 0x80,r3 /* Restore CR0 */
  626. mtmsr r0
  627. b DataAccess
  628. /*
  629.  * Handle TLB miss for DATA Store on 603/603e
  630.  */
  631. . = 0x1200
  632. DataStoreTLBMiss:
  633. /*
  634.  * r0: stored ctr
  635.  * r1: linux style pte ( later becomes ppc hardware pte )
  636.  * r2: ptr to linux-style pte
  637.  * r3: scratch
  638.  */
  639. mfctr r0
  640. /* Get PTE (linux-style) and check access */
  641. mfspr r3,DMISS
  642. lis r1,KERNELBASE@h /* check if kernel address */
  643. cmplw 0,r3,r1
  644. mfspr r2,SPRG3
  645. li r1,_PAGE_RW|_PAGE_USER|_PAGE_PRESENT /* access flags */
  646. lwz r2,PGDIR(r2)
  647. blt+ 112f
  648. lis r2,swapper_pg_dir@ha /* if kernel address, use */
  649. addi r2,r2,swapper_pg_dir@l /* kernel page table */
  650. mfspr r1,SRR1 /* and MSR_PR bit from SRR1 */
  651. rlwinm r1,r1,32-12,29,29 /* shift MSR_PR to _PAGE_USER posn */
  652. 112: tophys(r2,r2)
  653. rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */
  654. lwz r2,0(r2) /* get pmd entry */
  655. rlwinm. r2,r2,0,0,19 /* extract address of pte page */
  656. beq- DataAddressInvalid /* return if no mapping */
  657. tophys(r2,r2)
  658. rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */
  659. lwz r3,0(r2) /* get linux-style pte */
  660. andc. r1,r1,r3 /* check access & ~permission */
  661. bne- DataAddressInvalid /* return if access not permitted */
  662. ori r3,r3,_PAGE_ACCESSED|_PAGE_DIRTY
  663. /*
  664.  * NOTE! We are assuming this is not an SMP system, otherwise
  665.  * we would need to update the pte atomically with lwarx/stwcx.
  666.  */
  667. stw r3,0(r2) /* update PTE (accessed/dirty bits) */
  668. /* Convert linux-style PTE to low word of PPC-style PTE */
  669. rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */
  670. li r1,0xe15 /* clear out reserved bits and M */
  671. andc r1,r3,r1 /* PP = user? 2: 0 */
  672. mtspr RPA,r1
  673. mfspr r3,DMISS
  674. tlbld r3
  675. mfspr r3,SRR1 /* Need to restore CR0 */
  676. mtcrf 0x80,r3
  677. rfi
  678. STD_EXCEPTION(0x1300, Trap_13, InstructionBreakpoint)
  679. STD_EXCEPTION(0x1400, SMI, SMIException)
  680. STD_EXCEPTION(0x1500, Trap_15, UnknownException)
  681. STD_EXCEPTION(0x1600, Trap_16, UnknownException)
  682. STD_EXCEPTION(0x1700, Trap_17, TAUException)
  683. STD_EXCEPTION(0x1800, Trap_18, UnknownException)
  684. STD_EXCEPTION(0x1900, Trap_19, UnknownException)
  685. STD_EXCEPTION(0x1a00, Trap_1a, UnknownException)
  686. STD_EXCEPTION(0x1b00, Trap_1b, UnknownException)
  687. STD_EXCEPTION(0x1c00, Trap_1c, UnknownException)
  688. STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
  689. STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
  690. STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
  691. STD_EXCEPTION(0x2000, RunMode, RunModeException)
  692. STD_EXCEPTION(0x2100, Trap_21, UnknownException)
  693. STD_EXCEPTION(0x2200, Trap_22, UnknownException)
  694. STD_EXCEPTION(0x2300, Trap_23, UnknownException)
  695. STD_EXCEPTION(0x2400, Trap_24, UnknownException)
  696. STD_EXCEPTION(0x2500, Trap_25, UnknownException)
  697. STD_EXCEPTION(0x2600, Trap_26, UnknownException)
  698. STD_EXCEPTION(0x2700, Trap_27, UnknownException)
  699. STD_EXCEPTION(0x2800, Trap_28, UnknownException)
  700. STD_EXCEPTION(0x2900, Trap_29, UnknownException)
  701. STD_EXCEPTION(0x2a00, Trap_2a, UnknownException)
  702. STD_EXCEPTION(0x2b00, Trap_2b, UnknownException)
  703. STD_EXCEPTION(0x2c00, Trap_2c, UnknownException)
  704. STD_EXCEPTION(0x2d00, Trap_2d, UnknownException)
  705. STD_EXCEPTION(0x2e00, Trap_2e, UnknownException)
  706. STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
  707. . = 0x3000
  708. #ifdef CONFIG_ALTIVEC
  709. AltiVecUnavailable:
  710. EXCEPTION_PROLOG
  711. bne load_up_altivec /* if from user, just load it up */
  712. li r20,MSR_KERNEL
  713. bl transfer_to_handler /* if from kernel, take a trap */
  714. .long KernelAltiVec
  715. .long ret_from_except
  716. #endif /* CONFIG_ALTIVEC */
  717. #ifdef CONFIG_PPC64BRIDGE
  718. DataAccess:
  719. EXCEPTION_PROLOG
  720. b DataAccessCont
  721. InstructionAccess:
  722. EXCEPTION_PROLOG
  723. b InstructionAccessCont
  724. DataSegment:
  725. EXCEPTION_PROLOG
  726. b DataSegmentCont
  727. InstructionSegment:
  728. EXCEPTION_PROLOG
  729. b InstructionSegmentCont
  730. #endif /* CONFIG_PPC64BRIDGE */
  731. /*
  732.  * This code finishes saving the registers to the exception frame
  733.  * and jumps to the appropriate handler for the exception, turning
  734.  * on address translation.
  735.  */
  736. .globl transfer_to_handler
  737. transfer_to_handler:
  738. stw r22,_NIP(r21)
  739. stw r23,_MSR(r21)
  740. SAVE_4GPRS(8, r21)
  741. SAVE_8GPRS(12, r21)
  742. SAVE_8GPRS(24, r21)
  743. andi. r23,r23,MSR_PR
  744. mfspr r23,SPRG3 /* if from user, fix up THREAD.regs */
  745. addi r2,r23,-THREAD /* set r2 to current */
  746. beq 2f
  747. addi r24,r1,STACK_FRAME_OVERHEAD
  748. stw r24,PT_REGS(r23)
  749. #ifdef CONFIG_ALTIVEC
  750. BEGIN_FTR_SECTION
  751. mfspr r22,SPRN_VRSAVE /* if G4, save vrsave register value */
  752. stw r22,THREAD_VRSAVE(r23)
  753. END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
  754. #endif /* CONFIG_ALTIVEC */
  755. .globl transfer_to_handler_cont
  756. transfer_to_handler_cont:
  757. tovirt(r2,r2)
  758. mflr r23
  759. andi. r24,r23,0x3f00 /* get vector offset */
  760. stw r24,TRAP(r21)
  761. li r22,0
  762. stw r22,RESULT(r21)
  763. mtspr SPRG2,r22 /* r1 is now kernel sp */
  764. addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */
  765. cmplw 0,r1,r2
  766. cmplw 1,r1,r24
  767. crand 1,1,4
  768. bgt- stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */
  769. lwz r24,0(r23) /* virtual address of handler */
  770. lwz r23,4(r23) /* where to go when done */
  771. FIX_SRR1(r20,r22)
  772. mtspr SRR0,r24
  773. mtspr SRR1,r20
  774. mtlr r23
  775. SYNC
  776. RFI /* jump to handler, enable MMU */
  777. 2:
  778. /* Out of line case when returning to kernel,
  779.  * check return from power_save_6xx
  780.  */
  781. #ifdef CONFIG_6xx
  782. mfspr r24,SPRN_HID0
  783. mtcr r24
  784. BEGIN_FTR_SECTION
  785. bt- 8,power_save_6xx_restore /* Check DOZE */
  786. END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
  787. BEGIN_FTR_SECTION
  788. bt- 9,power_save_6xx_restore /* Check NAP */
  789. END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
  790. b transfer_to_handler_cont
  791. #endif /* CONFIG_6xx */
  792. /*
  793.  * On kernel stack overflow, load up an initial stack pointer
  794.  * and call StackOverflow(regs), which should not return.
  795.  */
  796. stack_ovf:
  797. addi r3,r1,STACK_FRAME_OVERHEAD
  798. lis r1,init_task_union@ha
  799. addi r1,r1,init_task_union@l
  800. addi r1,r1,TASK_UNION_SIZE-STACK_FRAME_OVERHEAD
  801. lis r24,StackOverflow@ha
  802. addi r24,r24,StackOverflow@l
  803. li r20,MSR_KERNEL
  804. FIX_SRR1(r20,r22)
  805. mtspr SRR0,r24
  806. mtspr SRR1,r20
  807. SYNC
  808. RFI
  809. /*
  810.  * Disable FP for the task which had the FPU previously,
  811.  * and save its floating-point registers in its thread_struct.
  812.  * Enables the FPU for use in the kernel on return.
  813.  * On SMP we know the fpu is free, since we give it up every
  814.  * switch.  -- Cort
  815.  */
  816. load_up_fpu:
  817. mfmsr r5
  818. ori r5,r5,MSR_FP
  819. #ifdef CONFIG_PPC64BRIDGE
  820. clrldi r5,r5,1 /* turn off 64-bit mode */
  821. #endif /* CONFIG_PPC64BRIDGE */
  822. SYNC
  823. MTMSRD(r5) /* enable use of fpu now */
  824. isync
  825. /*
  826.  * For SMP, we don't do lazy FPU switching because it just gets too
  827.  * horrendously complex, especially when a task switches from one CPU
  828.  * to another.  Instead we call giveup_fpu in switch_to.
  829.  */
  830. #ifndef CONFIG_SMP
  831. lis r6,0                    /* get __pa constant */
  832. tophys(r6,r6)
  833. addis r3,r6,last_task_used_math@ha
  834. lwz r4,last_task_used_math@l(r3)
  835. cmpi 0,r4,0
  836. beq 1f
  837. add r4,r4,r6
  838. addi r4,r4,THREAD         /* want THREAD of last_task_used_math */
  839. SAVE_32FPRS(0, r4)
  840. mffs fr0
  841. stfd fr0,THREAD_FPSCR-4(r4)
  842. lwz r5,PT_REGS(r4)
  843. add r5,r5,r6
  844. lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
  845. li r20,MSR_FP|MSR_FE0|MSR_FE1
  846. andc r4,r4,r20 /* disable FP for previous task */
  847. stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
  848. 1:
  849. #endif /* CONFIG_SMP */
  850. /* enable use of FP after return */
  851. ori r23,r23,MSR_FP|MSR_FE0|MSR_FE1
  852. mfspr r5,SPRG3 /* current task's THREAD (phys) */
  853. lfd fr0,THREAD_FPSCR-4(r5)
  854. mtfsf 0xff,fr0
  855. REST_32FPRS(0, r5)
  856. #ifndef CONFIG_SMP
  857. subi r4,r5,THREAD
  858. sub r4,r4,r6
  859. stw r4,last_task_used_math@l(r3)
  860. #endif /* CONFIG_SMP */
  861. /* restore registers and return */
  862. lwz r3,_CCR(r21)
  863. lwz r4,_LINK(r21)
  864. mtcrf 0xff,r3
  865. mtlr r4
  866. REST_GPR(1, r21)
  867. REST_4GPRS(3, r21)
  868. /* we haven't used ctr or xer */
  869. mtspr SRR1,r23
  870. mtspr SRR0,r22
  871. REST_GPR(20, r21)
  872. REST_2GPRS(22, r21)
  873. lwz r21,GPR21(r21)
  874. SYNC
  875. RFI
  876. /*
  877.  * FP unavailable trap from kernel - print a message, but let
  878.  * the task use FP in the kernel until it returns to user mode.
  879.  */
  880. KernelFP:
  881. lwz r3,_MSR(r1)
  882. ori r3,r3,MSR_FP
  883. stw r3,_MSR(r1) /* enable use of FP after return */
  884. lis r3,86f@h
  885. ori r3,r3,86f@l
  886. mr r4,r2 /* current */
  887. lwz r5,_NIP(r1)
  888. bl printk
  889. b ret_from_except
  890. 86: .string "floating point used in kernel (task=%p, pc=%x)n"
  891. .align 4
  892. #ifdef CONFIG_ALTIVEC
  893. /* Note that the AltiVec support is closely modeled after the FP
  894.  * support.  Changes to one are likely to be applicable to the
  895.  * other!  */
  896. load_up_altivec:
  897. /*
  898.  * Disable AltiVec for the task which had AltiVec previously,
  899.  * and save its AltiVec registers in its thread_struct.
  900.  * Enables AltiVec for use in the kernel on return.
  901.  * On SMP we know the AltiVec units are free, since we give it up every
  902.  * switch.  -- Kumar
  903.  */
  904. mfmsr r5
  905. oris r5,r5,MSR_VEC@h
  906. mtmsr r5 /* enable use of AltiVec now */
  907. isync
  908. /*
  909.  * For SMP, we don't do lazy AltiVec switching because it just gets too
  910.  * horrendously complex, especially when a task switches from one CPU
  911.  * to another.  Instead we call giveup_altivec in switch_to.
  912.  */
  913. #ifndef CONFIG_SMP
  914. #ifndef CONFIG_APUS
  915. lis r6,-KERNELBASE@h
  916. #else
  917. lis r6,CYBERBASEp@h
  918. lwz r6,0(r6)
  919. #endif
  920. addis r3,r6,last_task_used_altivec@ha
  921. lwz r4,last_task_used_altivec@l(r3)
  922. cmpi 0,r4,0
  923. beq 1f
  924. add r4,r4,r6
  925. addi r4,r4,THREAD /* want THREAD of last_task_used_altivec */
  926. SAVE_32VR(0,r20,r4)
  927. MFVSCR(vr0)
  928. li r20,THREAD_VSCR
  929. STVX(vr0,r20,r4)
  930. lwz r5,PT_REGS(r4)
  931. add r5,r5,r6
  932. lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
  933. lis r20,MSR_VEC@h
  934. andc r4,r4,r20 /* disable altivec for previous task */
  935. stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
  936. 1:
  937. #endif /* CONFIG_SMP */
  938. /* enable use of AltiVec after return */
  939. oris r23,r23,MSR_VEC@h
  940. mfspr r5,SPRG3 /* current task's THREAD (phys) */
  941. li r20,THREAD_VSCR
  942. LVX(vr0,r20,r5)
  943. MTVSCR(vr0)
  944. REST_32VR(0,r20,r5)
  945. #ifndef CONFIG_SMP
  946. subi r4,r5,THREAD
  947. sub r4,r4,r6
  948. stw r4,last_task_used_altivec@l(r3)
  949. #endif /* CONFIG_SMP */
  950. /* restore registers and return */
  951. lwz r3,_CCR(r21)
  952. lwz r4,_LINK(r21)
  953. mtcrf 0xff,r3
  954. mtlr r4
  955. REST_GPR(1, r21)
  956. REST_4GPRS(3, r21)
  957. /* we haven't used ctr or xer */
  958. mtspr SRR1,r23
  959. mtspr SRR0,r22
  960. REST_GPR(20, r21)
  961. REST_2GPRS(22, r21)
  962. lwz r21,GPR21(r21)
  963. SYNC
  964. RFI
  965. /*
  966.  * AltiVec unavailable trap from kernel - print a message, but let
  967.  * the task use AltiVec in the kernel until it returns to user mode.
  968.  */
  969. KernelAltiVec:
  970. lwz r3,_MSR(r1)
  971. oris r3,r3,MSR_VEC@h
  972. stw r3,_MSR(r1) /* enable use of AltiVec after return */
  973. lis r3,87f@h
  974. ori r3,r3,87f@l
  975. mr r4,r2 /* current */
  976. lwz r5,_NIP(r1)
  977. bl printk
  978. b ret_from_except
  979. 87: .string "AltiVec used in kernel  (task=%p, pc=%x)  n"
  980. .align 4
  981. /*
  982.  * giveup_altivec(tsk)
  983.  * Disable AltiVec for the task given as the argument,
  984.  * and save the AltiVec registers in its thread_struct.
  985.  * Enables AltiVec for use in the kernel on return.
  986.  */
  987. .globl giveup_altivec
  988. giveup_altivec:
  989. mfmsr r5
  990. oris r5,r5,MSR_VEC@h
  991. SYNC
  992. mtmsr r5 /* enable use of AltiVec now */
  993. isync
  994. cmpi 0,r3,0
  995. beqlr- /* if no previous owner, done */
  996. addi r3,r3,THREAD /* want THREAD of task */
  997. lwz r5,PT_REGS(r3)
  998. cmpi 0,r5,0
  999. SAVE_32VR(0, r4, r3)
  1000. MFVSCR(vr0)
  1001. li r4,THREAD_VSCR
  1002. STVX(vr0, r4, r3)
  1003. beq 1f
  1004. lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
  1005. lis r3,MSR_VEC@h
  1006. andc r4,r4,r3 /* disable AltiVec for previous task */
  1007. stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
  1008. 1:
  1009. #ifndef CONFIG_SMP
  1010. li r5,0
  1011. lis r4,last_task_used_altivec@ha
  1012. stw r5,last_task_used_altivec@l(r4)
  1013. #endif /* CONFIG_SMP */
  1014. blr
  1015. #endif /* CONFIG_ALTIVEC */
  1016. /*
  1017.  * giveup_fpu(tsk)
  1018.  * Disable FP for the task given as the argument,
  1019.  * and save the floating-point registers in its thread_struct.
  1020.  * Enables the FPU for use in the kernel on return.
  1021.  */
  1022. .globl giveup_fpu
  1023. giveup_fpu:
  1024. mfmsr r5
  1025. ori r5,r5,MSR_FP
  1026. SYNC
  1027. mtmsr r5 /* enable use of fpu now */
  1028. SYNC
  1029. isync
  1030. cmpi 0,r3,0
  1031. beqlr- /* if no previous owner, done */
  1032. addi r3,r3,THREAD         /* want THREAD of task */
  1033. lwz r5,PT_REGS(r3)
  1034. cmpi 0,r5,0
  1035. SAVE_32FPRS(0, r3)
  1036. mffs fr0
  1037. stfd fr0,THREAD_FPSCR-4(r3)
  1038. beq 1f
  1039. lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5)
  1040. li r3,MSR_FP|MSR_FE0|MSR_FE1
  1041. andc r4,r4,r3 /* disable FP for previous task */
  1042. stw r4,_MSR-STACK_FRAME_OVERHEAD(r5)
  1043. 1:
  1044. #ifndef CONFIG_SMP
  1045. li r5,0
  1046. lis r4,last_task_used_math@ha
  1047. stw r5,last_task_used_math@l(r4)
  1048. #endif /* CONFIG_SMP */
  1049. blr
  1050. /*
  1051.  * This code is jumped to from the startup code to copy
  1052.  * the kernel image to physical address 0.
  1053.  */
  1054. relocate_kernel:
  1055. addis r9,r26,klimit@ha /* fetch klimit */
  1056. lwz r25,klimit@l(r9)
  1057. addis r25,r25,-KERNELBASE@h
  1058. li r3,0 /* Destination base address */
  1059. li r6,0 /* Destination offset */
  1060. li r5,0x4000 /* # bytes of memory to copy */
  1061. bl copy_and_flush /* copy the first 0x4000 bytes */
  1062. addi r0,r3,4f@l /* jump to the address of 4f */
  1063. mtctr r0 /* in copy and do the rest. */
  1064. bctr /* jump to the copy */
  1065. 4: mr r5,r25
  1066. bl copy_and_flush /* copy the rest */
  1067. b turn_on_mmu
  1068. /*
  1069.  * Copy routine used to copy the kernel to start at physical address 0
  1070.  * and flush and invalidate the caches as needed.
  1071.  * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
  1072.  * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
  1073.  */
  1074. copy_and_flush:
  1075. addi r5,r5,-4
  1076. addi r6,r6,-4
  1077. 4: li r0,L1_CACHE_LINE_SIZE/4
  1078. mtctr r0
  1079. 3: addi r6,r6,4 /* copy a cache line */
  1080. lwzx r0,r6,r4
  1081. stwx r0,r6,r3
  1082. bdnz 3b
  1083. dcbst r6,r3 /* write it to memory */
  1084. sync
  1085. icbi r6,r3 /* flush the icache line */
  1086. cmplw 0,r6,r5
  1087. blt 4b
  1088. sync /* additional sync needed on g4 */
  1089. isync
  1090. addi r5,r5,4
  1091. addi r6,r6,4
  1092. blr
  1093. #ifdef CONFIG_APUS
  1094. /*
  1095.  * On APUS the physical base address of the kernel is not known at compile
  1096.  * time, which means the __pa/__va constants used are incorrect. In the
  1097.  * __init section is recorded the virtual addresses of instructions using
  1098.  * these constants, so all that has to be done is fix these before
  1099.  * continuing the kernel boot.
  1100.  *
  1101.  * r4 = The physical address of the kernel base.
  1102.  */
  1103. fix_mem_constants:
  1104. mr r10,r4
  1105. addis r10,r10,-KERNELBASE@h    /* virt_to_phys constant */
  1106. neg r11,r10                  /* phys_to_virt constant */
  1107. lis r12,__vtop_table_begin@h
  1108. ori r12,r12,__vtop_table_begin@l
  1109. add r12,r12,r10          /* table begin phys address */
  1110. lis r13,__vtop_table_end@h
  1111. ori r13,r13,__vtop_table_end@l
  1112. add r13,r13,r10          /* table end phys address */
  1113. subi r12,r12,4
  1114. subi r13,r13,4
  1115. 1: lwzu r14,4(r12)               /* virt address of instruction */
  1116. add     r14,r14,r10              /* phys address of instruction */
  1117. lwz     r15,0(r14)               /* instruction, now insert top */
  1118. rlwimi  r15,r10,16,16,31         /* half of vp const in low half */
  1119. stw r15,0(r14)               /* of instruction and restore. */
  1120. dcbst r0,r14  /* write it to memory */
  1121. sync
  1122. icbi r0,r14  /* flush the icache line */
  1123. cmpw r12,r13
  1124. bne     1b
  1125. sync /* additional sync needed on g4 */
  1126. isync
  1127. /*
  1128.  * Map the memory where the exception handlers will
  1129.  * be copied to when hash constants have been patched.  
  1130.  */
  1131. #ifdef CONFIG_APUS_FAST_EXCEPT
  1132. lis r8,0xfff0
  1133. #else
  1134. lis r8,0
  1135. #endif
  1136. ori r8,r8,0x2 /* 128KB, supervisor */
  1137. mtspr DBAT3U,r8
  1138. mtspr DBAT3L,r8
  1139. lis r12,__ptov_table_begin@h
  1140. ori r12,r12,__ptov_table_begin@l
  1141. add r12,r12,r10          /* table begin phys address */
  1142. lis r13,__ptov_table_end@h
  1143. ori r13,r13,__ptov_table_end@l
  1144. add r13,r13,r10          /* table end phys address */
  1145. subi r12,r12,4
  1146. subi r13,r13,4
  1147. 1: lwzu r14,4(r12)               /* virt address of instruction */
  1148. add     r14,r14,r10              /* phys address of instruction */
  1149. lwz     r15,0(r14)               /* instruction, now insert top */
  1150. rlwimi  r15,r11,16,16,31         /* half of pv const in low half*/
  1151. stw r15,0(r14)               /* of instruction and restore. */
  1152. dcbst r0,r14  /* write it to memory */
  1153. sync
  1154. icbi r0,r14  /* flush the icache line */
  1155. cmpw r12,r13
  1156. bne     1b
  1157. sync /* additional sync needed on g4 */
  1158. isync /* No speculative loading until now */
  1159. blr
  1160. /***********************************************************************
  1161.  *  Please note that on APUS the exception handlers are located at the
  1162.  *  physical address 0xfff0000. For this reason, the exception handlers
  1163.  *  cannot use relative branches to access the code below.
  1164.  ***********************************************************************/
  1165. #endif /* CONFIG_APUS */
  1166. #ifdef CONFIG_SMP
  1167. #ifdef CONFIG_GEMINI
  1168. .globl __secondary_start_gemini
  1169. __secondary_start_gemini:
  1170.         mfspr   r4,HID0
  1171.         ori     r4,r4,HID0_ICFI
  1172.         li      r3,0
  1173.         ori     r3,r3,HID0_ICE
  1174.         andc    r4,r4,r3
  1175.         mtspr   HID0,r4
  1176.         sync
  1177.         bl      prom_init
  1178.         b       __secondary_start
  1179. #endif /* CONFIG_GEMINI */
  1180. .globl __secondary_start_psurge
  1181. __secondary_start_psurge:
  1182. li r24,1 /* cpu # */
  1183. b __secondary_start_psurge99
  1184. .globl __secondary_start_psurge2
  1185. __secondary_start_psurge2:
  1186. li r24,2 /* cpu # */
  1187. b __secondary_start_psurge99
  1188. .globl __secondary_start_psurge3
  1189. __secondary_start_psurge3:
  1190. li r24,3 /* cpu # */
  1191. b __secondary_start_psurge99
  1192. __secondary_start_psurge99:
  1193. /* we come in here with IR=0 and DR=1, and DBAT 0
  1194.    set to map the 0xf0000000 - 0xffffffff region */
  1195. mfmsr r0
  1196. rlwinm r0,r0,0,28,26 /* clear DR (0x10) */
  1197. SYNC
  1198. mtmsr r0
  1199. isync
  1200. .globl __secondary_start
  1201. __secondary_start:
  1202. #ifdef CONFIG_PPC64BRIDGE
  1203. mfmsr r0
  1204. clrldi r0,r0,1 /* make sure it's in 32-bit mode */
  1205. SYNC
  1206. MTMSRD(r0)
  1207. isync
  1208. #endif
  1209. lis r3,-KERNELBASE@h
  1210. mr r4,r24
  1211. bl identify_cpu
  1212. bl call_setup_cpu /* Call setup_cpu for this CPU */
  1213. #ifdef CONFIG_6xx
  1214. lis r3,-KERNELBASE@h
  1215. bl init_idle_6xx
  1216. #endif /* CONFIG_6xx */
  1217. /* get current */
  1218. lis r2,current_set@h
  1219. ori r2,r2,current_set@l
  1220. tophys(r2,r2)
  1221. slwi r24,r24,2 /* get current_set[cpu#] */
  1222. lwzx r2,r2,r24
  1223. /* stack */
  1224. addi r1,r2,TASK_UNION_SIZE-STACK_FRAME_OVERHEAD
  1225. li r0,0
  1226. tophys(r3,r1)
  1227. stw r0,0(r3)
  1228. /* load up the MMU */
  1229. bl load_up_mmu
  1230. /* ptr to phys current thread */
  1231. tophys(r4,r2)
  1232. addi r4,r4,THREAD /* phys address of our thread_struct */
  1233. CLR_TOP32(r4)
  1234. mtspr SPRG3,r4
  1235. li r3,0
  1236. mtspr SPRG2,r3 /* 0 => r1 has kernel sp */
  1237. stw r3,PT_REGS(r4) /* set thread.regs to 0 for kernel thread */
  1238. /* enable MMU and jump to start_secondary */
  1239. li r4,MSR_KERNEL
  1240. lis r3,start_secondary@h
  1241. ori r3,r3,start_secondary@l
  1242. mtspr SRR0,r3
  1243. mtspr SRR1,r4
  1244. SYNC
  1245. RFI
  1246. #endif /* CONFIG_SMP */
  1247. /*
  1248.  * Enable caches and 604-specific features if necessary.
  1249.  */
  1250. _GLOBAL(__setup_cpu_601)
  1251. blr
  1252. _GLOBAL(__setup_cpu_603)
  1253. b setup_common_caches
  1254. _GLOBAL(__setup_cpu_604)
  1255. mflr r4
  1256. bl setup_common_caches
  1257. bl setup_604_hid0
  1258. mtlr r4
  1259. blr
  1260. _GLOBAL(__setup_cpu_750)
  1261. mflr r4
  1262. bl setup_common_caches
  1263. bl setup_750_7400_hid0
  1264. mtlr r4
  1265. blr
  1266. _GLOBAL(__setup_cpu_750cx)
  1267. mflr r4
  1268. bl setup_common_caches
  1269. bl setup_750_7400_hid0
  1270. bl setup_750cx
  1271. mtlr r4
  1272. blr
  1273. _GLOBAL(__setup_cpu_750fx)
  1274. mflr r4
  1275. bl setup_common_caches
  1276. bl setup_750_7400_hid0
  1277. bl setup_750fx
  1278. mtlr r4
  1279. blr
  1280. _GLOBAL(__setup_cpu_7400)
  1281. mflr r4
  1282. bl setup_common_caches
  1283. bl setup_750_7400_hid0
  1284. mtlr r4
  1285. blr
  1286. _GLOBAL(__setup_cpu_7410)
  1287. mflr r4
  1288. bl setup_common_caches
  1289. bl setup_750_7400_hid0
  1290. li r3,0
  1291. mtspr SPRN_L2CR2,r3
  1292. mtlr r4
  1293. blr
  1294. _GLOBAL(__setup_cpu_7450)
  1295. mflr r4
  1296. bl setup_common_caches
  1297. bl setup_745x_specifics
  1298. mtlr r4
  1299. blr
  1300. _GLOBAL(__setup_cpu_7455)
  1301. mflr r4
  1302. bl setup_common_caches
  1303. bl setup_745x_specifics
  1304. mtlr r4
  1305. blr
  1306. _GLOBAL(__setup_cpu_power3)
  1307. blr
  1308. _GLOBAL(__setup_cpu_power4)
  1309. blr
  1310. _GLOBAL(__setup_cpu_generic)
  1311. blr
  1312. /* Enable caches for 603's, 604, 750 & 7400 */
  1313. setup_common_caches:
  1314. mfspr r11,HID0
  1315. andi. r0,r11,HID0_DCE
  1316. #ifdef CONFIG_DCACHE_DISABLE
  1317. ori r11,r11,HID0_ICE
  1318. #else
  1319. ori r11,r11,HID0_ICE|HID0_DCE
  1320. #endif
  1321. ori r8,r11,HID0_ICFI
  1322. bne 1f /* don't invalidate the D-cache */
  1323. ori r8,r8,HID0_DCI /* unless it wasn't enabled */
  1324. 1: sync
  1325. mtspr HID0,r8 /* enable and invalidate caches */
  1326. sync
  1327. mtspr HID0,r11 /* enable caches */
  1328. sync
  1329. isync
  1330. blr
  1331. /* 604, 604e, 604ev, ...
  1332.  * Enable superscalar execution & branch history table
  1333.  */
  1334. setup_604_hid0:
  1335. mfspr r11,HID0
  1336. ori r11,r11,HID0_SIED|HID0_BHTE
  1337. ori r8,r11,HID0_BTCD
  1338. sync
  1339. mtspr HID0,r8 /* flush branch target address cache */
  1340. sync /* on 604e/604r */
  1341. mtspr HID0,r11
  1342. sync
  1343. isync
  1344. blr
  1345. /* 740/750/7400/7410
  1346.  * Enable Store Gathering (SGE), Address Brodcast (ABE),
  1347.  * Branch History Table (BHTE), Branch Target ICache (BTIC)
  1348.  * Dynamic Power Management (DPM), Speculative (SPD)
  1349.  * Clear Instruction cache throttling (ICTC)
  1350.  */
  1351. setup_750_7400_hid0:
  1352. mfspr r11,HID0
  1353. ori r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC
  1354. oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */
  1355. li r3,HID0_SPD
  1356. andc r11,r11,r3 /* clear SPD: enable speculative */
  1357.   li r3,0
  1358.   mtspr ICTC,r3 /* Instruction Cache Throttling off */
  1359. isync
  1360. mtspr HID0,r11
  1361. sync
  1362. isync
  1363. blr
  1364. /* 750cx specific
  1365.  * Looks like we have to disable NAP feature for some PLL settings...
  1366.  * (waiting for confirmation)
  1367.  */
  1368. setup_750cx:
  1369. blr
  1370. /* 750fx specific
  1371.  */
  1372. setup_750fx:
  1373. blr
  1374. /* MPC 745x
  1375.  * Enable Store Gathering (SGE), Branch Folding (FOLD)
  1376.  * Branch History Table (BHTE), Branch Target ICache (BTIC)
  1377.  * Dynamic Power Management (DPM), Speculative (SPD)
  1378.  * Ensure our data cache instructions really operate.
  1379.  * Timebase has to be running or we wouldn't have made it here,
  1380.  * just ensure we don't disable it.
  1381.  * Clear Instruction cache throttling (ICTC)
  1382.  * Enable L2 HW prefetch
  1383.  */
  1384. setup_745x_specifics:
  1385. /* We check for the presence of an L3 cache setup by
  1386.  * the firmware. If any, we disable NAP capability as
  1387.  * it's known to be bogus on rev 2.1 and earlier
  1388.  */
  1389. mfspr r11,SPRN_L3CR
  1390. andis. r11,r11,L3CR_L3E@h
  1391. beq 1f
  1392. lwz r6,CPU_SPEC_FEATURES(r5)
  1393. andi. r0,r6,CPU_FTR_L3_DISABLE_NAP
  1394. beq 1f
  1395. li r7,CPU_FTR_CAN_NAP
  1396. andc r6,r6,r7
  1397. stw r6,CPU_SPEC_FEATURES(r5)
  1398. 1:
  1399. mfspr r11,HID0
  1400. /* All of the bits we have to set.....
  1401.  */
  1402. ori r11,r11,HID0_SGE | HID0_FOLD | HID0_BHTE | HID0_BTIC | HID0_LRSTK
  1403. oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */
  1404. /* All of the bits we have to clear....
  1405.  */
  1406. li r3,HID0_SPD | HID0_NOPDST | HID0_NOPTI
  1407. andc r11,r11,r3 /* clear SPD: enable speculative */
  1408.   li r3,0
  1409.   mtspr ICTC,r3 /* Instruction Cache Throttling off */
  1410. isync
  1411. mtspr HID0,r11
  1412. sync
  1413. isync
  1414. /* Enable L2 HW prefetch
  1415.  */
  1416. mfspr r3,SPRN_MSSCR0
  1417. ori r3,r3,3
  1418. sync
  1419. mtspr SPRN_MSSCR0,r3
  1420. sync
  1421. isync
  1422. blr
  1423. /*
  1424.  * Load stuff into the MMU.  Intended to be called with
  1425.  * IR=0 and DR=0.
  1426.  */
  1427. load_up_mmu:
  1428. /* Load the SDR1 register (hash table base & size) */
  1429. lis r6,_SDR1@ha
  1430. tophys(r6,r6)
  1431. lwz r6,_SDR1@l(r6)
  1432. mtspr SDR1,r6
  1433. #ifdef CONFIG_PPC64BRIDGE
  1434. /* clear the ASR so we only use the pseudo-segment registers. */
  1435. li r6,0
  1436. mtasr r6
  1437. #endif /* CONFIG_PPC64BRIDGE */
  1438. li r0,16 /* load up segment register values */
  1439. mtctr r0 /* for context 0 */
  1440. lis r3,0x2000 /* Ku = 1, VSID = 0 */
  1441. li r4,0
  1442. 3: mtsrin r3,r4
  1443. addi r3,r3,0x111 /* increment VSID */
  1444. addis r4,r4,0x1000 /* address of next segment */
  1445. bdnz 3b
  1446. #ifndef CONFIG_POWER4
  1447. /* Load the BAT registers with the values set up by MMU_init.
  1448.    MMU_init takes care of whether we're on a 601 or not. */
  1449. mfpvr r3
  1450. srwi r3,r3,16
  1451. cmpwi r3,1
  1452. lis r3,BATS@ha
  1453. addi r3,r3,BATS@l
  1454. tophys(r3,r3)
  1455. LOAD_BAT(0,r3,r4,r5)
  1456. LOAD_BAT(1,r3,r4,r5)
  1457. LOAD_BAT(2,r3,r4,r5)
  1458. LOAD_BAT(3,r3,r4,r5)
  1459. #endif /* CONFIG_POWER4 */
  1460. blr
  1461. /*
  1462.  * This is where the main kernel code starts.
  1463.  */
  1464. start_here:
  1465. /* ptr to current */
  1466. lis r2,init_task_union@h
  1467. ori r2,r2,init_task_union@l
  1468. /* Set up for using our exception vectors */
  1469. /* ptr to phys current thread */
  1470. tophys(r4,r2)
  1471. addi r4,r4,THREAD /* init task's THREAD */
  1472. CLR_TOP32(r4)
  1473. mtspr SPRG3,r4
  1474. li r3,0
  1475. mtspr SPRG2,r3 /* 0 => r1 has kernel sp */
  1476. /* stack */
  1477. addi r1,r2,TASK_UNION_SIZE
  1478. li r0,0
  1479. stwu r0,-STACK_FRAME_OVERHEAD(r1)
  1480. /*
  1481.  * Do early bootinfo parsing, platform-specific initialization,
  1482.  * and set up the MMU.
  1483.  */
  1484. mr r3,r31
  1485. mr r4,r30
  1486. mr r5,r29
  1487. mr r6,r28
  1488. mr r7,r27
  1489. bl machine_init
  1490. bl MMU_init
  1491. #ifdef CONFIG_APUS
  1492. /* Copy exception code to exception vector base on APUS. */
  1493. lis r4,KERNELBASE@h
  1494. #ifdef CONFIG_APUS_FAST_EXCEPT
  1495. lis r3,0xfff0 /* Copy to 0xfff00000 */
  1496. #else
  1497. lis r3,0 /* Copy to 0x00000000 */
  1498. #endif
  1499. li r5,0x4000 /* # bytes of memory to copy */
  1500. li r6,0
  1501. bl copy_and_flush /* copy the first 0x4000 bytes */
  1502. #endif  /* CONFIG_APUS */
  1503. /*
  1504.  * Go back to running unmapped so we can load up new values
  1505.  * for SDR1 (hash table pointer) and the segment registers
  1506.  * and change to using our exception vectors.
  1507.  */
  1508. lis r4,2f@h
  1509. ori r4,r4,2f@l
  1510. tophys(r4,r4)
  1511. li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
  1512. FIX_SRR1(r3,r5)
  1513. mtspr SRR0,r4
  1514. mtspr SRR1,r3
  1515. SYNC
  1516. RFI
  1517. /* Load up the kernel context */
  1518. 2:
  1519. sync /* Force all PTE updates to finish */
  1520. isync
  1521. tlbia /* Clear all TLB entries */
  1522. sync /* wait for tlbia/tlbie to finish */
  1523. TLBSYNC /* ... on all CPUs */
  1524. bl load_up_mmu
  1525. #ifdef CONFIG_BDI_SWITCH
  1526. /* Add helper information for the Abatron bdiGDB debugger.
  1527.  * We do this here because we know the mmu is disabled, and
  1528.  * will be enabled for real in just a few instructions.
  1529.  */
  1530. lis r5, abatron_pteptrs@h
  1531. ori r5, r5, abatron_pteptrs@l
  1532. stw r5, 0xf0(r0) /* This much match your Abatron config */
  1533. lis r6, swapper_pg_dir@h
  1534. ori r6, r6, swapper_pg_dir@l
  1535. tophys(r5, r5)
  1536. stw r6, 0(r5)
  1537. #endif
  1538. /* Now turn on the MMU for real! */
  1539. li r4,MSR_KERNEL
  1540. FIX_SRR1(r4,r5)
  1541. lis r3,start_kernel@h
  1542. ori r3,r3,start_kernel@l
  1543. mtspr SRR0,r3
  1544. mtspr SRR1,r4
  1545. SYNC
  1546. RFI
  1547. /*
  1548.  * Set up the segment registers for a new context.
  1549.  */
  1550. _GLOBAL(set_context)
  1551. mulli r3,r3,897 /* multiply context by skew factor */
  1552. rlwinm r3,r3,4,8,27 /* VSID = (context & 0xfffff) << 4 */
  1553. addis r3,r3,0x6000 /* Set Ks, Ku bits */
  1554. li r0,NUM_USER_SEGMENTS
  1555. mtctr r0
  1556. #ifdef CONFIG_BDI_SWITCH
  1557. /* Context switch the PTE pointer for the Abatron BDI2000.
  1558.  * The PGDIR is passed as second argument.
  1559.  */
  1560. lis r5, KERNELBASE@h
  1561. lwz r5, 0xf0(r5)
  1562. stw r4, 0x4(r5)
  1563. #endif
  1564. li r4,0
  1565. BEGIN_FTR_SECTION
  1566. DSSALL
  1567. sync
  1568. END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
  1569. 3: isync
  1570. #ifdef CONFIG_PPC64BRIDGE
  1571. slbie r4
  1572. #endif /* CONFIG_PPC64BRIDGE */
  1573. mtsrin r3,r4
  1574. addi r3,r3,0x111 /* next VSID */
  1575. rlwinm r3,r3,0,8,3 /* clear out any overflow from VSID field */
  1576. addis r4,r4,0x1000 /* address of next segment */
  1577. bdnz 3b
  1578. sync
  1579. isync
  1580. blr
  1581. /* 
  1582.  * An undocumented "feature" of 604e requires that the v bit
  1583.  * be cleared before changing BAT values.
  1584.  *
  1585.  * Also, newer IBM firmware does not clear bat3 and 4 so
  1586.  * this makes sure it's done.
  1587.  *  -- Cort 
  1588.  */
  1589. clear_bats:
  1590. #if !defined(CONFIG_GEMINI)
  1591. li r20,0
  1592. mfspr r9,PVR
  1593. rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
  1594. cmpwi r9, 1
  1595. beq 1f
  1596. mtspr DBAT0U,r20
  1597. mtspr DBAT0L,r20
  1598. mtspr DBAT1U,r20
  1599. mtspr DBAT1L,r20
  1600. mtspr DBAT2U,r20
  1601. mtspr DBAT2L,r20
  1602. mtspr DBAT3U,r20
  1603. mtspr DBAT3L,r20
  1604. 1:
  1605. mtspr IBAT0U,r20
  1606. mtspr IBAT0L,r20
  1607. mtspr IBAT1U,r20
  1608. mtspr IBAT1L,r20
  1609. mtspr IBAT2U,r20
  1610. mtspr IBAT2L,r20
  1611. mtspr IBAT3U,r20
  1612. mtspr IBAT3L,r20
  1613. #endif /* !defined(CONFIG_GEMINI) */
  1614. blr
  1615. #ifndef CONFIG_GEMINI
  1616. flush_tlbs:
  1617. lis r20, 0x40
  1618. 1: addic. r20, r20, -0x1000
  1619. tlbie r20
  1620. blt 1b
  1621. sync
  1622. blr
  1623. mmu_off:
  1624.   addi r4, r3, __after_mmu_off - _start
  1625. mfmsr r3
  1626. andi. r0,r3,MSR_DR|MSR_IR /* MMU enabled? */
  1627. beqlr
  1628. andc r3,r3,r0
  1629. mtspr SRR0,r4
  1630. mtspr SRR1,r3
  1631. sync
  1632. RFI
  1633. #endif
  1634. #ifndef CONFIG_POWER4
  1635. /*
  1636.  * Use the first pair of BAT registers to map the 1st 16MB
  1637.  * of RAM to KERNELBASE.  From this point on we can't safely
  1638.  * call OF any more.
  1639.  */
  1640. initial_bats:
  1641. lis r11,KERNELBASE@h
  1642. #ifndef CONFIG_PPC64BRIDGE
  1643. mfspr r9,PVR
  1644. rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
  1645. cmpi 0,r9,1
  1646. bne 4f
  1647. ori r11,r11,4 /* set up BAT registers for 601 */
  1648. li r8,0x7f /* valid, block length = 8MB */
  1649. oris r9,r11,0x800000@h /* set up BAT reg for 2nd 8M */
  1650. oris r10,r8,0x800000@h /* set up BAT reg for 2nd 8M */
  1651. mtspr IBAT0U,r11 /* N.B. 601 has valid bit in */
  1652. mtspr IBAT0L,r8 /* lower BAT register */
  1653. mtspr IBAT1U,r9
  1654. mtspr IBAT1L,r10
  1655. isync
  1656. blr
  1657. #endif /* CONFIG_PPC64BRIDGE */
  1658. 4: tophys(r8,r11)
  1659. #ifdef CONFIG_SMP
  1660. ori r8,r8,0x12 /* R/W access, M=1 */
  1661. #else
  1662. ori r8,r8,2 /* R/W access */
  1663. #endif /* CONFIG_SMP */
  1664. #ifdef CONFIG_APUS
  1665. ori r11,r11,BL_8M<<2|0x2 /* set up 8MB BAT registers for 604 */
  1666. #else
  1667. ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */
  1668. #endif /* CONFIG_APUS */
  1669. #ifdef CONFIG_PPC64BRIDGE
  1670. /* clear out the high 32 bits in the BAT */
  1671. clrldi r11,r11,32
  1672. clrldi r8,r8,32
  1673. #endif /* CONFIG_PPC64BRIDGE */
  1674. mtspr DBAT0L,r8 /* N.B. 6xx (not 601) have valid */
  1675. mtspr DBAT0U,r11 /* bit in upper BAT register */
  1676. mtspr IBAT0L,r8
  1677. mtspr IBAT0U,r11
  1678. isync
  1679. blr
  1680. #if !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT)
  1681. setup_disp_bat:
  1682. /*
  1683.  * setup the display bat prepared for us in prom.c
  1684.  */
  1685. mflr r8
  1686. bl reloc_offset
  1687. mtlr r8
  1688. addis r8,r3,disp_BAT@ha
  1689. addi r8,r8,disp_BAT@l
  1690. lwz r11,0(r8)
  1691. lwz r8,4(r8)
  1692. mfspr r9,PVR
  1693. rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
  1694. cmpi 0,r9,1
  1695. beq 1f
  1696. mtspr DBAT3L,r8
  1697. mtspr DBAT3U,r11
  1698. blr
  1699. 1: mtspr IBAT3L,r8
  1700. mtspr IBAT3U,r11
  1701. blr
  1702. #endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */
  1703. #endif /* CONFIG_POWER4 */
  1704. #ifdef CONFIG_8260
  1705. /* Jump into the system reset for the rom.
  1706.  * We first disable the MMU, and then jump to the ROM reset address.
  1707.  *
  1708.  * r3 is the board info structure, r4 is the location for starting.
  1709.  * I use this for building a small kernel that can load other kernels,
  1710.  * rather than trying to write or rely on a rom monitor that can tftp load.
  1711.  */
  1712.        .globl  m8260_gorom
  1713. m8260_gorom:
  1714. mfmsr r0
  1715. rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */
  1716. sync
  1717. mtmsr r0
  1718. sync
  1719. mfspr r11, HID0
  1720. lis r10, 0
  1721. ori r10,r10,HID0_ICE|HID0_DCE
  1722. andc r11, r11, r10
  1723. mtspr HID0, r11
  1724. isync
  1725. li r5, MSR_
  1726. lis r6,2f@h
  1727. addis r6,r6,-KERNELBASE@h
  1728. ori r6,r6,2f@l
  1729. mtspr SRR0,r6
  1730. mtspr SRR1,r5
  1731. isync
  1732. sync
  1733. rfi
  1734. 2:
  1735. mtlr r4
  1736. blr
  1737. #endif
  1738. /*
  1739.  * We put a few things here that have to be page-aligned.
  1740.  * This stuff goes at the beginning of the data segment,
  1741.  * which is page-aligned.
  1742.  */
  1743. .data
  1744. .globl sdata
  1745. sdata:
  1746. .globl empty_zero_page
  1747. empty_zero_page:
  1748. .space 4096
  1749. .globl swapper_pg_dir
  1750. swapper_pg_dir:
  1751. .space 4096
  1752. /*
  1753.  * This space gets a copy of optional info passed to us by the bootstrap
  1754.  * Used to pass parameters into the kernel like root=/dev/sda1, etc.
  1755.  */
  1756. .globl cmd_line
  1757. cmd_line:
  1758. .space 512
  1759. .globl intercept_table
  1760. intercept_table:
  1761. .long 0, 0, i0x200, i0x300, i0x400, 0, i0x600, i0x700
  1762. .long i0x800, 0, 0, 0, 0, i0xd00, 0, 0
  1763. .long 0, 0, 0, i0x1300, 0, 0, 0, 0
  1764. .long 0, 0, 0, 0, 0, 0, 0, 0
  1765. .long 0, 0, 0, 0, 0, 0, 0, 0
  1766. .long 0, 0, 0, 0, 0, 0, 0, 0
  1767. #ifdef CONFIG_BDI_SWITCH
  1768. /* Room for two PTE pointers, usually the kernel and current user pointers
  1769.  * to their respective root page table.
  1770.  */
  1771. abatron_pteptrs:
  1772. .space 8
  1773. #endif