Date: Mon, 19 Feb 2007 10:04:33 +1300 From: Andrew Turner <andrew@fubar.geek.nz> To: freebsd-ppc@freebsd.org Subject: Patch to partially boot an EFIKA Message-ID: <20070219100433.66d7ff49@hermies.int.fubar.geek.nz>
index | next in thread | raw e-mail
[-- Attachment #1 --]
The attached patch helps me to partially boot my EFIKA. The file
ofwread.S is from NetBSD and needs to be placed in sys/powerpc/powerpc.
The patch takes the real-mode ofw interface code from NetBSD and the
TLB exception handlers from //depot/user/jaras in perforce.
The call to ofwr_init in locore.S is not enabled by default as
it doesn't currently work on my Apple. By commenting out the
FIRMWORKSBUGS ifdef, to call ofwr_init, I can get my EFIKA to boot until
it attempts to schedule work.
Andrew
[-- Attachment #2 --]
/* $NetBSD: ofwreal.S,v 1.9 2007/01/14 22:11:27 aymeric Exp $ */
/*
* Copyright (C) 1996 Wolfgang Solfrank.
* Copyright (C) 1996 TooLs GmbH.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by TooLs GmbH.
* 4. The name of TooLs GmbH may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* This file provides a real-mode client interface on machines, that
* (incorrectly) only implement virtual mode client interface.
*
* It assumes though, that any actual memory in the machine is
* mapped 1:1 even by the virtual mode OpenFirmware.
* Furthermore it assumes that addresses returned by OpenFirmware are not
* accessed by the client.
*
* TODO: handle set-callback specially
*/
#include <machine/psl.h>
#include <machine/trap.h>
#define _NOREGNAMES
#include <machine/asm.h>
#define CACHELINE 32 /* Note that this value is really
hardwired */
.data
ofentry:
.long 0 /* actual entry to firmware in
virtual mode */
#define BATSIZE (8*8)
#define SRSIZE (16*4)
#define SPRGSIZE (4*4)
#define SDR1SIZE 4
#define SI1SIZE (2*256)
#define SI2SIZE (3*256)
#define SVSIZE (BATSIZE+SRSIZE+SPRGSIZE+SDR1SIZE+SI1SIZE+SI2SIZE)
.local fwsave
.comm fwsave,SVSIZE,8
.local clsave
.comm clsave,SVSIZE,8
ENTRY(ofwr_init)
mflr %r31 /* save return address */
mr %r13,%r6 /* save args */
mr %r12,%r7 /* save argslen */
lis %r8,ofentry@ha
stw %r5,ofentry@l(%r8) /* save virtual mode firmware entry */
lis %r3,fwsave@ha /* save the mmu values of the
firmware */
addi %r3,%r3,fwsave@l
bl savemmu
lis %r5,fwentry@ha /* get new firmware entry */
addi %r5,%r5,fwentry@l
mr %r6,%r13 /* restore args pointer */
mr %r7,%r12 /* restore args length */
mtlr %r31 /* restore return address */
blr
/*
* Emulated firmware entry.
*/
fwentry:
mflr %r0 /* save return address */
stw %r0,4(%r1)
stwu %r1,-16(%r1) /* setup stack frame */
stw %r3,8(%r1) /* save arg */
lis %r3,clsave@ha /* save mmu values of client */
addi %r3,%r3,clsave@l
bl savemmu
lis %r3,fwsave@ha /* restore mmu values of firmware */
addi %r3,%r3,fwsave@l
bl restoremmu
lis %r3,ofentry@ha
lwz %r3,ofentry@l(%r3) /* get actual firmware entry */
mtlr %r3
mfmsr %r4
stw %r4,12(%r1) /* save MSR */
ori %r4,%r4,PSL_IR|PSL_DR /* turn on MMU */
andi. %r4,%r4,~PSL_EE@l /* turn off interrupts */
mtmsr %r4
isync
lwz %r3,8(%r1) /* restore arg */
blrl /* do actual firmware call */
stw %r3,8(%r1) /* save return value */
lwz %r4,12(%r1) /* get saved MSR */
mtmsr %r4
isync
lis %r3,fwsave@ha /* save mmu values of firmare */
addi %r3,%r3,fwsave@l /* (might not be necessary, but... */
bl savemmu
lis %r3,clsave@ha /* restore mmu values of client */
addi %r3,%r3,clsave@l
bl restoremmu
lwz %r3,8(%r1) /* restore return value */
lwz %r1,0(%r1) /* and return */
lwz %r0,4(%r1)
mtlr %r0
blr
/*
* Save everyting related to the mmu to the saveare pointed to by r3.
*/
savemmu:
mfibatl %r4,0 /* save BATs */
stw %r4,0(%r3)
mfibatu %r4,0
stw %r4,4(%r3)
mfibatl %r4,1
stw %r4,8(%r3)
mfibatu %r4,1
stw %r4,12(%r3)
mfibatl %r4,2
stw %r4,16(%r3)
mfibatu %r4,2
stw %r4,20(%r3)
mfibatl %r4,3
stw %r4,24(%r3)
mfibatu %r4,3
stw %r4,28(%r3)
mfdbatl %r4,0
stw %r4,32(%r3)
mfdbatu %r4,0
stw %r4,36(%r3)
mfdbatl %r4,1
stw %r4,40(%r3)
mfdbatu %r4,1
stw %r4,44(%r3)
mfdbatl %r4,2
stw %r4,48(%r3)
mfdbatu %r4,2
stw %r4,52(%r3)
mfdbatl %r4,3
stw %r4,56(%r3)
mfdbatu %r4,3
stwu %r4,60(%r3)
li %r4,0 /* save SRs */
1:
addis %r4,%r4,-0x10000000@ha
or. %r4,%r4,%r4
mfsrin %r5,%r4
stwu %r5,4(%r3)
bne 1b
mfsprg0 %r4 /* save SPRGs */
stw %r4,4(%r3)
mfsprg1 %r4
stw %r4,8(%r3)
mfsprg2 %r4
stw %r4,12(%r3)
mfsprg3 %r4
stw %r4,16(%r3)
mfsdr1 %r4 /* save SDR1 */
stw %r4,20(%r3)
addi %r4,%r3,24
mflr %r11
li %r3,EXC_DSI /* save DSI/ISI trap vectors */
li %r5,SI1SIZE
bl copy
mtlr %r11
li %r3,EXC_IMISS /* save MISS trap vectors */
li %r5,SI2SIZE
/* Copy an exception handler */
copy:
li %r6,CACHELINE
1:
lwz %r7,0(%r3)
lwz %r8,4(%r3)
lwz %r9,8(%r3)
lwz %r10,12(%r3)
stw %r7,0(%r4)
stw %r8,4(%r4)
stw %r9,8(%r4)
stw %r10,12(%r4)
lwz %r7,16(%r3)
lwz %r8,20(%r3)
lwz %r9,24(%r3)
lwz %r10,28(%r3)
stw %r7,16(%r4)
stw %r8,20(%r4)
stw %r9,24(%r4)
stw %r10,28(%r4)
dcbst %r0,%r4
icbi %r0,%r4
add %r3,%r3,%r6
add %r4,%r4,%r6
subf. %r5,%r6,%r5
bgt 1b
dcbst %r0,%r4
icbi %r0,%r4
sync
isync
blr
/*
* Restore everyting related to the mmu from the saveare pointed to by r3.
*/
restoremmu:
mfmsr %r12
andi. %r4,%r12,~(PSL_IR|PSL_DR)@l
mtmsr %r4 /* Disable MMU */
isync
li %r4,0 /* first, invalidate BATs */
mtibatu 0,%r4
mtibatu 1,%r4
mtibatu 2,%r4
mtibatu 3,%r4
mtdbatu 0,%r4
mtdbatu 1,%r4
mtdbatu 2,%r4
mtdbatu 3,%r4
lwz %r4,0(%r3)
mtibatl 0,%r4 /* restore BATs */
lwz %r4,4(%r3)
mtibatu 0,%r4
lwz %r4,8(%r3)
mtibatl 1,%r4
lwz %r4,12(%r3)
mtibatu 1,%r4
lwz %r4,16(%r3)
mtibatl 2,%r4
lwz %r4,20(%r3)
mtibatu 2,%r4
lwz %r4,24(%r3)
mtibatl 3,%r4
lwz %r4,28(%r3)
mtibatu 3,%r4
lwz %r4,32(%r3)
mtdbatl 0,%r4
lwz %r4,36(%r3)
mtdbatu 0,%r4
lwz %r4,40(%r3)
mtdbatl 1,%r4
lwz %r4,44(%r3)
mtdbatu 1,%r4
lwz %r4,48(%r3)
mtdbatl 2,%r4
lwz %r4,52(%r3)
mtdbatu 2,%r4
lwz %r4,56(%r3)
mtdbatl 3,%r4
lwzu %r4,60(%r3)
mtdbatu 3,%r4
li %r4,0 /* restore SRs */
1:
lwzu %r5,4(%r3)
addis %r4,%r4,-0x10000000@ha
or. %r4,%r4,%r4
mtsrin %r5,%r4
bne 1b
lwz %r4,4(%r3)
mtsprg0 %r4 /* restore SPRGs */
lwz %r4,8(%r3)
mtsprg1 %r4
lwz %r4,12(%r3)
mtsprg2 %r4
lwz %r4,16(%r3)
mtsprg3 %r4
sync /* remove everything from tlb */
lis %r4,0x40000@ha
li %r5,0x1000
1:
subf. %r4,%r5,%r4
tlbie %r4
bne 1b
sync
tlbsync
sync
lwz %r4,20(%r3)
sync
mtsdr1 %r4 /* restore SDR1 */
addi %r3,%r3,24
mflr %r11
li %r4,EXC_DSI /* restore DSI/ISI trap vectors */
li %r5,SI1SIZE
bl copy
li %r4,EXC_IMISS /* restore MISS trap vectors */
li %r5,SI2SIZE
bl copy
/* tlbia */
sync
li %r3,0x40
mtctr %r3
li %r4,0
1:
tlbie %r4
addi %r4,%r4,0x1000
bdnz 1b
sync
tlbsync
sync
mtmsr %r12 /* restore MMU */
mtlr %r11
blr
[-- Attachment #3 --]
Index: sys/conf/files.powerpc
===================================================================
RCS file: /cvsroot/src/sys/conf/files.powerpc,v
retrieving revision 1.60
diff -u -r1.60 files.powerpc
--- sys/conf/files.powerpc 23 Oct 2006 13:05:01 -0000 1.60
+++ sys/conf/files.powerpc 8 Jan 2007 09:21:55 -0000
@@ -56,6 +56,7 @@
powerpc/powerpc/nexus.c standard
powerpc/powerpc/ofwmagic.S standard
powerpc/powerpc/ofw_machdep.c standard
+powerpc/powerpc/ofwreal.S standard
powerpc/powerpc/openpic.c standard
powerpc/powerpc/pic_if.m standard
powerpc/powerpc/pmap_dispatch.c standard
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 18 Feb 2007 20:47:41 -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 18 Feb 2007 20:40:25 -0000
@@ -66,6 +66,7 @@
#include <machine/spr.h>
#include <machine/psl.h>
#include <machine/asm.h>
+#include <machine/pte.h>
/* 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.100
diff -u -r1.100 machdep.c
--- sys/powerpc/powerpc/machdep.c 12 Feb 2007 08:59:33 -0000 1.100
+++ sys/powerpc/powerpc/machdep.c 18 Feb 2007 20:40:45 -0000
@@ -253,6 +253,9 @@
extern void *extint, *extsize;
extern void *dblow, *dbsize;
extern void *vectrap, *vectrapsize;
+extern void *imisstrap, *imisssize;
+extern void *dlmisstrap, *dlmisssize;
+extern void *dsmisstrap, *dsmisssize;
void
powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp)
@@ -347,6 +350,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(&imisstrap, (void *)EXC_IMISS, (size_t)&imisssize);
+ bcopy(&dlmisstrap, (void *)EXC_DLMISS, (size_t)&dlmisssize);
+ bcopy(&dsmisstrap, (void *)EXC_DSMISS, (size_t)&dsmisssize);
#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 18 Feb 2007 20:54:16 -0000
@@ -284,6 +284,292 @@
CNAME(alisize) = .-CNAME(alitrap)
/*
+ * It's G2 specific. Instuction TLB miss.
+ */
+ .globl CNAME(imisstrap),CNAME(imisssize)
+CNAME(imisstrap):
+/*
+ * Instruction TLB miss flow
+ * Entry:
+ * Vec = 1000
+ * srr0 -> address of instruction that missed
+ * srr1 -> 0:3=cr0 4=lru way bit 16:31 = saved MSR
+ * msr<tgpr> -> 1
+ * iMiss -> ea that missed
+ * iCmp -> the compare value for the va that missed
+ * hash1 -> pointer to first hash pteg
+ * hash2 -> pointer to second hash pteg
+ *
+ * Register usage:
+ * r0 is saved counter
+ * r1 is junk
+ * r2 is pointer to pteg
+ * r3 is current compare value
+ */
+
+ mfspr %r2, SPR_HASH1 /* get first pointer */
+ addi %r1, 0, 8 /* load 8 for counter */
+ mfctr %r0 /* save counter */
+ mfspr %r3, SPR_ICMP /* get first compare value */
+ addi %r2, %r2, -8 /* pre dec the pointer */
+im0:
+ mtctr %r1 /* load counter */
+im1:
+ lwzu %r1, 8(%r2) /* get next pte */
+ cmp 0, %r1, %r3 /* see if found pte */
+ bdnzf 2, im1 /* dec count br if cmp ne and if count not zero */
+ bne instrSecHash /* if not found set up second hash or exit */
+ lwz %r1, +4(%r2) /* load tlb entry lower-word */
+ andi. %r3, %r1, 8 /* check G bit */
+ bne doISIp /* if guarded, take an ISI */
+ mtctr %r0 /* restore counter */
+ mfspr %r0, SPR_IMISS /* get the miss address for the tlbli */
+ mfspr %r3, SPR_SRR1 /* get the saved cr0 bits */
+ mtcrf 0x80, %r3 /* restore CR0 */
+ mtspr SPR_RPA, %r1 /* set the pte */
+ ori %r1, %r1, 0x100 /* set reference bit */
+ srwi %r1, %r1, 8 /* get byte 7 of pte */
+ tlbli %r0 /* load the itlb */
+ stb %r1, +6(%r2) /* update page table */
+ rfi /* return to executing program */
+/*
+ * register usage:
+ * r0 is saved counter
+ * r1 is junk
+ * r2 is pointer to pteg
+ * r3 is current compare value
+ */
+instrSecHash:
+ andi. %r1, %r3, 0x0040 /* see if we have done second hash */
+ bne doISI /* if so, go to ISI interrupt */
+ mfspr %r2, SPR_HASH2 /* get the second pointer */
+ ori %r3, %r3, 0x0040 /* change the compare value */
+ addi %r1, %r0, 8 /* load 8 for counter */
+ addi %r2, %r2, -8 /* pre dec for update on load */
+ b im0 /* try second hash */
+/*
+ * entry Not Found: synthesize an ISI interrupt
+ * guarded memory protection violation: synthesize an ISI interrupt
+ * Entry:
+ * r0 is saved counter
+ * r1 is junk
+ * r2 is pointer to pteg
+ * r3 is current compare value
+ */
+
+doISIp:
+ mfspr %r3, SPR_SRR1 /* get srr1 */
+ andi. %r2, %r3, 0xffff /* clean upper srr1 */
+ addis %r2, %r2, 0x0800 /* or in srr<4> = 1 to flag prot violation */
+ b isi1
+doISI:
+ mfspr %r3, SPR_SRR1 /* get srr1 */
+ andi. %r2, %r3, 0xffff /* clean srr1 */
+ addis %r2, %r2, 0x4000 /* or in srr1<1> = 1 to flag pte not found */
+isi1:
+ mtctr %r0 /* restore counter */
+ mtspr SPR_SRR1, %r2 /* set srr1 */
+ mfmsr %r0 /* get msr */
+ xoris %r0, %r0, 0x2 /* flip the msr<tgpr> bit */
+ mtcrf 0x80, %r3 /* restore CR0 */
+ mtmsr %r0 /* flip back to the native gprs */
+ ba 0x400 /* go to instr. access interrupt */
+
+CNAME(imisssize) = .-CNAME(imisstrap)
+
+/*
+ * It's G2 specific. Data load TLB miss.
+ */
+ .globl CNAME(dlmisstrap),CNAME(dlmisssize)
+CNAME(dlmisstrap):
+/*
+ * Data TLB miss flow
+ * Entry:
+ * Vec = 1100
+ * srr0 -> address of instruction that caused data tlb miss
+ * srr1 -> 0:3=cr0 4=lru way bit 5=1 if store 16:31 = saved MSR
+ * msr<tgpr> -> 1
+ * dMiss -> ea that missed
+ * dCmp -> the compare value for the va that missed
+ * hash1 -> pointer to first hash pteg
+ * hash2 -> pointer to second hash pteg
+ *
+ * Register usage:
+ * r0 is saved counter
+ * r1 is junk
+ * r2 is pointer to pteg
+ * r3 is current compare value
+ */
+
+ mfspr %r2, SPR_HASH1 /* get first pointer */
+ addi %r1, 0, 8 /* load 8 for counter */
+ mfctr %r0 /* save counter */
+ mfspr %r3, SPR_DCMP /* get first compare value */
+ addi %r2, %r2, -8 /* pre dec the pointer */
+dm0:
+ mtctr %r1 /* load counter */
+dm1:
+ lwzu %r1, 8(%r2) /* get next pte */
+ cmp 0, 0, %r1, %r3 /* see if found pte */
+ bdnzf 2, dm1 /* dec count br if cmp ne and if count not zero */
+ bne dataSecHash /* if not found set up second hash or exit */
+ lwz %r1, +4(%r2) /* load tlb entry lower-word */
+ mtctr %r0 /* restore counter */
+ mfspr %r0, SPR_DMISS /* get the miss address for the tlbld */
+ mfspr %r3, SPR_SRR1 /* get the saved cr0 bits */
+ mtcrf 0x80, %r3 /* restore CR0 */
+ mtspr SPR_RPA, %r1 /* set the pte */
+ ori %r1, %r1, 0x100 /* set reference bit */
+ srwi %r1, %r1, 8 /* get byte 7 of pte */
+ tlbld %r0 /* load the dtlb */
+ stb %r1, +6(%r2) /* update page table */
+ rfi /* return to executing program */
+/*
+ * Register usage:
+ * r0 is saved counter
+ * r1 is junk
+ * r2 is pointer to pteg
+ * r3 is current compare value
+ */
+
+dataSecHash:
+ andi. %r1, %r3, 0x0040 /* see if we have done second hash */
+ bne doDSI /* if so, go to DSI interrupt */
+ mfspr %r2, SPR_HASH2 /* get the second pointer */
+ ori %r3, %r3, 0x0040 /* change the compare value */
+ addi %r1, 0, 8 /* load 8 for counter */
+ addi %r2, %r2, -8 /* pre dec for update on load */
+ b dm0 /* try second hash */
+
+CNAME(dlmisssize) = .-CNAME(dlmisstrap)
+
+/*
+ * It's G2 specific. Data store TLB miss.
+ */
+ .globl CNAME(dsmisstrap),CNAME(dsmisssize)
+CNAME(dsmisstrap):
+
+/*
+ * Data TLB miss flow
+ * C=0 in dtlb and dtlb miss on store flow
+ * Entry:
+ * Vec = 1200
+ * srr0 -> address of store that caused the interrupt
+ * srr1 -> 0:3=cr0 4=lru way bit 5=1 16:31 = saved MSR
+ * msr<tgpr> -> 1
+ * dMiss -> ea that missed
+ * dCmp -> the compare value for the va that missed
+ * hash1 -> pointer to first hash pteg
+ * hash2 -> pointer to second hash pteg
+ *
+ * Register usage:
+ * r0 is saved counter
+ * r1 is junk
+ * r2 is pointer to pteg
+ * r3 is current compare value
+ */
+ mfspr %r2, SPR_HASH1 /* get first pointer */
+ addi %r1, 0, 8 /* load 8 for counter */
+ mfctr %r0 /* save counter */
+ mfspr %r3, SPR_DCMP /* get first compare value */
+ addi %r2, %r2, -8 /* pre dec the pointer */
+ceq0:
+ mtctr %r1 /* load counter */
+ceq1:
+ lwzu %r1, 8(%r2) /* get next pte */
+ cmp 0, 0, %r1, %r3 /* see if found pte */
+ bdnzf 2, ceq1 /* dec count br if cmp ne and if count not zero */
+ bne cEq0SecHash /* if not found set up second hash or exit */
+ lwz %r1, +4(%r2) /* load tlb entry lower-word */
+ andi. %r3, %r1, 0x80 /* check the C-bit */
+ beq cEq0ChkProt /* if (C==0) go check protection modes */
+ceq2:
+ mtctr %r0 /* restore counter */
+ mfspr %r0, SPR_DMISS /* get the miss address for the tlbld */
+ mfspr %r3, SPR_SRR1 /* get the saved cr0 bits */
+ mtcrf 0x80, %r3 /* restore CR0 */
+ mtspr SPR_RPA, %r1 /* set the pte */
+ tlbld %r0 /* load the dtlb */
+ rfi /* return to executing program */
+/*
+ * Register usage:
+ * r0 is saved counter
+ * r1 is junk
+ * r2 is pointer to pteg
+ * r3 is current compare value
+*/
+
+cEq0SecHash:
+ andi. %r1, %r3, 0x0040 /* see if we have done second hash */
+ bne doDSI /* if so, go to DSI interrupt */
+ mfspr %r2, SPR_HASH2 /* get the second pointer */
+ ori %r3, %r3, 0x0040 /* change the compare value */
+ addi %r1, 0, 8 /* load 8 for counter */
+ addi %r2, %r2, -8 /* pre dec for update on load */
+ b ceq0 /* try second hash */
+
+/*
+ * entry found and PTE(c-bit==0):
+ * (check protection before setting PTE(c-bit)
+ * Register usage:
+ * r0 is saved counter
+ * r1 is PTE entry
+ * r2 is pointer to pteg
+ * r3 is trashed
+ */
+cEq0ChkProt:
+ rlwinm. %r3,%r1,30,0,1 /* test PP */
+ bge- chk0 /* if (PP == 00 or PP == 01) goto chk0: */
+ andi. %r3, %r1, 1 /* test PP[0] */
+ beq+ chk2 /* return if PP[0] == 0 */
+ b doDSIp /* else DSIp */
+chk0:
+ mfspr %r3,SPR_SRR1 /* get old msr */
+ andis. %r3,%r3,0x0008 /* test the KEY bit (SRR1-bit 12) */
+ beq chk2 /* if (KEY==0) goto chk2: */
+ b doDSIp /* else DSIp */
+chk2:
+ ori %r1, %r1, 0x180 /* set reference and change bit */
+ sth %r1, 6(%r2) /* update page table */
+ b ceq2 /* and back we go */
+
+/*
+ * entry Not Found: synthesize a DSI interrupt
+ * Entry:
+ * r0 is saved counter
+ * r1 is junk
+ * r2 is pointer to pteg
+ * r3 is current compare value
+ */
+doDSI:
+ mfspr %r3, SPR_SRR1 /* get srr1 */
+ rlwinm %r1,%r3,9,6,6 /* get srr1<flag> to bit 6 for load/store, zero rest */
+ addis %r1, %r1, 0x4000 /* or in dsisr<1> = 1 to flag pte not found */
+ b dsi1
+doDSIp:
+ mfspr %r3, SPR_SRR1 /* get srr1 */
+ rlwinm %r1,%r3,9,6,6 /* get srr1<flag> to bit 6 for load/store, zero rest */
+ addis %r1, %r1, 0x0800 /* or in dsisr<4> = 1 to flag prot violation */
+dsi1:
+ mtctr %r0 /* restore counter */
+ andi. %r2, %r3, 0xffff /* clear upper bits of srr1 */
+ mtspr SPR_SRR1, %r2 /* set srr1 */
+ mtspr SPR_DSISR, %r1 /* load the dsisr */
+ mfspr %r1, SPR_DMISS /* get miss address */
+ rlwinm. %r2,%r2,0,31,31 /* test LE bit */
+ beq dsi2 /* if little endian then: */
+ xor %r1, %r1, 0x07 /* de-mung the data address */
+dsi2:
+ mtspr SPR_DAR, %r1 /* put in dar */
+ mfmsr %r0 /* get msr */
+ xoris %r0, %r0, 0x2 /* flip the msr<tgpr> bit */
+ mtcrf 0x80, %r3 /* restore CR0 */
+ mtmsr %r0 /* flip back to the native gprs */
+ ba 0x300 /* branch to DSI interrupt */
+
+CNAME(dsmisssize) = .-CNAME(dsmisstrap)
+
+/*
* Similar to the above for DSI
* Has to handle BAT spills
* and standard pagetable spills
home |
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070219100433.66d7ff49>
