svn commit: r211968 - user/nwhitehorn/ps3/powerpc/ps3
Nathan Whitehorn
nwhitehorn at FreeBSD.org
Sun Aug 29 18:31:05 UTC 2010
Author: nwhitehorn
Date: Sun Aug 29 18:31:04 2010
New Revision: 211968
URL: http://svn.freebsd.org/changeset/base/211968
Log:
Fix recording of ref/change bits. Before we overwrote the entire lower
12 bits of the PVO PTE with the equivalent ones from the hardware PTE,
but these also store the page protection bits. The result was that
these would be overwritten with old values when syncing ref/changed during
a protection update, making all protection updates fail, breaking
copy-on-write as well as many other things.
With this change, my Playstation 3 now boots multiuser!
Modified:
user/nwhitehorn/ps3/powerpc/ps3/mmu_ps3.c
Modified: user/nwhitehorn/ps3/powerpc/ps3/mmu_ps3.c
==============================================================================
--- user/nwhitehorn/ps3/powerpc/ps3/mmu_ps3.c Sun Aug 29 18:17:38 2010 (r211967)
+++ user/nwhitehorn/ps3/powerpc/ps3/mmu_ps3.c Sun Aug 29 18:31:04 2010 (r211968)
@@ -51,7 +51,6 @@
#include "ps3-hvcall.h"
#define VSID_HASH_MASK 0x0000007fffffffffUL
-#define LV1_READ_HTAB_LO_MASK 0xfffUL
extern int ps3fb_remap(void);
@@ -199,7 +198,6 @@ mps3_pte_synch(struct lpte *pt, struct l
uint64_t halfbucket[4], rcbits;
uint64_t slot = (uint64_t)(pt)-1;
- __asm __volatile("ptesync");
lv1_read_htab_entries(mps3_vas_id, slot & ~0x3UL, &halfbucket[0],
&halfbucket[1], &halfbucket[2], &halfbucket[3], &rcbits);
@@ -213,9 +211,9 @@ mps3_pte_synch(struct lpte *pt, struct l
("PTE upper word %#lx != %#lx\n",
halfbucket[slot & 0x3], pvo_pt->pte_hi));
- pvo_pt->pte_lo &= ~LV1_READ_HTAB_LO_MASK;
+ pvo_pt->pte_lo &= ~(LPTE_CHG | LPTE_REF);
pvo_pt->pte_lo |= (rcbits >> ((3 - (slot & 0x3))*16)) &
- LV1_READ_HTAB_LO_MASK;
+ (LPTE_CHG | LPTE_REF);
}
static void
@@ -245,11 +243,10 @@ mps3_pte_change(struct lpte *pt, struct
uint64_t slot = (uint64_t)(pt)-1;
mps3_pte_synch(pt, pvo_pt);
- pvo_pt->pte_hi |= LPTE_VALID;
- lv1_write_htab_entry(mps3_vas_id, slot & ~0x3UL, pvo_pt->pte_hi,
+ lv1_write_htab_entry(mps3_vas_id, slot, pvo_pt->pte_hi,
pvo_pt->pte_lo);
}
-
+
static int
mps3_pte_insert(u_int ptegidx, struct lpte *pvo_pt)
{
@@ -292,7 +289,8 @@ mps3_pte_insert(u_int ptegidx, struct lp
ptegidx ^= moea64_pteg_mask; /* PTEs indexed by primary */
LIST_FOREACH(pvo, &moea64_pvo_table[ptegidx], pvo_olink) {
- if (pvo->pvo_pte.lpte.pte_hi == evicted.pte_hi) {
+ if ((pvo->pvo_pte.lpte.pte_hi & LPTE_AVPN_MASK)
+ == (evicted.pte_hi & LPTE_AVPN_MASK)) {
KASSERT(pvo->pvo_pte.lpte.pte_hi & LPTE_VALID,
("Invalid PVO for valid PTE!"));
pvo->pvo_pte.lpte.pte_hi &= ~LPTE_VALID;
More information about the svn-src-user
mailing list