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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  arch/ppc64/kernel/head.S
  3.  *
  4.  *  PowerPC version
  5.  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  6.  *
  7.  *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
  8.  *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
  9.  *  Adapted for Power Macintosh by Paul Mackerras.
  10.  *  Low-level exception handlers and MMU support
  11.  *  rewritten by Paul Mackerras.
  12.  *    Copyright (C) 1996 Paul Mackerras.
  13.  *
  14.  *  Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and
  15.  *    Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com
  16.  *
  17.  *  This file contains the low-level support and setup for the
  18.  *  PowerPC-64 platform, including trap and interrupt dispatch.
  19.  *
  20.  *  This program is free software; you can redistribute it and/or
  21.  *  modify it under the terms of the GNU General Public License
  22.  *  as published by the Free Software Foundation; either version
  23.  *  2 of the License, or (at your option) any later version.
  24.  */
  25. #define SECONDARY_PROCESSORS
  26. #include "ppc_asm.h"
  27. #include "ppc_defs.h"
  28. #include <asm/processor.h>
  29. #include <asm/page.h>
  30. #include <linux/config.h>
  31. #include <asm/mmu.h>
  32. #include <asm/perfmon.h>
  33. #ifdef CONFIG_PPC_ISERIES
  34. #define DO_SOFT_DISABLE
  35. #endif
  36. /*
  37.  * hcall interface to pSeries LPAR
  38.  */
  39. #define HSC .long 0x44000022
  40. #define H_SET_ASR 0x30
  41. /*
  42.  * We layout physical memory as follows:
  43.  * 0x0000 - 0x00ff : Secondary processor spin code
  44.  * 0x0100 - 0x2fff : pSeries Interrupt prologs
  45.  * 0x3000 - 0x3fff : Interrupt support
  46.  * 0x4000 - 0x4fff : NACA
  47.  * 0x5000 - 0x5fff : Initial segment table
  48.  * 0x6000          : iSeries and common interrupt prologs
  49.  */
  50. /*
  51.  *   SPRG Usage
  52.  *
  53.  *   Register          Definition
  54.  *
  55.  *   SPRG0             reserved for hypervisor
  56.  *   SPRG1             temp - used to save gpr
  57.  *   SPRG2             temp - used to save gpr
  58.  *   SPRG3             virt addr of paca
  59.  */
  60. /*
  61.  * Entering into this code we make the following assumptions:
  62.  *  For pSeries:
  63.  *   1. The MMU is off & open firmware is running in real mode.
  64.  *   2. The kernel is entered at __start
  65.  *
  66.  *  For iSeries:
  67.  *   1. The MMU is on (as it always is for iSeries)
  68.  *   2. The kernel is entered at SystemReset_Iseries
  69.  */
  70. .text
  71. .globl  _stext
  72. _stext:
  73. _STATIC(__start)
  74. b .__start_initialization_pSeries
  75. /* At offset 0x20, there is a pointer to iSeries LPAR data.
  76.  * This is required by the hypervisor */
  77. . = 0x20
  78. .llong hvReleaseData-KERNELBASE
  79. /* At offset 0x28 and 0x30 are offsets to the msChunks
  80.  * array (used by the iSeries LPAR debugger to do translation
  81.  * between physical addresses and absolute addresses) and
  82.  * to the pidhash table (also used by the debugger) */
  83. .llong msChunks-KERNELBASE
  84. .llong pidhash-KERNELBASE
  85. /* Offset 0x38 - Pointer to start of embedded System.map */
  86. .globl embedded_sysmap_start
  87. embedded_sysmap_start:
  88. .llong 0
  89. /* Offset 0x40 - Pointer to end of embedded System.map */
  90. .globl embedded_sysmap_end
  91. embedded_sysmap_end:
  92. .llong 0
  93. /* Secondary processors spin on this value until it goes to 1. */
  94. .globl  __secondary_hold_spinloop
  95. __secondary_hold_spinloop:
  96. .llong  0x0
  97. /* Secondary processors write this value with their cpu # */
  98. /* after they enter the spin loop immediatly below.       */
  99. .globl  __secondary_hold_acknowledge
  100. __secondary_hold_acknowledge:
  101. .llong  0x0
  102. . = 0x60
  103. /*
  104.  * The following code is used on pSeries to hold secondary processors
  105.  * in a spin loop after they have been freed from OpenFirmware, but
  106.  * before the bulk of the kernel has been relocated.  This code
  107.  * is relocated to physical address 0x60 before prom_init is run.
  108.  * All of it must fit below the first exception vector at 0x100.
  109.  */
  110. _GLOBAL(__secondary_hold)
  111. /* Grab our linux cpu number */
  112. mr      r24,r3
  113. /* Tell the master cpu we're here */
  114. /* Relocation is off & we are located at an address less */
  115. /* than 0x100, so only need to grab low order offset.    */
  116. std     r24,__secondary_hold_acknowledge@l(0)
  117. /* All secondary cpu's wait here until told to start. */
  118. 100:    ld      r4,__secondary_hold_spinloop@l(0)
  119. cmpdi   0,r4,1
  120. bne     100b
  121. #ifdef CONFIG_HMT
  122. b .hmt_init
  123. #else
  124. #ifdef CONFIG_SMP
  125. mr      r3,r24
  126. b       .pseries_secondary_smp_init
  127. #else
  128. BUG_OPCODE
  129. #endif
  130. #endif
  131. /*
  132.  * The following macros define the code that appears as
  133.  * the prologue to each of the exception handlers.  They
  134.  * are split into two parts to allow a single kernel binary
  135.  * to be used for pSeries, and iSeries.
  136.  */
  137. /*
  138.  * We make as much of the exception code common between native
  139.  * exception handlers (including pSeries LPAR) and iSeries LPAR
  140.  * implementations as possible.
  141.  */
  142. /*
  143.  * This is the start of the interrupt handlers for pSeries
  144.  * This code runs with relocation off.
  145.  */
  146. #define EX_SRR0 0
  147. #define EX_SRR1 8
  148. #define EX_R20 16
  149. #define EX_R21 24
  150. #define EX_R22 32
  151. #define EX_R23 40
  152. #define EX_DAR 48
  153. #define EX_DSISR 56
  154. #define EX_CCR    60
  155. #define EX_TRAP    60
  156. #define EXCEPTION_PROLOG_PSERIES(n,label)                                
  157. mtspr   SPRG2,r20;              /* use SPRG2 as scratch reg   */ 
  158. mtspr   SPRG1,r21;              /* save r21                   */ 
  159. mfspr   r20,SPRG3;              /* get paca virt addr         */ 
  160. ld      r21,PACAEXCSP(r20);     /* get exception stack ptr    */ 
  161. addi    r21,r21,EXC_FRAME_SIZE; /* make exception frame       */ 
  162. std r22,EX_R22(r21); /* Save r22 in exc. frame     */ 
  163. li r22,n;                  /* Save the ex # in exc. frame*/ 
  164. stw r22,EX_TRAP(r21); /*                            */ 
  165. std r23,EX_R23(r21); /* Save r23 in exc. frame     */ 
  166. mfspr   r22,SRR0;               /* EA of interrupted instr    */ 
  167. std r22,EX_SRR0(r21); /* Save SRR0 in exc. frame    */ 
  168. mfspr   r23,SRR1;               /* machine state at interrupt */ 
  169. std r23,EX_SRR1(r21); /* Save SRR1 in exc. frame    */ 
  170. clrrdi  r22,r20,60;             /* Get 0xc part of the vaddr  */ 
  171. ori r22,r22,(label)@l;      /* add in the vaddr offset    */ 
  172.                         /*   assumes *_common < 16b   */ 
  173. mfmsr   r23;                                                     
  174. rotldi  r23,r23,4;                                               
  175. ori     r23,r23,0x30B;          /* Set IR, DR, SF, ISF, HV    */ 
  176. rotldi  r23,r23,60;             /* for generic handlers       */ 
  177. mtspr   SRR0,r22;                                                
  178. mtspr   SRR1,r23;                                                
  179. mfcr    r23;                    /* save CR in r23             */ 
  180. rfid
  181. /*
  182.  * This is the start of the interrupt handlers for iSeries
  183.  * This code runs with relocation on.
  184.  */
  185. #define EXCEPTION_PROLOG_ISERIES(n)                                       
  186. mtspr SPRG2,r20;     /* use SPRG2 as scratch reg    */ 
  187. mtspr   SPRG1,r21;                  /* save r21                    */ 
  188. mfspr r20,SPRG3;     /* get paca                    */ 
  189. ld      r21,PACAEXCSP(r20);         /* get exception stack ptr     */ 
  190. addi    r21,r21,EXC_FRAME_SIZE;     /* make exception frame        */ 
  191. std r22,EX_R22(r21);     /* save r22 on exception frame */ 
  192. li r22,n;                      /* Save the ex # in exc. frame */ 
  193. stw r22,EX_TRAP(r21);     /*                             */ 
  194. std r23,EX_R23(r21);     /* Save r23 in exc. frame      */ 
  195. ld      r22,LPPACA+LPPACASRR0(r20); /* Get SRR0 from ItLpPaca      */ 
  196. std r22,EX_SRR0(r21);     /* save SRR0 in exc. frame     */ 
  197. ld      r23,LPPACA+LPPACASRR1(r20); /* Get SRR1 from ItLpPaca      */ 
  198. std r23,EX_SRR1(r21);     /* save SRR1 in exc. frame     */ 
  199. mfcr    r23;                        /* save CR in r23              */
  200. /*
  201.  * The common exception prolog is used for all except a few exceptions
  202.  * such as a segment miss on a kernel address.  We have to be prepared
  203.  * to take another exception from the point where we first touch the
  204.  * kernel stack onwards.
  205.  *
  206.  * On entry r20 points to the paca and r21 points to the exception
  207.  * frame on entry, r23 contains the saved CR, and relocation is on.
  208.  */
  209. #define EXCEPTION_PROLOG_COMMON                                           
  210. mfspr r22,SPRG2; /* Save r20 in exc. frame      */ 
  211. std r22,EX_R20(r21);                                   
  212. mfspr r22,SPRG1; /* Save r21 in exc. frame      */ 
  213. std r22,EX_R21(r21);                                   
  214. mfspr   r22,DAR;                /* Save DAR in exc. frame      */ 
  215. std r22,EX_DAR(r21);                                   
  216. std     r21,PACAEXCSP(r20);     /* update exception stack ptr  */ 
  217.                         /*   iff no protection flt     */ 
  218. mfspr r22,DSISR; /* Save DSISR in exc. frame    */ 
  219. stw r22,EX_DSISR(r21);                                   
  220. ld r22,EX_SRR1(r21); /* Get SRR1 from exc. frame    */ 
  221. andi.   r22,r22,MSR_PR;         /* Set CR for later branch     */ 
  222. mr      r22,r1;                 /* Save r1                     */ 
  223. subi    r1,r1,INT_FRAME_SIZE;   /* alloc frame on kernel stack */ 
  224. beq-    1f;                                                       
  225. ld      r1,PACAKSAVE(r20);      /* kernel stack to use         */ 
  226. 1:      std     r22,GPR1(r1);           /* save r1 in stackframe       */ 
  227. std     r22,0(r1);              /* make stack chain pointer    */ 
  228. std     r23,_CCR(r1);           /* save CR in stackframe       */ 
  229. ld r22,EX_R20(r21); /* move r20 to stackframe      */ 
  230. std r22,GPR20(r1);                                   
  231. ld r23,EX_R21(r21); /* move r21 to stackframe      */ 
  232. std r23,GPR21(r1);                                   
  233. ld r22,EX_R22(r21); /* move r22 to stackframe      */ 
  234. std r22,GPR22(r1);                                   
  235. ld r23,EX_R23(r21); /* move r23 to stackframe      */ 
  236. std r23,GPR23(r1);                                   
  237. mflr    r22;                    /* save LR in stackframe       */ 
  238. std     r22,_LINK(r1);                                            
  239. mfctr   r23;                    /* save CTR in stackframe      */ 
  240. std     r23,_CTR(r1);                                             
  241. mfspr   r22,XER;                /* save XER in stackframe      */ 
  242. std     r22,_XER(r1);                                             
  243. ld r23,EX_DAR(r21); /* move DAR to stackframe      */ 
  244. std r23,_DAR(r1);                                   
  245. lwz     r22,EX_DSISR(r21); /* move DSISR to stackframe    */ 
  246. std r22,_DSISR(r1);                                   
  247. lbz r22,PACAPROCENABLED(r20);                                 
  248. std r22,SOFTE(r1);                                   
  249. ld r22,EX_SRR0(r21); /* get SRR0 from exc. frame    */ 
  250. ld r23,EX_SRR1(r21); /* get SRR1 from exc. frame    */ 
  251. addi    r21,r21,-EXC_FRAME_SIZE;/* pop off exception frame     */ 
  252. std     r21,PACAEXCSP(r20);                                       
  253. SAVE_GPR(0, r1);                /* save r0 in stackframe       */ 
  254. SAVE_8GPRS(2, r1);              /* save r2 - r13 in stackframe */ 
  255. SAVE_4GPRS(10, r1);                                               
  256. ld      r2,PACATOC(r20);                                   
  257. ld      r13,PACACURRENT(r20)
  258. /*
  259.  * Note: code which follows this uses cr0.eq (set if from kernel),
  260.  * r1, r22 (SRR0), and r23 (SRR1).
  261.  */
  262. /*
  263.  * Exception vectors.
  264.  */
  265. #define STD_EXCEPTION_PSERIES(n, label )
  266. . = n;
  267. .globl label##_Pseries;
  268. label##_Pseries:
  269. EXCEPTION_PROLOG_PSERIES( n, label##_common )
  270. #define STD_EXCEPTION_ISERIES( n, label )
  271. .globl label##_Iseries;
  272. label##_Iseries:
  273. EXCEPTION_PROLOG_ISERIES( n );          
  274. b label##_common
  275. #define MASKABLE_EXCEPTION_ISERIES( n, label )
  276. .globl label##_Iseries;
  277. label##_Iseries:
  278. EXCEPTION_PROLOG_ISERIES( n );
  279. lbz r22,PACAPROFMODE(r20);
  280. cmpi 0,r22,PMC_STATE_DECR_PROFILE;
  281. beq- label##_Iseries_profile;
  282. label##_Iseries_prof_ret:
  283. lbz r22,PACAPROCENABLED(r20);
  284. cmpi 0,r22,0;
  285. beq- label##_Iseries_masked;
  286. b label##_common;
  287. label##_Iseries_profile:
  288. std r24,48(r21);
  289. std r25,56(r21);
  290. mflr r24;
  291. bl do_profile;
  292. mtlr r24;
  293. ld r24,48(r21);
  294. ld r25,56(r21);
  295. b label##_Iseries_prof_ret
  296. #define STD_EXCEPTION_COMMON( trap, label, hdlr )
  297. .globl label##_common;
  298. label##_common:
  299. EXCEPTION_PROLOG_COMMON;
  300. addi r3,r1,STACK_FRAME_OVERHEAD;
  301. li r20,0;
  302. li r6,trap;
  303. bl      .save_remaining_regs;           
  304. bl      hdlr;                           
  305. b       .ret_from_except
  306. /*
  307.  * Start of pSeries system interrupt routines
  308.  */
  309. . = 0x100
  310. .globl __start_interupts
  311. __start_interupts:
  312. STD_EXCEPTION_PSERIES( 0x100, SystemReset )
  313. STD_EXCEPTION_PSERIES( 0x200, MachineCheck )
  314. STD_EXCEPTION_PSERIES( 0x300, DataAccess )
  315. STD_EXCEPTION_PSERIES( 0x380, DataAccessSLB )
  316. STD_EXCEPTION_PSERIES( 0x400, InstructionAccess )
  317. STD_EXCEPTION_PSERIES( 0x480, InstructionAccessSLB )
  318. STD_EXCEPTION_PSERIES( 0x500, HardwareInterrupt )
  319. STD_EXCEPTION_PSERIES( 0x600, Alignment )
  320. STD_EXCEPTION_PSERIES( 0x700, ProgramCheck )
  321. STD_EXCEPTION_PSERIES( 0x800, FPUnavailable )
  322. STD_EXCEPTION_PSERIES( 0x900, Decrementer )
  323. STD_EXCEPTION_PSERIES( 0xa00, Trap_0a )
  324. STD_EXCEPTION_PSERIES( 0xb00, Trap_0b )
  325. STD_EXCEPTION_PSERIES( 0xc00, SystemCall )
  326. STD_EXCEPTION_PSERIES( 0xd00, SingleStep )
  327. STD_EXCEPTION_PSERIES( 0xe00, Trap_0e )
  328. STD_EXCEPTION_PSERIES( 0xf00, PerformanceMonitor )
  329. STD_EXCEPTION_PSERIES( 0x1300, InstructionBreakpoint )
  330. /* Space for the naca.  Architected to be located at real address
  331.  * 0x4000.  Various tools rely on this location being fixed.
  332.  * The first dword of the naca is required by iSeries LPAR to
  333.  * point to itVpdAreas.  On pSeries native, this value is not used.
  334.  */
  335. . = 0x4000
  336. .globl __end_interupts
  337. .globl __start_naca
  338. __end_interupts:
  339. __start_naca:
  340. .llong itVpdAreas
  341. .llong 0x0
  342. .llong 0x0
  343. .llong paca
  344. /*
  345.  * Space for the initial segment table
  346.  * For LPAR, the hypervisor must fill in at least one entry
  347.  * before we get control (with relocate on)
  348.  */
  349. . = 0x5000
  350. .globl __end_naca
  351. .globl __start_stab
  352. __end_naca:
  353. __start_stab:
  354. . = 0x6000
  355. .globl __end_stab
  356. __end_stab:
  357. /*
  358.  * The iSeries LPAR map is at this fixed address
  359.  * so that the HvReleaseData structure can address
  360.  * it with a 32-bit offset.
  361.  *
  362.  * The VSID values below are dependent on the
  363.  * VSID generation algorithm.  See include/asm/mmu_context.h.
  364.  */
  365. .llong 1 /* # ESIDs to be mapped by hypervisor         */
  366. .llong 1 /* # memory ranges to be mapped by hypervisor */
  367. .llong 5 /* Page # of segment table within load area   */
  368. .llong 0 /* Reserved */
  369. .llong  0 /* Reserved */
  370. .llong  0 /* Reserved */
  371. .llong 0 /* Reserved */
  372. .llong 0 /* Reserved */
  373. .llong 0x0c00000000 /* ESID to map (Kernel at EA = 0xC000000000000000) */
  374. .llong 0x06a99b4b14    /* VSID to map (Kernel at VA = 0x6a99b4b140000000) */
  375. .llong 8192 /* # pages to map (32 MB) */
  376. .llong 0 /* Offset from start of loadarea to start of map */
  377. .llong 0x0006a99b4b140000 /* VPN of first page to map */
  378. . = 0x6100
  379. /***  ISeries-LPAR interrupt handlers ***/
  380. STD_EXCEPTION_ISERIES( 0x200, MachineCheck )
  381. STD_EXCEPTION_ISERIES( 0x300, DataAccess )
  382. STD_EXCEPTION_ISERIES( 0x380, DataAccessSLB )
  383. STD_EXCEPTION_ISERIES( 0x400, InstructionAccess )
  384. STD_EXCEPTION_ISERIES( 0x480, InstructionAccessSLB )
  385. MASKABLE_EXCEPTION_ISERIES( 0x500, HardwareInterrupt )
  386. STD_EXCEPTION_ISERIES( 0x600, Alignment )
  387. STD_EXCEPTION_ISERIES( 0x700, ProgramCheck )
  388. STD_EXCEPTION_ISERIES( 0x800, FPUnavailable )
  389. MASKABLE_EXCEPTION_ISERIES( 0x900, Decrementer )
  390. STD_EXCEPTION_ISERIES( 0xa00, Trap_0a )
  391. STD_EXCEPTION_ISERIES( 0xb00, Trap_0b )
  392. STD_EXCEPTION_ISERIES( 0xc00, SystemCall )
  393. STD_EXCEPTION_ISERIES( 0xd00, SingleStep )
  394. STD_EXCEPTION_ISERIES( 0xe00, Trap_0e )
  395. MASKABLE_EXCEPTION_ISERIES( 0xf00, PerformanceMonitor )
  396. .globl SystemReset_Iseries
  397. SystemReset_Iseries:
  398. mfspr 25,SPRG3 /* Get paca address */
  399. lhz r24,PACAPACAINDEX(r25) /* Get processor # */
  400. cmpi 0,r24,0 /* Are we processor 0? */
  401. beq .__start_initialization_iSeries /* Start up the first processor */
  402. mfspr r4,CTRLF
  403. li r5,RUNLATCH /* Turn off the run light */
  404. andc r4,r4,r5
  405. mtspr CTRLT,r4
  406. 1:
  407. HMT_LOW
  408. #ifdef CONFIG_SMP
  409. lbz r23,PACAPROCSTART(r25) /* Test if this processor
  410.  * should start */
  411. sync
  412. LOADADDR(r3,current_set)
  413. sldi r28,r24,4 /* get current_set[cpu#] */
  414. ldx r3,r3,r28
  415. addi r1,r3,TASK_UNION_SIZE
  416. subi r1,r1,STACK_FRAME_OVERHEAD
  417. cmpi 0,r23,0
  418. beq iseries_secondary_smp_loop /* Loop until told to go */
  419. #ifdef SECONDARY_PROCESSORS
  420. bne .__secondary_start /* Loop until told to go */
  421. #endif
  422. iseries_secondary_smp_loop:
  423. /* Let the Hypervisor know we are alive */
  424. /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
  425. lis r3,0x8002
  426. rldicr r3,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */
  427. #else /* CONFIG_SMP */
  428. /* Yield the processor.  This is required for non-SMP kernels
  429.    which are running on multi-threaded machines. */
  430. lis r3,0x8000
  431. rldicr r3,r3,32,15 /* r3 = (r3 << 32) & 0xffff000000000000 */
  432. addi r3,r3,18 /* r3 = 0x8000000000000012 which is "yield" */
  433. li r4,0 /* "yield timed" */
  434. li r5,-1 /* "yield forever" */
  435. #endif /* CONFIG_SMP */
  436. li r0,-1 /* r0=-1 indicates a Hypervisor call */
  437. sc /* Invoke the hypervisor via a system call */
  438. mfspr r25,SPRG3 /* Put r25 back ???? */
  439. b 1b /* If SMP not configured, secondaries
  440.  * loop forever */
  441. .globl HardwareInterrupt_Iseries_masked
  442. HardwareInterrupt_Iseries_masked:
  443. b maskable_exception_exit
  444. .globl PerformanceMonitor_Iseries_masked
  445. PerformanceMonitor_Iseries_masked:
  446. li r22,1
  447. stb r22,PACALPPACA+LPPACAPDCINT(r20)
  448. b maskable_exception_exit
  449. .globl Decrementer_Iseries_masked
  450. Decrementer_Iseries_masked:
  451. li r22,1
  452. stb r22,PACALPPACA+LPPACADECRINT(r20)
  453. lwz r22,PACADEFAULTDECR(r20)
  454. mtspr DEC,r22
  455. maskable_exception_exit:
  456. mtcrf 0xff,r23 /* Restore regs and free exception frame */
  457. ld r22,EX_SRR0(r21)
  458. ld r23,EX_SRR1(r21)
  459. mtspr SRR0,r22
  460. mtspr SRR1,r23
  461. ld r22,EX_R22(r21)
  462. ld r23,EX_R23(r21)
  463. mfspr r21,SPRG1
  464. mfspr r20,SPRG2
  465. rfid
  466. /*
  467.  * Data area reserved for FWNMI option.
  468.  */
  469.         .= 0x7000
  470. .globl fwnmi_data_area
  471. fwnmi_data_area:
  472. /*
  473.  * Vectors for the FWNMI option.  Share common code.
  474.  */
  475. . = 0x8000
  476. .globl SystemReset_FWNMI
  477. SystemReset_FWNMI:
  478. EXCEPTION_PROLOG_PSERIES(0x100, SystemReset_common)
  479. .globl MachineCheck_FWNMI
  480. MachineCheck_FWNMI:
  481. EXCEPTION_PROLOG_PSERIES(0x200, MachineCheck_common)
  482. /*** Common interrupt handlers ***/
  483. STD_EXCEPTION_COMMON( 0x100, SystemReset, .SystemResetException )
  484. STD_EXCEPTION_COMMON( 0x200, MachineCheck, .MachineCheckException )
  485. STD_EXCEPTION_COMMON( 0x900, Decrementer, .timer_interrupt )
  486. STD_EXCEPTION_COMMON( 0xa00, Trap_0a, .UnknownException )
  487. STD_EXCEPTION_COMMON( 0xb00, Trap_0b, .UnknownException )
  488. STD_EXCEPTION_COMMON( 0xd00, SingleStep, .SingleStepException )
  489. STD_EXCEPTION_COMMON( 0xe00, Trap_0e, .UnknownException )
  490. STD_EXCEPTION_COMMON(0x1300, InstructionBreakpoint, .InstructionBreakpointException )
  491. /*
  492.  * Return from an exception which is handled without calling
  493.  * save_remaining_regs.  The caller is assumed to have done
  494.  * EXCEPTION_PROLOG_COMMON.
  495.  */
  496. fast_exception_return:
  497. ld      r3,_CCR(r1)
  498. ld      r4,_LINK(r1)
  499. ld      r5,_CTR(r1)
  500. ld      r6,_XER(r1)
  501. mtcr    r3
  502. mtlr    r4
  503. mtctr   r5
  504. mtspr   XER,r6
  505. REST_GPR(0, r1)
  506. REST_8GPRS(2, r1)
  507. REST_4GPRS(10, r1)
  508. mtspr   SRR1,r23
  509. mtspr   SRR0,r22
  510. REST_4GPRS(20, r1)
  511. ld      r1,GPR1(r1)
  512. rfid
  513. /*
  514.  * Here r20 points to the PACA, r21 to the exception frame,
  515.  * r23 contains the saved CR.
  516.  * r20 - r23, SRR0 and SRR1 are saved in the exception frame.
  517.  */
  518. .globl DataAccess_common
  519. DataAccess_common:
  520. mfspr   r22,DAR
  521. srdi    r22,r22,60
  522. cmpi    0,r22,0xc
  523. beq     .do_stab_bolted
  524. cmpi    0,r22,0xb
  525. beq     .do_stab_bolted
  526. stab_bolted_user_return:
  527. EXCEPTION_PROLOG_COMMON
  528. ld      r3,_DSISR(r1)
  529. andis. r0,r3,0xa450 /* weird error? */
  530. bne 1f /* if not, try to put a PTE */
  531. andis. r0,r3,0x0020 /* Is it a page table fault? */
  532. rlwinm r4,r3,32-23,29,29 /* DSISR_STORE -> _PAGE_RW */
  533. ld      r3,_DAR(r1)             /* into the hash table */
  534. beq 2f /* If so handle it */
  535. li r4,0x300                /* Trap number */
  536. bl .do_stab_SI
  537. b 1f
  538. 2: li r5,0x300
  539. bl .do_hash_page_DSI  /* Try to handle as hpte fault */
  540. 1:
  541. ld      r4,_DAR(r1)
  542. ld      r5,_DSISR(r1)
  543. addi r3,r1,STACK_FRAME_OVERHEAD
  544. #ifdef DO_SOFT_DISABLE
  545. ld r20,SOFTE(r1) /* Copy saved SOFTE bit */
  546. #else
  547. rldicl r20,r23,49,63    /* copy EE bit from saved MSR */
  548. #endif
  549. li r6,0x300
  550. bl      .save_remaining_regs
  551. bl      .do_page_fault
  552. b       .ret_from_except
  553. .globl DataAccessSLB_common
  554. DataAccessSLB_common:
  555. mfspr   r22,DAR
  556. srdi    r22,r22,60
  557. cmpi    0,r22,0xc
  558. beq     .do_slb_bolted
  559. cmpi    0,r22,0xb
  560. beq     .do_slb_bolted
  561. EXCEPTION_PROLOG_COMMON
  562. ld      r3,_DAR(r1)
  563. li      r4,0x380                /* Exception vector  */
  564. bl .ste_allocate
  565. or. r3,r3,r3 /* Check return code */
  566. beq     fast_exception_return   /* Return if we succeeded */
  567. addi r3,r1,STACK_FRAME_OVERHEAD
  568. #ifdef DO_SOFT_DISABLE
  569. ld r20,SOFTE(r1)
  570. #else
  571. rldicl r20,r23,49,63    /* copy EE bit from saved MSR */
  572. #endif
  573. li r6,0x380
  574. bl      .save_remaining_regs
  575. bl      .do_page_fault
  576. b       .ret_from_except
  577. .globl InstructionAccess_common
  578. InstructionAccess_common:
  579. EXCEPTION_PROLOG_COMMON
  580. andis. r0,r23,0x0020 /* no ste found? */
  581. beq 2f
  582. mr r3,r22 /* SRR0 at interrupt */
  583. li r4,0x400 /* Trap number       */
  584. bl .do_stab_SI
  585. b 1f
  586. 2: andis. r0,r23,0x4000 /* no pte found? */
  587. beq 1f /* if so, try to put a PTE */
  588. mr r3,r22 /* into the hash table */
  589. bl .do_hash_page_ISI /* Try to handle as hpte fault */
  590. 1:
  591. mr r4,r22
  592. mr r5,r23
  593. addi r3,r1,STACK_FRAME_OVERHEAD
  594. #ifdef DO_SOFT_DISABLE
  595. ld r20,SOFTE(r1)
  596. #else
  597. rldicl r20,r23,49,63    /* copy EE bit from saved MSR */
  598. #endif
  599. li r6,0x400
  600. bl      .save_remaining_regs
  601. bl      .do_page_fault
  602. b       .ret_from_except
  603. .globl InstructionAccessSLB_common
  604. InstructionAccessSLB_common:
  605. EXCEPTION_PROLOG_COMMON
  606. mr      r3,r22                  /* SRR0 = NIA        */
  607. li r4,0x480                /* Exception vector  */
  608. bl .ste_allocate
  609. or. r3,r3,r3 /* Check return code */
  610. beq     fast_exception_return   /* Return if we succeeded */
  611. addi r3,r1,STACK_FRAME_OVERHEAD
  612. #ifdef DO_SOFT_DISABLE
  613. ld r20,SOFTE(r1)
  614. #else
  615. rldicl r20,r23,49,63    /* copy EE bit from saved MSR */
  616. #endif
  617. li r6,0x480
  618. bl      .save_remaining_regs
  619. bl      .do_page_fault
  620. b       .ret_from_except
  621. .globl HardwareInterrupt_common
  622. HardwareInterrupt_common:
  623. EXCEPTION_PROLOG_COMMON
  624. HardwareInterrupt_entry:
  625. addi r3,r1,STACK_FRAME_OVERHEAD
  626. li r20,0
  627. li r6,0x500
  628. bl      .save_remaining_regs
  629. /* Determine if need to run do_irq on a hardware interrupt stack  */
  630. /*   The first invocation of do_irq will occur on the kernel      */
  631. /*   stack in the current stack                                   */
  632. /*   All other invocations of do_irq will run on the hardware     */
  633. /*   interrupt stack associated with the PACA of the current      */
  634. /*   processor.                                                   */
  635. /*                                                                */
  636. /*  The call to do_irq will preserve the value of r14 - r31       */
  637. /*                                                                */
  638. mfspr r20,SPRG3      /* get paca                   */
  639. lbz     r21,PACAHRDWINTCOUNT(r20)    /* get hardware interrupt cnt */
  640. cmpi    0,r21,0                     /*                            */
  641. addi    r21,r21,1                   /* incr hardware interrupt cnt*/
  642. stb     r21,PACAHRDWINTCOUNT(r20)   /*                            */
  643. bne     2f                          /*                            */
  644. mr      r14,r1                      /* preserve current r1        */
  645. ld      r1,PACAHRDWINTSTACK(r20)    /*                            */
  646. std     r14,0(r1)                   /* set the back chain         */
  647. bl      .do_IRQ
  648. lbz     r22,PACAHRDWINTCOUNT(r20)   /* get hardware interrupt cnt */
  649. cmp     0,r22,r21                   /* debug test                 */
  650. bne     3f
  651. subi    r21,r21,1
  652. stb     r21,PACAHRDWINTCOUNT(r20)   /*                            */
  653. mr      r1,r14                      /*                            */
  654. b       .ret_from_except
  655. 2:
  656. bl      .do_IRQ
  657. lbz     r22,PACAHRDWINTCOUNT(r20)   /* get hardware interrupt cnt */
  658. cmp     0,r22,r21                   /* debug test                 */
  659. bne     3f                          /*                            */
  660. subi    r21,r21,1                   /* decr hardware interrupt cnt*/
  661. stb     r21,PACAHRDWINTCOUNT(r20)   /*                            */
  662. b       .ret_from_except
  663. 3:
  664. /* error - counts out of sync                                      */
  665. #ifdef CONFIG_XMON
  666. bl .xmon
  667. #endif
  668. 4: b 4b
  669. .globl Alignment_common
  670. Alignment_common:
  671. EXCEPTION_PROLOG_COMMON
  672. addi r3,r1,STACK_FRAME_OVERHEAD
  673. #ifdef DO_SOFT_DISABLE
  674. ld r20,SOFTE(r1)
  675. #else
  676. rldicl r20,r23,49,63    /* copy EE bit from saved MSR */
  677. #endif
  678. li r6,0x600
  679. bl      .save_remaining_regs
  680. bl      .AlignmentException
  681. b       .ret_from_except
  682. .globl ProgramCheck_common
  683. ProgramCheck_common:
  684. EXCEPTION_PROLOG_COMMON
  685. addi r3,r1,STACK_FRAME_OVERHEAD
  686. #ifdef DO_SOFT_DISABLE
  687. ld r20,SOFTE(r1)
  688. #else
  689. rldicl r20,r23,49,63    /* copy EE bit from saved MSR */
  690. #endif
  691. li r6,0x700
  692. bl      .save_remaining_regs
  693. bl      .ProgramCheckException
  694. b       .ret_from_except
  695. .globl FPUnavailable_common
  696. FPUnavailable_common:
  697. EXCEPTION_PROLOG_COMMON
  698. bne .load_up_fpu /* if from user, just load it up */
  699. li r20,0
  700. li r6,0x800
  701. bl      .save_remaining_regs    /* if from kernel, take a trap */
  702. bl      .KernelFP
  703. b       .ret_from_except
  704. .globl SystemCall_common
  705. SystemCall_common:
  706. EXCEPTION_PROLOG_COMMON
  707. #ifdef CONFIG_PPC_ISERIES
  708. cmpi 0,r0,0x5555 /* Special syscall to handle pending */
  709. bne+ 1f /* interrupts */
  710. andi. r6,r23,MSR_PR /* Only allowed from kernel */
  711. beq+ HardwareInterrupt_entry
  712. 1:
  713. #endif
  714. std r3,ORIG_GPR3(r1)
  715. #ifdef DO_SOFT_DISABLE
  716. ld r20,SOFTE(r1)
  717. #else
  718. rldicl r20,r23,49,63    /* copy EE bit from saved MSR */
  719. #endif
  720. li r6,0xC00
  721. bl      .save_remaining_regs
  722. bl      .DoSyscall
  723. b       .ret_from_except
  724. .globl PerformanceMonitor_common
  725. PerformanceMonitor_common:
  726. EXCEPTION_PROLOG_COMMON
  727. bl .PerformanceMonitorException
  728. b fast_exception_return
  729. _GLOBAL(PerformanceMonitorException)
  730. mfspr r7,SPRG3
  731. lbz r8,PACAPROFMODE(r7)
  732. cmpi 0,r8,PMC_STATE_PROFILE_KERN
  733. beq  5f
  734. cmpi 0,r8,PMC_STATE_TRACE_KERN
  735. beq  6f
  736. cmpi 0,r8,PMC_STATE_TRACE_USER
  737. beq  9f
  738. blr
  739. /* PMC Profile Kernel */
  740. 5: mfspr   r9,SIAR
  741. srdi    r8,r9,60
  742. cmpi    0,r8,0xc
  743. beq     3f
  744. li r9,0xc
  745. sldi r9,r9,60
  746. 3:      ld r8,PACAPROFSTEXT(r7) /* _stext */
  747. subf r9,r8,r9 /* offset into kernel */
  748. lwz r8,PACAPROFSHIFT(r7)
  749. srd r9,r9,r8
  750. lwz r8,PACAPROFLEN(r7) /* length of profile table (-1) */
  751. srdi r8,r8,2
  752. cmpd r9,r8 /* off end? */
  753. ble 1f
  754. mr r9,r8 /* force into last entry */
  755. srdi r9,r9,2
  756. 1: sldi r9,r9,2 /* convert to offset into buffer */
  757. ld r8,PACAPROFBUFFER(r7) /* profile buffer */
  758. add r8,r8,r9
  759. 2: lwarx r9,0,r8 /* atomically increment */
  760. addi r9,r9,1
  761. stwcx. r9,0,r8
  762. bne- 2b
  763. addi r10,r7,PACAPMC1
  764. addi r7,r7,PACAPMCC1
  765. b 7f
  766. /* PMC Trace Kernel */
  767. 6: LOADADDR(r11, perfmon_base)
  768.    addi r8,r11,32
  769. ld r12,24(r11)
  770. subi r12,r12,1
  771. 8: ldarx r10,0,r8
  772. addi r9,r10,16
  773. and r9,r9,r12
  774. stdcx. r9,0,r8
  775. bne- 8b
  776. ld r9,16(r11) /* profile buffer */
  777. add r8,r9,r10
  778.    mfspr   r9,SIAR
  779. std r9,0(r8)
  780. mfspr   r9,SDAR
  781. std r9,8(r8)
  782. addi r10,r7,PACAPMC1
  783. addi r7,r7,PACAPMCC1
  784. b 7f
  785. /* PMC Trace User */
  786. 9: LOADADDR(r11, perfmon_base)
  787. #if 0
  788.    addi r8,r11,32
  789. ld r12,24(r11)
  790. subi r12,r12,1
  791. 8: ldarx r10,0,r8
  792. addi r9,r10,16
  793. and r9,r9,r12
  794. stdcx. r9,0,r8
  795. bne- 8b
  796. ld r9,16(r11) /* profile buffer */
  797. add r8,r9,r10
  798.    mfspr   r9,SIAR
  799. std r9,0(r8)
  800. mfspr   r9,SDAR
  801. std r9,8(r8)
  802. addi r10,r13,THREAD+THREAD_PMC1
  803. addi r7,r13,THREAD+THREAD_PMCC1
  804. #endif
  805. /* Accumulate counter values for kernel traces */
  806. 7: ld r9,0(r7)
  807. mfspr   r8,PMC1
  808. add r9,r9,r8
  809. std r9,0(r7)
  810. ld r9,8(r7)
  811. mfspr r8,PMC2
  812. add r9,r9,r8
  813. std r9,8(r7)
  814. ld r9,16(r7)
  815. mfspr r8,PMC3
  816. add r9,r9,r8
  817. std r9,16(r7)
  818. ld r9,24(r7)
  819. mfspr r8,PMC4
  820. add r9,r9,r8
  821. std r9,24(r7)
  822. ld r9,32(r7)
  823. mfspr r8,PMC5
  824. add r9,r9,r8
  825. std r9,32(r7)
  826. ld r9,40(r7)
  827. mfspr r8,PMC6
  828. add r9,r9,r8
  829. std r9,40(r7)
  830. ld r9,48(r7)
  831. mfspr r8,PMC7
  832. add r9,r9,r8
  833. std r9,48(r7)
  834. ld r9,56(r7)
  835. mfspr r8,PMC8
  836. add r9,r9,r8
  837. std r9,56(r7)
  838. /* Reset all counters for kernel traces */
  839. lwz r9,0(r10)
  840. mtspr PMC1,r9
  841. lwz r9,4(r10)
  842. mtspr PMC2,r9
  843. lwz r9,8(r10)
  844. mtspr PMC3,r9
  845. lwz r9,12(r10)
  846. mtspr PMC4,r9
  847. lwz r9,16(r10)
  848. mtspr PMC5,r9
  849. lwz r9,20(r10)
  850. mtspr PMC6,r9
  851. lwz r9,24(r10)
  852. mtspr PMC7,r9
  853. lwz r9,28(r10)
  854. mtspr PMC8,r9
  855. lwz r9,32(r10)
  856. mtspr MMCR0,r9
  857. lwz r9,36(r10)
  858. mtspr MMCR1,r9
  859. lwz r9,40(r10)
  860. mtspr MMCRA,r9
  861. blr
  862. _GLOBAL(do_hash_page_ISI)
  863. li r4,0
  864. _GLOBAL(do_hash_page_DSI)
  865. rlwimi r4,r23,32-13,30,30 /* Insert MSR_PR as _PAGE_USER */
  866. ori r4,r4,1 /* add _PAGE_PRESENT */
  867. mflr r21 /* Save LR in r21 */
  868. #ifdef DO_SOFT_DISABLE
  869. /*
  870.  * We hard enable here (but first soft disable) so that the hash_page
  871.  * code can spin on the hash_table_lock with problem on a shared
  872.  * processor.
  873.  */
  874. li r0,0
  875. stb r0,PACAPROCENABLED(r20) /* Soft Disabled */
  876. mfmsr r0
  877. ori r0,r0,MSR_EE+MSR_RI
  878. mtmsrd r0 /* Hard Enable, RI on */
  879. #endif
  880. /*
  881.  * r3 contains the faulting address
  882.  * r4 contains the required access permissions
  883.  * r5 contains the trap number
  884.  *
  885.  * at return r3 = 0 for success
  886.  */
  887. bl .hash_page /* build HPTE if possible */
  888. #ifdef DO_SOFT_DISABLE
  889. /*
  890.  * Now go back to hard disabled.
  891.  */
  892. mfmsr r0
  893. li r4,0
  894. ori r4,r4,MSR_EE+MSR_RI
  895. andc r0,r0,r4
  896. mtmsrd r0 /* Hard Disable, RI off */
  897. ld r0,SOFTE(r1)
  898. cmpdi 0,r0,0 /* See if we will soft enable in */
  899. /* save_remaining_regs */
  900. beq 5f
  901. CHECKANYINT(r4,r5)
  902. bne- HardwareInterrupt_entry /* Convert this DSI into an External */
  903. /* to process interrupts which occurred */
  904. /* during hash_page */
  905. 5:
  906. stb r0,PACAPROCENABLED(r20) /* Restore soft enable/disable status */
  907. #endif
  908. or. r3,r3,r3 /* Check return code */
  909. beq     fast_exception_return   /* Return from exception on success */
  910. mtlr    r21                     /* restore LR */
  911. blr                             /* Return to DSI or ISI on failure */
  912. /*
  913.  * r20 points to the PACA, r21 to the exception frame,
  914.  * r23 contains the saved CR.
  915.  * r20 - r23, SRR0 and SRR1 are saved in the exception frame.
  916.  * We assume we aren't going to take any exceptions during this procedure.
  917.  */
  918. _GLOBAL(do_stab_bolted)
  919. stw r23,EX_CCR(r21) /* save CR in exc. frame */
  920. mfspr   r22,DSISR
  921. andis.  r22,r22,0x0020
  922. bne+    2f
  923. ld r22,8(r21) /* get SRR1 */
  924. andi. r22,r22,MSR_PR /* check if from user */
  925. bne+ stab_bolted_user_return  /* from user, send the error on up */
  926. li r3,0
  927. #ifdef CONFIG_XMON
  928. bl .xmon
  929. #endif
  930. 1: b 1b
  931. 2:
  932. /* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */
  933. mfspr r21,DAR
  934. rldicl  r20,r21,36,32   /* Permits a full 32b of ESID */
  935. rldicr  r20,r20,15,48
  936. rldicl  r21,r21,4,60
  937. or      r20,r20,r21
  938. li      r21,9           /* VSID_RANDOMIZER */
  939. sldi    r21,r21,32
  940. oris    r21,r21,58231
  941. ori     r21,r21,39831
  942. mulld   r20,r20,r21
  943. clrldi  r20,r20,28      /* r20 = vsid */
  944. mfsprg  r21,3
  945. ld      r21,PACASTABVIRT(r21)
  946. /* Hash to the primary group */
  947. mfspr r22,DAR
  948. rldicl  r22,r22,36,59
  949. rldicr  r22,r22,7,56
  950. or      r21,r21,r22     /* r21 = first ste of the group */
  951. /* Search the primary group for a free entry */
  952. li      r22,0
  953. 1:
  954. ld      r23,0(r21)      /* Test valid bit of the current ste   */
  955. rldicl  r23,r23,57,63
  956. cmpwi   r23,0
  957. bne     2f
  958. ld      r23,8(r21)      /* Get the current vsid part of the ste */
  959. rldimi  r23,r20,12,0    /* Insert the new vsid value            */
  960. std     r23,8(r21)      /* Put new entry back into the stab     */
  961. eieio                  /* Order vsid update                    */
  962. ld      r23,0(r21)      /* Get the esid part of the ste         */
  963. mfspr r20,DAR        /* Get the new esid                     */
  964. rldicl  r20,r20,36,28  /* Permits a full 36b of ESID           */
  965. rldimi  r23,r20,28,0    /* Insert the new esid value            */
  966. ori     r23,r23,144      /* Turn on valid and kp                 */
  967. std     r23,0(r21)      /* Put new entry back into the stab     */
  968. sync                   /* Order the update                     */
  969. b       3f
  970. 2:
  971. addi    r22,r22,1
  972. addi    r21,r21,16
  973. cmpldi  r22,7
  974. ble     1b
  975. /* Stick for only searching the primary group for now.          */
  976. /* At least for now, we use a very simple random castout scheme */
  977. /* Use the TB as a random number ;  OR in 1 to avoid entry 0    */
  978. mftb    r22
  979. andi.   r22,r22,7
  980. ori r22,r22,1
  981. sldi r22,r22,4
  982. /* r21 currently points to and ste one past the group of interest */
  983. /* make it point to the randomly selected entry                   */
  984. subi r21,r21,128
  985. or  r21,r21,r22      /* r21 is the entry to invalidate        */
  986. isync                    /* mark the entry invalid                */
  987. ld      r23,0(r21)
  988. li      r22,-129
  989. and     r23,r23,r22
  990. std     r23,0(r21)
  991. sync
  992. ld      r23,8(r21)
  993. rldimi  r23,r20,12,0
  994. std     r23,8(r21)
  995. eieio
  996. ld      r23,0(r21)      /* Get the esid part of the ste         */
  997. mr      r22,r23
  998. mfspr r20,DAR         /* Get the new esid                     */
  999. rldicl  r20,r20,36,28   /* Permits a full 32b of ESID           */
  1000. rldimi  r23,r20,28,0    /* Insert the new esid value            */
  1001. ori     r23,r23,144     /* Turn on valid and kp                 */
  1002. std     r23,0(r21)      /* Put new entry back into the stab     */
  1003. rldicl  r22,r22,36,28
  1004. rldicr  r22,r22,28,35
  1005. slbie   r22
  1006. sync
  1007. 3:
  1008. /* All done -- return from exception. */
  1009. mfsprg  r20,3                   /* Load the PACA pointer  */
  1010. ld      r21,PACAEXCSP(r20)      /* Get the exception frame pointer */
  1011. addi    r21,r21,EXC_FRAME_SIZE
  1012. lwz r23,EX_CCR(r21) /* get saved CR */
  1013. /* note that this is almost identical to maskable_exception_exit */
  1014. mtcr    r23                     /* restore CR */
  1015. ld r22,EX_SRR0(r21) /* Get SRR0 from exc. frame */
  1016. ld r23,EX_SRR1(r21) /* Get SRR1 from exc. frame */
  1017. mtspr SRR0,r22
  1018. mtspr   SRR1,r23
  1019. ld r22,EX_R22(r21) /* restore r22 and r23 */
  1020. ld r23,EX_R23(r21)
  1021. mfspr r20,SPRG2
  1022. mfspr r21,SPRG1
  1023. rfid
  1024. _TRACEBACK(do_stab_bolted)
  1025. /*
  1026.  * r20 points to the PACA, r21 to the exception frame,
  1027.  * r23 contains the saved CR.
  1028.  * r20 - r23, SRR0 and SRR1 are saved in the exception frame.
  1029.  * We assume we aren't going to take any exceptions during this procedure.
  1030.  */
  1031. _GLOBAL(do_slb_bolted)
  1032. stw     r23,EX_CCR(r21) /* save CR in exc. frame */
  1033. /* (((ea >> 28) & 0x1fff) << 15) | (ea >> 60) */
  1034. mfspr r21,DAR
  1035. rldicl  r20,r21,36,32   /* Permits a full 32b of ESID */
  1036. rldicr  r20,r20,15,48
  1037. rldicl  r21,r21,4,60
  1038. or      r20,r20,r21
  1039. li      r21,9           /* VSID_RANDOMIZER */
  1040. sldi    r21,r21,32
  1041. oris    r21,r21,58231
  1042. ori     r21,r21,39831
  1043. mulld   r20,r20,r21
  1044. clrldi  r20,r20,28      /* r20 = vsid */
  1045. /* Search the SLB for a free entry */
  1046. li      r22,1
  1047. 1:
  1048. slbmfee r23,r22
  1049. rldicl  r23,r23,37,63
  1050. cmpwi   r23,0
  1051. beq     3f              /* Found an invalid entry              */
  1052. addi r22,r22,1
  1053. cmpldi r22,64
  1054. blt 1b
  1055. /* No free entry - just take the next entry, round-robin */
  1056. /* XXX we should get the number of SLB entries from the naca */
  1057. SLB_NUM_ENTRIES = 64
  1058. mfspr r21,SPRG3
  1059. ld r22,PACASTABRR(r21)
  1060. addi r23,r22,1
  1061. cmpdi r23,SLB_NUM_ENTRIES
  1062. blt 2f
  1063. li r23,1
  1064. 2: std r23,PACASTABRR(r21)
  1065. /* r20 = vsid, r22 = entry */
  1066. 3:
  1067. /* Put together the vsid portion of the entry. */
  1068. li      r21,0
  1069. rldimi  r21,r20,12,0
  1070. ori     r20,r21,1024
  1071. #ifndef CONFIG_PPC_ISERIES
  1072. ori r20,r20,256    /* map kernel region with large ptes */
  1073. #endif
  1074. /* Invalidate the old entry */
  1075. slbmfee r21,r22
  1076. lis r23,-2049
  1077. ori r23,r23,65535
  1078. and r21,r21,r23
  1079. slbie r21
  1080. /* Put together the esid portion of the entry. */
  1081. mfspr r21,DAR        /* Get the new esid                     */
  1082. rldicl  r21,r21,36,28  /* Permits a full 36b of ESID           */
  1083. li      r23,0
  1084. rldimi  r23,r21,28,0   /* Insert esid  */
  1085. oris    r21,r23,2048   /* valid bit    */
  1086. rldimi  r21,r22,0,52   /* Insert entry */
  1087. isync
  1088. slbmte  r20,r21
  1089. isync
  1090. /* All done -- return from exception. */
  1091. mfsprg  r20,3                   /* Load the PACA pointer  */
  1092. ld      r21,PACAEXCSP(r20)      /* Get the exception frame pointer */
  1093. addi    r21,r21,EXC_FRAME_SIZE
  1094. lwz r23,EX_CCR(r21) /* get saved CR */
  1095. /* note that this is almost identical to maskable_exception_exit */
  1096. mtcr    r23                     /* restore CR */
  1097. ld r22,EX_SRR0(r21) /* Get SRR0 from exc. frame */
  1098. ld r23,EX_SRR1(r21) /* Get SRR1 from exc. frame */
  1099. mtspr SRR0,r22
  1100. mtspr   SRR1,r23
  1101. ld r22,EX_R22(r21) /* restore r22 and r23 */
  1102. ld r23,EX_R23(r21)
  1103. mfspr r20,SPRG2
  1104. mfspr r21,SPRG1
  1105. rfid
  1106. _TRACEBACK(do_slb_bolted)
  1107. _GLOBAL(do_stab_SI)
  1108. mflr r21 /* Save LR in r21 */
  1109. /*
  1110.  * r3 contains the faulting address
  1111.  * r4 contains the required access permissions
  1112.  *
  1113.  * at return r3 = 0 for success
  1114.  */
  1115. bl .ste_allocate /* build STE if possible */
  1116. or. r3,r3,r3 /* Check return code */
  1117. beq     fast_exception_return   /* Return from exception on success */
  1118. mtlr    r21                     /* restore LR */
  1119. blr                             /* Return to DSI or ISI on failure */
  1120. /*
  1121.  * This code finishes saving the registers to the exception frame.
  1122.  * Address translation is already on.
  1123.  */
  1124. _GLOBAL(save_remaining_regs)
  1125. /*
  1126.  * Save the rest of the registers into the pt_regs structure
  1127.  */
  1128. std     r22,_NIP(r1)
  1129. std     r23,_MSR(r1)
  1130. std     r6,TRAP(r1)
  1131. ld      r6,GPR6(r1)
  1132. SAVE_2GPRS(14, r1)
  1133. SAVE_4GPRS(16, r1)
  1134. SAVE_8GPRS(24, r1)
  1135. /*
  1136.  * Clear the RESULT field
  1137.  */
  1138. li r22,0
  1139. std r22,RESULT(r1)
  1140. /*
  1141.  * Test if from user state; result will be tested later
  1142.  */
  1143. andi. r23,r23,MSR_PR /* Set CR for later branch */
  1144. /*
  1145.  * Indicate that r1 contains the kernel stack and
  1146.  * get the Kernel TOC and CURRENT pointers from the paca
  1147.  */
  1148. mfspr r23,SPRG3 /* Get PACA */
  1149. std r22,PACAKSAVE(r23) /* r1 is now kernel sp */
  1150. ld r2,PACATOC(r23) /* Get Kernel TOC pointer */
  1151. /*
  1152.  * If from user state, update THREAD.regs
  1153.  */
  1154. beq 2f /* Modify THREAD.regs if from user */
  1155. addi r24,r1,STACK_FRAME_OVERHEAD
  1156. std r24,THREAD+PT_REGS(r13)
  1157. 2:
  1158. SET_REG_TO_CONST(r22, MSR_KERNEL)
  1159. #ifdef DO_SOFT_DISABLE
  1160. stb r20,PACAPROCENABLED(r23) /* possibly soft enable */
  1161. ori r22,r22,MSR_EE /* always hard enable */
  1162. #else
  1163. rldimi r22,r20,15,48 /* Insert desired EE value */
  1164. #endif
  1165. mtmsrd  r22
  1166. blr
  1167. /*
  1168.  * Kernel profiling with soft disable on iSeries
  1169.  */
  1170. do_profile:
  1171. ld r22,8(r21) /* Get SRR1 */
  1172. andi. r22,r22,MSR_PR /* Test if in kernel */
  1173. bnelr /* return if not in kernel */
  1174. ld r22,0(r21) /* Get SRR0 */
  1175. ld r25,PACAPROFSTEXT(r20) /* _stext */
  1176. subf r22,r25,r22 /* offset into kernel */
  1177. lwz r25,PACAPROFSHIFT(r20)
  1178. srd r22,r22,r25
  1179. lwz r25,PACAPROFLEN(r20) /* length of profile table (-1) */
  1180. cmp 0,r22,r25 /* off end? */
  1181. ble 1f
  1182. mr r22,r25 /* force into last entry */
  1183. 1: sldi r22,r22,2 /* convert to offset into buffer */
  1184. ld r25,PACAPROFBUFFER(r20) /* profile buffer */
  1185. add r25,r25,r22
  1186. 2: lwarx r22,0,r25 /* atomically increment */
  1187. addi r22,r22,1
  1188. stwcx. r22,0,r25
  1189. bne- 2b
  1190. blr
  1191. /*
  1192.  * On pSeries, secondary processors spin in the following code.
  1193.  * At entry, r3 = this processor's number (in Linux terms, not hardware).
  1194.  */
  1195. _GLOBAL(pseries_secondary_smp_init)
  1196. /* turn on 64-bit mode */
  1197. bl .enable_64b_mode
  1198. isync
  1199. /* Set up a paca value for this processor. */
  1200. LOADADDR(r24, paca)   /* Get base vaddr of Paca array  */
  1201. mulli r25,r3,PACA_SIZE  /* Calculate vaddr of right Paca */
  1202. add r25,r25,r24              /* for this processor.           */
  1203. mtspr SPRG3,r25  /* Save vaddr of Paca in SPRG3   */
  1204. mr r24,r3  /* __secondary_start needs cpu#  */
  1205. 1:
  1206. HMT_LOW
  1207. lbz r23,PACAPROCSTART(r25)  /* Test if this processor should */
  1208.  /* start.                        */
  1209. sync
  1210.         /* Create a temp kernel stack for use before relocation is on.    */
  1211.         mr      r1,r25
  1212.         addi    r1,r1,PACAGUARD
  1213.         addi    r1,r1,0x1000
  1214.         subi    r1,r1,STACK_FRAME_OVERHEAD
  1215. cmpi 0,r23,0
  1216. #ifdef CONFIG_SMP
  1217. #ifdef SECONDARY_PROCESSORS
  1218. bne .__secondary_start
  1219. #endif
  1220. #endif
  1221. b  1b  /* Loop until told to go         */
  1222. _GLOBAL(__start_initialization_iSeries)
  1223. LOADADDR(r1,init_task_union)
  1224. addi r1,r1,TASK_UNION_SIZE
  1225. li r0,0
  1226. stdu r0,-STACK_FRAME_OVERHEAD(r1)
  1227. LOADADDR(r2,__toc_start)
  1228. addi r2,r2,0x4000
  1229. addi r2,r2,0x4000
  1230. LOADADDR(r9,naca)
  1231. SET_REG_TO_CONST(r4, KERNELBASE)
  1232. addi r4,r4,0x4000
  1233. std r4,0(r9) /* set the naca pointer */
  1234. /* Get the pointer to the segment table */
  1235. ld r6,PACA(r4)             /* Get the base paca pointer       */
  1236. ld r4,PACASTABVIRT(r6)
  1237. bl      .iSeries_fixup_klimit
  1238. b .start_here_common
  1239. _GLOBAL(__start_initialization_pSeries)
  1240. mr r31,r3 /* save parameters */
  1241. mr r30,r4
  1242. mr r29,r5
  1243. mr r28,r6
  1244. mr r27,r7
  1245. mr r26,r8                  /* YABOOT: debug_print() routine */
  1246. mr r25,r9                  /* YABOOT: debug_delay() routine */
  1247. mr r24,r10                 /* YABOOT: debug_prom() routine */
  1248. bl .enable_64b_mode
  1249. /* put a relocation offset into r3 */
  1250. bl .reloc_offset
  1251. LOADADDR(r2,__toc_start)
  1252. addi    r2,r2,0x4000
  1253. addi    r2,r2,0x4000
  1254. /* Relocate the TOC from a virt addr to a real addr */
  1255. sub r2,r2,r3
  1256. /* setup the naca pointer which is needed by prom_init            */
  1257. LOADADDR(r9,naca)
  1258. sub r9,r9,r3                /* addr of the variable naca      */
  1259. SET_REG_TO_CONST(r4, KERNELBASE)
  1260. sub r4,r4,r3
  1261. addi r4,r4,0x4000
  1262. std r4,0(r9) /* set the value of naca          */
  1263. /* DRENG / PPPBBB Fix the following comment!!! -Peter */
  1264. /* The following copies the first 0x100 bytes of code from the    */
  1265. /* load addr to physical addr 0x0.  This code causes secondary    */
  1266. /* processors to spin until a flag in the PACA is set.  This      */
  1267. /* is done at this time rather than with the entire kernel        */
  1268. /* relocation which is done below because we need to cause the    */
  1269. /* processors to spin on code that is not going to move while OF  */
  1270. /* is still alive. Although the spin code is not actually run on  */
  1271. /* a uniprocessor, we always do this copy.                        */
  1272. SET_REG_TO_CONST(r4, KERNELBASE)/* Src addr                       */
  1273. sub r4,r4,r3   /* current address of __start     */
  1274.                 /*        the source addr         */
  1275. li r3,0                    /* Dest addr                      */
  1276. li r5,0x100  /* # bytes of memory to copy      */
  1277. li r6,0 /* Destination offset             */
  1278. bl .copy_and_flush /* copy the first 0x100 bytes     */
  1279. mr r3,r31
  1280. mr r4,r30
  1281. mr r5,r29
  1282. mr r6,r28
  1283. mr r7,r27
  1284. mr r8,r26
  1285. mr r9,r25
  1286. mr r10,r24
  1287. bl .prom_init
  1288. li r24,0 /* cpu # */
  1289. /*
  1290.  * At this point, r3 contains the physical address we are running at,
  1291.  * returned by prom_init()
  1292.  */
  1293. _STATIC(__after_prom_start)
  1294. /*
  1295.  * We need to run with __start at physical address 0.
  1296.  * This will leave some code in the first 256B of
  1297.  * real memory, which are reserved for software use.
  1298.  * The remainder of the first page is loaded with the fixed
  1299.  * interrupt vectors.  The next two pages are filled with
  1300.  * unknown exception placeholders.
  1301.  *
  1302.  * Note: This process overwrites the OF exception vectors.
  1303.  *       r26 == relocation offset
  1304.  *       r27 == KERNELBASE
  1305.  */
  1306. bl .reloc_offset
  1307. mr r26,r3
  1308. SET_REG_TO_CONST(r27,KERNELBASE)
  1309. li r3,0                    /* target addr */
  1310. sub r4,r27,r26  /* source addr */
  1311. /* current address of _start   */
  1312.                 /*   i.e. where we are running */
  1313.                 /*        the source addr      */
  1314. LOADADDR(r5,copy_to_here) /* # bytes of memory to copy      */
  1315. sub r5,r5,r27
  1316. li r6,0x100 /* Start offset, the first 0x100  */
  1317. /* bytes were copied earlier.   */
  1318. bl .copy_and_flush /* copy the first n bytes         */
  1319. /* this includes the code being   */
  1320. /* executed here.                 */
  1321.         LOADADDR(r0, 4f)                /* Jump to the copy of this code  */
  1322. mtctr r0 /* that we just made/relocated    */
  1323. bctr
  1324. 4: LOADADDR(r5,klimit)
  1325. sub r5,r5,r26
  1326. ld r5,0(r5) /* get the value of klimit */
  1327. sub r5,r5,r27
  1328. bl .copy_and_flush /* copy the rest */
  1329. b .start_here_pSeries
  1330. /*
  1331.  * Copy routine used to copy the kernel to start at physical address 0
  1332.  * and flush and invalidate the caches as needed.
  1333.  * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
  1334.  * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
  1335.  *
  1336.  * Note: this routine *only* clobbers r0, r6 and lr
  1337.  */
  1338. _STATIC(copy_and_flush)
  1339. addi r5,r5,-8
  1340. addi r6,r6,-8
  1341. 4: li r0,16                   /* Use the least common      */
  1342. /* denominator cache line    */
  1343.                 /* size.  This results in    */
  1344. /* extra cache line flushes  */
  1345. /* but operation is correct. */
  1346. /* Can't get cache line size */
  1347. /* from NACA as it is being  */
  1348. /* moved too.                */
  1349. mtctr r0 /* put # words/line in ctr */
  1350. 3: addi r6,r6,8 /* copy a cache line */
  1351. ldx r0,r6,r4
  1352. stdx r0,r6,r3
  1353. bdnz 3b
  1354. dcbst r6,r3 /* write it to memory */
  1355. sync
  1356. icbi r6,r3 /* flush the icache line */
  1357. cmpld 0,r6,r5
  1358. blt 4b
  1359. sync
  1360. addi r5,r5,8
  1361. addi r6,r6,8
  1362. blr
  1363. .align 8
  1364. copy_to_here:
  1365. /*
  1366.  * Disable FP for the task which had the FPU previously,
  1367.  * and save its floating-point registers in its thread_struct.
  1368.  * Enables the FPU for use in the kernel on return.
  1369.  * On SMP we know the fpu is free, since we give it up every
  1370.  * switch.  -- Cort
  1371.  */
  1372. _STATIC(load_up_fpu)
  1373. mfmsr r5                      /* grab the current MSR */
  1374. ori r5,r5,MSR_FP
  1375. mtmsrd  r5 /* enable use of fpu now */
  1376. isync
  1377. /*
  1378.  * For SMP, we don't do lazy FPU switching because it just gets too
  1379.  * horrendously complex, especially when a task switches from one CPU
  1380.  * to another.  Instead we call giveup_fpu in switch_to.
  1381.  *
  1382.  */
  1383. #ifndef CONFIG_SMP
  1384. LOADBASE(r3,last_task_used_math)
  1385. ld r4,last_task_used_math@l(r3)
  1386. cmpi 0,r4,0
  1387. beq 1f
  1388. addi r4,r4,THREAD        /* want THREAD of last_task_used_math */
  1389. SAVE_32FPRS(0, r4)
  1390. mffs fr0
  1391. stfd fr0,THREAD_FPSCR-4(r4)
  1392. ld r5,PT_REGS(r4)
  1393. ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
  1394. li r20,MSR_FP|MSR_FE0|MSR_FE1
  1395. andc r4,r4,r20 /* disable FP for previous task */
  1396. std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
  1397. 1:
  1398. #endif /* CONFIG_SMP */
  1399. /* enable use of FP after return */
  1400. ori r23,r23,MSR_FP|MSR_FE0|MSR_FE1
  1401. addi r5,r13,THREAD /* Get THREAD */
  1402. lfd fr0,THREAD_FPSCR-4(r5)
  1403. mtfsf 0xff,fr0
  1404. REST_32FPRS(0, r5)
  1405. #ifndef CONFIG_SMP
  1406. subi r4,r5,THREAD /* Back to 'current' */
  1407. std r4,last_task_used_math@l(r3)
  1408. #endif /* CONFIG_SMP */
  1409. /* restore registers and return */
  1410. b fast_exception_return
  1411. /*
  1412.  * FP unavailable trap from kernel - print a message, but let
  1413.  * the task use FP in the kernel until it returns to user mode.
  1414.  */
  1415. _GLOBAL(KernelFP)
  1416. ld r3,_MSR(r1)
  1417. ori r3,r3,MSR_FP
  1418. std r3,_MSR(r1) /* enable use of FP after return */
  1419. LOADADDR(r3,86f)
  1420. mfspr r4,SPRG3 /* Get PACA */
  1421. ld r4,PACACURRENT(r4) /* current */
  1422. ld r5,_NIP(r1)
  1423. b .ret_from_except
  1424. 86: .string "floating point used in kernel (task=%p, pc=%x)n"
  1425. .align 4
  1426. /*
  1427.  * giveup_fpu(tsk)
  1428.  * Disable FP for the task given as the argument,
  1429.  * and save the floating-point registers in its thread_struct.
  1430.  * Enables the FPU for use in the kernel on return.
  1431.  */
  1432. _GLOBAL(giveup_fpu)
  1433. mfmsr r5
  1434. ori r5,r5,MSR_FP
  1435. mtmsrd r5 /* enable use of fpu now */
  1436. isync
  1437. cmpi 0,r3,0
  1438. beqlr- /* if no previous owner, done */
  1439. addi r3,r3,THREAD /* want THREAD of task */
  1440. ld r5,PT_REGS(r3)
  1441. cmpi 0,r5,0
  1442. SAVE_32FPRS(0, r3)
  1443. mffs fr0
  1444. stfd fr0,THREAD_FPSCR-4(r3)
  1445. beq 1f
  1446. ld r4,_MSR-STACK_FRAME_OVERHEAD(r5)
  1447. li r3,MSR_FP|MSR_FE0|MSR_FE1
  1448. andc r4,r4,r3 /* disable FP for previous task */
  1449. std r4,_MSR-STACK_FRAME_OVERHEAD(r5)
  1450. 1:
  1451. #ifndef CONFIG_SMP
  1452. li r5,0
  1453. LOADBASE(r4,last_task_used_math)
  1454. std r5,last_task_used_math@l(r4)
  1455. #endif /* CONFIG_SMP */
  1456. blr
  1457. #ifdef CONFIG_SMP
  1458. /*
  1459.  * This function is called after the master CPU has released the
  1460.  * secondary processors.  The execution environment is relocation off.
  1461.  * The paca for this processor has the following fields initialized at
  1462.  * this point:
  1463.  *   1. Processor number
  1464.  *   2. Segment table pointer (virtual address)
  1465.  * On entry the following are set:
  1466.  *   r1    = stack pointer.  vaddr for iSeries, raddr (temp stack) for pSeries
  1467.  *   r24   = cpu# (in Linux terms)
  1468.  *   r25   = paca virtual address
  1469.  *   SPRG3 = paca virtual address
  1470.  */
  1471. _GLOBAL(__secondary_start)
  1472. HMT_MEDIUM /* Set thread priority to MEDIUM */
  1473. /* set up the TOC (virtual address) */
  1474. LOADADDR(r2,__toc_start)
  1475. addi    r2,r2,0x4000
  1476. addi    r2,r2,0x4000
  1477. std r2,PACATOC(r25)
  1478. li r6,0
  1479. std r6,PACAKSAVE(r25)
  1480. stb r6,PACAPROCENABLED(r25)
  1481. #ifndef CONFIG_PPC_ISERIES
  1482. /* Initialize the page table pointer register. */
  1483. LOADADDR(r6,_SDR1)
  1484. ld r6,0(r6) /* get the value of _SDR1 */
  1485. mtspr SDR1,r6 /* set the htab location  */
  1486. #endif
  1487. /* Initialize the first segment table (or SLB) entry                */
  1488. ld r3,PACASTABVIRT(r25)    /* get addr of segment table        */
  1489. bl .stab_initialize
  1490. /* Initialize the kernel stack.  Just a repeat for iSeries.         */
  1491. LOADADDR(r3,current_set)
  1492. sldi r28,r24,4 /* get current_set[cpu#] */
  1493. ldx r13,r3,r28
  1494. std r13,PACACURRENT(r25)
  1495. addi r1,r13,TASK_UNION_SIZE
  1496. subi r1,r1,STACK_FRAME_OVERHEAD
  1497. ld r3,PACASTABREAL(r25)    /* get raddr of segment table       */
  1498. ori r4,r3,1 /* turn on valid bit                */
  1499. #ifdef CONFIG_PPC_ISERIES
  1500. li r0,-1 /* hypervisor call */
  1501. li r3,1
  1502. sldi r3,r3,63 /* 0x8000000000000000 */
  1503. ori r3,r3,4 /* 0x8000000000000004 */
  1504. sc /* HvCall_setASR */
  1505. #else
  1506. /* set the ASR */
  1507. addi r3,0,0x4000     /* r3 = ptr to naca */
  1508. lhz    r3,PLATFORM(r3) /* r3 = platform flags */
  1509. cmpldi  r3,PLATFORM_PSERIES_LPAR
  1510. bne    98f
  1511. mfspr r3,PVR
  1512. srwi r3,r3,16
  1513. cmpwi r3,0x37         /* SStar */
  1514. bne 98f
  1515. li r3,H_SET_ASR    /* hcall = H_SET_ASR */
  1516. HSC      /* Invoking hcall */
  1517. b 99f
  1518. 98:                             /* !(rpa hypervisor) || !(sstar) */
  1519. mtasr r4         /* set the stab location         */
  1520. 99:
  1521. #endif
  1522. li r7,0
  1523. mtlr r7
  1524. /* enable MMU and jump to start_secondary */
  1525. LOADADDR(r3,.start_secondary_prolog)
  1526. SET_REG_TO_CONST(r4, MSR_KERNEL)
  1527. #ifdef DO_SOFT_DISABLE
  1528. ori r4,r4,MSR_EE
  1529. #endif
  1530. mtspr SRR0,r3
  1531. mtspr SRR1,r4
  1532. rfid
  1533. #endif /* CONFIG_SMP */
  1534. /* 
  1535.  * Running with relocation on at this point.  All we want to do is
  1536.  * zero the stack back-chain pointer before going into C code.
  1537.  */
  1538. _GLOBAL(start_secondary_prolog)
  1539. li r3,0
  1540. std r3,0(r1)                /* Zero the stack frame pointer     */
  1541. bl .start_secondary
  1542. /*
  1543.  * This subroutine clobbers r11, r12 and the LR
  1544.  */
  1545. _GLOBAL(enable_64b_mode)
  1546. mfmsr   r11                      /* grab the current MSR */
  1547. li      r12,1
  1548. rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
  1549. or      r11,r11,r12
  1550. li      r12,1
  1551. rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
  1552. or      r11,r11,r12
  1553. mtmsrd  r11
  1554. isync
  1555. blr
  1556. /*
  1557.  * This subroutine clobbers r11, r12 and the LR
  1558.  */
  1559. _GLOBAL(enable_32b_mode)
  1560. mfmsr   r11                      /* grab the current MSR */
  1561. li      r12,1
  1562. rldicr  r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
  1563. andc r11,r11,r12
  1564. li      r12,1
  1565. rldicr  r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
  1566. andc r11,r11,r12
  1567. mtmsrd  r11
  1568. isync
  1569. blr
  1570. /*
  1571.  * This is where the main kernel code starts.
  1572.  */
  1573. _STATIC(start_here_pSeries)
  1574. /* get a new offset, now that the kernel has moved. */
  1575. bl .reloc_offset
  1576. mr r26,r3
  1577. /* setup the naca pointer which is needed by *tab_initialize       */
  1578. LOADADDR(r6,naca)
  1579. sub r6,r6,r26                /* addr of the variable naca      */
  1580. li r27,0x4000
  1581. std r27,0(r6)    /* set the value of naca          */
  1582. #ifdef CONFIG_HMT
  1583. /* Start up the second thread on cpu 0 */
  1584. mfspr r3,PVR
  1585. srwi r3,r3,16
  1586. cmpwi r3,0x34                 /* Pulsar  */
  1587. beq 90f
  1588. cmpwi r3,0x36                 /* Icestar */
  1589. beq 90f
  1590. cmpwi r3,0x37                 /* SStar   */
  1591. beq 90f
  1592. b 91f                     /* HMT not supported */
  1593. 90: li      r3,0
  1594. bl .hmt_start_secondary
  1595. 91:
  1596. #endif
  1597. #ifdef CONFIG_SMP
  1598. /* All secondary cpus are now spinning on a common
  1599.  * spinloop, release them all now so they can start
  1600.  * to spin on their individual paca spinloops.
  1601.  * For non SMP kernels, the secondary cpus never
  1602.  * get out of the common spinloop.
  1603.  */
  1604. li r3,1
  1605. LOADADDR(r5,__secondary_hold_spinloop)
  1606. tophys(r4,r5)
  1607. std     r3,0(r4)
  1608. #endif
  1609. /* The following gets the stack and TOC set up with the regs */
  1610. /* pointing to the real addr of the kernel stack.  This is   */
  1611. /* all done to support the C function call below which sets  */
  1612. /* up the htab.  This is done because we have relocated the  */
  1613. /* kernel but are still running in real mode. */
  1614. /* real ptr to current */
  1615. LOADADDR(r3,init_task_union)
  1616. sub r3,r3,r26
  1617. /* set up a stack pointer (physical address) */
  1618. addi r1,r3,TASK_UNION_SIZE
  1619. li r0,0
  1620. stdu r0,-STACK_FRAME_OVERHEAD(r1)
  1621. /* set up the TOC (physical address) */
  1622. LOADADDR(r2,__toc_start)
  1623. addi    r2,r2,0x4000
  1624. addi    r2,r2,0x4000
  1625. sub r2,r2,r26
  1626. /* Get the pointer to the segment table which is used by           */
  1627. /* stab_initialize                                                 */
  1628. li r27,0x4000
  1629. ld r6,PACA(r27)            /* Get the base paca pointer       */
  1630. sub r6,r6,r26 /* convert to physical addr         */
  1631. mtspr SPRG3,r6 /* PPPBBB: Temp... -Peter */
  1632. ld r3,PACASTABREAL(r6)
  1633. ori r4,r3,1 /* turn on valid bit                */
  1634. /* set the ASR */
  1635. addi r3,0,0x4000     /* r3 = ptr to naca */
  1636. lhz    r3,PLATFORM(r3) /* r3 = platform flags */
  1637. cmpldi  r3,PLATFORM_PSERIES_LPAR
  1638. bne    98f
  1639. mfspr r3,PVR
  1640. srwi r3,r3,16
  1641. cmpwi r3,0x37         /* SStar */
  1642. bne 98f
  1643. li r3,H_SET_ASR    /* hcall = H_SET_ASR */
  1644. HSC              /* Invoking hcall */
  1645. b      99f
  1646. 98:                 /* This is not a hypervisor machine */
  1647. mtasr r4 /* set the stab location            */
  1648. 99:
  1649. mfspr r6,SPRG3
  1650. ld r3,PACASTABREAL(r6)     /* restore r3 for stab_initialize */
  1651. /* Initialize an initial memory mapping and turn on relocation.   */
  1652. bl .stab_initialize
  1653. bl .htab_initialize
  1654. addi  r3,0,0x4000     /* r3 = ptr to naca */
  1655. lhz   r3,PLATFORM(r3) /* r3 = platform flags */
  1656. cmpldi r3,PLATFORM_PSERIES
  1657. bne    98f
  1658. LOADADDR(r6,_SDR1) /* Only if NOT LPAR */
  1659. sub r6,r6,r26
  1660. ld r6,0(r6) /* get the value of _SDR1 */
  1661. mtspr SDR1,r6 /* set the htab location  */
  1662. 98: 
  1663. LOADADDR(r3,.start_here_common)
  1664. SET_REG_TO_CONST(r4, MSR_KERNEL)
  1665. mtspr SRR0,r3
  1666. mtspr SRR1,r4
  1667. rfid
  1668. /* This is where all platforms converge execution */
  1669. _STATIC(start_here_common)
  1670. /* relocation is on at this point */
  1671. /* Clear out the BSS */
  1672. LOADADDR(r11,_end)
  1673. LOADADDR(r8,__bss_start)
  1674. sub r11,r11,r8        /* bss size                        */
  1675. addi r11,r11,7         /* round up to an even double word */
  1676. rldicl. r11,r11,61,3      /* shift right by 3                */
  1677. beq 4f
  1678. addi r8,r8,-8
  1679. li r0,0
  1680. mtctr r11   /* zero this many doublewords      */
  1681. 3: stdu r0,8(r8)
  1682. bdnz 3b
  1683. 4:
  1684. /* The following code sets up the SP and TOC now that we are */
  1685. /* running with translation enabled. */
  1686. /* ptr to current */
  1687. LOADADDR(r3,init_task_union)
  1688. /* set up the stack */
  1689. addi r1,r3,TASK_UNION_SIZE
  1690. li r0,0
  1691. stdu r0,-STACK_FRAME_OVERHEAD(r1)
  1692. /* set up the TOC */
  1693. LOADADDR(r2,__toc_start)
  1694. addi    r2,r2,0x4000
  1695. addi    r2,r2,0x4000
  1696. /* setup the naca pointer                                         */
  1697. LOADADDR(r9,naca)
  1698. SET_REG_TO_CONST(r8, KERNELBASE)
  1699. addi r8,r8,0x4000
  1700. std r8,0(r9) /* set the value of the naca ptr  */
  1701. LOADADDR(r4,naca)               /* Get naca ptr address           */
  1702. ld r4,0(r4)                /* Get the location of the naca   */
  1703. ld r4,PACA(r4)             /* Get the base paca pointer      */
  1704. mtspr SPRG3,r4
  1705. /* ptr to current */
  1706. LOADADDR(r13,init_task_union)
  1707. std r13,PACACURRENT(r4)
  1708. std r2,PACATOC(r4)
  1709. li r5,0
  1710. std r0,PACAKSAVE(r4)
  1711. /* ptr to hardware interrupt stack for processor 0                */
  1712. LOADADDR(r3, hardware_int_paca0)
  1713. li      r5,0x1000
  1714. sldi    r5,r5,3
  1715. subi    r5,r5,STACK_FRAME_OVERHEAD
  1716. add     r3,r3,r5
  1717. std     r3,PACAHRDWINTSTACK(r4)
  1718. li      r3,0
  1719. stb     r3,PACAHRDWINTCOUNT(r4)
  1720. /* Restore the parms passed in from the bootloader. */
  1721. mr r3,r31
  1722. mr r4,r30
  1723. mr r5,r29
  1724. mr r6,r28
  1725. mr r7,r27
  1726. bl .setup_system
  1727. /* Load up the kernel context */
  1728. 5:
  1729. #ifdef DO_SOFT_DISABLE
  1730. mfspr r4,SPRG3
  1731. li r5,0
  1732. stb r5,PACAPROCENABLED(r4) /* Soft Disabled */
  1733. mfmsr r5
  1734. ori r5,r5,MSR_EE /* Hard Enabled */
  1735. mtmsrd r5
  1736. #endif
  1737. bl .start_kernel
  1738. _GLOBAL(hmt_init)
  1739. #ifdef CONFIG_HMT
  1740. LOADADDR(r5, hmt_thread_data)
  1741. mfspr r7,PVR
  1742. srwi r7,r7,16
  1743. cmpwi r7,0x34                 /* Pulsar  */
  1744. beq 90f
  1745. cmpwi r7,0x36                 /* Icestar */
  1746. beq 91f
  1747. cmpwi r7,0x37                 /* SStar   */
  1748. beq 91f
  1749. b 101f
  1750. 90: mfspr r6,PIR
  1751. andi. r6,r6,0x1f
  1752. b 92f
  1753. 91: mfspr r6,PIR
  1754. andi. r6,r6,0x3ff
  1755. 92: sldi r4,r24,3
  1756. stwx r6,r5,r4
  1757. bl .hmt_start_secondary
  1758. b 101f
  1759. __hmt_secondary_hold:
  1760. LOADADDR(r5, hmt_thread_data)
  1761. clrldi r5,r5,4
  1762. li r7,0
  1763. mfspr r6,PIR
  1764. mfspr r8,PVR
  1765. srwi r8,r8,16
  1766. cmpwi r8,0x34
  1767. bne 93f
  1768. andi. r6,r6,0x1f
  1769. b 103f
  1770. 93: andi. r6,r6,0x3f
  1771. 103: lwzx r8,r5,r7
  1772. cmpw r8,r6
  1773. beq 104f
  1774. addi r7,r7,8
  1775. b 103b
  1776. 104: addi r7,r7,4
  1777. lwzx r9,r5,r7
  1778. mr      r24,r9
  1779. 101:
  1780. #endif
  1781. mr      r3,r24
  1782. b       .pseries_secondary_smp_init
  1783. #ifdef CONFIG_HMT
  1784. _GLOBAL(hmt_start_secondary)
  1785. LOADADDR(r4,__hmt_secondary_hold)
  1786. clrldi r4,r4,4
  1787. mtspr   NIADORM, r4
  1788. mfspr   r4, MSRDORM
  1789. li      r5, -65
  1790. and     r4, r4, r5
  1791. mtspr   MSRDORM, r4
  1792. lis r4,0xffef
  1793. ori r4,r4,0x7403
  1794. mtspr TSC, r4
  1795. li r4,0x1f4
  1796. mtspr TST, r4
  1797. mfspr   r4, HID0
  1798. ori     r4, r4, 0x1
  1799. mtspr   HID0, r4
  1800. mfspr   r4, CTRLF
  1801. oris    r4, r4, 0x40
  1802. mtspr   CTRLT, r4
  1803. blr
  1804. #endif
  1805. /*
  1806.  * We put a few things here that have to be page-aligned.
  1807.  * This stuff goes at the beginning of the data segment,
  1808.  * which is page-aligned.
  1809.  */
  1810. .data
  1811. .align  12
  1812. .globl sdata
  1813. sdata:
  1814. .globl empty_zero_page
  1815. empty_zero_page:
  1816. .space 4096
  1817. .globl swapper_pg_dir
  1818. swapper_pg_dir:
  1819. .space 4096
  1820. .globl ioremap_dir
  1821. ioremap_dir:
  1822. .space 4096
  1823. .globl bolted_dir
  1824. bolted_dir:
  1825. .space 4096
  1826. .globl  hardware_int_paca0
  1827. hardware_int_paca0:
  1828. .space 8*4096
  1829. /* 1 page segment table per cpu (max 48, cpu0 allocated at 0x5000) */
  1830. .globl stab_array
  1831. stab_array:
  1832.         .space 4096 * (48 - 1)