From owner-freebsd-ppc@FreeBSD.ORG Wed Dec 20 06:26:26 2006 Return-Path: X-Original-To: freebsd-ppc@freebsd.org Delivered-To: freebsd-ppc@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 50D1B16A403; Wed, 20 Dec 2006 06:26:26 +0000 (UTC) (envelope-from andrew@fubar.geek.nz) Received: from fep05.xtra.co.nz (fep05.xtra.co.nz [210.54.141.241]) by mx1.FreeBSD.org (Postfix) with ESMTP id 75BEF43C9F; Wed, 20 Dec 2006 06:26:25 +0000 (GMT) (envelope-from andrew@fubar.geek.nz) Received: from serv.int.fubar.geek.nz ([125.237.119.17]) by fep05.xtra.co.nz with ESMTP id <20061220062620.CGNS7885.fep05.xtra.co.nz@serv.int.fubar.geek.nz>; Wed, 20 Dec 2006 19:26:20 +1300 Date: Wed, 20 Dec 2006 19:26:14 +1300 From: Andrew Turner To: Peter Grehan Message-ID: <20061220192614.04c53dbf@hermies.int.fubar.geek.nz> In-Reply-To: <4587316C.1070500@freebsd.org> References: <20061218104841.72ba51ea@hermies.int.fubar.geek.nz> <4585CCC1.7050005@freebsd.org> <20061218222327.308dca53@hermies.int.fubar.geek.nz> <4586CA29.10803@freebsd.org> <20061219113230.34182787@hermies.int.fubar.geek.nz> <4587316C.1070500@freebsd.org> X-Mailer: Sylpheed-Claws 2.6.0 (GTK+ 2.10.6; i386-portbld-freebsd6.2) Mime-Version: 1.0 Content-Type: multipart/mixed; boundary=MP_UpkjTp9EV.oiE3bclM4Ix92 Cc: grehan@freebsd.org, freebsd-ppc@freebsd.org Subject: Re: FreeBSD on an Efika X-BeenThere: freebsd-ppc@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Porting FreeBSD to the PowerPC List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 20 Dec 2006 06:26:26 -0000 --MP_UpkjTp9EV.oiE3bclM4Ix92 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline On Mon, 18 Dec 2006 16:25:16 -0800 Peter Grehan wrote: > a) Put in exception handlers at 0x1000, 0x1100 and 0x1200 to catch > the TLB miss e.g. > > bcopy(&trapcode, (void *)0x1000, (size_t)&trapsize); > > As you can see in , the existing vector definition > don't match these, or are incorrect for the G2 core. There is EXC_IMISS, EXC_DLMISS and EXC_DSMISS. > d) Now the fun part: for those exceptions, change the handler to > point to code that will walk the PTEG table and insert a TLB if > found. If not found, fake a DSI or ISI trap. This can be done in C, > though you will have to be careful to use a pre-allocated stack and > not touch any virtual addresses while doing this, since it could > result in another fault. The attached patch adds the NetBSD handlers. There is a bug in the patch where I can read data once but on the next read or write the kernel crashes. Andrew --MP_UpkjTp9EV.oiE3bclM4Ix92 Content-Type: text/x-patch; name=efika-1.diff Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=efika-1.diff Index: sys/powerpc/include/psl.h =================================================================== RCS file: /cvsroot/src/sys/powerpc/include/psl.h,v retrieving revision 1.4 diff -u -r1.4 psl.h --- sys/powerpc/include/psl.h 7 Jan 2005 02:29:19 -0000 1.4 +++ sys/powerpc/include/psl.h 19 Dec 2006 11:44:10 -0000 @@ -46,6 +46,7 @@ */ #define PSL_VEC 0x02000000 /* AltiVec vector unit available */ #define PSL_POW 0x00040000 /* power management */ +#define PSL_TGPR 0x00020000 /* temp. gpr remapping (mpc603e) */ #define PSL_ILE 0x00010000 /* interrupt endian mode (1 == le) */ #define PSL_EE 0x00008000 /* external interrupt enable */ #define PSL_PR 0x00004000 /* privilege mode (1 == user) */ Index: sys/powerpc/powerpc/locore.S =================================================================== RCS file: /cvsroot/src/sys/powerpc/powerpc/locore.S,v retrieving revision 1.22 diff -u -r1.22 locore.S --- sys/powerpc/powerpc/locore.S 30 Oct 2005 21:29:59 -0000 1.22 +++ sys/powerpc/powerpc/locore.S 19 Dec 2006 11:44:18 -0000 @@ -66,6 +66,7 @@ #include #include #include +#include /* Locate the per-CPU data structure */ #define GET_CPUINFO(r) \ Index: sys/powerpc/powerpc/machdep.c =================================================================== RCS file: /cvsroot/src/sys/powerpc/powerpc/machdep.c,v retrieving revision 1.98 diff -u -r1.98 machdep.c --- sys/powerpc/powerpc/machdep.c 6 Dec 2006 06:34:56 -0000 1.98 +++ sys/powerpc/powerpc/machdep.c 20 Dec 2006 00:27:47 -0000 @@ -256,6 +256,9 @@ extern void *extint, *extsize; extern void *dblow, *dbsize; extern void *vectrap, *vectrapsize; +extern void *tlbimiss, *tlbimsize; +extern void *tlbdlmiss, *tlbdlmsize; +extern void *tlbdsmiss, *tlbdsmsize; void powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp) @@ -350,6 +353,9 @@ bcopy(&trapcode, (void *)EXC_VECAST, (size_t)&trapsize); bcopy(&trapcode, (void *)EXC_THRM, (size_t)&trapsize); bcopy(&trapcode, (void *)EXC_BPT, (size_t)&trapsize); + bcopy(&tlbimiss, (void *)EXC_IMISS, (size_t)&tlbimsize); + bcopy(&tlbdlmiss, (void *)EXC_DLMISS, (size_t)&tlbdlmsize); + bcopy(&tlbdsmiss, (void *)EXC_DSMISS, (size_t)&tlbdsmsize); #ifdef KDB bcopy(&dblow, (void *)EXC_RST, (size_t)&dbsize); bcopy(&dblow, (void *)EXC_MCHK, (size_t)&dbsize); Index: sys/powerpc/powerpc/trap_subr.S =================================================================== RCS file: /cvsroot/src/sys/powerpc/powerpc/trap_subr.S,v retrieving revision 1.16 diff -u -r1.16 trap_subr.S --- sys/powerpc/powerpc/trap_subr.S 23 Dec 2005 13:05:27 -0000 1.16 +++ sys/powerpc/powerpc/trap_subr.S 20 Dec 2006 00:30:53 -0000 @@ -342,6 +342,205 @@ CNAME(dsisize) = .-CNAME(dsitrap) /* + * Now the tlb software load for 603 processors: + * (Code essentially from the 603e User Manual, Chapter 5, but + * corrected a lot.) + */ + +/* + * For tlb instruction misses + */ + .globl CNAME(tlbimiss),CNAME(tlbimsize) +CNAME(tlbimiss): + mfspr %r2,SPR_HASH1 /* get first pointer */ + li %r1,8 + mfctr %r0 /* save counter */ + mfspr %r3,SPR_ICMP /* get first compare value */ + addi %r2,%r2,-8 /* predec pointer */ +1: + mtctr %r1 /* load counter */ +2: + lwzu %r1,8(%r2) /* get next pte */ + cmpl %cr0,%r1,%r3 /* see if found pte */ + bdnzf 2,2b /* loop if not eq */ + bne 3f /* not found */ + lwz %r1,4(%r2) /* load tlb entry lower word */ + andi. %r3,%r1,PTE_G /* check G-bit */ + bne 4f /* if guarded, take ISI */ + mtctr %r0 /* restore counter */ + mfspr %r0,SPR_IMISS /* get the miss address for the tlbli */ + mfsrr1 %r3 /* get the saved cr0 bits */ + mtcrf 0x80,%r3 /* and restore */ + ori %r1,%r1,PTE_REF /* set the reference bit */ + mtspr SPR_RPA,1 /* set the pte */ + srwi %r1,%r1,8 /* get byte 7 of pte */ + tlbli %r0 /* load the itlb */ + stb %r1,6(%r2) /* update page table */ + RFI + +3: /* not found in pteg */ + andi. %r1,%r3,PTE_HID /* have we already done second hash? */ + bne 5f + mfspr %r2,SPR_HASH2 /* get the second pointer */ + ori %r3,%r3,PTE_HID /* change the compare value */ + li %r1,8 + addi %r2,%r2,-8 /* predec pointer */ + b 1b +4: /* guarded */ + mfsrr1 %r3 + andi. %r2,%r3,0xffff /* clean upper srr1 */ + oris %r2,%r2,DSISR_PROTECT@h /* set srr<4> to flag prot violation */ + b 6f +5: /* not found anywhere */ + mfsrr1 %r3 + andi. %r2,%r3,0xffff /* clean upper srr1 */ + oris %r2,%r2,DSISR_NOTFOUND@h /* set srr1<1> to flag pte not found */ +6: + mtctr %r0 /* restore counter */ + mtsrr1 %r2 + mfmsr %r0 + xoris %r0,%r0,PSL_TGPR@h /* flip the msr bit */ + mtcrf 0x80,%r3 /* restore cr0 */ + mtmsr %r0 /* now with native gprs */ + isync + ba EXC_ISI +CNAME(tlbimsize) = .-CNAME(tlbimiss) + +/* + * For tlb data load misses + */ + .globl CNAME(tlbdlmiss),CNAME(tlbdlmsize) +CNAME(tlbdlmiss): + mfspr %r2,SPR_HASH1 /* get first pointer */ + li %r1,8 + mfctr %r0 /* save counter */ + mfspr %r3,SPR_DCMP /* get first compare value */ + addi %r2,%r2,-8 /* predec pointer */ +1: + mtctr %r1 /* load counter */ +2: + lwzu %r1,8(%r2) /* get next pte */ + cmpl %cr0,%r1,%r3 /* see if found pte */ + bdnzf 2,2b /* loop if not eq */ + bne 3f /* not found */ + lwz %r1,4(%r2) /* load tlb entry lower word */ + mtctr %r0 /* restore counter */ + mfspr %r0,SPR_DMISS /* get the miss address for the tlbld */ + mfsrr1 %r3 /* get the saved cr0 bits */ + mtcrf 0x80,%r3 /* and restore */ + ori %r1,%r1,PTE_REF /* set the reference bit */ + mtspr SPR_RPA,%r1 /* set the pte */ + srwi %r1,%r1,8 /* get byte 7 of pte */ + tlbld %r0 /* load the dtlb */ + stb %r1,6(%r2) /* update page table */ + RFI + +3: /* not found in pteg */ + andi. %r1,%r3,PTE_HID /* have we already done second hash? */ + bne 5f + mfspr %r2,SPR_HASH2 /* get the second pointer */ + ori %r3,%r3,PTE_HID /* change the compare value */ + li %r1,8 + addi %r2,%r2,-8 /* predec pointer */ + b 1b +5: /* not found anywhere */ + mfsrr1 %r3 + lis %r1,DSISR_NOTFOUND@h /* set dsisr<1> to flag pte not found */ + mtctr %r0 /* restore counter */ + andi. %r2,%r3,0xffff /* clean upper srr1 */ + mtsrr1 %r2 + mtdsisr %r1 /* load the dsisr */ + mfspr %r1,SPR_DMISS /* get the miss address */ + mtdar %r1 /* put in dar */ + mfmsr %r0 + xoris %r0,%r0,PSL_TGPR@h /* flip the msr bit */ + mtcrf 0x80,%r3 /* restore cr0 */ + mtmsr %r0 /* now with native gprs */ + isync + ba EXC_DSI +CNAME(tlbdlmsize) = .-CNAME(tlbdlmiss) + +/* + * For tlb data store misses + */ + .globl CNAME(tlbdsmiss),CNAME(tlbdsmsize) +CNAME(tlbdsmiss): + mfspr %r2,SPR_HASH1 /* get first pointer */ + li %r1,%r8 + mfctr %r0 /* save counter */ + mfspr %r3,SPR_DCMP /* get first compare value */ + addi %r2,%r2,-8 /* predec pointer */ +1: + mtctr %r1 /* load counter */ +2: + lwzu %r1,8(%r2) /* get next pte */ + cmpl %cr0,%r1,%r3 /* see if found pte */ + bdnzf 2,2b /* loop if not eq */ + bne 3f /* not found */ + lwz %r1,4(%r2) /* load tlb entry lower word */ + andi. %r3,%r1,PTE_CHG /* check the C-bit */ + beq 4f +5: + mtctr %r0 /* restore counter */ + mfspr %r0,SPR_DMISS /* get the miss address for the tlbld */ + mfsrr1 %r3 /* get the saved cr0 bits */ + mtcrf 0x80,%r3 /* and restore */ + mtspr SPR_RPA,%r1 /* set the pte */ + tlbld %r0 /* load the dtlb */ + RFI + +3: /* not found in pteg */ + andi. %r1,%r3,PTE_HID /* have we already done second hash? */ + bne 5f + mfspr %r2,SPR_HASH2 /* get the second pointer */ + ori %r3,%r3,PTE_HID /* change the compare value */ + li %r1,8 + addi %r2,%r2,-8 /* predec pointer */ + b 1b +4: /* found, but C-bit = 0 */ + rlwinm. %r3,%r1,30,0,1 /* test PP */ + bge- 7f + andi. %r3,%r1,1 + beq+ 8f +9: /* found, but protection violation (PP==00)*/ + mfsrr1 %r3 + lis %r1,(DSISR_PROTECT|DSISR_STORE)@h + /* indicate protection violation + on store */ + b 1f +7: /* found, PP=1x */ + mfspr %r3,SPR_DMISS /* get the miss address */ + mfsrin %r1,%r3 /* get the segment register */ + mfsrr1 %r3 + rlwinm %r3,%r3,18,31,31 /* get PR-bit */ + rlwnm. %r2,%r2,%r3,1,1 /* get the key */ + bne- 9b /* protection violation */ +8: /* found, set reference/change bits */ + lwz %r1,4(%r2) /* reload tlb entry */ + ori %r1,%r1,(PTE_REF|PTE_CHG) + sth %r1,6(%r2) + b 5b +5: /* not found anywhere */ + mfsrr1 %r3 + lis %r1,(DSISR_NOTFOUND|DSISR_STORE)@h + /* set dsisr<1> to flag pte not found */ + /* dsisr<6> to flag store */ +1: + mtctr %r0 /* restore counter */ + andi. %r2,%r3,0xffff /* clean upper srr1 */ + mtsrr1 %r2 + mtdsisr %r1 /* load the dsisr */ + mfspr %r1,SPR_DMISS /* get the miss address */ + mtdar %r1 /* put in dar */ + mfmsr %r0 + xoris %r0,%r0,PSL_TGPR@h /* flip the msr bit */ + mtcrf 0x80,%r3 /* restore cr0 */ + mtmsr %r0 /* now with native gprs */ + isync + ba EXC_DSI +CNAME(tlbdsmsize) = .-CNAME(tlbdsmiss) + +/* * Preamble code for DSI/ISI traps */ disitrap: --MP_UpkjTp9EV.oiE3bclM4Ix92--