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 4295719Sbenno/* 43125441Sgrehan * Save/restore segment registers 4495719Sbenno */ 4595719Sbenno 4695719Sbenno/* 47209975Snwhitehorn * Restore SRs for a pmap 48209975Snwhitehorn * 49209975Snwhitehorn * Requires that r28-r31 be scratch, with r28 initialized to the SLB cache 50209975Snwhitehorn */ 51209975Snwhitehorn 52212722Snwhitehorn/* 53212722Snwhitehorn * User SRs are loaded through a pointer to the current pmap. 54212722Snwhitehorn */ 55212722Snwhitehornrestore_usersrs: 56222620Snwhitehorn GET_CPUINFO(%r28) 57222620Snwhitehorn ld %r28,PC_USERSLB(%r28) 58209975Snwhitehorn li %r29, 0 /* Set the counter to zero */ 59209975Snwhitehorn 60209975Snwhitehorn slbia 61209975Snwhitehorn slbmfee %r31,%r29 62209975Snwhitehorn clrrdi %r31,%r31,28 63209975Snwhitehorn slbie %r31 64222620Snwhitehorn1: ld %r31, 0(%r28) /* Load SLB entry pointer */ 65222620Snwhitehorn cmpli 0, %r31, 0 /* If NULL, stop */ 66222620Snwhitehorn beqlr 67209975Snwhitehorn 68212722Snwhitehorn ld %r30, 0(%r31) /* Load SLBV */ 69212722Snwhitehorn ld %r31, 8(%r31) /* Load SLBE */ 70212722Snwhitehorn or %r31, %r31, %r29 /* Set SLBE slot */ 71222620Snwhitehorn slbmte %r30, %r31 /* Install SLB entry */ 72209975Snwhitehorn 73222620Snwhitehorn addi %r28, %r28, 8 /* Advance pointer */ 74222620Snwhitehorn addi %r29, %r29, 1 75222620Snwhitehorn b 1b /* Repeat */ 76209975Snwhitehorn 77209975Snwhitehorn/* 78212722Snwhitehorn * Kernel SRs are loaded directly from the PCPU fields 7995719Sbenno */ 80212722Snwhitehornrestore_kernsrs: 81222620Snwhitehorn GET_CPUINFO(%r28) 82222620Snwhitehorn addi %r28,%r28,PC_KERNSLB 83212722Snwhitehorn li %r29, 0 /* Set the counter to zero */ 8495719Sbenno 85212722Snwhitehorn slbia 86212722Snwhitehorn slbmfee %r31,%r29 87212722Snwhitehorn clrrdi %r31,%r31,28 88212722Snwhitehorn slbie %r31 89222620Snwhitehorn1: cmpli 0, %r29, USER_SLB_SLOT /* Skip the user slot */ 90222620Snwhitehorn beq- 2f 9195719Sbenno 92222620Snwhitehorn ld %r31, 8(%r28) /* Load SLBE */ 93222620Snwhitehorn cmpli 0, %r31, 0 /* If SLBE is not valid, stop */ 94222620Snwhitehorn beqlr 95212722Snwhitehorn ld %r30, 0(%r28) /* Load SLBV */ 96222620Snwhitehorn slbmte %r30, %r31 /* Install SLB entry */ 97212722Snwhitehorn 98222620Snwhitehorn2: addi %r28, %r28, 16 /* Advance pointer */ 99222620Snwhitehorn addi %r29, %r29, 1 100222620Snwhitehorn cmpli 0, %r29, 64 /* Repeat if we are not at the end */ 101222620Snwhitehorn blt 1b 102222620Snwhitehorn blr 103212722Snwhitehorn 104125441Sgrehan/* 105125441Sgrehan * FRAME_SETUP assumes: 106125441Sgrehan * SPRG1 SP (1) 107188860Snwhitehorn * SPRG3 trap type 108209975Snwhitehorn * savearea r27-r31,DAR,DSISR (DAR & DSISR only for DSI traps) 109125441Sgrehan * r28 LR 110125441Sgrehan * r29 CR 111125441Sgrehan * r30 scratch 112125441Sgrehan * r31 scratch 113125441Sgrehan * r1 kernel stack 114125441Sgrehan * SRR0/1 as at start of trap 115230123Snwhitehorn * 116230123Snwhitehorn * NOTE: SPRG1 is never used while the MMU is on, making it safe to reuse 117230123Snwhitehorn * in any real-mode fault handler, including those handling double faults. 118125441Sgrehan */ 119125441Sgrehan#define FRAME_SETUP(savearea) \ 120125441Sgrehan/* Have to enable translation to allow access of kernel stack: */ \ 121125441Sgrehan GET_CPUINFO(%r31); \ 122125441Sgrehan mfsrr0 %r30; \ 123209975Snwhitehorn std %r30,(savearea+CPUSAVE_SRR0)(%r31); /* save SRR0 */ \ 124125441Sgrehan mfsrr1 %r30; \ 125209975Snwhitehorn std %r30,(savearea+CPUSAVE_SRR1)(%r31); /* save SRR1 */ \ 126230123Snwhitehorn mfsprg1 %r31; /* get saved SP (clears SPRG1) */ \ 127125441Sgrehan mfmsr %r30; \ 128125441Sgrehan ori %r30,%r30,(PSL_DR|PSL_IR|PSL_RI)@l; /* relocation on */ \ 129125441Sgrehan mtmsr %r30; /* stack can now be accessed */ \ 130125441Sgrehan isync; \ 131209975Snwhitehorn stdu %r31,-(FRAMELEN+288)(%r1); /* save it in the callframe */ \ 132209975Snwhitehorn std %r0, FRAME_0+48(%r1); /* save r0 in the trapframe */ \ 133209975Snwhitehorn std %r31,FRAME_1+48(%r1); /* save SP " " */ \ 134209975Snwhitehorn std %r2, FRAME_2+48(%r1); /* save r2 " " */ \ 135209975Snwhitehorn std %r28,FRAME_LR+48(%r1); /* save LR " " */ \ 136209975Snwhitehorn std %r29,FRAME_CR+48(%r1); /* save CR " " */ \ 137125441Sgrehan GET_CPUINFO(%r2); \ 138209975Snwhitehorn ld %r27,(savearea+CPUSAVE_R27)(%r2); /* get saved r27 */ \ 139209975Snwhitehorn ld %r28,(savearea+CPUSAVE_R28)(%r2); /* get saved r28 */ \ 140209975Snwhitehorn ld %r29,(savearea+CPUSAVE_R29)(%r2); /* get saved r29 */ \ 141209975Snwhitehorn ld %r30,(savearea+CPUSAVE_R30)(%r2); /* get saved r30 */ \ 142209975Snwhitehorn ld %r31,(savearea+CPUSAVE_R31)(%r2); /* get saved r31 */ \ 143209975Snwhitehorn std %r3, FRAME_3+48(%r1); /* save r3-r31 */ \ 144209975Snwhitehorn std %r4, FRAME_4+48(%r1); \ 145209975Snwhitehorn std %r5, FRAME_5+48(%r1); \ 146209975Snwhitehorn std %r6, FRAME_6+48(%r1); \ 147209975Snwhitehorn std %r7, FRAME_7+48(%r1); \ 148209975Snwhitehorn std %r8, FRAME_8+48(%r1); \ 149209975Snwhitehorn std %r9, FRAME_9+48(%r1); \ 150209975Snwhitehorn std %r10, FRAME_10+48(%r1); \ 151209975Snwhitehorn std %r11, FRAME_11+48(%r1); \ 152209975Snwhitehorn std %r12, FRAME_12+48(%r1); \ 153209975Snwhitehorn std %r13, FRAME_13+48(%r1); \ 154209975Snwhitehorn std %r14, FRAME_14+48(%r1); \ 155209975Snwhitehorn std %r15, FRAME_15+48(%r1); \ 156209975Snwhitehorn std %r16, FRAME_16+48(%r1); \ 157209975Snwhitehorn std %r17, FRAME_17+48(%r1); \ 158209975Snwhitehorn std %r18, FRAME_18+48(%r1); \ 159209975Snwhitehorn std %r19, FRAME_19+48(%r1); \ 160209975Snwhitehorn std %r20, FRAME_20+48(%r1); \ 161209975Snwhitehorn std %r21, FRAME_21+48(%r1); \ 162209975Snwhitehorn std %r22, FRAME_22+48(%r1); \ 163209975Snwhitehorn std %r23, FRAME_23+48(%r1); \ 164209975Snwhitehorn std %r24, FRAME_24+48(%r1); \ 165209975Snwhitehorn std %r25, FRAME_25+48(%r1); \ 166209975Snwhitehorn std %r26, FRAME_26+48(%r1); \ 167209975Snwhitehorn std %r27, FRAME_27+48(%r1); \ 168209975Snwhitehorn std %r28, FRAME_28+48(%r1); \ 169209975Snwhitehorn std %r29, FRAME_29+48(%r1); \ 170209975Snwhitehorn std %r30, FRAME_30+48(%r1); \ 171209975Snwhitehorn std %r31, FRAME_31+48(%r1); \ 172209975Snwhitehorn ld %r28,(savearea+CPUSAVE_AIM_DAR)(%r2); /* saved DAR */ \ 173209975Snwhitehorn ld %r29,(savearea+CPUSAVE_AIM_DSISR)(%r2);/* saved DSISR */\ 174209975Snwhitehorn ld %r30,(savearea+CPUSAVE_SRR0)(%r2); /* saved SRR0 */ \ 175209975Snwhitehorn ld %r31,(savearea+CPUSAVE_SRR1)(%r2); /* saved SRR1 */ \ 176125441Sgrehan mfxer %r3; \ 177125441Sgrehan mfctr %r4; \ 178188860Snwhitehorn mfsprg3 %r5; \ 179209975Snwhitehorn std %r3, FRAME_XER+48(1); /* save xer/ctr/exc */ \ 180209975Snwhitehorn std %r4, FRAME_CTR+48(1); \ 181209975Snwhitehorn std %r5, FRAME_EXC+48(1); \ 182209975Snwhitehorn std %r28,FRAME_AIM_DAR+48(1); \ 183209975Snwhitehorn std %r29,FRAME_AIM_DSISR+48(1); /* save dsisr/srr0/srr1 */ \ 184209975Snwhitehorn std %r30,FRAME_SRR0+48(1); \ 185223485Snwhitehorn std %r31,FRAME_SRR1+48(1); \ 186223485Snwhitehorn ld %r13,PC_CURTHREAD(%r2) /* set kernel curthread */ 18795719Sbenno 188125441Sgrehan#define FRAME_LEAVE(savearea) \ 189223485Snwhitehorn/* Disable exceptions: */ \ 190223485Snwhitehorn mfmsr %r2; \ 191223485Snwhitehorn andi. %r2,%r2,~PSL_EE@l; \ 192223485Snwhitehorn mtmsr %r2; \ 193223485Snwhitehorn isync; \ 194125441Sgrehan/* Now restore regs: */ \ 195209975Snwhitehorn ld %r2,FRAME_SRR0+48(%r1); \ 196209975Snwhitehorn ld %r3,FRAME_SRR1+48(%r1); \ 197209975Snwhitehorn ld %r4,FRAME_CTR+48(%r1); \ 198209975Snwhitehorn ld %r5,FRAME_XER+48(%r1); \ 199209975Snwhitehorn ld %r6,FRAME_LR+48(%r1); \ 200125441Sgrehan GET_CPUINFO(%r7); \ 201209975Snwhitehorn std %r2,(savearea+CPUSAVE_SRR0)(%r7); /* save SRR0 */ \ 202209975Snwhitehorn std %r3,(savearea+CPUSAVE_SRR1)(%r7); /* save SRR1 */ \ 203209975Snwhitehorn ld %r7,FRAME_CR+48(%r1); \ 204125441Sgrehan mtctr %r4; \ 205125441Sgrehan mtxer %r5; \ 206125441Sgrehan mtlr %r6; \ 207230123Snwhitehorn mtsprg2 %r7; /* save cr */ \ 208209975Snwhitehorn ld %r31,FRAME_31+48(%r1); /* restore r0-31 */ \ 209209975Snwhitehorn ld %r30,FRAME_30+48(%r1); \ 210209975Snwhitehorn ld %r29,FRAME_29+48(%r1); \ 211209975Snwhitehorn ld %r28,FRAME_28+48(%r1); \ 212209975Snwhitehorn ld %r27,FRAME_27+48(%r1); \ 213209975Snwhitehorn ld %r26,FRAME_26+48(%r1); \ 214209975Snwhitehorn ld %r25,FRAME_25+48(%r1); \ 215209975Snwhitehorn ld %r24,FRAME_24+48(%r1); \ 216209975Snwhitehorn ld %r23,FRAME_23+48(%r1); \ 217209975Snwhitehorn ld %r22,FRAME_22+48(%r1); \ 218209975Snwhitehorn ld %r21,FRAME_21+48(%r1); \ 219209975Snwhitehorn ld %r20,FRAME_20+48(%r1); \ 220209975Snwhitehorn ld %r19,FRAME_19+48(%r1); \ 221209975Snwhitehorn ld %r18,FRAME_18+48(%r1); \ 222209975Snwhitehorn ld %r17,FRAME_17+48(%r1); \ 223209975Snwhitehorn ld %r16,FRAME_16+48(%r1); \ 224209975Snwhitehorn ld %r15,FRAME_15+48(%r1); \ 225209975Snwhitehorn ld %r14,FRAME_14+48(%r1); \ 226209975Snwhitehorn ld %r13,FRAME_13+48(%r1); \ 227209975Snwhitehorn ld %r12,FRAME_12+48(%r1); \ 228209975Snwhitehorn ld %r11,FRAME_11+48(%r1); \ 229209975Snwhitehorn ld %r10,FRAME_10+48(%r1); \ 230209975Snwhitehorn ld %r9, FRAME_9+48(%r1); \ 231209975Snwhitehorn ld %r8, FRAME_8+48(%r1); \ 232209975Snwhitehorn ld %r7, FRAME_7+48(%r1); \ 233209975Snwhitehorn ld %r6, FRAME_6+48(%r1); \ 234209975Snwhitehorn ld %r5, FRAME_5+48(%r1); \ 235209975Snwhitehorn ld %r4, FRAME_4+48(%r1); \ 236209975Snwhitehorn ld %r3, FRAME_3+48(%r1); \ 237209975Snwhitehorn ld %r2, FRAME_2+48(%r1); \ 238209975Snwhitehorn ld %r0, FRAME_0+48(%r1); \ 239209975Snwhitehorn ld %r1, FRAME_1+48(%r1); \ 240125441Sgrehan/* Can't touch %r1 from here on */ \ 241230123Snwhitehorn mtsprg3 %r3; /* save r3 */ \ 242125441Sgrehan/* Disable translation, machine check and recoverability: */ \ 243230123Snwhitehorn mfmsr %r3; \ 244230123Snwhitehorn andi. %r3,%r3,~(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l; \ 245230123Snwhitehorn mtmsr %r3; \ 246125441Sgrehan isync; \ 247125441Sgrehan/* Decide whether we return to user mode: */ \ 248230123Snwhitehorn GET_CPUINFO(%r3); \ 249230123Snwhitehorn ld %r3,(savearea+CPUSAVE_SRR1)(%r3); \ 250125441Sgrehan mtcr %r3; \ 251125441Sgrehan bf 17,1f; /* branch if PSL_PR is false */ \ 252125441Sgrehan/* Restore user SRs */ \ 253209975Snwhitehorn GET_CPUINFO(%r3); \ 254209975Snwhitehorn std %r27,(savearea+CPUSAVE_R27)(%r3); \ 255209975Snwhitehorn std %r28,(savearea+CPUSAVE_R28)(%r3); \ 256209975Snwhitehorn std %r29,(savearea+CPUSAVE_R29)(%r3); \ 257209975Snwhitehorn std %r30,(savearea+CPUSAVE_R30)(%r3); \ 258209975Snwhitehorn std %r31,(savearea+CPUSAVE_R31)(%r3); \ 259209975Snwhitehorn mflr %r27; /* preserve LR */ \ 260212722Snwhitehorn bl restore_usersrs; /* uses r28-r31 */ \ 261209975Snwhitehorn mtlr %r27; \ 262209975Snwhitehorn ld %r31,(savearea+CPUSAVE_R31)(%r3); \ 263209975Snwhitehorn ld %r30,(savearea+CPUSAVE_R30)(%r3); \ 264209975Snwhitehorn ld %r29,(savearea+CPUSAVE_R29)(%r3); \ 265209975Snwhitehorn ld %r28,(savearea+CPUSAVE_R28)(%r3); \ 266209975Snwhitehorn ld %r27,(savearea+CPUSAVE_R27)(%r3); \ 267230123Snwhitehorn1: mfsprg2 %r3; /* restore cr */ \ 268230123Snwhitehorn mtcr %r3; \ 269230123Snwhitehorn GET_CPUINFO(%r3); \ 270230123Snwhitehorn ld %r3,(savearea+CPUSAVE_SRR0)(%r3); /* restore srr0 */ \ 271125441Sgrehan mtsrr0 %r3; \ 272230123Snwhitehorn GET_CPUINFO(%r3); \ 273230123Snwhitehorn ld %r3,(savearea+CPUSAVE_SRR1)(%r3); /* restore srr1 */ \ 274125441Sgrehan mtsrr1 %r3; \ 275230123Snwhitehorn mfsprg3 %r3 /* restore r3 */ 27695719Sbenno 277242723Sjhibbits#ifdef KDTRACE_HOOKS 278242723Sjhibbits .data 279242723Sjhibbits .globl dtrace_invop_calltrap_addr 280242723Sjhibbits .align 8 281242723Sjhibbits .type dtrace_invop_calltrap_addr, @object 282242723Sjhibbits .size dtrace_invop_calltrap_addr, 8 283242723Sjhibbitsdtrace_invop_calltrap_addr: 284242723Sjhibbits .word 0 285242723Sjhibbits .word 0 286242723Sjhibbits 287242723Sjhibbits .text 288242723Sjhibbits#endif 289242723Sjhibbits 290178628Smarcel#ifdef SMP 29195719Sbenno/* 292178628Smarcel * Processor reset exception handler. These are typically 293178628Smarcel * the first instructions the processor executes after a 294198400Snwhitehorn * software reset. We do this in two bits so that we are 295198400Snwhitehorn * not still hanging around in the trap handling region 296198400Snwhitehorn * once the MMU is turned on. 297132571Sgrehan */ 298178628Smarcel .globl CNAME(rstcode), CNAME(rstsize) 299178628SmarcelCNAME(rstcode): 300209975Snwhitehorn /* Explicitly set MSR[SF] */ 301209975Snwhitehorn mfmsr %r9 302209975Snwhitehorn li %r8,1 303209975Snwhitehorn insrdi %r9,%r8,1,0 304209975Snwhitehorn mtmsrd %r9 305209975Snwhitehorn isync 306209975Snwhitehorn 307198400Snwhitehorn ba cpu_reset 308198400SnwhitehornCNAME(rstsize) = . - CNAME(rstcode) 309198400Snwhitehorn 310198400Snwhitehorncpu_reset: 311209975Snwhitehorn lis %r1,(tmpstk+TMPSTKSZ-48)@ha /* get new SP */ 312209975Snwhitehorn addi %r1,%r1,(tmpstk+TMPSTKSZ-48)@l 313178628Smarcel 314209975Snwhitehorn lis %r3,tocbase@ha 315209975Snwhitehorn ld %r2,tocbase@l(%r3) 316183060Smarcel lis %r3,1@l 317218824Snwhitehorn bl CNAME(cpudep_ap_early_bootstrap) /* Set PCPU */ 318209975Snwhitehorn nop 319227386Snwhitehorn lis %r3,1@l 320218824Snwhitehorn bl CNAME(pmap_cpu_bootstrap) /* Turn on virtual memory */ 321209975Snwhitehorn nop 322218824Snwhitehorn bl CNAME(cpudep_ap_bootstrap) /* Set up PCPU and stack */ 323209975Snwhitehorn nop 324209975Snwhitehorn mr %r1,%r3 /* Use new stack */ 325218824Snwhitehorn bl CNAME(machdep_ap_bootstrap) /* And away! */ 326209975Snwhitehorn nop 327178628Smarcel 328178628Smarcel /* Should not be reached */ 329178628Smarcel9: 330178628Smarcel b 9b 331132571Sgrehan#endif 332132571Sgrehan 333132571Sgrehan/* 33495719Sbenno * This code gets copied to all the trap vectors 335125441Sgrehan * (except ISI/DSI, ALI, and the interrupts) 33695719Sbenno */ 337178628Smarcel 33896773Sbenno .globl CNAME(trapcode),CNAME(trapsize) 33996773SbennoCNAME(trapcode): 340125441Sgrehan mtsprg1 %r1 /* save SP */ 341188860Snwhitehorn mflr %r1 /* Save the old LR in r1 */ 342188860Snwhitehorn mtsprg2 %r1 /* And then in SPRG2 */ 343209975Snwhitehorn li %r1, 0xA0 /* How to get the vector from LR */ 344188860Snwhitehorn bla generictrap /* LR & SPRG3 is exception # */ 34596773SbennoCNAME(trapsize) = .-CNAME(trapcode) 34695719Sbenno 34795719Sbenno/* 348230123Snwhitehorn * For SLB misses: do special things for the kernel 349230123Snwhitehorn * 350230123Snwhitehorn * Note: SPRG1 is always safe to overwrite any time the MMU is on, which is 351230123Snwhitehorn * the only time this can be called. 352230123Snwhitehorn */ 353230123Snwhitehorn .globl CNAME(slbtrap),CNAME(slbtrapsize) 354230123SnwhitehornCNAME(slbtrap): 355230123Snwhitehorn mtsprg1 %r1 /* save SP */ 356230123Snwhitehorn GET_CPUINFO(%r1) 357230123Snwhitehorn std %r2,(PC_SLBSAVE+16)(%r1) 358230123Snwhitehorn mfcr %r2 /* save CR */ 359230123Snwhitehorn std %r2,(PC_SLBSAVE+104)(%r1) 360230123Snwhitehorn mfsrr1 %r2 /* test kernel mode */ 361230123Snwhitehorn mtcr %r2 362230123Snwhitehorn bf 17,1f /* branch if PSL_PR is false */ 363230123Snwhitehorn /* User mode */ 364230123Snwhitehorn ld %r2,(PC_SLBSAVE+104)(%r1) /* Restore CR */ 365230123Snwhitehorn mtcr %r2 366230123Snwhitehorn ld %r2,(PC_SLBSAVE+16)(%r1) /* Restore R2 */ 367230123Snwhitehorn mflr %r1 /* Save the old LR in r1 */ 368230123Snwhitehorn mtsprg2 %r1 /* And then in SPRG2 */ 369230123Snwhitehorn li %r1, 0x80 /* How to get the vector from LR */ 370230123Snwhitehorn bla generictrap /* LR & SPRG3 is exception # */ 371230123Snwhitehorn1: mflr %r2 /* Save the old LR in r2 */ 372230123Snwhitehorn bla kern_slbtrap 373230123SnwhitehornCNAME(slbtrapsize) = .-CNAME(slbtrap) 374230123Snwhitehorn 375230123Snwhitehornkern_slbtrap: 376230123Snwhitehorn std %r2,(PC_SLBSAVE+136)(%r1) /* old LR */ 377230123Snwhitehorn std %r3,(PC_SLBSAVE+24)(%r1) /* save R3 */ 378230123Snwhitehorn 379230123Snwhitehorn /* Check if this needs to be handled as a regular trap (userseg miss) */ 380230123Snwhitehorn mflr %r2 381230123Snwhitehorn andi. %r2,%r2,0xff80 382230123Snwhitehorn cmpwi %r2,0x380 383230123Snwhitehorn bne 1f 384230123Snwhitehorn mfdar %r2 385230123Snwhitehorn b 2f 386230123Snwhitehorn1: mfsrr0 %r2 387230123Snwhitehorn2: /* r2 now contains the fault address */ 388230123Snwhitehorn lis %r3,SEGMENT_MASK@highesta 389230123Snwhitehorn ori %r3,%r3,SEGMENT_MASK@highera 390230123Snwhitehorn sldi %r3,%r3,32 391230123Snwhitehorn oris %r3,%r3,SEGMENT_MASK@ha 392230123Snwhitehorn ori %r3,%r3,SEGMENT_MASK@l 393230123Snwhitehorn and %r2,%r2,%r3 /* R2 = segment base address */ 394230123Snwhitehorn lis %r3,USER_ADDR@highesta 395230123Snwhitehorn ori %r3,%r3,USER_ADDR@highera 396230123Snwhitehorn sldi %r3,%r3,32 397230123Snwhitehorn oris %r3,%r3,USER_ADDR@ha 398230123Snwhitehorn ori %r3,%r3,USER_ADDR@l 399230123Snwhitehorn cmpd %r2,%r3 /* Compare fault base to USER_ADDR */ 400230123Snwhitehorn bne 3f 401230123Snwhitehorn 402230123Snwhitehorn /* User seg miss, handle as a regular trap */ 403230123Snwhitehorn ld %r2,(PC_SLBSAVE+104)(%r1) /* Restore CR */ 404230123Snwhitehorn mtcr %r2 405230123Snwhitehorn ld %r2,(PC_SLBSAVE+16)(%r1) /* Restore R2,R3 */ 406230123Snwhitehorn ld %r3,(PC_SLBSAVE+24)(%r1) 407230123Snwhitehorn ld %r1,(PC_SLBSAVE+136)(%r1) /* Save the old LR in r1 */ 408230123Snwhitehorn mtsprg2 %r1 /* And then in SPRG2 */ 409230123Snwhitehorn li %r1, 0x80 /* How to get the vector from LR */ 410230123Snwhitehorn b generictrap /* Retain old LR using b */ 411230123Snwhitehorn 412230123Snwhitehorn3: /* Real kernel SLB miss */ 413230123Snwhitehorn std %r0,(PC_SLBSAVE+0)(%r1) /* free all volatile regs */ 414230123Snwhitehorn mfsprg1 %r2 /* Old R1 */ 415230123Snwhitehorn std %r2,(PC_SLBSAVE+8)(%r1) 416230123Snwhitehorn /* R2,R3 already saved */ 417230123Snwhitehorn std %r4,(PC_SLBSAVE+32)(%r1) 418230123Snwhitehorn std %r5,(PC_SLBSAVE+40)(%r1) 419230123Snwhitehorn std %r6,(PC_SLBSAVE+48)(%r1) 420230123Snwhitehorn std %r7,(PC_SLBSAVE+56)(%r1) 421230123Snwhitehorn std %r8,(PC_SLBSAVE+64)(%r1) 422230123Snwhitehorn std %r9,(PC_SLBSAVE+72)(%r1) 423230123Snwhitehorn std %r10,(PC_SLBSAVE+80)(%r1) 424230123Snwhitehorn std %r11,(PC_SLBSAVE+88)(%r1) 425230123Snwhitehorn std %r12,(PC_SLBSAVE+96)(%r1) 426230123Snwhitehorn /* CR already saved */ 427230123Snwhitehorn mfxer %r2 /* save XER */ 428230123Snwhitehorn std %r2,(PC_SLBSAVE+112)(%r1) 429230123Snwhitehorn mflr %r2 /* save LR (SP already saved) */ 430230123Snwhitehorn std %r2,(PC_SLBSAVE+120)(%r1) 431230123Snwhitehorn mfctr %r2 /* save CTR */ 432230123Snwhitehorn std %r2,(PC_SLBSAVE+128)(%r1) 433230123Snwhitehorn 434230123Snwhitehorn /* Call handler */ 435230123Snwhitehorn addi %r1,%r1,PC_SLBSTACK-48+1024 436230123Snwhitehorn li %r2,~15 437230123Snwhitehorn and %r1,%r1,%r2 438230123Snwhitehorn lis %r3,tocbase@ha 439230123Snwhitehorn ld %r2,tocbase@l(%r3) 440230123Snwhitehorn mflr %r3 441230123Snwhitehorn andi. %r3,%r3,0xff80 442230123Snwhitehorn mfdar %r4 443230123Snwhitehorn mfsrr0 %r5 444230123Snwhitehorn bl handle_kernel_slb_spill 445230123Snwhitehorn nop 446230123Snwhitehorn 447230123Snwhitehorn /* Save r28-31, restore r4-r12 */ 448230123Snwhitehorn GET_CPUINFO(%r1) 449230123Snwhitehorn ld %r4,(PC_SLBSAVE+32)(%r1) 450230123Snwhitehorn ld %r5,(PC_SLBSAVE+40)(%r1) 451230123Snwhitehorn ld %r6,(PC_SLBSAVE+48)(%r1) 452230123Snwhitehorn ld %r7,(PC_SLBSAVE+56)(%r1) 453230123Snwhitehorn ld %r8,(PC_SLBSAVE+64)(%r1) 454230123Snwhitehorn ld %r9,(PC_SLBSAVE+72)(%r1) 455230123Snwhitehorn ld %r10,(PC_SLBSAVE+80)(%r1) 456230123Snwhitehorn ld %r11,(PC_SLBSAVE+88)(%r1) 457230123Snwhitehorn ld %r12,(PC_SLBSAVE+96)(%r1) 458230123Snwhitehorn std %r28,(PC_SLBSAVE+64)(%r1) 459230123Snwhitehorn std %r29,(PC_SLBSAVE+72)(%r1) 460230123Snwhitehorn std %r30,(PC_SLBSAVE+80)(%r1) 461230123Snwhitehorn std %r31,(PC_SLBSAVE+88)(%r1) 462230123Snwhitehorn 463230123Snwhitehorn /* Restore kernel mapping */ 464230123Snwhitehorn bl restore_kernsrs 465230123Snwhitehorn 466230123Snwhitehorn /* Restore remaining registers */ 467230123Snwhitehorn ld %r28,(PC_SLBSAVE+64)(%r1) 468230123Snwhitehorn ld %r29,(PC_SLBSAVE+72)(%r1) 469230123Snwhitehorn ld %r30,(PC_SLBSAVE+80)(%r1) 470230123Snwhitehorn ld %r31,(PC_SLBSAVE+88)(%r1) 471230123Snwhitehorn 472230123Snwhitehorn ld %r2,(PC_SLBSAVE+104)(%r1) 473230123Snwhitehorn mtcr %r2 474230123Snwhitehorn ld %r2,(PC_SLBSAVE+112)(%r1) 475230123Snwhitehorn mtxer %r2 476230123Snwhitehorn ld %r2,(PC_SLBSAVE+120)(%r1) 477230123Snwhitehorn mtlr %r2 478230123Snwhitehorn ld %r2,(PC_SLBSAVE+128)(%r1) 479230123Snwhitehorn mtctr %r2 480230123Snwhitehorn ld %r2,(PC_SLBSAVE+136)(%r1) 481230123Snwhitehorn mtlr %r2 482230123Snwhitehorn 483230123Snwhitehorn /* Restore r0-r3 */ 484230123Snwhitehorn ld %r0,(PC_SLBSAVE+0)(%r1) 485230123Snwhitehorn ld %r2,(PC_SLBSAVE+16)(%r1) 486230123Snwhitehorn ld %r3,(PC_SLBSAVE+24)(%r1) 487230123Snwhitehorn mfsprg1 %r1 488230123Snwhitehorn 489230123Snwhitehorn /* Back to whatever we were doing */ 490230123Snwhitehorn rfid 491230123Snwhitehorn 492230123Snwhitehorn/* 49395719Sbenno * For ALI: has to save DSISR and DAR 49495719Sbenno */ 49596773Sbenno .globl CNAME(alitrap),CNAME(alisize) 49696773SbennoCNAME(alitrap): 497125441Sgrehan mtsprg1 %r1 /* save SP */ 498125441Sgrehan GET_CPUINFO(%r1) 499209975Snwhitehorn std %r27,(PC_TEMPSAVE+CPUSAVE_R27)(%r1) /* free r27-r31 */ 500209975Snwhitehorn std %r28,(PC_TEMPSAVE+CPUSAVE_R28)(%r1) 501209975Snwhitehorn std %r29,(PC_TEMPSAVE+CPUSAVE_R29)(%r1) 502209975Snwhitehorn std %r30,(PC_TEMPSAVE+CPUSAVE_R30)(%r1) 503209975Snwhitehorn std %r31,(PC_TEMPSAVE+CPUSAVE_R31)(%r1) 504125441Sgrehan mfdar %r30 505125441Sgrehan mfdsisr %r31 506209975Snwhitehorn std %r30,(PC_TEMPSAVE+CPUSAVE_AIM_DAR)(%r1) 507209975Snwhitehorn std %r31,(PC_TEMPSAVE+CPUSAVE_AIM_DSISR)(%r1) 508125441Sgrehan mfsprg1 %r1 /* restore SP, in case of branch */ 509125441Sgrehan mflr %r28 /* save LR */ 510125441Sgrehan mfcr %r29 /* save CR */ 511188860Snwhitehorn 512188951Snwhitehorn /* Put our exception vector in SPRG3 */ 513188860Snwhitehorn li %r31, EXC_ALI 514188860Snwhitehorn mtsprg3 %r31 515188860Snwhitehorn 516188860Snwhitehorn /* Test whether we already had PR set */ 517125441Sgrehan mfsrr1 %r31 518125441Sgrehan mtcr %r31 519188860Snwhitehorn bla s_trap 52096773SbennoCNAME(alisize) = .-CNAME(alitrap) 52195719Sbenno 52295719Sbenno/* 52395719Sbenno * Similar to the above for DSI 52495719Sbenno * Has to handle BAT spills 52595719Sbenno * and standard pagetable spills 52695719Sbenno */ 52796773Sbenno .globl CNAME(dsitrap),CNAME(dsisize) 52896773SbennoCNAME(dsitrap): 529125441Sgrehan mtsprg1 %r1 /* save SP */ 530125441Sgrehan GET_CPUINFO(%r1) 531209975Snwhitehorn std %r27,(PC_DISISAVE+CPUSAVE_R27)(%r1) /* free r27-r31 */ 532209975Snwhitehorn std %r28,(PC_DISISAVE+CPUSAVE_R28)(%r1) 533209975Snwhitehorn std %r29,(PC_DISISAVE+CPUSAVE_R29)(%r1) 534209975Snwhitehorn std %r30,(PC_DISISAVE+CPUSAVE_R30)(%r1) 535209975Snwhitehorn std %r31,(PC_DISISAVE+CPUSAVE_R31)(%r1) 536125441Sgrehan mfsprg1 %r1 /* restore SP */ 537125441Sgrehan mfcr %r29 /* save CR */ 538125441Sgrehan mfxer %r30 /* save XER */ 539125441Sgrehan mtsprg2 %r30 /* in SPRG2 */ 540125441Sgrehan mfsrr1 %r31 /* test kernel mode */ 541125441Sgrehan mtcr %r31 542125441Sgrehan mflr %r28 /* save LR (SP already saved) */ 543125441Sgrehan bla disitrap 54496773SbennoCNAME(dsisize) = .-CNAME(dsitrap) 54595719Sbenno 54695719Sbenno/* 54795719Sbenno * Preamble code for DSI/ISI traps 54895719Sbenno */ 54995719Sbennodisitrap: 550188951Snwhitehorn /* Write the trap vector to SPRG3 by computing LR & 0xff00 */ 551188860Snwhitehorn mflr %r1 552188860Snwhitehorn andi. %r1,%r1,0xff00 553188860Snwhitehorn mtsprg3 %r1 554188860Snwhitehorn 555125441Sgrehan GET_CPUINFO(%r1) 556209975Snwhitehorn ld %r31,(PC_DISISAVE+CPUSAVE_R27)(%r1) 557209975Snwhitehorn std %r31,(PC_TEMPSAVE+CPUSAVE_R27)(%r1) 558209975Snwhitehorn ld %r30,(PC_DISISAVE+CPUSAVE_R28)(%r1) 559209975Snwhitehorn std %r30,(PC_TEMPSAVE+CPUSAVE_R28)(%r1) 560209975Snwhitehorn ld %r31,(PC_DISISAVE+CPUSAVE_R29)(%r1) 561209975Snwhitehorn std %r31,(PC_TEMPSAVE+CPUSAVE_R29)(%r1) 562209975Snwhitehorn ld %r30,(PC_DISISAVE+CPUSAVE_R30)(%r1) 563209975Snwhitehorn std %r30,(PC_TEMPSAVE+CPUSAVE_R30)(%r1) 564209975Snwhitehorn ld %r31,(PC_DISISAVE+CPUSAVE_R31)(%r1) 565209975Snwhitehorn std %r31,(PC_TEMPSAVE+CPUSAVE_R31)(%r1) 566125441Sgrehan mfdar %r30 567125441Sgrehan mfdsisr %r31 568209975Snwhitehorn std %r30,(PC_TEMPSAVE+CPUSAVE_AIM_DAR)(%r1) 569209975Snwhitehorn std %r31,(PC_TEMPSAVE+CPUSAVE_AIM_DSISR)(%r1) 570125441Sgrehan 571132571Sgrehan#ifdef KDB 572132571Sgrehan /* Try and detect a kernel stack overflow */ 573132571Sgrehan mfsrr1 %r31 574132571Sgrehan mtcr %r31 575132571Sgrehan bt 17,realtrap /* branch is user mode */ 576132571Sgrehan mfsprg1 %r31 /* get old SP */ 577132571Sgrehan sub. %r30,%r31,%r30 /* SP - DAR */ 578132571Sgrehan bge 1f 579132571Sgrehan neg %r30,%r30 /* modulo value */ 580209975Snwhitehorn1: cmpldi %cr0,%r30,4096 /* is DAR within a page of SP? */ 581132571Sgrehan bge %cr0,realtrap /* no, too far away. */ 582132571Sgrehan 583132571Sgrehan /* Now convert this DSI into a DDB trap. */ 584132571Sgrehan GET_CPUINFO(%r1) 585209975Snwhitehorn ld %r30,(PC_TEMPSAVE+CPUSAVE_AIM_DAR)(%r1) /* get DAR */ 586209975Snwhitehorn std %r30,(PC_DBSAVE +CPUSAVE_AIM_DAR)(%r1) /* save DAR */ 587209975Snwhitehorn ld %r30,(PC_TEMPSAVE+CPUSAVE_AIM_DSISR)(%r1) /* get DSISR */ 588209975Snwhitehorn std %r30,(PC_DBSAVE +CPUSAVE_AIM_DSISR)(%r1) /* save DSISR */ 589209975Snwhitehorn ld %r31,(PC_DISISAVE+CPUSAVE_R27)(%r1) /* get r27 */ 590209975Snwhitehorn std %r31,(PC_DBSAVE +CPUSAVE_R27)(%r1) /* save r27 */ 591209975Snwhitehorn ld %r30,(PC_DISISAVE+CPUSAVE_R28)(%r1) /* get r28 */ 592209975Snwhitehorn std %r30,(PC_DBSAVE +CPUSAVE_R28)(%r1) /* save r28 */ 593209975Snwhitehorn ld %r31,(PC_DISISAVE+CPUSAVE_R29)(%r1) /* get r29 */ 594209975Snwhitehorn std %r31,(PC_DBSAVE +CPUSAVE_R29)(%r1) /* save r29 */ 595209975Snwhitehorn ld %r30,(PC_DISISAVE+CPUSAVE_R30)(%r1) /* get r30 */ 596209975Snwhitehorn std %r30,(PC_DBSAVE +CPUSAVE_R30)(%r1) /* save r30 */ 597209975Snwhitehorn ld %r31,(PC_DISISAVE+CPUSAVE_R31)(%r1) /* get r31 */ 598209975Snwhitehorn std %r31,(PC_DBSAVE +CPUSAVE_R31)(%r1) /* save r31 */ 599191039Snwhitehorn b dbtrap 600132571Sgrehan#endif 601132571Sgrehan 602125441Sgrehan /* XXX need stack probe here */ 60395719Sbennorealtrap: 60495719Sbenno/* Test whether we already had PR set */ 605125441Sgrehan mfsrr1 %r1 606125441Sgrehan mtcr %r1 607125441Sgrehan mfsprg1 %r1 /* restore SP (might have been 60895719Sbenno overwritten) */ 609188860Snwhitehorn bf 17,k_trap /* branch if PSL_PR is false */ 610188860Snwhitehorn GET_CPUINFO(%r1) 611209975Snwhitehorn ld %r1,PC_CURPCB(%r1) 612209975Snwhitehorn mr %r27,%r28 /* Save LR, r29 */ 613209975Snwhitehorn mtsprg2 %r29 614212722Snwhitehorn bl restore_kernsrs /* enable kernel mapping */ 615209975Snwhitehorn mfsprg2 %r29 616209975Snwhitehorn mr %r28,%r27 617188860Snwhitehorn ba s_trap 618188860Snwhitehorn 619188860Snwhitehorn/* 620188860Snwhitehorn * generictrap does some standard setup for trap handling to minimize 621188860Snwhitehorn * the code that need be installed in the actual vectors. It expects 622188860Snwhitehorn * the following conditions. 623188860Snwhitehorn * 624188860Snwhitehorn * R1 - Trap vector = LR & (0xff00 | R1) 625188860Snwhitehorn * SPRG1 - Original R1 contents 626188860Snwhitehorn * SPRG2 - Original LR 627188860Snwhitehorn */ 628188860Snwhitehorn 629188860Snwhitehorngenerictrap: 630188860Snwhitehorn /* Save R1 for computing the exception vector */ 631188860Snwhitehorn mtsprg3 %r1 632188860Snwhitehorn 633188860Snwhitehorn /* Save interesting registers */ 634188860Snwhitehorn GET_CPUINFO(%r1) 635209975Snwhitehorn std %r27,(PC_TEMPSAVE+CPUSAVE_R27)(%r1) /* free r27-r31 */ 636209975Snwhitehorn std %r28,(PC_TEMPSAVE+CPUSAVE_R28)(%r1) 637209975Snwhitehorn std %r29,(PC_TEMPSAVE+CPUSAVE_R29)(%r1) 638209975Snwhitehorn std %r30,(PC_TEMPSAVE+CPUSAVE_R30)(%r1) 639209975Snwhitehorn std %r31,(PC_TEMPSAVE+CPUSAVE_R31)(%r1) 640209975Snwhitehorn mfdar %r30 641209975Snwhitehorn std %r30,(PC_TEMPSAVE+CPUSAVE_AIM_DAR)(%r1) 642188860Snwhitehorn mfsprg1 %r1 /* restore SP, in case of branch */ 643188860Snwhitehorn mfsprg2 %r28 /* save LR */ 644188860Snwhitehorn mfcr %r29 /* save CR */ 645188860Snwhitehorn 646188860Snwhitehorn /* Compute the exception vector from the link register */ 647188860Snwhitehorn mfsprg3 %r31 648188860Snwhitehorn ori %r31,%r31,0xff00 649188860Snwhitehorn mflr %r30 650188860Snwhitehorn and %r30,%r30,%r31 651188860Snwhitehorn mtsprg3 %r30 652188860Snwhitehorn 653188860Snwhitehorn /* Test whether we already had PR set */ 654188860Snwhitehorn mfsrr1 %r31 655188860Snwhitehorn mtcr %r31 656188860Snwhitehorn 657125441Sgrehans_trap: 658125441Sgrehan bf 17,k_trap /* branch if PSL_PR is false */ 659125441Sgrehan GET_CPUINFO(%r1) 660125441Sgrehanu_trap: 661209975Snwhitehorn ld %r1,PC_CURPCB(%r1) 662209975Snwhitehorn mr %r27,%r28 /* Save LR, r29 */ 663209975Snwhitehorn mtsprg2 %r29 664212722Snwhitehorn bl restore_kernsrs /* enable kernel mapping */ 665209975Snwhitehorn mfsprg2 %r29 666209975Snwhitehorn mr %r28,%r27 66795719Sbenno 66895719Sbenno/* 66995719Sbenno * Now the common trap catching code. 67095719Sbenno */ 671125441Sgrehank_trap: 672125441Sgrehan FRAME_SETUP(PC_TEMPSAVE) 67399032Sbenno/* Call C interrupt dispatcher: */ 67495719Sbennotrapagain: 675209975Snwhitehorn lis %r3,tocbase@ha 676209975Snwhitehorn ld %r2,tocbase@l(%r3) 677209975Snwhitehorn addi %r3,%r1,48 678218824Snwhitehorn bl CNAME(powerpc_interrupt) 679209975Snwhitehorn nop 680209975Snwhitehorn 681209975Snwhitehorn .globl CNAME(trapexit) /* backtrace code sentinel */ 68296773SbennoCNAME(trapexit): 68395719Sbenno/* Disable interrupts: */ 684125441Sgrehan mfmsr %r3 685125441Sgrehan andi. %r3,%r3,~PSL_EE@l 686125441Sgrehan mtmsr %r3 687222309Snwhitehorn isync 68895719Sbenno/* Test AST pending: */ 689209975Snwhitehorn ld %r5,FRAME_SRR1+48(%r1) 690125441Sgrehan mtcr %r5 691125441Sgrehan bf 17,1f /* branch if PSL_PR is false */ 69299032Sbenno 693125441Sgrehan GET_CPUINFO(%r3) /* get per-CPU pointer */ 694223485Snwhitehorn lwz %r4, TD_FLAGS(%r13) /* get thread flags value */ 695125441Sgrehan lis %r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@h 696125441Sgrehan ori %r5,%r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@l 697125441Sgrehan and. %r4,%r4,%r5 69895719Sbenno beq 1f 699125441Sgrehan mfmsr %r3 /* re-enable interrupts */ 700125441Sgrehan ori %r3,%r3,PSL_EE@l 701125441Sgrehan mtmsr %r3 70299032Sbenno isync 703209975Snwhitehorn lis %r3,tocbase@ha 704209975Snwhitehorn ld %r2,tocbase@l(%r3) 705209975Snwhitehorn addi %r3,%r1,48 706218824Snwhitehorn bl CNAME(ast) 707209975Snwhitehorn nop 708153685Sgrehan .globl CNAME(asttrapexit) /* backtrace code sentinel #2 */ 709153685SgrehanCNAME(asttrapexit): 71099032Sbenno b trapexit /* test ast ret value ? */ 71195719Sbenno1: 712125441Sgrehan FRAME_LEAVE(PC_TEMPSAVE) 713190681Snwhitehorn rfid 714190681Snwhitehorn 715132075Sgrehan#if defined(KDB) 71695719Sbenno/* 717132075Sgrehan * Deliberate entry to dbtrap 71895719Sbenno */ 719230400SandreastASENTRY_NOPROF(breakpoint) 720125441Sgrehan mtsprg1 %r1 721125441Sgrehan mfmsr %r3 722125441Sgrehan mtsrr1 %r3 723125441Sgrehan andi. %r3,%r3,~(PSL_EE|PSL_ME)@l 724125441Sgrehan mtmsr %r3 /* disable interrupts */ 72595719Sbenno isync 726125441Sgrehan GET_CPUINFO(%r3) 727209975Snwhitehorn std %r27,(PC_DBSAVE+CPUSAVE_R27)(%r3) 728209975Snwhitehorn std %r28,(PC_DBSAVE+CPUSAVE_R28)(%r3) 729209975Snwhitehorn std %r29,(PC_DBSAVE+CPUSAVE_R29)(%r3) 730209975Snwhitehorn std %r30,(PC_DBSAVE+CPUSAVE_R30)(%r3) 731209975Snwhitehorn std %r31,(PC_DBSAVE+CPUSAVE_R31)(%r3) 732125441Sgrehan mflr %r28 733125441Sgrehan li %r29,EXC_BPT 734125441Sgrehan mtlr %r29 735125441Sgrehan mfcr %r29 736125441Sgrehan mtsrr0 %r28 73795719Sbenno 73895719Sbenno/* 739132075Sgrehan * Now the kdb trap catching code. 74095719Sbenno */ 741132075Sgrehandbtrap: 742188951Snwhitehorn /* Write the trap vector to SPRG3 by computing LR & 0xff00 */ 743188860Snwhitehorn mflr %r1 744188860Snwhitehorn andi. %r1,%r1,0xff00 745188860Snwhitehorn mtsprg3 %r1 746188860Snwhitehorn 747209975Snwhitehorn lis %r1,(tmpstk+TMPSTKSZ-48)@ha /* get new SP */ 748209975Snwhitehorn addi %r1,%r1,(tmpstk+TMPSTKSZ-48)@l 749188860Snwhitehorn 750132075Sgrehan FRAME_SETUP(PC_DBSAVE) 75195719Sbenno/* Call C trap code: */ 752209975Snwhitehorn lis %r3,tocbase@ha 753209975Snwhitehorn ld %r2,tocbase@l(%r3) 754209975Snwhitehorn addi %r3,%r1,48 755218824Snwhitehorn bl CNAME(db_trap_glue) 756209975Snwhitehorn nop 757125441Sgrehan or. %r3,%r3,%r3 758132075Sgrehan bne dbleave 759132075Sgrehan/* This wasn't for KDB, so switch to real trap: */ 760209975Snwhitehorn ld %r3,FRAME_EXC+48(%r1) /* save exception */ 761125441Sgrehan GET_CPUINFO(%r4) 762209975Snwhitehorn std %r3,(PC_DBSAVE+CPUSAVE_R31)(%r4) 763132075Sgrehan FRAME_LEAVE(PC_DBSAVE) 764125441Sgrehan mtsprg1 %r1 /* prepare for entrance to realtrap */ 765125441Sgrehan GET_CPUINFO(%r1) 766209975Snwhitehorn std %r27,(PC_TEMPSAVE+CPUSAVE_R27)(%r1) 767209975Snwhitehorn std %r28,(PC_TEMPSAVE+CPUSAVE_R28)(%r1) 768209975Snwhitehorn std %r29,(PC_TEMPSAVE+CPUSAVE_R29)(%r1) 769209975Snwhitehorn std %r30,(PC_TEMPSAVE+CPUSAVE_R30)(%r1) 770209975Snwhitehorn std %r31,(PC_TEMPSAVE+CPUSAVE_R31)(%r1) 771125441Sgrehan mflr %r28 772125441Sgrehan mfcr %r29 773209975Snwhitehorn ld %r31,(PC_DBSAVE+CPUSAVE_R31)(%r1) 774190946Snwhitehorn mtsprg3 %r31 /* SPRG3 was clobbered by FRAME_LEAVE */ 775125441Sgrehan mfsprg1 %r1 77695719Sbenno b realtrap 777132075Sgrehandbleave: 778132075Sgrehan FRAME_LEAVE(PC_DBSAVE) 779209975Snwhitehorn rfid 78095719Sbenno 78195719Sbenno/* 782132075Sgrehan * In case of KDB we want a separate trap catcher for it 78395719Sbenno */ 784132075Sgrehan .globl CNAME(dblow),CNAME(dbsize) 785132075SgrehanCNAME(dblow): 786125441Sgrehan mtsprg1 %r1 /* save SP */ 787125441Sgrehan mtsprg2 %r29 /* save r29 */ 788125441Sgrehan mfcr %r29 /* save CR in r29 */ 789125441Sgrehan mfsrr1 %r1 790125441Sgrehan mtcr %r1 791125441Sgrehan bf 17,1f /* branch if privileged */ 792188860Snwhitehorn 793188860Snwhitehorn /* Unprivileged case */ 794188860Snwhitehorn mtcr %r29 /* put the condition register back */ 795188860Snwhitehorn mfsprg2 %r29 /* ... and r29 */ 796188860Snwhitehorn mflr %r1 /* save LR */ 797188860Snwhitehorn mtsprg2 %r1 /* And then in SPRG2 */ 798188860Snwhitehorn li %r1, 0 /* How to get the vector from LR */ 799188860Snwhitehorn 800188860Snwhitehorn bla generictrap /* and we look like a generic trap */ 801125441Sgrehan1: 802188860Snwhitehorn /* Privileged, so drop to KDB */ 803188860Snwhitehorn GET_CPUINFO(%r1) 804209975Snwhitehorn std %r27,(PC_DBSAVE+CPUSAVE_R27)(%r1) /* free r27 */ 805209975Snwhitehorn std %r28,(PC_DBSAVE+CPUSAVE_R28)(%r1) /* free r28 */ 806125441Sgrehan mfsprg2 %r28 /* r29 holds cr... */ 807209975Snwhitehorn std %r28,(PC_DBSAVE+CPUSAVE_R29)(%r1) /* free r29 */ 808209975Snwhitehorn std %r30,(PC_DBSAVE+CPUSAVE_R30)(%r1) /* free r30 */ 809209975Snwhitehorn std %r31,(PC_DBSAVE+CPUSAVE_R31)(%r1) /* free r31 */ 810125441Sgrehan mflr %r28 /* save LR */ 811132075Sgrehan bla dbtrap 812132075SgrehanCNAME(dbsize) = .-CNAME(dblow) 813132075Sgrehan#endif /* KDB */ 814