From patchwork Mon Oct 5 12:16:38 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joakim Tjernlund X-Patchwork-Id: 35002 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from bilbo.ozlabs.org (localhost [127.0.0.1]) by ozlabs.org (Postfix) with ESMTP id D9865B85BD for ; Mon, 5 Oct 2009 23:17:17 +1100 (EST) Received: by ozlabs.org (Postfix) id 75E75B7BB7; Mon, 5 Oct 2009 23:16:51 +1100 (EST) Delivered-To: linuxppc-dev@ozlabs.org Received: from gw1.transmode.se (gw1.transmode.se [213.115.205.20]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id B6D2FB7B88 for ; Mon, 5 Oct 2009 23:16:49 +1100 (EST) Received: from sesr04.transmode.se (sesr04.transmode.se [192.168.201.15]) by gw1.transmode.se (Postfix) with ESMTP id 2C00D650007; Mon, 5 Oct 2009 14:16:45 +0200 (CEST) Received: from gentoo-jocke.transmode.se ([192.168.1.15]) by sesr04.transmode.se (Lotus Domino Release 8.5 HF407) with ESMTP id 2009100514164524-588 ; Mon, 5 Oct 2009 14:16:45 +0200 Received: from gentoo-jocke.transmode.se (gentoo-jocke.transmode.se [127.0.0.1]) by gentoo-jocke.transmode.se (8.14.0/8.14.0) with ESMTP id n95CGiuS009082; Mon, 5 Oct 2009 14:16:44 +0200 Received: (from jocke@localhost) by gentoo-jocke.transmode.se (8.14.0/8.14.0/Submit) id n95CGiDm009080; Mon, 5 Oct 2009 14:16:44 +0200 From: Joakim Tjernlund To: Scott Wood , Rex Feany , "linuxppc-dev@ozlabs.org" , Benjamin Herrenschmidt Subject: [PATCH 5/6] 8xx: Fixup DAR from buggy dcbX instructions. Date: Mon, 5 Oct 2009 14:16:38 +0200 Message-Id: <1254744999-3158-6-git-send-email-Joakim.Tjernlund@transmode.se> X-Mailer: git-send-email 1.6.4.4 In-Reply-To: <1254744999-3158-5-git-send-email-Joakim.Tjernlund@transmode.se> References: <1254744999-3158-1-git-send-email-Joakim.Tjernlund@transmode.se> <1254744999-3158-2-git-send-email-Joakim.Tjernlund@transmode.se> <1254744999-3158-3-git-send-email-Joakim.Tjernlund@transmode.se> <1254744999-3158-4-git-send-email-Joakim.Tjernlund@transmode.se> <1254744999-3158-5-git-send-email-Joakim.Tjernlund@transmode.se> X-MIMETrack: Itemize by SMTP Server on sesr04/Transmode(Release 8.5 HF407|May 07, 2009) at 2009-10-05 14:16:45, Serialize by Router on sesr04/Transmode(Release 8.5 HF407|May 07, 2009) at 2009-10-05 14:16:45, Serialize complete at 2009-10-05 14:16:45 X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org This is an assembler version to fixup DAR not being set by dcbX, icbi instructions. There are two versions, one uses selfmodifing code(default), the other uses jump table but is much bigger. --- arch/powerpc/kernel/head_8xx.S | 146 +++++++++++++++++++++++++++++++++++++++- 1 files changed, 145 insertions(+), 1 deletions(-) diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index b93e32f..bddaf26 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -551,7 +551,8 @@ DataTLBError: mfspr r10, SPRN_DAR cmpwi cr0, r10, 0x00f0 - beq- 2f /* must be a buggy dcbX, icbi insn. */ + beq- FixDAR /* must be a buggy dcbX, icbi insn. */ +DARFix: /* Return from dcbx instruction bug workaround, r10 holds value of DAR */ /* First, make sure this was a store operation. */ @@ -674,6 +675,149 @@ DataTLBError: . = 0x2000 +/* This is the procedure to calculate the data EA for buggy dcbx,dcbi instructions + * by decoding the registers used by the dcbx instruction and adding them. + * DAR is set to the calculated address and r10 also holds the EA on exit. + */ +//#define NO_SELF_MODIFYING_CODE /* define if you don't want to use self modifying code */ + nop /* A few nops to make the modified_instr: space below cache line aligned */ + nop +139: /* fetch instruction from userspace memory */ + DO_8xx_CPU6(0x3780, r3) + mtspr SPRN_MD_EPN, r10 + mfspr r11, SPRN_M_TWB /* Get level 1 table entry address */ + lwz r11, 0(r11) /* Get the level 1 entry */ + tophys (r11, r11) + DO_8xx_CPU6(0x3b80, r3) + mtspr SPRN_MD_TWC, r11 /* Load pte table base address */ + mfspr r11, SPRN_MD_TWC /* ....and get the pte address */ + lwz r11, 0(r11) /* Get the pte */ + /* concat physical page address(r11) and page offset(r10) */ + rlwimi r11, r10, 0, 20, 31 + b 140f +FixDAR: /* Entry point for dcbx workaround. */ + /* fetch instruction from memory. */ + mfspr r10, SPRN_SRR0 + andis. r11, r10, 0x8000 + tophys (r11, r10) + beq- 139b /* Branch if user space address */ +140: lwz r11,0(r11) +#ifdef CONFIG_8xx_CPU6 + lwz r3, 8(r0) /* restore r3 from memory */ +#endif +#ifndef NO_SELF_MODIFYING_CODE + andis. r10,r11,0x1f /* test if reg RA is r0 */ + li r10,modified_instr@l + dcbtst r0,r10 /* touch for store */ + rlwinm r11,r11,0,0,20 /* Zero lower 10 bits */ + oris r11,r11,640 /* Transform instr. to a "add r10,RA,RB" */ + ori r11,r11,532 + stw r11,0(r10) /* store add/and instruction */ + dcbf 0,r10 /* flush new instr. to memory. */ + icbi 0,r10 /* invalidate instr. cache line */ + lwz r11, 4(r0) /* restore r11 from memory */ + mfspr r10, SPRN_M_TW /* restore r10 from M_TW */ + isync /* Wait until new instr is loaded from memory */ +modified_instr: + .space 4 /* this is where the add/and instr. is stored */ + bne+ 143f + subf r10,r0,r10 /* r10=r10-r0, only if reg RA is r0 */ +143: mtdar r10 /* store faulting EA in DAR */ + b DARFix /* Go back to normal TLB handling */ +#else + mfctr r10 + mtdar r10 /* save ctr reg in DAR */ + rlwinm r10, r11, 24, 24, 28 /* offset into jump table for reg RB */ + addi r10, r10, 150f@l /* add start of table */ + mtctr r10 /* load ctr with jump address */ + xor r10, r10, r10 /* sum starts at zero */ + bctr /* jump into table */ +150: + add r10, r10, r0 + b 151f + add r10, r10, r1 + b 151f + add r10, r10, r2 + b 151f + add r10, r10, r3 + b 151f + add r10, r10, r4 + b 151f + add r10, r10, r5 + b 151f + add r10, r10, r6 + b 151f + add r10, r10, r7 + b 151f + add r10, r10, r8 + b 151f + add r10, r10, r9 + b 151f + add r10, r10, r10 + b 151f + add r10, r10, r11 + b 151f + add r10, r10, r12 + b 151f + add r10, r10, r13 + b 151f + add r10, r10, r14 + b 151f + add r10, r10, r15 + b 151f + add r10, r10, r16 + b 151f + add r10, r10, r17 + b 151f + add r10, r10, r18 + b 151f + add r10, r10, r19 + b 151f + mtctr r11 /* r10 needs special handling */ + b 154f + mtctr r11 /* r11 needs special handling */ + b 153f + add r10, r10, r22 + b 151f + add r10, r10, r23 + b 151f + add r10, r10, r24 + b 151f + add r10, r10, r25 + b 151f + add r10, r10, r25 + b 151f + add r10, r10, r27 + b 151f + add r10, r10, r28 + b 151f + add r10, r10, r29 + b 151f + add r10, r10, r30 + b 151f + add r10, r10, r31 +151: + rlwinm. r11,r11,19,24,28 /* offset into jump table for reg RA */ + beq 152f /* if reg RA is zero, don't add it */ + addi r11, r11, 150b@l /* add start of table */ + mtctr r11 /* load ctr with jump address */ + rlwinm r11,r11,0,16,10 /* make sure we don't execute this more than once */ + bctr /* jump into table */ +152: + mfdar r11 + mtctr r11 /* restore ctr reg from DAR */ + mtdar r10 /* save fault EA to DAR */ + b DARFix /* Go back to normal TLB handling */ + + /* special handling for r10,r11 since these are modified already */ +153: lwz r11, 4(r0) /* load r11 from memory */ + b 155f +154: mfspr r11, SPRN_M_TW /* load r10 from M_TW */ +155: add r10, r10, r11 /* add it */ + mfctr r11 /* restore r11 */ + b 151b +#endif + .globl giveup_fpu giveup_fpu: blr