195719Sbenno/* $FreeBSD$ */ 295719Sbenno/* $NetBSD: trap_subr.S,v 1.20 2002/04/22 23:20:08 kleink Exp $ */ 395719Sbenno 4139825Simp/*- 595719Sbenno * Copyright (C) 1995, 1996 Wolfgang Solfrank. 695719Sbenno * Copyright (C) 1995, 1996 TooLs GmbH. 795719Sbenno * All rights reserved. 895719Sbenno * 995719Sbenno * Redistribution and use in source and binary forms, with or without 1095719Sbenno * modification, are permitted provided that the following conditions 1195719Sbenno * are met: 1295719Sbenno * 1. Redistributions of source code must retain the above copyright 1395719Sbenno * notice, this list of conditions and the following disclaimer. 1495719Sbenno * 2. Redistributions in binary form must reproduce the above copyright 1595719Sbenno * notice, this list of conditions and the following disclaimer in the 1695719Sbenno * documentation and/or other materials provided with the distribution. 1795719Sbenno * 3. All advertising materials mentioning features or use of this software 1895719Sbenno * must display the following acknowledgement: 1995719Sbenno * This product includes software developed by TooLs GmbH. 2095719Sbenno * 4. The name of TooLs GmbH may not be used to endorse or promote products 2195719Sbenno * derived from this software without specific prior written permission. 2295719Sbenno * 2395719Sbenno * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 2495719Sbenno * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2595719Sbenno * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2695719Sbenno * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2795719Sbenno * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2895719Sbenno * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 2995719Sbenno * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 3095719Sbenno * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 3195719Sbenno * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 3295719Sbenno * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3395719Sbenno */ 3495719Sbenno 3595719Sbenno/* 3695719Sbenno * NOTICE: This is not a standalone file. to use it, #include it in 3795719Sbenno * your port's locore.S, like so: 3895719Sbenno * 39174599Smarcel * #include <powerpc/aim/trap_subr.S> 4095719Sbenno */ 4195719Sbenno 42293641Snwhitehorn/* Locate the per-CPU data structure */ 43293641Snwhitehorn#define GET_CPUINFO(r) \ 44293641Snwhitehorn mfsprg0 r 45293641Snwhitehorn#define GET_TOCBASE(r) \ 46293641Snwhitehorn li r,TRAP_TOCBASE; /* Magic address for TOC */ \ 47293641Snwhitehorn ld r,0(r) 4895719Sbenno 4995719Sbenno/* 50209975Snwhitehorn * Restore SRs for a pmap 51209975Snwhitehorn * 52209975Snwhitehorn * Requires that r28-r31 be scratch, with r28 initialized to the SLB cache 53209975Snwhitehorn */ 54209975Snwhitehorn 55212722Snwhitehorn/* 56212722Snwhitehorn * User SRs are loaded through a pointer to the current pmap. 57212722Snwhitehorn */ 58212722Snwhitehornrestore_usersrs: 59222620Snwhitehorn GET_CPUINFO(%r28) 60222620Snwhitehorn ld %r28,PC_USERSLB(%r28) 61209975Snwhitehorn li %r29, 0 /* Set the counter to zero */ 62209975Snwhitehorn 63209975Snwhitehorn slbia 64209975Snwhitehorn slbmfee %r31,%r29 65209975Snwhitehorn clrrdi %r31,%r31,28 66209975Snwhitehorn slbie %r31 67222620Snwhitehorn1: ld %r31, 0(%r28) /* Load SLB entry pointer */ 68279751Snwhitehorn cmpdi %r31, 0 /* If NULL, stop */ 69222620Snwhitehorn beqlr 70209975Snwhitehorn 71212722Snwhitehorn ld %r30, 0(%r31) /* Load SLBV */ 72212722Snwhitehorn ld %r31, 8(%r31) /* Load SLBE */ 73212722Snwhitehorn or %r31, %r31, %r29 /* Set SLBE slot */ 74222620Snwhitehorn slbmte %r30, %r31 /* Install SLB entry */ 75209975Snwhitehorn 76222620Snwhitehorn addi %r28, %r28, 8 /* Advance pointer */ 77222620Snwhitehorn addi %r29, %r29, 1 78222620Snwhitehorn b 1b /* Repeat */ 79209975Snwhitehorn 80209975Snwhitehorn/* 81212722Snwhitehorn * Kernel SRs are loaded directly from the PCPU fields 8295719Sbenno */ 83212722Snwhitehornrestore_kernsrs: 84222620Snwhitehorn GET_CPUINFO(%r28) 85222620Snwhitehorn addi %r28,%r28,PC_KERNSLB 86212722Snwhitehorn li %r29, 0 /* Set the counter to zero */ 8795719Sbenno 88212722Snwhitehorn slbia 89212722Snwhitehorn slbmfee %r31,%r29 90212722Snwhitehorn clrrdi %r31,%r31,28 91212722Snwhitehorn slbie %r31 92279751Snwhitehorn1: cmpdi %r29, USER_SLB_SLOT /* Skip the user slot */ 93222620Snwhitehorn beq- 2f 9495719Sbenno 95222620Snwhitehorn ld %r31, 8(%r28) /* Load SLBE */ 96279751Snwhitehorn cmpdi %r31, 0 /* If SLBE is not valid, stop */ 97222620Snwhitehorn beqlr 98212722Snwhitehorn ld %r30, 0(%r28) /* Load SLBV */ 99222620Snwhitehorn slbmte %r30, %r31 /* Install SLB entry */ 100212722Snwhitehorn 101222620Snwhitehorn2: addi %r28, %r28, 16 /* Advance pointer */ 102222620Snwhitehorn addi %r29, %r29, 1 103279751Snwhitehorn cmpdi %r29, 64 /* Repeat if we are not at the end */ 104222620Snwhitehorn blt 1b 105222620Snwhitehorn blr 106212722Snwhitehorn 107125441Sgrehan/* 108125441Sgrehan * FRAME_SETUP assumes: 109125441Sgrehan * SPRG1 SP (1) 110188860Snwhitehorn * SPRG3 trap type 111209975Snwhitehorn * savearea r27-r31,DAR,DSISR (DAR & DSISR only for DSI traps) 112125441Sgrehan * r28 LR 113125441Sgrehan * r29 CR 114125441Sgrehan * r30 scratch 115125441Sgrehan * r31 scratch 116125441Sgrehan * r1 kernel stack 117125441Sgrehan * SRR0/1 as at start of trap 118230123Snwhitehorn * 119230123Snwhitehorn * NOTE: SPRG1 is never used while the MMU is on, making it safe to reuse 120230123Snwhitehorn * in any real-mode fault handler, including those handling double faults. 121125441Sgrehan */ 122125441Sgrehan#define FRAME_SETUP(savearea) \ 123125441Sgrehan/* Have to enable translation to allow access of kernel stack: */ \ 124125441Sgrehan GET_CPUINFO(%r31); \ 125125441Sgrehan mfsrr0 %r30; \ 126209975Snwhitehorn std %r30,(savearea+CPUSAVE_SRR0)(%r31); /* save SRR0 */ \ 127125441Sgrehan mfsrr1 %r30; \ 128209975Snwhitehorn std %r30,(savearea+CPUSAVE_SRR1)(%r31); /* save SRR1 */ \ 129230123Snwhitehorn mfsprg1 %r31; /* get saved SP (clears SPRG1) */ \ 130125441Sgrehan mfmsr %r30; \ 131125441Sgrehan ori %r30,%r30,(PSL_DR|PSL_IR|PSL_RI)@l; /* relocation on */ \ 132125441Sgrehan mtmsr %r30; /* stack can now be accessed */ \ 133125441Sgrehan isync; \ 134209975Snwhitehorn stdu %r31,-(FRAMELEN+288)(%r1); /* save it in the callframe */ \ 135209975Snwhitehorn std %r0, FRAME_0+48(%r1); /* save r0 in the trapframe */ \ 136209975Snwhitehorn std %r31,FRAME_1+48(%r1); /* save SP " " */ \ 137209975Snwhitehorn std %r2, FRAME_2+48(%r1); /* save r2 " " */ \ 138209975Snwhitehorn std %r28,FRAME_LR+48(%r1); /* save LR " " */ \ 139209975Snwhitehorn std %r29,FRAME_CR+48(%r1); /* save CR " " */ \ 140125441Sgrehan GET_CPUINFO(%r2); \ 141209975Snwhitehorn ld %r27,(savearea+CPUSAVE_R27)(%r2); /* get saved r27 */ \ 142209975Snwhitehorn ld %r28,(savearea+CPUSAVE_R28)(%r2); /* get saved r28 */ \ 143209975Snwhitehorn ld %r29,(savearea+CPUSAVE_R29)(%r2); /* get saved r29 */ \ 144209975Snwhitehorn ld %r30,(savearea+CPUSAVE_R30)(%r2); /* get saved r30 */ \ 145209975Snwhitehorn ld %r31,(savearea+CPUSAVE_R31)(%r2); /* get saved r31 */ \ 146209975Snwhitehorn std %r3, FRAME_3+48(%r1); /* save r3-r31 */ \ 147209975Snwhitehorn std %r4, FRAME_4+48(%r1); \ 148209975Snwhitehorn std %r5, FRAME_5+48(%r1); \ 149209975Snwhitehorn std %r6, FRAME_6+48(%r1); \ 150209975Snwhitehorn std %r7, FRAME_7+48(%r1); \ 151209975Snwhitehorn std %r8, FRAME_8+48(%r1); \ 152209975Snwhitehorn std %r9, FRAME_9+48(%r1); \ 153209975Snwhitehorn std %r10, FRAME_10+48(%r1); \ 154209975Snwhitehorn std %r11, FRAME_11+48(%r1); \ 155209975Snwhitehorn std %r12, FRAME_12+48(%r1); \ 156209975Snwhitehorn std %r13, FRAME_13+48(%r1); \ 157209975Snwhitehorn std %r14, FRAME_14+48(%r1); \ 158209975Snwhitehorn std %r15, FRAME_15+48(%r1); \ 159209975Snwhitehorn std %r16, FRAME_16+48(%r1); \ 160209975Snwhitehorn std %r17, FRAME_17+48(%r1); \ 161209975Snwhitehorn std %r18, FRAME_18+48(%r1); \ 162209975Snwhitehorn std %r19, FRAME_19+48(%r1); \ 163209975Snwhitehorn std %r20, FRAME_20+48(%r1); \ 164209975Snwhitehorn std %r21, FRAME_21+48(%r1); \ 165209975Snwhitehorn std %r22, FRAME_22+48(%r1); \ 166209975Snwhitehorn std %r23, FRAME_23+48(%r1); \ 167209975Snwhitehorn std %r24, FRAME_24+48(%r1); \ 168209975Snwhitehorn std %r25, FRAME_25+48(%r1); \ 169209975Snwhitehorn std %r26, FRAME_26+48(%r1); \ 170209975Snwhitehorn std %r27, FRAME_27+48(%r1); \ 171209975Snwhitehorn std %r28, FRAME_28+48(%r1); \ 172209975Snwhitehorn std %r29, FRAME_29+48(%r1); \ 173209975Snwhitehorn std %r30, FRAME_30+48(%r1); \ 174209975Snwhitehorn std %r31, FRAME_31+48(%r1); \ 175209975Snwhitehorn ld %r28,(savearea+CPUSAVE_AIM_DAR)(%r2); /* saved DAR */ \ 176209975Snwhitehorn ld %r29,(savearea+CPUSAVE_AIM_DSISR)(%r2);/* saved DSISR */\ 177209975Snwhitehorn ld %r30,(savearea+CPUSAVE_SRR0)(%r2); /* saved SRR0 */ \ 178209975Snwhitehorn ld %r31,(savearea+CPUSAVE_SRR1)(%r2); /* saved SRR1 */ \ 179125441Sgrehan mfxer %r3; \ 180125441Sgrehan mfctr %r4; \ 181188860Snwhitehorn mfsprg3 %r5; \ 182209975Snwhitehorn std %r3, FRAME_XER+48(1); /* save xer/ctr/exc */ \ 183209975Snwhitehorn std %r4, FRAME_CTR+48(1); \ 184209975Snwhitehorn std %r5, FRAME_EXC+48(1); \ 185209975Snwhitehorn std %r28,FRAME_AIM_DAR+48(1); \ 186209975Snwhitehorn std %r29,FRAME_AIM_DSISR+48(1); /* save dsisr/srr0/srr1 */ \ 187209975Snwhitehorn std %r30,FRAME_SRR0+48(1); \ 188223485Snwhitehorn std %r31,FRAME_SRR1+48(1); \ 189223485Snwhitehorn ld %r13,PC_CURTHREAD(%r2) /* set kernel curthread */ 19095719Sbenno 191125441Sgrehan#define FRAME_LEAVE(savearea) \ 192223485Snwhitehorn/* Disable exceptions: */ \ 193223485Snwhitehorn mfmsr %r2; \ 194223485Snwhitehorn andi. %r2,%r2,~PSL_EE@l; \ 195223485Snwhitehorn mtmsr %r2; \ 196223485Snwhitehorn isync; \ 197125441Sgrehan/* Now restore regs: */ \ 198209975Snwhitehorn ld %r2,FRAME_SRR0+48(%r1); \ 199209975Snwhitehorn ld %r3,FRAME_SRR1+48(%r1); \ 200209975Snwhitehorn ld %r4,FRAME_CTR+48(%r1); \ 201209975Snwhitehorn ld %r5,FRAME_XER+48(%r1); \ 202209975Snwhitehorn ld %r6,FRAME_LR+48(%r1); \ 203125441Sgrehan GET_CPUINFO(%r7); \ 204209975Snwhitehorn std %r2,(savearea+CPUSAVE_SRR0)(%r7); /* save SRR0 */ \ 205209975Snwhitehorn std %r3,(savearea+CPUSAVE_SRR1)(%r7); /* save SRR1 */ \ 206209975Snwhitehorn ld %r7,FRAME_CR+48(%r1); \ 207125441Sgrehan mtctr %r4; \ 208125441Sgrehan mtxer %r5; \ 209125441Sgrehan mtlr %r6; \ 210230123Snwhitehorn mtsprg2 %r7; /* save cr */ \ 211209975Snwhitehorn ld %r31,FRAME_31+48(%r1); /* restore r0-31 */ \ 212209975Snwhitehorn ld %r30,FRAME_30+48(%r1); \ 213209975Snwhitehorn ld %r29,FRAME_29+48(%r1); \ 214209975Snwhitehorn ld %r28,FRAME_28+48(%r1); \ 215209975Snwhitehorn ld %r27,FRAME_27+48(%r1); \ 216209975Snwhitehorn ld %r26,FRAME_26+48(%r1); \ 217209975Snwhitehorn ld %r25,FRAME_25+48(%r1); \ 218209975Snwhitehorn ld %r24,FRAME_24+48(%r1); \ 219209975Snwhitehorn ld %r23,FRAME_23+48(%r1); \ 220209975Snwhitehorn ld %r22,FRAME_22+48(%r1); \ 221209975Snwhitehorn ld %r21,FRAME_21+48(%r1); \ 222209975Snwhitehorn ld %r20,FRAME_20+48(%r1); \ 223209975Snwhitehorn ld %r19,FRAME_19+48(%r1); \ 224209975Snwhitehorn ld %r18,FRAME_18+48(%r1); \ 225209975Snwhitehorn ld %r17,FRAME_17+48(%r1); \ 226209975Snwhitehorn ld %r16,FRAME_16+48(%r1); \ 227209975Snwhitehorn ld %r15,FRAME_15+48(%r1); \ 228209975Snwhitehorn ld %r14,FRAME_14+48(%r1); \ 229209975Snwhitehorn ld %r13,FRAME_13+48(%r1); \ 230209975Snwhitehorn ld %r12,FRAME_12+48(%r1); \ 231209975Snwhitehorn ld %r11,FRAME_11+48(%r1); \ 232209975Snwhitehorn ld %r10,FRAME_10+48(%r1); \ 233209975Snwhitehorn ld %r9, FRAME_9+48(%r1); \ 234209975Snwhitehorn ld %r8, FRAME_8+48(%r1); \ 235209975Snwhitehorn ld %r7, FRAME_7+48(%r1); \ 236209975Snwhitehorn ld %r6, FRAME_6+48(%r1); \ 237209975Snwhitehorn ld %r5, FRAME_5+48(%r1); \ 238209975Snwhitehorn ld %r4, FRAME_4+48(%r1); \ 239209975Snwhitehorn ld %r3, FRAME_3+48(%r1); \ 240209975Snwhitehorn ld %r2, FRAME_2+48(%r1); \ 241209975Snwhitehorn ld %r0, FRAME_0+48(%r1); \ 242209975Snwhitehorn ld %r1, FRAME_1+48(%r1); \ 243125441Sgrehan/* Can't touch %r1 from here on */ \ 244230123Snwhitehorn mtsprg3 %r3; /* save r3 */ \ 245125441Sgrehan/* Disable translation, machine check and recoverability: */ \ 246230123Snwhitehorn mfmsr %r3; \ 247230123Snwhitehorn andi. %r3,%r3,~(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l; \ 248230123Snwhitehorn mtmsr %r3; \ 249125441Sgrehan isync; \ 250125441Sgrehan/* Decide whether we return to user mode: */ \ 251230123Snwhitehorn GET_CPUINFO(%r3); \ 252230123Snwhitehorn ld %r3,(savearea+CPUSAVE_SRR1)(%r3); \ 253125441Sgrehan mtcr %r3; \ 254125441Sgrehan bf 17,1f; /* branch if PSL_PR is false */ \ 255125441Sgrehan/* Restore user SRs */ \ 256209975Snwhitehorn GET_CPUINFO(%r3); \ 257209975Snwhitehorn std %r27,(savearea+CPUSAVE_R27)(%r3); \ 258209975Snwhitehorn std %r28,(savearea+CPUSAVE_R28)(%r3); \ 259209975Snwhitehorn std %r29,(savearea+CPUSAVE_R29)(%r3); \ 260209975Snwhitehorn std %r30,(savearea+CPUSAVE_R30)(%r3); \ 261209975Snwhitehorn std %r31,(savearea+CPUSAVE_R31)(%r3); \ 262209975Snwhitehorn mflr %r27; /* preserve LR */ \ 263212722Snwhitehorn bl restore_usersrs; /* uses r28-r31 */ \ 264209975Snwhitehorn mtlr %r27; \ 265209975Snwhitehorn ld %r31,(savearea+CPUSAVE_R31)(%r3); \ 266209975Snwhitehorn ld %r30,(savearea+CPUSAVE_R30)(%r3); \ 267209975Snwhitehorn ld %r29,(savearea+CPUSAVE_R29)(%r3); \ 268209975Snwhitehorn ld %r28,(savearea+CPUSAVE_R28)(%r3); \ 269209975Snwhitehorn ld %r27,(savearea+CPUSAVE_R27)(%r3); \ 270230123Snwhitehorn1: mfsprg2 %r3; /* restore cr */ \ 271230123Snwhitehorn mtcr %r3; \ 272230123Snwhitehorn GET_CPUINFO(%r3); \ 273230123Snwhitehorn ld %r3,(savearea+CPUSAVE_SRR0)(%r3); /* restore srr0 */ \ 274125441Sgrehan mtsrr0 %r3; \ 275230123Snwhitehorn GET_CPUINFO(%r3); \ 276230123Snwhitehorn ld %r3,(savearea+CPUSAVE_SRR1)(%r3); /* restore srr1 */ \ 277125441Sgrehan mtsrr1 %r3; \ 278230123Snwhitehorn mfsprg3 %r3 /* restore r3 */ 27995719Sbenno 280242723Sjhibbits#ifdef KDTRACE_HOOKS 281242723Sjhibbits .data 282242723Sjhibbits .globl dtrace_invop_calltrap_addr 283242723Sjhibbits .align 8 284242723Sjhibbits .type dtrace_invop_calltrap_addr, @object 285242723Sjhibbits .size dtrace_invop_calltrap_addr, 8 286242723Sjhibbitsdtrace_invop_calltrap_addr: 287242723Sjhibbits .word 0 288242723Sjhibbits .word 0 289242723Sjhibbits 290242723Sjhibbits .text 291242723Sjhibbits#endif 292242723Sjhibbits 29395719Sbenno/* 294178628Smarcel * Processor reset exception handler. These are typically 295178628Smarcel * the first instructions the processor executes after a 296198400Snwhitehorn * software reset. We do this in two bits so that we are 297198400Snwhitehorn * not still hanging around in the trap handling region 298198400Snwhitehorn * once the MMU is turned on. 299132571Sgrehan */ 300277561Snwhitehorn .globl CNAME(rstcode), CNAME(rstcodeend) 301178628SmarcelCNAME(rstcode): 302209975Snwhitehorn /* Explicitly set MSR[SF] */ 303209975Snwhitehorn mfmsr %r9 304209975Snwhitehorn li %r8,1 305209975Snwhitehorn insrdi %r9,%r8,1,0 306209975Snwhitehorn mtmsrd %r9 307209975Snwhitehorn isync 308277498Snwhitehorn bl 1f 309277498Snwhitehorn .llong cpu_reset 310277498Snwhitehorn1: mflr %r9 311277498Snwhitehorn ld %r9,0(%r9) 312277498Snwhitehorn mtlr %r9 313209975Snwhitehorn 314277498Snwhitehorn blr 315277561SnwhitehornCNAME(rstcodeend): 316198400Snwhitehorn 317198400Snwhitehorncpu_reset: 318277335Snwhitehorn GET_TOCBASE(%r2) 319178628Smarcel 320277335Snwhitehorn ld %r1,TOC_REF(tmpstk)(%r2) /* get new SP */ 321277335Snwhitehorn addi %r1,%r1,(TMPSTKSZ-48) 322277335Snwhitehorn 323218824Snwhitehorn bl CNAME(cpudep_ap_early_bootstrap) /* Set PCPU */ 324209975Snwhitehorn nop 325227386Snwhitehorn lis %r3,1@l 326218824Snwhitehorn bl CNAME(pmap_cpu_bootstrap) /* Turn on virtual memory */ 327209975Snwhitehorn nop 328218824Snwhitehorn bl CNAME(cpudep_ap_bootstrap) /* Set up PCPU and stack */ 329209975Snwhitehorn nop 330209975Snwhitehorn mr %r1,%r3 /* Use new stack */ 331261309Sjhibbits bl CNAME(cpudep_ap_setup) 332261309Sjhibbits nop 333261309Sjhibbits GET_CPUINFO(%r5) 334261309Sjhibbits ld %r3,(PC_RESTORE)(%r5) 335261309Sjhibbits cmpldi %cr0,%r3,0 336261309Sjhibbits beq %cr0,2f 337261309Sjhibbits nop 338261309Sjhibbits li %r4,1 339261309Sjhibbits b CNAME(longjmp) 340261309Sjhibbits nop 341261309Sjhibbits2: 342261309Sjhibbits#ifdef SMP 343218824Snwhitehorn bl CNAME(machdep_ap_bootstrap) /* And away! */ 344209975Snwhitehorn nop 345261309Sjhibbits#endif 346178628Smarcel 347178628Smarcel /* Should not be reached */ 348178628Smarcel9: 349178628Smarcel b 9b 350132571Sgrehan 351132571Sgrehan/* 35295719Sbenno * This code gets copied to all the trap vectors 353277498Snwhitehorn * (except ISI/DSI, ALI, and the interrupts). Has to fit in 8 instructions! 35495719Sbenno */ 355178628Smarcel 356277561Snwhitehorn .globl CNAME(trapcode),CNAME(trapcodeend) 357277498Snwhitehorn .p2align 3 35896773SbennoCNAME(trapcode): 359125441Sgrehan mtsprg1 %r1 /* save SP */ 360188860Snwhitehorn mflr %r1 /* Save the old LR in r1 */ 361188860Snwhitehorn mtsprg2 %r1 /* And then in SPRG2 */ 362279751Snwhitehorn ld %r1,TRAP_GENTRAP(0) 363277498Snwhitehorn mtlr %r1 364279189Snwhitehorn li %r1, 0xe0 /* How to get the vector from LR */ 365277498Snwhitehorn blrl /* Branch to generictrap */ 366277561SnwhitehornCNAME(trapcodeend): 36795719Sbenno 36895719Sbenno/* 369230123Snwhitehorn * For SLB misses: do special things for the kernel 370230123Snwhitehorn * 371230123Snwhitehorn * Note: SPRG1 is always safe to overwrite any time the MMU is on, which is 372230123Snwhitehorn * the only time this can be called. 373230123Snwhitehorn */ 374277561Snwhitehorn .globl CNAME(slbtrap),CNAME(slbtrapend) 375277498Snwhitehorn .p2align 3 376230123SnwhitehornCNAME(slbtrap): 377230123Snwhitehorn mtsprg1 %r1 /* save SP */ 378230123Snwhitehorn GET_CPUINFO(%r1) 379230123Snwhitehorn std %r2,(PC_SLBSAVE+16)(%r1) 380230123Snwhitehorn mfcr %r2 /* save CR */ 381230123Snwhitehorn std %r2,(PC_SLBSAVE+104)(%r1) 382230123Snwhitehorn mfsrr1 %r2 /* test kernel mode */ 383230123Snwhitehorn mtcr %r2 384277498Snwhitehorn bf 17,2f /* branch if PSL_PR is false */ 385230123Snwhitehorn /* User mode */ 386230123Snwhitehorn ld %r2,(PC_SLBSAVE+104)(%r1) /* Restore CR */ 387230123Snwhitehorn mtcr %r2 388230123Snwhitehorn ld %r2,(PC_SLBSAVE+16)(%r1) /* Restore R2 */ 389230123Snwhitehorn mflr %r1 /* Save the old LR in r1 */ 390230123Snwhitehorn mtsprg2 %r1 /* And then in SPRG2 */ 391277498Snwhitehorn /* 52 bytes so far */ 392277498Snwhitehorn bl 1f 393277498Snwhitehorn .llong generictrap 394277498Snwhitehorn1: mflr %r1 395277498Snwhitehorn ld %r1,0(%r1) 396277498Snwhitehorn mtlr %r1 397230123Snwhitehorn li %r1, 0x80 /* How to get the vector from LR */ 398277498Snwhitehorn blrl /* Branch to generictrap */ 399277498Snwhitehorn /* 84 bytes */ 400277498Snwhitehorn2: mflr %r2 /* Save the old LR in r2 */ 401277498Snwhitehorn nop 402277498Snwhitehorn bl 3f /* Begin dance to jump to kern_slbtrap*/ 403277498Snwhitehorn .llong kern_slbtrap 404277498Snwhitehorn3: mflr %r1 405277498Snwhitehorn ld %r1,0(%r1) 406277498Snwhitehorn mtlr %r1 407277498Snwhitehorn GET_CPUINFO(%r1) 408277498Snwhitehorn blrl /* 124 bytes -- 4 to spare */ 409277561SnwhitehornCNAME(slbtrapend): 410230123Snwhitehorn 411230123Snwhitehornkern_slbtrap: 412230123Snwhitehorn std %r2,(PC_SLBSAVE+136)(%r1) /* old LR */ 413230123Snwhitehorn std %r3,(PC_SLBSAVE+24)(%r1) /* save R3 */ 414230123Snwhitehorn 415230123Snwhitehorn /* Check if this needs to be handled as a regular trap (userseg miss) */ 416230123Snwhitehorn mflr %r2 417230123Snwhitehorn andi. %r2,%r2,0xff80 418230123Snwhitehorn cmpwi %r2,0x380 419230123Snwhitehorn bne 1f 420230123Snwhitehorn mfdar %r2 421230123Snwhitehorn b 2f 422230123Snwhitehorn1: mfsrr0 %r2 423230123Snwhitehorn2: /* r2 now contains the fault address */ 424230123Snwhitehorn lis %r3,SEGMENT_MASK@highesta 425230123Snwhitehorn ori %r3,%r3,SEGMENT_MASK@highera 426230123Snwhitehorn sldi %r3,%r3,32 427230123Snwhitehorn oris %r3,%r3,SEGMENT_MASK@ha 428230123Snwhitehorn ori %r3,%r3,SEGMENT_MASK@l 429230123Snwhitehorn and %r2,%r2,%r3 /* R2 = segment base address */ 430230123Snwhitehorn lis %r3,USER_ADDR@highesta 431230123Snwhitehorn ori %r3,%r3,USER_ADDR@highera 432230123Snwhitehorn sldi %r3,%r3,32 433230123Snwhitehorn oris %r3,%r3,USER_ADDR@ha 434230123Snwhitehorn ori %r3,%r3,USER_ADDR@l 435230123Snwhitehorn cmpd %r2,%r3 /* Compare fault base to USER_ADDR */ 436230123Snwhitehorn bne 3f 437230123Snwhitehorn 438230123Snwhitehorn /* User seg miss, handle as a regular trap */ 439230123Snwhitehorn ld %r2,(PC_SLBSAVE+104)(%r1) /* Restore CR */ 440230123Snwhitehorn mtcr %r2 441230123Snwhitehorn ld %r2,(PC_SLBSAVE+16)(%r1) /* Restore R2,R3 */ 442230123Snwhitehorn ld %r3,(PC_SLBSAVE+24)(%r1) 443230123Snwhitehorn ld %r1,(PC_SLBSAVE+136)(%r1) /* Save the old LR in r1 */ 444230123Snwhitehorn mtsprg2 %r1 /* And then in SPRG2 */ 445230123Snwhitehorn li %r1, 0x80 /* How to get the vector from LR */ 446230123Snwhitehorn b generictrap /* Retain old LR using b */ 447230123Snwhitehorn 448230123Snwhitehorn3: /* Real kernel SLB miss */ 449230123Snwhitehorn std %r0,(PC_SLBSAVE+0)(%r1) /* free all volatile regs */ 450230123Snwhitehorn mfsprg1 %r2 /* Old R1 */ 451230123Snwhitehorn std %r2,(PC_SLBSAVE+8)(%r1) 452230123Snwhitehorn /* R2,R3 already saved */ 453230123Snwhitehorn std %r4,(PC_SLBSAVE+32)(%r1) 454230123Snwhitehorn std %r5,(PC_SLBSAVE+40)(%r1) 455230123Snwhitehorn std %r6,(PC_SLBSAVE+48)(%r1) 456230123Snwhitehorn std %r7,(PC_SLBSAVE+56)(%r1) 457230123Snwhitehorn std %r8,(PC_SLBSAVE+64)(%r1) 458230123Snwhitehorn std %r9,(PC_SLBSAVE+72)(%r1) 459230123Snwhitehorn std %r10,(PC_SLBSAVE+80)(%r1) 460230123Snwhitehorn std %r11,(PC_SLBSAVE+88)(%r1) 461230123Snwhitehorn std %r12,(PC_SLBSAVE+96)(%r1) 462230123Snwhitehorn /* CR already saved */ 463230123Snwhitehorn mfxer %r2 /* save XER */ 464230123Snwhitehorn std %r2,(PC_SLBSAVE+112)(%r1) 465230123Snwhitehorn mflr %r2 /* save LR (SP already saved) */ 466230123Snwhitehorn std %r2,(PC_SLBSAVE+120)(%r1) 467230123Snwhitehorn mfctr %r2 /* save CTR */ 468230123Snwhitehorn std %r2,(PC_SLBSAVE+128)(%r1) 469230123Snwhitehorn 470230123Snwhitehorn /* Call handler */ 471230123Snwhitehorn addi %r1,%r1,PC_SLBSTACK-48+1024 472230123Snwhitehorn li %r2,~15 473230123Snwhitehorn and %r1,%r1,%r2 474277334Snwhitehorn GET_TOCBASE(%r2) 475230123Snwhitehorn mflr %r3 476230123Snwhitehorn andi. %r3,%r3,0xff80 477230123Snwhitehorn mfdar %r4 478230123Snwhitehorn mfsrr0 %r5 479230123Snwhitehorn bl handle_kernel_slb_spill 480230123Snwhitehorn nop 481230123Snwhitehorn 482230123Snwhitehorn /* Save r28-31, restore r4-r12 */ 483230123Snwhitehorn GET_CPUINFO(%r1) 484230123Snwhitehorn ld %r4,(PC_SLBSAVE+32)(%r1) 485230123Snwhitehorn ld %r5,(PC_SLBSAVE+40)(%r1) 486230123Snwhitehorn ld %r6,(PC_SLBSAVE+48)(%r1) 487230123Snwhitehorn ld %r7,(PC_SLBSAVE+56)(%r1) 488230123Snwhitehorn ld %r8,(PC_SLBSAVE+64)(%r1) 489230123Snwhitehorn ld %r9,(PC_SLBSAVE+72)(%r1) 490230123Snwhitehorn ld %r10,(PC_SLBSAVE+80)(%r1) 491230123Snwhitehorn ld %r11,(PC_SLBSAVE+88)(%r1) 492230123Snwhitehorn ld %r12,(PC_SLBSAVE+96)(%r1) 493230123Snwhitehorn std %r28,(PC_SLBSAVE+64)(%r1) 494230123Snwhitehorn std %r29,(PC_SLBSAVE+72)(%r1) 495230123Snwhitehorn std %r30,(PC_SLBSAVE+80)(%r1) 496230123Snwhitehorn std %r31,(PC_SLBSAVE+88)(%r1) 497230123Snwhitehorn 498230123Snwhitehorn /* Restore kernel mapping */ 499230123Snwhitehorn bl restore_kernsrs 500230123Snwhitehorn 501230123Snwhitehorn /* Restore remaining registers */ 502230123Snwhitehorn ld %r28,(PC_SLBSAVE+64)(%r1) 503230123Snwhitehorn ld %r29,(PC_SLBSAVE+72)(%r1) 504230123Snwhitehorn ld %r30,(PC_SLBSAVE+80)(%r1) 505230123Snwhitehorn ld %r31,(PC_SLBSAVE+88)(%r1) 506230123Snwhitehorn 507230123Snwhitehorn ld %r2,(PC_SLBSAVE+104)(%r1) 508230123Snwhitehorn mtcr %r2 509230123Snwhitehorn ld %r2,(PC_SLBSAVE+112)(%r1) 510230123Snwhitehorn mtxer %r2 511230123Snwhitehorn ld %r2,(PC_SLBSAVE+120)(%r1) 512230123Snwhitehorn mtlr %r2 513230123Snwhitehorn ld %r2,(PC_SLBSAVE+128)(%r1) 514230123Snwhitehorn mtctr %r2 515230123Snwhitehorn ld %r2,(PC_SLBSAVE+136)(%r1) 516230123Snwhitehorn mtlr %r2 517230123Snwhitehorn 518230123Snwhitehorn /* Restore r0-r3 */ 519230123Snwhitehorn ld %r0,(PC_SLBSAVE+0)(%r1) 520230123Snwhitehorn ld %r2,(PC_SLBSAVE+16)(%r1) 521230123Snwhitehorn ld %r3,(PC_SLBSAVE+24)(%r1) 522230123Snwhitehorn mfsprg1 %r1 523230123Snwhitehorn 524230123Snwhitehorn /* Back to whatever we were doing */ 525230123Snwhitehorn rfid 526230123Snwhitehorn 527230123Snwhitehorn/* 52895719Sbenno * For ALI: has to save DSISR and DAR 52995719Sbenno */ 530277561Snwhitehorn .globl CNAME(alitrap),CNAME(aliend) 53196773SbennoCNAME(alitrap): 532125441Sgrehan mtsprg1 %r1 /* save SP */ 533125441Sgrehan GET_CPUINFO(%r1) 534209975Snwhitehorn std %r27,(PC_TEMPSAVE+CPUSAVE_R27)(%r1) /* free r27-r31 */ 535209975Snwhitehorn std %r28,(PC_TEMPSAVE+CPUSAVE_R28)(%r1) 536209975Snwhitehorn std %r29,(PC_TEMPSAVE+CPUSAVE_R29)(%r1) 537209975Snwhitehorn std %r30,(PC_TEMPSAVE+CPUSAVE_R30)(%r1) 538209975Snwhitehorn std %r31,(PC_TEMPSAVE+CPUSAVE_R31)(%r1) 539125441Sgrehan mfdar %r30 540125441Sgrehan mfdsisr %r31 541209975Snwhitehorn std %r30,(PC_TEMPSAVE+CPUSAVE_AIM_DAR)(%r1) 542209975Snwhitehorn std %r31,(PC_TEMPSAVE+CPUSAVE_AIM_DSISR)(%r1) 543125441Sgrehan mfsprg1 %r1 /* restore SP, in case of branch */ 544125441Sgrehan mflr %r28 /* save LR */ 545125441Sgrehan mfcr %r29 /* save CR */ 546188860Snwhitehorn 547277498Snwhitehorn /* Begin dance to branch to s_trap in a bit */ 548277498Snwhitehorn b 1f 549277498Snwhitehorn .p2align 3 550277498Snwhitehorn1: nop 551277498Snwhitehorn bl 1f 552277498Snwhitehorn .llong s_trap 553277498Snwhitehorn1: mflr %r31 554277498Snwhitehorn ld %r31,0(%r31) 555277498Snwhitehorn mtlr %r31 556277498Snwhitehorn 557188951Snwhitehorn /* Put our exception vector in SPRG3 */ 558188860Snwhitehorn li %r31, EXC_ALI 559188860Snwhitehorn mtsprg3 %r31 560188860Snwhitehorn 561188860Snwhitehorn /* Test whether we already had PR set */ 562125441Sgrehan mfsrr1 %r31 563125441Sgrehan mtcr %r31 564277498Snwhitehorn blrl 565277561SnwhitehornCNAME(aliend): 56695719Sbenno 56795719Sbenno/* 56895719Sbenno * Similar to the above for DSI 569277498Snwhitehorn * Has to handle standard pagetable spills 57095719Sbenno */ 571277561Snwhitehorn .globl CNAME(dsitrap),CNAME(dsiend) 57296773SbennoCNAME(dsitrap): 573125441Sgrehan mtsprg1 %r1 /* save SP */ 574125441Sgrehan GET_CPUINFO(%r1) 575209975Snwhitehorn std %r27,(PC_DISISAVE+CPUSAVE_R27)(%r1) /* free r27-r31 */ 576209975Snwhitehorn std %r28,(PC_DISISAVE+CPUSAVE_R28)(%r1) 577209975Snwhitehorn std %r29,(PC_DISISAVE+CPUSAVE_R29)(%r1) 578209975Snwhitehorn std %r30,(PC_DISISAVE+CPUSAVE_R30)(%r1) 579209975Snwhitehorn std %r31,(PC_DISISAVE+CPUSAVE_R31)(%r1) 580125441Sgrehan mfcr %r29 /* save CR */ 581125441Sgrehan mfxer %r30 /* save XER */ 582125441Sgrehan mtsprg2 %r30 /* in SPRG2 */ 583125441Sgrehan mfsrr1 %r31 /* test kernel mode */ 584125441Sgrehan mtcr %r31 585125441Sgrehan mflr %r28 /* save LR (SP already saved) */ 586277498Snwhitehorn bl 1f /* Begin branching to disitrap */ 587277498Snwhitehorn .llong disitrap 588277498Snwhitehorn1: mflr %r1 589277498Snwhitehorn ld %r1,0(%r1) 590277498Snwhitehorn mtlr %r1 591277498Snwhitehorn blrl /* Branch to generictrap */ 592277561SnwhitehornCNAME(dsiend): 59395719Sbenno 59495719Sbenno/* 59595719Sbenno * Preamble code for DSI/ISI traps 59695719Sbenno */ 59795719Sbennodisitrap: 598188951Snwhitehorn /* Write the trap vector to SPRG3 by computing LR & 0xff00 */ 599188860Snwhitehorn mflr %r1 600188860Snwhitehorn andi. %r1,%r1,0xff00 601188860Snwhitehorn mtsprg3 %r1 602188860Snwhitehorn 603125441Sgrehan GET_CPUINFO(%r1) 604209975Snwhitehorn ld %r31,(PC_DISISAVE+CPUSAVE_R27)(%r1) 605209975Snwhitehorn std %r31,(PC_TEMPSAVE+CPUSAVE_R27)(%r1) 606209975Snwhitehorn ld %r30,(PC_DISISAVE+CPUSAVE_R28)(%r1) 607209975Snwhitehorn std %r30,(PC_TEMPSAVE+CPUSAVE_R28)(%r1) 608209975Snwhitehorn ld %r31,(PC_DISISAVE+CPUSAVE_R29)(%r1) 609209975Snwhitehorn std %r31,(PC_TEMPSAVE+CPUSAVE_R29)(%r1) 610209975Snwhitehorn ld %r30,(PC_DISISAVE+CPUSAVE_R30)(%r1) 611209975Snwhitehorn std %r30,(PC_TEMPSAVE+CPUSAVE_R30)(%r1) 612209975Snwhitehorn ld %r31,(PC_DISISAVE+CPUSAVE_R31)(%r1) 613209975Snwhitehorn std %r31,(PC_TEMPSAVE+CPUSAVE_R31)(%r1) 614125441Sgrehan mfdar %r30 615125441Sgrehan mfdsisr %r31 616209975Snwhitehorn std %r30,(PC_TEMPSAVE+CPUSAVE_AIM_DAR)(%r1) 617209975Snwhitehorn std %r31,(PC_TEMPSAVE+CPUSAVE_AIM_DSISR)(%r1) 618125441Sgrehan 619132571Sgrehan#ifdef KDB 620258800Snwhitehorn /* Try to detect a kernel stack overflow */ 621132571Sgrehan mfsrr1 %r31 622132571Sgrehan mtcr %r31 623132571Sgrehan bt 17,realtrap /* branch is user mode */ 624132571Sgrehan mfsprg1 %r31 /* get old SP */ 625266136Sjhibbits clrrdi %r31,%r31,12 /* Round SP down to nearest page */ 626132571Sgrehan sub. %r30,%r31,%r30 /* SP - DAR */ 627132571Sgrehan bge 1f 628132571Sgrehan neg %r30,%r30 /* modulo value */ 629209975Snwhitehorn1: cmpldi %cr0,%r30,4096 /* is DAR within a page of SP? */ 630132571Sgrehan bge %cr0,realtrap /* no, too far away. */ 631132571Sgrehan 632132571Sgrehan /* Now convert this DSI into a DDB trap. */ 633132571Sgrehan GET_CPUINFO(%r1) 634209975Snwhitehorn ld %r30,(PC_TEMPSAVE+CPUSAVE_AIM_DAR)(%r1) /* get DAR */ 635209975Snwhitehorn std %r30,(PC_DBSAVE +CPUSAVE_AIM_DAR)(%r1) /* save DAR */ 636209975Snwhitehorn ld %r30,(PC_TEMPSAVE+CPUSAVE_AIM_DSISR)(%r1) /* get DSISR */ 637209975Snwhitehorn std %r30,(PC_DBSAVE +CPUSAVE_AIM_DSISR)(%r1) /* save DSISR */ 638209975Snwhitehorn ld %r31,(PC_DISISAVE+CPUSAVE_R27)(%r1) /* get r27 */ 639209975Snwhitehorn std %r31,(PC_DBSAVE +CPUSAVE_R27)(%r1) /* save r27 */ 640209975Snwhitehorn ld %r30,(PC_DISISAVE+CPUSAVE_R28)(%r1) /* get r28 */ 641209975Snwhitehorn std %r30,(PC_DBSAVE +CPUSAVE_R28)(%r1) /* save r28 */ 642209975Snwhitehorn ld %r31,(PC_DISISAVE+CPUSAVE_R29)(%r1) /* get r29 */ 643209975Snwhitehorn std %r31,(PC_DBSAVE +CPUSAVE_R29)(%r1) /* save r29 */ 644209975Snwhitehorn ld %r30,(PC_DISISAVE+CPUSAVE_R30)(%r1) /* get r30 */ 645209975Snwhitehorn std %r30,(PC_DBSAVE +CPUSAVE_R30)(%r1) /* save r30 */ 646209975Snwhitehorn ld %r31,(PC_DISISAVE+CPUSAVE_R31)(%r1) /* get r31 */ 647209975Snwhitehorn std %r31,(PC_DBSAVE +CPUSAVE_R31)(%r1) /* save r31 */ 648191039Snwhitehorn b dbtrap 649132571Sgrehan#endif 650132571Sgrehan 651125441Sgrehan /* XXX need stack probe here */ 65295719Sbennorealtrap: 65395719Sbenno/* Test whether we already had PR set */ 654125441Sgrehan mfsrr1 %r1 655125441Sgrehan mtcr %r1 656125441Sgrehan mfsprg1 %r1 /* restore SP (might have been 65795719Sbenno overwritten) */ 658188860Snwhitehorn bf 17,k_trap /* branch if PSL_PR is false */ 659188860Snwhitehorn GET_CPUINFO(%r1) 660209975Snwhitehorn ld %r1,PC_CURPCB(%r1) 661209975Snwhitehorn mr %r27,%r28 /* Save LR, r29 */ 662209975Snwhitehorn mtsprg2 %r29 663212722Snwhitehorn bl restore_kernsrs /* enable kernel mapping */ 664209975Snwhitehorn mfsprg2 %r29 665209975Snwhitehorn mr %r28,%r27 666277498Snwhitehorn b s_trap 667188860Snwhitehorn 668188860Snwhitehorn/* 669188860Snwhitehorn * generictrap does some standard setup for trap handling to minimize 670188860Snwhitehorn * the code that need be installed in the actual vectors. It expects 671188860Snwhitehorn * the following conditions. 672188860Snwhitehorn * 673188860Snwhitehorn * R1 - Trap vector = LR & (0xff00 | R1) 674188860Snwhitehorn * SPRG1 - Original R1 contents 675188860Snwhitehorn * SPRG2 - Original LR 676188860Snwhitehorn */ 677188860Snwhitehorn 678279750Snwhitehorn .globl CNAME(generictrap) 679188860Snwhitehorngenerictrap: 680188860Snwhitehorn /* Save R1 for computing the exception vector */ 681188860Snwhitehorn mtsprg3 %r1 682188860Snwhitehorn 683188860Snwhitehorn /* Save interesting registers */ 684188860Snwhitehorn GET_CPUINFO(%r1) 685209975Snwhitehorn std %r27,(PC_TEMPSAVE+CPUSAVE_R27)(%r1) /* free r27-r31 */ 686209975Snwhitehorn std %r28,(PC_TEMPSAVE+CPUSAVE_R28)(%r1) 687209975Snwhitehorn std %r29,(PC_TEMPSAVE+CPUSAVE_R29)(%r1) 688209975Snwhitehorn std %r30,(PC_TEMPSAVE+CPUSAVE_R30)(%r1) 689209975Snwhitehorn std %r31,(PC_TEMPSAVE+CPUSAVE_R31)(%r1) 690209975Snwhitehorn mfdar %r30 691209975Snwhitehorn std %r30,(PC_TEMPSAVE+CPUSAVE_AIM_DAR)(%r1) 692188860Snwhitehorn mfsprg1 %r1 /* restore SP, in case of branch */ 693188860Snwhitehorn mfsprg2 %r28 /* save LR */ 694188860Snwhitehorn mfcr %r29 /* save CR */ 695188860Snwhitehorn 696188860Snwhitehorn /* Compute the exception vector from the link register */ 697188860Snwhitehorn mfsprg3 %r31 698188860Snwhitehorn ori %r31,%r31,0xff00 699188860Snwhitehorn mflr %r30 700277498Snwhitehorn addi %r30,%r30,-4 /* The branch instruction, not the next */ 701188860Snwhitehorn and %r30,%r30,%r31 702188860Snwhitehorn mtsprg3 %r30 703188860Snwhitehorn 704188860Snwhitehorn /* Test whether we already had PR set */ 705188860Snwhitehorn mfsrr1 %r31 706188860Snwhitehorn mtcr %r31 707188860Snwhitehorn 708125441Sgrehans_trap: 709125441Sgrehan bf 17,k_trap /* branch if PSL_PR is false */ 710125441Sgrehan GET_CPUINFO(%r1) 711125441Sgrehanu_trap: 712209975Snwhitehorn ld %r1,PC_CURPCB(%r1) 713209975Snwhitehorn mr %r27,%r28 /* Save LR, r29 */ 714209975Snwhitehorn mtsprg2 %r29 715212722Snwhitehorn bl restore_kernsrs /* enable kernel mapping */ 716209975Snwhitehorn mfsprg2 %r29 717209975Snwhitehorn mr %r28,%r27 71895719Sbenno 71995719Sbenno/* 72095719Sbenno * Now the common trap catching code. 72195719Sbenno */ 722125441Sgrehank_trap: 723125441Sgrehan FRAME_SETUP(PC_TEMPSAVE) 72499032Sbenno/* Call C interrupt dispatcher: */ 72595719Sbennotrapagain: 726277334Snwhitehorn GET_TOCBASE(%r2) 727209975Snwhitehorn addi %r3,%r1,48 728218824Snwhitehorn bl CNAME(powerpc_interrupt) 729209975Snwhitehorn nop 730209975Snwhitehorn 731209975Snwhitehorn .globl CNAME(trapexit) /* backtrace code sentinel */ 73296773SbennoCNAME(trapexit): 73395719Sbenno/* Disable interrupts: */ 734125441Sgrehan mfmsr %r3 735125441Sgrehan andi. %r3,%r3,~PSL_EE@l 736125441Sgrehan mtmsr %r3 737222309Snwhitehorn isync 73895719Sbenno/* Test AST pending: */ 739209975Snwhitehorn ld %r5,FRAME_SRR1+48(%r1) 740125441Sgrehan mtcr %r5 741125441Sgrehan bf 17,1f /* branch if PSL_PR is false */ 74299032Sbenno 743125441Sgrehan GET_CPUINFO(%r3) /* get per-CPU pointer */ 744223485Snwhitehorn lwz %r4, TD_FLAGS(%r13) /* get thread flags value */ 745125441Sgrehan lis %r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@h 746125441Sgrehan ori %r5,%r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@l 747125441Sgrehan and. %r4,%r4,%r5 74895719Sbenno beq 1f 749125441Sgrehan mfmsr %r3 /* re-enable interrupts */ 750125441Sgrehan ori %r3,%r3,PSL_EE@l 751125441Sgrehan mtmsr %r3 75299032Sbenno isync 753277334Snwhitehorn GET_TOCBASE(%r2) 754209975Snwhitehorn addi %r3,%r1,48 755218824Snwhitehorn bl CNAME(ast) 756209975Snwhitehorn nop 757153685Sgrehan .globl CNAME(asttrapexit) /* backtrace code sentinel #2 */ 758153685SgrehanCNAME(asttrapexit): 75999032Sbenno b trapexit /* test ast ret value ? */ 76095719Sbenno1: 761125441Sgrehan FRAME_LEAVE(PC_TEMPSAVE) 762190681Snwhitehorn rfid 763190681Snwhitehorn 764132075Sgrehan#if defined(KDB) 76595719Sbenno/* 766132075Sgrehan * Deliberate entry to dbtrap 76795719Sbenno */ 768230400SandreastASENTRY_NOPROF(breakpoint) 769125441Sgrehan mtsprg1 %r1 770125441Sgrehan mfmsr %r3 771125441Sgrehan mtsrr1 %r3 772125441Sgrehan andi. %r3,%r3,~(PSL_EE|PSL_ME)@l 773125441Sgrehan mtmsr %r3 /* disable interrupts */ 77495719Sbenno isync 775125441Sgrehan GET_CPUINFO(%r3) 776209975Snwhitehorn std %r27,(PC_DBSAVE+CPUSAVE_R27)(%r3) 777209975Snwhitehorn std %r28,(PC_DBSAVE+CPUSAVE_R28)(%r3) 778209975Snwhitehorn std %r29,(PC_DBSAVE+CPUSAVE_R29)(%r3) 779209975Snwhitehorn std %r30,(PC_DBSAVE+CPUSAVE_R30)(%r3) 780209975Snwhitehorn std %r31,(PC_DBSAVE+CPUSAVE_R31)(%r3) 781125441Sgrehan mflr %r28 782125441Sgrehan li %r29,EXC_BPT 783125441Sgrehan mtlr %r29 784125441Sgrehan mfcr %r29 785125441Sgrehan mtsrr0 %r28 78695719Sbenno 78795719Sbenno/* 788132075Sgrehan * Now the kdb trap catching code. 78995719Sbenno */ 790132075Sgrehandbtrap: 791188951Snwhitehorn /* Write the trap vector to SPRG3 by computing LR & 0xff00 */ 792188860Snwhitehorn mflr %r1 793188860Snwhitehorn andi. %r1,%r1,0xff00 794188860Snwhitehorn mtsprg3 %r1 795188860Snwhitehorn 796279751Snwhitehorn ld %r1,TRAP_TOCBASE(0) /* get new SP */ 797277335Snwhitehorn ld %r1,TOC_REF(tmpstk)(%r1) 798277335Snwhitehorn addi %r1,%r1,(TMPSTKSZ-48) 799188860Snwhitehorn 800132075Sgrehan FRAME_SETUP(PC_DBSAVE) 80195719Sbenno/* Call C trap code: */ 802277334Snwhitehorn GET_TOCBASE(%r2) 803209975Snwhitehorn addi %r3,%r1,48 804218824Snwhitehorn bl CNAME(db_trap_glue) 805209975Snwhitehorn nop 806125441Sgrehan or. %r3,%r3,%r3 807132075Sgrehan bne dbleave 808132075Sgrehan/* This wasn't for KDB, so switch to real trap: */ 809209975Snwhitehorn ld %r3,FRAME_EXC+48(%r1) /* save exception */ 810125441Sgrehan GET_CPUINFO(%r4) 811209975Snwhitehorn std %r3,(PC_DBSAVE+CPUSAVE_R31)(%r4) 812132075Sgrehan FRAME_LEAVE(PC_DBSAVE) 813125441Sgrehan mtsprg1 %r1 /* prepare for entrance to realtrap */ 814125441Sgrehan GET_CPUINFO(%r1) 815209975Snwhitehorn std %r27,(PC_TEMPSAVE+CPUSAVE_R27)(%r1) 816209975Snwhitehorn std %r28,(PC_TEMPSAVE+CPUSAVE_R28)(%r1) 817209975Snwhitehorn std %r29,(PC_TEMPSAVE+CPUSAVE_R29)(%r1) 818209975Snwhitehorn std %r30,(PC_TEMPSAVE+CPUSAVE_R30)(%r1) 819209975Snwhitehorn std %r31,(PC_TEMPSAVE+CPUSAVE_R31)(%r1) 820125441Sgrehan mflr %r28 821125441Sgrehan mfcr %r29 822209975Snwhitehorn ld %r31,(PC_DBSAVE+CPUSAVE_R31)(%r1) 823190946Snwhitehorn mtsprg3 %r31 /* SPRG3 was clobbered by FRAME_LEAVE */ 824125441Sgrehan mfsprg1 %r1 82595719Sbenno b realtrap 826132075Sgrehandbleave: 827132075Sgrehan FRAME_LEAVE(PC_DBSAVE) 828209975Snwhitehorn rfid 82995719Sbenno 83095719Sbenno/* 831132075Sgrehan * In case of KDB we want a separate trap catcher for it 83295719Sbenno */ 833277561Snwhitehorn .globl CNAME(dblow),CNAME(dbend) 834132075SgrehanCNAME(dblow): 835125441Sgrehan mtsprg1 %r1 /* save SP */ 836125441Sgrehan mtsprg2 %r29 /* save r29 */ 837125441Sgrehan mfcr %r29 /* save CR in r29 */ 838125441Sgrehan mfsrr1 %r1 839125441Sgrehan mtcr %r1 840275268Sjhibbits bf 17,1f /* branch if privileged */ 841188860Snwhitehorn 842188860Snwhitehorn /* Unprivileged case */ 843188860Snwhitehorn mtcr %r29 /* put the condition register back */ 844188860Snwhitehorn mfsprg2 %r29 /* ... and r29 */ 845188860Snwhitehorn mflr %r1 /* save LR */ 846188860Snwhitehorn mtsprg2 %r1 /* And then in SPRG2 */ 847277498Snwhitehorn 848285620Sjhibbits ld %r1, TRAP_GENTRAP(0) /* Get branch address */ 849277498Snwhitehorn mtlr %r1 850188860Snwhitehorn li %r1, 0 /* How to get the vector from LR */ 851277498Snwhitehorn blrl /* Branch to generictrap */ 852188860Snwhitehorn 853275268Sjhibbits1: 854188860Snwhitehorn GET_CPUINFO(%r1) 855209975Snwhitehorn std %r27,(PC_DBSAVE+CPUSAVE_R27)(%r1) /* free r27 */ 856209975Snwhitehorn std %r28,(PC_DBSAVE+CPUSAVE_R28)(%r1) /* free r28 */ 857125441Sgrehan mfsprg2 %r28 /* r29 holds cr... */ 858209975Snwhitehorn std %r28,(PC_DBSAVE+CPUSAVE_R29)(%r1) /* free r29 */ 859209975Snwhitehorn std %r30,(PC_DBSAVE+CPUSAVE_R30)(%r1) /* free r30 */ 860209975Snwhitehorn std %r31,(PC_DBSAVE+CPUSAVE_R31)(%r1) /* free r31 */ 861125441Sgrehan mflr %r28 /* save LR */ 862277498Snwhitehorn bl 9f /* Begin branch */ 863277498Snwhitehorn .llong dbtrap 864277498Snwhitehorn9: mflr %r1 865277498Snwhitehorn ld %r1,0(%r1) 866277498Snwhitehorn mtlr %r1 867277498Snwhitehorn blrl /* Branch to generictrap */ 868277561SnwhitehornCNAME(dbend): 869132075Sgrehan#endif /* KDB */ 870