Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 Aug 2008 19:56:00 GMT
From:      Nathan Whitehorn <nwhitehorn@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 148545 for review
Message-ID:  <200808261956.m7QJu09K004108@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=148545

Change 148545 by nwhitehorn@nwhitehorn_trantor on 2008/08/26 19:55:27

	Support for the G5 as it currently stands. Boots multiuser and is self-hosting on my iMac. Built-in SATA nonfunctional, and INVARIANTS is broken.

Affected files ...

.. //depot/projects/ppc-g5/lib/libc/powerpc/gen/syncicache.c#2 edit
.. //depot/projects/ppc-g5/sys/conf/files.powerpc#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/aim/machdep.c#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/aim/mmu_oea.c#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/aim/mmu_oea64.c#1 add
.. //depot/projects/ppc-g5/sys/powerpc/aim/ofw_machdep.c#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/aim/trap_subr.S#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/aim/uio_machdep.c#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/aim/uma_machdep.c#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/aim/vm_machdep.c#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/booke/machdep.c#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/include/hid.h#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/include/md_var.h#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/include/pmap.h#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/include/pte.h#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/include/sf_buf.h#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/include/spr.h#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/include/vmparam.h#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/ofw/ofw_pci.c#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/powermac/ata_kauai.c#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/powermac/cpcht.c#1 add
.. //depot/projects/ppc-g5/sys/powerpc/powermac/cpchtvar.h#1 add
.. //depot/projects/ppc-g5/sys/powerpc/powermac/macio.c#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/powermac/uninorth.c#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/powermac/uninorthvar.h#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/powerpc/cpu.c#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/powerpc/syncicache.c#2 edit

Differences ...

==== //depot/projects/ppc-g5/lib/libc/powerpc/gen/syncicache.c#2 (text+ko) ====

@@ -48,27 +48,23 @@
 #include <machine/md_var.h>
 
 #if	defined(_KERNEL) || defined(_STANDALONE)
-#ifndef	CACHELINESIZE
-#error "Must know the size of a cache line"
-#endif
+int cacheline_size = 32;
 #else
 #include <stdlib.h>
 
+static int cacheline_size;
 static void getcachelinesize(void);
 
-static int _cachelinesize;
-#define	CACHELINESIZE	_cachelinesize
-
 static void
 getcachelinesize()
 {
 	static int	cachemib[] = { CTL_MACHDEP, CPU_CACHELINE };
 	int		clen;
 
-	clen = sizeof(_cachelinesize);
+	clen = sizeof(cacheline_size);
 
 	if (sysctl(cachemib, sizeof(cachemib) / sizeof(cachemib[0]),
-	    &_cachelinesize, &clen, NULL, 0) < 0 || !_cachelinesize) {
+	    &cacheline_size, &clen, NULL, 0) < 0 || !cacheline_size) {
 		abort();
 	}
 }
@@ -81,21 +77,23 @@
 	char	*p;
 
 #if	!defined(_KERNEL) && !defined(_STANDALONE)
-	if (!_cachelinesize)
+	if (!cacheline_size)
 		getcachelinesize();
 #endif	
-	off = (u_int)from & (CACHELINESIZE - 1);
+
+	off = (u_int)from & (cacheline_size - 1);
 	l = len += off;
 	p = (char *)from - off;
+
 	do {
 		__asm __volatile ("dcbst 0,%0" :: "r"(p));
-		p += CACHELINESIZE;
-	} while ((l -= CACHELINESIZE) > 0);
+		p += cacheline_size;
+	} while ((l -= cacheline_size) > 0);
 	__asm __volatile ("sync");
 	p = (char *)from - off;
 	do {
 		__asm __volatile ("icbi 0,%0" :: "r"(p));
-		p += CACHELINESIZE;
-	} while ((len -= CACHELINESIZE) > 0);
+		p += cacheline_size;
+	} while ((len -= cacheline_size) > 0);
 	__asm __volatile ("sync; isync");
 }

==== //depot/projects/ppc-g5/sys/conf/files.powerpc#2 (text+ko) ====

@@ -70,6 +70,7 @@
 powerpc/aim/locore.S		optional	aim no-obj
 powerpc/aim/machdep.c		optional	aim
 powerpc/aim/mmu_oea.c		optional	aim
+powerpc/aim/mmu_oea64.c		optional	aim
 powerpc/aim/mp_cpudep.c		optional	aim smp
 powerpc/aim/nexus.c		optional	aim
 powerpc/aim/ofw_machdep.c	optional	aim
@@ -116,6 +117,7 @@
 powerpc/powermac/openpic_macio.c optional	powermac pci
 powerpc/powermac/pswitch.c	optional	powermac pswitch
 powerpc/powermac/uninorth.c	optional	powermac pci
+powerpc/powermac/cpcht.c	optional	powermac pci
 powerpc/powerpc/atomic.S	standard
 powerpc/powerpc/autoconf.c	standard
 powerpc/powerpc/bcopy.c		standard

==== //depot/projects/ppc-g5/sys/powerpc/aim/machdep.c#2 (text+ko) ====

@@ -128,6 +128,8 @@
 #endif
 
 int cold = 1;
+int ppc64 = 0;
+int hw_direct_map = 1;
 
 struct pcpu __pcpu[MAXCPU];
 
@@ -136,7 +138,7 @@
 char		machine[] = "powerpc";
 SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
 
-static int cacheline_size = CACHELINESIZE;
+extern int cacheline_size;
 SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size,
 	   CTLFLAG_RD, &cacheline_size, 0, "");
 
@@ -229,6 +231,9 @@
 
 extern char	kernel_text[], _end[];
 
+extern void	*testppc64, *testppc64size;
+extern void	*restorebridge, *restorebridgesize;
+extern void	*rfid_patch, *rfi_patch1, *rfi_patch2;
 #ifdef SMP
 extern void	*rstcode, *rstsize;
 #endif
@@ -245,11 +250,15 @@
 {
 	struct		pcpu *pc;
 	vm_offset_t	end;
+	size_t		trap_offset;
 	void		*kmdp;
         char		*env;
+	int		vers;
+	uint32_t	msr, scratch;
 
 	end = 0;
 	kmdp = NULL;
+	trap_offset = 0;
 
 	/*
 	 * Parse metadata if present and fetch parameters.  Must be done
@@ -305,6 +314,26 @@
 		printf("powerpc_init: no loader metadata.\n");
 	}
 
+	/*
+	 * Set cacheline_size based on the CPU model.
+	 */
+
+	vers = mfpvr() >> 16;
+	switch (vers) {
+		case IBM970:
+		case IBM970FX:
+		case IBM970MP:
+		case IBM970GX:
+			cacheline_size = 128;
+			break;
+		default:
+			cacheline_size = 32;
+	}
+
+	/*
+	 * Init KDB and KOBJ
+	 */
+
 	kdb_init();
 
 	kobj_machdep_init();
@@ -314,47 +343,110 @@
 	 *      Disable translation in case the vector area
 	 *      hasn't been mapped (G5)
 	 */
-	mtmsr(mfmsr() & ~(PSL_IR | PSL_DR));
+	msr = mfmsr();
+	mtmsr(msr & ~(PSL_IR | PSL_DR));
 	isync();
+
+	/*
+	 * Figure out whether we need to use the 64 bit PMAP. This works by
+	 * executing an instruction that is only legal on 64-bit PPC (mtmsrd),
+	 * and setting ppc64 = 0 if that causes a trap.
+	 */
+
+	ppc64 = 1;
+
+	bcopy(&testppc64, (void *)EXC_PGM,  (size_t)&testppc64size);
+	__syncicache((void *)EXC_PGM, (size_t)&testppc64size);
+
+	__asm __volatile("\
+		mfmsr %0;	\
+		mtsprg2 %1;	\
+				\
+		mtmsrd %0;	\
+		mfsprg2 %1;"
+	    : "=r"(scratch), "=r"(ppc64));
+
+	/*
+	 * Now copy restorebridge into all the handlers, if necessary,
+	 * and set up the trap tables.
+	 */
+
+	if (ppc64) {
+		/* Patch the two instances of rfi -> rfid */
+		bcopy(&rfid_patch,&rfi_patch1,4);
+		bcopy(&rfid_patch,&rfi_patch2,4);
+
+		/* Copy a code snippet to restore 32-bit bridge mode
+		 * to the top of every trap handler */
+		trap_offset += (size_t)&restorebridgesize;
+		bcopy(&restorebridge, (void *)EXC_RST, trap_offset); 
+		bcopy(&restorebridge, (void *)EXC_MCHK, trap_offset); 
+		bcopy(&restorebridge, (void *)EXC_DSI, trap_offset); 
+		bcopy(&restorebridge, (void *)EXC_ISI, trap_offset); 
+		bcopy(&restorebridge, (void *)EXC_EXI, trap_offset); 
+		bcopy(&restorebridge, (void *)EXC_ALI, trap_offset); 
+		bcopy(&restorebridge, (void *)EXC_PGM, trap_offset); 
+		bcopy(&restorebridge, (void *)EXC_FPU, trap_offset); 
+		bcopy(&restorebridge, (void *)EXC_DECR, trap_offset); 
+		bcopy(&restorebridge, (void *)EXC_SC, trap_offset); 
+		bcopy(&restorebridge, (void *)EXC_TRC, trap_offset); 
+		bcopy(&restorebridge, (void *)EXC_FPA, trap_offset); 
+		bcopy(&restorebridge, (void *)EXC_VEC, trap_offset); 
+		bcopy(&restorebridge, (void *)EXC_VECAST, trap_offset); 
+		bcopy(&restorebridge, (void *)EXC_THRM, trap_offset); 
+		bcopy(&restorebridge, (void *)EXC_BPT, trap_offset); 
+	}
+
 #ifdef SMP
-	bcopy(&rstcode,  (void *)EXC_RST,  (size_t)&rstsize);
+	bcopy(&rstcode, (void *)(EXC_RST + trap_offset),  (size_t)&rstsize);
 #else
-	bcopy(&trapcode, (void *)EXC_RST,  (size_t)&trapsize);
+	bcopy(&trapcode, (void *)(EXC_RST + trap_offset),  (size_t)&trapsize);
+#endif
+	bcopy(&trapcode, (void *)(EXC_MCHK + trap_offset), (size_t)&trapsize);
+#if 0
+	if (ppc64)
+		bcopy(&alitrap, (void *)(EXC_DSI + trap_offset),  (size_t)&alisize);
+	else
 #endif
-	bcopy(&trapcode, (void *)EXC_MCHK, (size_t)&trapsize);
-	bcopy(&dsitrap,  (void *)EXC_DSI,  (size_t)&dsisize);
-	bcopy(&trapcode, (void *)EXC_ISI,  (size_t)&trapsize);
-	bcopy(&trapcode, (void *)EXC_EXI,  (size_t)&trapsize);
-	bcopy(&alitrap,  (void *)EXC_ALI,  (size_t)&alisize);
-	bcopy(&trapcode, (void *)EXC_PGM,  (size_t)&trapsize);
-	bcopy(&trapcode, (void *)EXC_FPU,  (size_t)&trapsize);
-	bcopy(&trapcode, (void *)EXC_DECR, (size_t)&trapsize);
-	bcopy(&trapcode, (void *)EXC_SC,   (size_t)&trapsize);
-	bcopy(&trapcode, (void *)EXC_TRC,  (size_t)&trapsize);
-	bcopy(&trapcode, (void *)EXC_FPA,  (size_t)&trapsize);
-	bcopy(&vectrap,  (void *)EXC_VEC,  (size_t)&vectrapsize);
-	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(&dsitrap,  (void *)(EXC_DSI + trap_offset),  (size_t)&dsisize);
+	bcopy(&trapcode, (void *)(EXC_ISI + trap_offset),  (size_t)&trapsize);
+	bcopy(&trapcode, (void *)(EXC_EXI + trap_offset),  (size_t)&trapsize);
+	bcopy(&alitrap,  (void *)(EXC_ALI + trap_offset),  (size_t)&alisize);
+	bcopy(&trapcode, (void *)(EXC_PGM + trap_offset),  (size_t)&trapsize);
+	bcopy(&trapcode, (void *)(EXC_FPU + trap_offset),  (size_t)&trapsize);
+	bcopy(&trapcode, (void *)(EXC_DECR + trap_offset), (size_t)&trapsize);
+	bcopy(&trapcode, (void *)(EXC_SC + trap_offset),   (size_t)&trapsize);
+	bcopy(&trapcode, (void *)(EXC_TRC + trap_offset),  (size_t)&trapsize);
+	bcopy(&trapcode, (void *)(EXC_FPA + trap_offset),  (size_t)&trapsize);
+	bcopy(&vectrap,  (void *)(EXC_VEC + trap_offset),  (size_t)&vectrapsize);
+	bcopy(&trapcode, (void *)(EXC_VECAST + trap_offset), (size_t)&trapsize);
+	bcopy(&trapcode, (void *)(EXC_THRM + trap_offset), (size_t)&trapsize);
+	bcopy(&trapcode, (void *)(EXC_BPT + trap_offset),  (size_t)&trapsize);
 #ifdef KDB
-	bcopy(&dblow,   (void *)EXC_MCHK, (size_t)&dbsize);
-	bcopy(&dblow,   (void *)EXC_PGM,  (size_t)&dbsize);
-	bcopy(&dblow,   (void *)EXC_TRC,  (size_t)&dbsize);
-	bcopy(&dblow,   (void *)EXC_BPT,  (size_t)&dbsize);
+	bcopy(&dblow,	(void *)(EXC_MCHK + trap_offset), (size_t)&dbsize);
+	bcopy(&dblow,   (void *)(EXC_PGM + trap_offset),  (size_t)&dbsize);
+	bcopy(&dblow,   (void *)(EXC_TRC + trap_offset),  (size_t)&dbsize);
+	bcopy(&dblow,   (void *)(EXC_BPT + trap_offset),  (size_t)&dbsize);
 #endif
 	__syncicache(EXC_RSVD, EXC_LAST - EXC_RSVD);
 
 	/*
-	 * Make sure translation has been enabled
+	 * Restore MSR
 	 */
-	mtmsr(mfmsr() | PSL_IR|PSL_DR|PSL_ME|PSL_RI);
+	mtmsr(msr);
 	isync();
 
 	/*
 	 * Initialise virtual memory.
 	 */
-	pmap_mmu_install(MMU_TYPE_OEA, 0);		/* XXX temporary */
+	if (ppc64)
+		pmap_mmu_install(MMU_TYPE_G5, 0);
+	else
+		pmap_mmu_install(MMU_TYPE_OEA, 0);
+
 	pmap_bootstrap(startkernel, endkernel);
+	mtmsr(mfmsr() | PSL_IR|PSL_DR|PSL_ME|PSL_RI);
+	isync();
 
 	/*
 	 * Initialize params/tunables that are derived from memsize

==== //depot/projects/ppc-g5/sys/powerpc/aim/mmu_oea.c#2 (text+ko) ====

@@ -714,6 +714,9 @@
 	__asm __volatile("mtdbatl 1,%0" :: "r"(battable[8].batl));
 	isync();
 
+	/* set global direct map flag */
+	hw_direct_map = 1;
+
 	mem_regions(&pregions, &pregions_sz, &regions, &regions_sz);
 	CTR0(KTR_PMAP, "moea_bootstrap: physical memory");
 
@@ -952,9 +955,7 @@
 	 * not issue any loads while we have interrupts disabled below.
 	 */
 	pm = &td->td_proc->p_vmspace->vm_pmap;
-
-	if ((pmr = (pmap_t)moea_kextract(mmu, (vm_offset_t)pm)) == NULL)
-		pmr = pm;
+	pmr = pm->pmap_phys;
 
 	pm->pm_active |= PCPU_GET(cpumask);
 	PCPU_SET(curpmap, pmr);
@@ -1206,7 +1207,7 @@
 	if (pvo == NULL)
 		pa = 0;
 	else
-		pa = (pvo->pvo_pte.pte_lo & PTE_RPGN) | (va & ADDR_POFF);
+		pa = (pvo->pvo_pte.pte.pte_lo & PTE_RPGN) | (va & ADDR_POFF);
 	PMAP_UNLOCK(pm);
 	return (pa);
 }
@@ -1226,10 +1227,10 @@
 	vm_page_lock_queues();
 	PMAP_LOCK(pmap);
 	pvo = moea_pvo_find_va(pmap, va & ~ADDR_POFF, NULL);
-	if (pvo != NULL && (pvo->pvo_pte.pte_hi & PTE_VALID) &&
-	    ((pvo->pvo_pte.pte_lo & PTE_PP) == PTE_RW ||
+	if (pvo != NULL && (pvo->pvo_pte.pte.pte_hi & PTE_VALID) &&
+	    ((pvo->pvo_pte.pte.pte_lo & PTE_PP) == PTE_RW ||
 	     (prot & VM_PROT_WRITE) == 0)) {
-		m = PHYS_TO_VM_PAGE(pvo->pvo_pte.pte_lo & PTE_RPGN);
+		m = PHYS_TO_VM_PAGE(pvo->pvo_pte.pte.pte_lo & PTE_RPGN);
 		vm_page_hold(m);
 	}
 	vm_page_unlock_queues();
@@ -1300,15 +1301,15 @@
 	LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
 		pmap = pvo->pvo_pmap;
 		PMAP_LOCK(pmap);
-		if ((pvo->pvo_pte.pte_lo & PTE_PP) != PTE_BR) {
+		if ((pvo->pvo_pte.pte.pte_lo & PTE_PP) != PTE_BR) {
 			pt = moea_pvo_to_pte(pvo, -1);
-			pvo->pvo_pte.pte_lo &= ~PTE_PP;
-			pvo->pvo_pte.pte_lo |= PTE_BR;
+			pvo->pvo_pte.pte.pte_lo &= ~PTE_PP;
+			pvo->pvo_pte.pte.pte_lo |= PTE_BR;
 			if (pt != NULL) {
-				moea_pte_synch(pt, &pvo->pvo_pte);
-				lo |= pvo->pvo_pte.pte_lo;
-				pvo->pvo_pte.pte_lo &= ~PTE_CHG;
-				moea_pte_change(pt, &pvo->pvo_pte,
+				moea_pte_synch(pt, &pvo->pvo_pte.pte);
+				lo |= pvo->pvo_pte.pte.pte_lo;
+				pvo->pvo_pte.pte.pte_lo &= ~PTE_CHG;
+				moea_pte_change(pt, &pvo->pvo_pte.pte,
 				    pvo->pvo_vaddr);
 				mtx_unlock(&moea_table_mutex);
 			}
@@ -1399,19 +1400,17 @@
 	struct		pvo_entry *pvo;
 	vm_paddr_t pa;
 
-#ifdef UMA_MD_SMALL_ALLOC
 	/*
-	 * Allow direct mappings
+	 * Allow direct mappings on 32-bit OEA
 	 */
 	if (va < VM_MIN_KERNEL_ADDRESS) {
 		return (va);
 	}
-#endif
 
 	PMAP_LOCK(kernel_pmap);
 	pvo = moea_pvo_find_va(kernel_pmap, va & ~ADDR_POFF, NULL);
 	KASSERT(pvo != NULL, ("moea_kextract: no addr found"));
-	pa = (pvo->pvo_pte.pte_lo & PTE_RPGN) | (va & ADDR_POFF);
+	pa = (pvo->pvo_pte.pte.pte_lo & PTE_RPGN) | (va & ADDR_POFF);
 	PMAP_UNLOCK(kernel_pmap);
 	return (pa);
 }
@@ -1510,6 +1509,10 @@
 	entropy = 0;
 	__asm __volatile("mftb %0" : "=r"(entropy));
 
+	if ((pmap->pmap_phys = (pmap_t)moea_kextract(mmu, (vm_offset_t)pmap)) == NULL)
+		pmap->pmap_phys = pmap;
+	
+
 	/*
 	 * Allocate some segment registers for this pmap.
 	 */
@@ -1602,14 +1605,14 @@
 		/*
 		 * Change the protection of the page.
 		 */
-		pvo->pvo_pte.pte_lo &= ~PTE_PP;
-		pvo->pvo_pte.pte_lo |= PTE_BR;
+		pvo->pvo_pte.pte.pte_lo &= ~PTE_PP;
+		pvo->pvo_pte.pte.pte_lo |= PTE_BR;
 
 		/*
 		 * If the PVO is in the page table, update that pte as well.
 		 */
 		if (pt != NULL) {
-			moea_pte_change(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
+			moea_pte_change(pt, &pvo->pvo_pte.pte, pvo->pvo_vaddr);
 			mtx_unlock(&moea_table_mutex);
 		}
 	}
@@ -1808,8 +1811,8 @@
 	mtx_lock(&moea_table_mutex);
 	LIST_FOREACH(pvo, &moea_pvo_table[ptegidx], pvo_olink) {
 		if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) {
-			if ((pvo->pvo_pte.pte_lo & PTE_RPGN) == pa &&
-			    (pvo->pvo_pte.pte_lo & PTE_PP) ==
+			if ((pvo->pvo_pte.pte.pte_lo & PTE_RPGN) == pa &&
+			    (pvo->pvo_pte.pte.pte_lo & PTE_PP) ==
 			    (pte_lo & PTE_PP)) {
 				mtx_unlock(&moea_table_mutex);
 				return (0);
@@ -1856,7 +1859,7 @@
 	if (flags & PVO_FAKE)
 		pvo->pvo_vaddr |= PVO_FAKE;
 
-	moea_pte_create(&pvo->pvo_pte, sr, va, pa | pte_lo);
+	moea_pte_create(&pvo->pvo_pte.pte, sr, va, pa | pte_lo);
 
 	/*
 	 * Remember if the list was empty and therefore will be the first
@@ -1866,14 +1869,14 @@
 		first = 1;
 	LIST_INSERT_HEAD(pvo_head, pvo, pvo_vlink);
 
-	if (pvo->pvo_pte.pte_lo & PVO_WIRED)
+	if (pvo->pvo_pte.pte.pte_lo & PVO_WIRED)
 		pm->pm_stats.wired_count++;
 	pm->pm_stats.resident_count++;
 
 	/*
 	 * We hope this succeeds but it isn't required.
 	 */
-	i = moea_pte_insert(ptegidx, &pvo->pvo_pte);
+	i = moea_pte_insert(ptegidx, &pvo->pvo_pte.pte);
 	if (i >= 0) {
 		PVO_PTEGIDX_SET(pvo, i);
 	} else {
@@ -1896,7 +1899,7 @@
 	 */
 	pt = moea_pvo_to_pte(pvo, pteidx);
 	if (pt != NULL) {
-		moea_pte_unset(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
+		moea_pte_unset(pt, &pvo->pvo_pte.pte, pvo->pvo_vaddr);
 		mtx_unlock(&moea_table_mutex);
 		PVO_PTEGIDX_CLR(pvo);
 	} else {
@@ -1907,7 +1910,7 @@
 	 * Update our statistics.
 	 */
 	pvo->pvo_pmap->pm_stats.resident_count--;
-	if (pvo->pvo_pte.pte_lo & PVO_WIRED)
+	if (pvo->pvo_pte.pte.pte_lo & PVO_WIRED)
 		pvo->pvo_pmap->pm_stats.wired_count--;
 
 	/*
@@ -1916,9 +1919,9 @@
 	if ((pvo->pvo_vaddr & (PVO_MANAGED|PVO_FAKE)) == PVO_MANAGED) {
 		struct	vm_page *pg;
 
-		pg = PHYS_TO_VM_PAGE(pvo->pvo_pte.pte_lo & PTE_RPGN);
+		pg = PHYS_TO_VM_PAGE(pvo->pvo_pte.pte.pte_lo & PTE_RPGN);
 		if (pg != NULL) {
-			moea_attr_save(pg, pvo->pvo_pte.pte_lo &
+			moea_attr_save(pg, pvo->pvo_pte.pte.pte_lo &
 			    (PTE_REF | PTE_CHG));
 		}
 	}
@@ -1951,7 +1954,7 @@
 	 * noticing the HID bit.
 	 */
 	pteidx = ptegidx * 8 + PVO_PTEGIDX_GET(pvo);
-	if (pvo->pvo_pte.pte_hi & PTE_HID)
+	if (pvo->pvo_pte.pte.pte_hi & PTE_HID)
 		pteidx ^= moea_pteg_mask * 8;
 
 	return (pteidx);
@@ -2001,23 +2004,23 @@
 	pt = &moea_pteg_table[pteidx >> 3].pt[pteidx & 7];
 	mtx_lock(&moea_table_mutex);
 
-	if ((pvo->pvo_pte.pte_hi & PTE_VALID) && !PVO_PTEGIDX_ISSET(pvo)) {
+	if ((pvo->pvo_pte.pte.pte_hi & PTE_VALID) && !PVO_PTEGIDX_ISSET(pvo)) {
 		panic("moea_pvo_to_pte: pvo %p has valid pte in pvo but no "
 		    "valid pte index", pvo);
 	}
 
-	if ((pvo->pvo_pte.pte_hi & PTE_VALID) == 0 && PVO_PTEGIDX_ISSET(pvo)) {
+	if ((pvo->pvo_pte.pte.pte_hi & PTE_VALID) == 0 && PVO_PTEGIDX_ISSET(pvo)) {
 		panic("moea_pvo_to_pte: pvo %p has valid pte index in pvo "
 		    "pvo but no valid pte", pvo);
 	}
 
-	if ((pt->pte_hi ^ (pvo->pvo_pte.pte_hi & ~PTE_VALID)) == PTE_VALID) {
-		if ((pvo->pvo_pte.pte_hi & PTE_VALID) == 0) {
+	if ((pt->pte_hi ^ (pvo->pvo_pte.pte.pte_hi & ~PTE_VALID)) == PTE_VALID) {
+		if ((pvo->pvo_pte.pte.pte_hi & PTE_VALID) == 0) {
 			panic("moea_pvo_to_pte: pvo %p has valid pte in "
 			    "moea_pteg_table %p but invalid in pvo", pvo, pt);
 		}
 
-		if (((pt->pte_lo ^ pvo->pvo_pte.pte_lo) & ~(PTE_CHG|PTE_REF))
+		if (((pt->pte_lo ^ pvo->pvo_pte.pte.pte_lo) & ~(PTE_CHG|PTE_REF))
 		    != 0) {
 			panic("moea_pvo_to_pte: pvo %p pte does not match "
 			    "pte %p in moea_pteg_table", pvo, pt);
@@ -2027,7 +2030,7 @@
 		return (pt);
 	}
 
-	if (pvo->pvo_pte.pte_hi & PTE_VALID) {
+	if (pvo->pvo_pte.pte.pte_hi & PTE_VALID) {
 		panic("moea_pvo_to_pte: pvo %p has invalid pte %p in "
 		    "moea_pteg_table but valid in pvo", pvo, pt);
 	}
@@ -2072,13 +2075,13 @@
 		 */
 		MOEA_PVO_CHECK(pvo);
 		if (source_pvo == NULL &&
-		    moea_pte_match(&pvo->pvo_pte, sr, addr,
-		    pvo->pvo_pte.pte_hi & PTE_HID)) {
+		    moea_pte_match(&pvo->pvo_pte.pte, sr, addr,
+		    pvo->pvo_pte.pte.pte_hi & PTE_HID)) {
 			/*
 			 * Now found an entry to be spilled into the pteg.
 			 * The PTE is now valid, so we know it's active.
 			 */
-			j = moea_pte_insert(ptegidx, &pvo->pvo_pte);
+			j = moea_pte_insert(ptegidx, &pvo->pvo_pte.pte);
 
 			if (j >= 0) {
 				PVO_PTEGIDX_SET(pvo, j);
@@ -2099,7 +2102,7 @@
 		 * so save the R & C bits of the PTE.
 		 */
 		if ((pt->pte_hi & PTE_HID) == 0 && victim_pvo == NULL &&
-		    moea_pte_compare(pt, &pvo->pvo_pte)) {
+		    moea_pte_compare(pt, &pvo->pvo_pte.pte)) {
 			victim_pvo = pvo;
 			if (source_pvo != NULL)
 				break;
@@ -2127,7 +2130,7 @@
 			 * We also need the pvo entry of the victim we are
 			 * replacing so save the R & C bits of the PTE.
 			 */
-			if (moea_pte_compare(pt, &pvo->pvo_pte)) {
+			if (moea_pte_compare(pt, &pvo->pvo_pte.pte)) {
 				victim_pvo = pvo;
 				break;
 			}
@@ -2143,10 +2146,10 @@
 	 * though it's valid.  If we don't, we lose any ref/chg bit changes
 	 * contained in the TLB entry.
 	 */
-	source_pvo->pvo_pte.pte_hi &= ~PTE_HID;
+	source_pvo->pvo_pte.pte.pte_hi &= ~PTE_HID;
 
-	moea_pte_unset(pt, &victim_pvo->pvo_pte, victim_pvo->pvo_vaddr);
-	moea_pte_set(pt, &source_pvo->pvo_pte);
+	moea_pte_unset(pt, &victim_pvo->pvo_pte.pte, victim_pvo->pvo_vaddr);
+	moea_pte_set(pt, &source_pvo->pvo_pte.pte);
 
 	PVO_PTEGIDX_CLR(victim_pvo);
 	PVO_PTEGIDX_SET(source_pvo, i);
@@ -2213,7 +2216,7 @@
 		 * See if we saved the bit off.  If so, cache it and return
 		 * success.
 		 */
-		if (pvo->pvo_pte.pte_lo & ptebit) {
+		if (pvo->pvo_pte.pte.pte_lo & ptebit) {
 			moea_attr_save(m, ptebit);
 			MOEA_PVO_CHECK(pvo);	/* sanity check */
 			return (TRUE);
@@ -2236,9 +2239,9 @@
 		 */
 		pt = moea_pvo_to_pte(pvo, -1);
 		if (pt != NULL) {
-			moea_pte_synch(pt, &pvo->pvo_pte);
+			moea_pte_synch(pt, &pvo->pvo_pte.pte);
 			mtx_unlock(&moea_table_mutex);
-			if (pvo->pvo_pte.pte_lo & ptebit) {
+			if (pvo->pvo_pte.pte.pte_lo & ptebit) {
 				moea_attr_save(m, ptebit);
 				MOEA_PVO_CHECK(pvo);	/* sanity check */
 				return (TRUE);
@@ -2281,15 +2284,15 @@
 		MOEA_PVO_CHECK(pvo);	/* sanity check */
 		pt = moea_pvo_to_pte(pvo, -1);
 		if (pt != NULL) {
-			moea_pte_synch(pt, &pvo->pvo_pte);
-			if (pvo->pvo_pte.pte_lo & ptebit) {
+			moea_pte_synch(pt, &pvo->pvo_pte.pte);
+			if (pvo->pvo_pte.pte.pte_lo & ptebit) {
 				count++;
 				moea_pte_clear(pt, PVO_VADDR(pvo), ptebit);
 			}
 			mtx_unlock(&moea_table_mutex);
 		}
-		rv |= pvo->pvo_pte.pte_lo;
-		pvo->pvo_pte.pte_lo &= ~ptebit;
+		rv |= pvo->pvo_pte.pte.pte_lo;
+		pvo->pvo_pte.pte.pte_lo &= ~ptebit;
 		MOEA_PVO_CHECK(pvo);	/* sanity check */
 	}
 

==== //depot/projects/ppc-g5/sys/powerpc/aim/ofw_machdep.c#2 (text+ko) ====

@@ -62,6 +62,12 @@
 static struct mem_region OFmem[OFMEM_REGIONS + 1], OFavail[OFMEM_REGIONS + 3];
 static struct mem_region OFfree[OFMEM_REGIONS + 3];
 
+struct mem_region64 {
+        vm_offset_t     mr_start_hi;
+        vm_offset_t     mr_start_lo;
+        vm_size_t       mr_size;
+};	
+
 extern register_t ofmsr[5];
 extern struct	pmap ofw_pmap;
 static int	(*ofwcall)(void *);
@@ -146,15 +152,35 @@
 	 * Get memory.
 	 */
 	if ((phandle = OF_finddevice("/memory")) == -1
-	    || (msz = OF_getprop(phandle, "reg",
-			  OFmem, sizeof OFmem[0] * OFMEM_REGIONS))
-	       <= 0
 	    || (asz = OF_getprop(phandle, "available",
 			  OFavail, sizeof OFavail[0] * OFMEM_REGIONS))
 	       <= 0)
 		panic("no memory?");
+
+	if (ppc64) {
+	    struct mem_region64 OFmem64[OFMEM_REGIONS + 1];
+	    if ((msz = OF_getprop(phandle, "reg",
+			  OFmem64, sizeof OFmem64[0] * OFMEM_REGIONS)) <= 0)
+		panic("Physical memory map not found");
+
+	    for (i = 0; i < msz/sizeof(OFmem64[0]); i++) {
+		if (OFmem64[i].mr_start_hi == 0) {
+			OFmem[i].mr_start = OFmem64[i].mr_start_lo;
+			OFmem[i].mr_size = OFmem64[i].mr_size;
+		} else {
+			OFmem[i].mr_size = 0;
+		}
+	    }
+	    msz = i*sizeof(OFmem[0]);
+	} else {
+	    if ((msz = OF_getprop(phandle, "reg",
+			  OFmem, sizeof OFmem[0] * OFMEM_REGIONS)) <= 0)
+		panic("Physical memory map not found");
+	}
+
 	*memp = OFmem;
 	*memsz = msz / sizeof(struct mem_region);
+	
 
 	/*
 	 * OFavail may have overlapping regions - collapse these
@@ -229,8 +255,10 @@
 		/*
 		 * Clear battable[] translations
 		 */
-		__asm __volatile("mtdbatu 2, %0\n"
-				 "mtdbatu 3, %0" : : "r" (0));
+		if (!ppc64) {
+			__asm __volatile("mtdbatu 2, %0\n"
+					 "mtdbatu 3, %0" : : "r" (0));
+		}
 		isync();
 	}
 

==== //depot/projects/ppc-g5/sys/powerpc/aim/trap_subr.S#2 (text+ko) ====

@@ -228,6 +228,45 @@
 	mfsprg2	%r2;			/* restore r2 & r3 */		\
 	mfsprg3	%r3
 
+/*
+ * The next two routines are 64-bit glue code. The first is used to test if
+ * we are on a 64-bit system. By copying it to the illegal instruction
+ * handler, we can test for 64-bit mode by trying to execute a 64-bit
+ * instruction and seeing what happens. The second gets copied in front
+ * of all the other handlers to restore 32-bit bridge mode when traps
+ * are taken.
+ */
+
+/* 64-bit test code. Sets SPRG2 to 0 if an illegal instruction is executed */
+
+	.globl	CNAME(testppc64),CNAME(testppc64size)
+CNAME(testppc64):
+	mtsprg1 %r31
+	mfsrr0  %r31
+	addi	%r31, %r31, 4
+	mtsrr0  %r31
+
+	li	%r31, 0
+	mtsprg2 %r31
+	mfsprg1 %r31
+
+	rfi
+CNAME(testppc64size) = .-CNAME(testppc64)
+
+
+/* 64-bit bridge mode restore snippet. Gets copied in front of everything else
+ * on 64-bit systems. */
+
+	.globl	CNAME(restorebridge),CNAME(restorebridgesize)
+CNAME(restorebridge):
+	mtsprg1	%r31
+	mfmsr	%r31
+	clrldi	%r31,%r31,1
+	mtmsrd	%r31
+	mfsprg1	%r31
+	isync
+CNAME(restorebridgesize) = .-CNAME(restorebridge)
+
 #ifdef SMP
 /*
  * Processor reset exception handler. These are typically
@@ -490,8 +529,15 @@
 	b	trapexit		/* test ast ret value ? */
 1:
 	FRAME_LEAVE(PC_TEMPSAVE)
+
+	.globl	CNAME(rfi_patch1)	/* replace rfi with rfid on ppc64 */
+CNAME(rfi_patch1):
 	rfi
 
+	.globl	CNAME(rfid_patch)
+CNAME(rfid_patch):
+	rfid
+
 /*
  *     Temporary: vector-unavailable traps are directed to vector-assist traps
  */
@@ -552,6 +598,8 @@
 	b	realtrap
 dbleave:
 	FRAME_LEAVE(PC_DBSAVE)
+	.globl	CNAME(rfi_patch2)	/* replace rfi with rfid on ppc64 */
+CNAME(rfi_patch2):
 	rfi
 
 /*

==== //depot/projects/ppc-g5/sys/powerpc/aim/uio_machdep.c#2 (text+ko) ====

@@ -45,15 +45,17 @@
 #include <sys/proc.h>
 #include <sys/systm.h>
 #include <sys/uio.h>
+#include <sys/sf_buf.h>
 
 #include <vm/vm.h>
 #include <vm/vm_page.h>
 
+#include <machine/cpu.h>
+#include <machine/vmparam.h>
 #include <machine/md_var.h>
-#include <machine/vmparam.h>
 
 /*
- * Implement uiomove(9) from physical memory using the direct map to
+ * Implement uiomove(9) from physical memory using sf_bufs to
  * avoid the creation and destruction of ephemeral mappings.
  */
 int
@@ -63,14 +65,17 @@
 	struct iovec *iov;
 	void *cp;
 	vm_offset_t page_offset;
+	vm_page_t m;
 	size_t cnt;
 	int error = 0;
 	int save = 0;
+	struct sf_buf *sf;
 
 	KASSERT(uio->uio_rw == UIO_READ || uio->uio_rw == UIO_WRITE,
 	    ("uiomove_fromphys: mode"));
 	KASSERT(uio->uio_segflg != UIO_USERSPACE || uio->uio_td == curthread,
 	    ("uiomove_fromphys proc"));
+
 	save = td->td_pflags & TDP_DEADLKTREAT;
 	td->td_pflags |= TDP_DEADLKTREAT;
 	while (n > 0 && uio->uio_resid) {
@@ -85,31 +90,37 @@
 			cnt = n;
 		page_offset = offset & PAGE_MASK;
 		cnt = min(cnt, PAGE_SIZE - page_offset);
-		cp = (char *)VM_PAGE_TO_PHYS(ma[offset >> PAGE_SHIFT]) +
-		    page_offset;
+
+		m = ma[offset >> PAGE_SHIFT];
+		sf = sf_buf_alloc(m, 0);
+		cp = (char*)sf_buf_kva(sf) + page_offset;
+
 		switch (uio->uio_segflg) {
-		case UIO_USERSPACE:
-			if (ticks - PCPU_GET(switchticks) >= hogticks)
-				uio_yield();
-			if (uio->uio_rw == UIO_READ)
-				error = copyout(cp, iov->iov_base, cnt);
-			else 
-				error = copyin(iov->iov_base, cp, cnt);
-			if (error)
-				goto out;
-			if (uio->uio_rw == UIO_WRITE &&
-			    pmap_page_executable(ma[offset >> PAGE_SHIFT]))
-				__syncicache(cp, cnt);
-			break;
-		case UIO_SYSSPACE:
-			if (uio->uio_rw == UIO_READ)
-				bcopy(cp, iov->iov_base, cnt);
-			else
-				bcopy(iov->iov_base, cp, cnt);
-			break;
-		case UIO_NOCOPY:
-			break;
+			case UIO_USERSPACE:
+				if (ticks - PCPU_GET(switchticks) >= hogticks)
+					uio_yield();
+				if (uio->uio_rw == UIO_READ)
+					error = copyout(cp, iov->iov_base, cnt);
+				else
+					error = copyin(iov->iov_base, cp, cnt);
+				if (error) {
+					sf_buf_free(sf);
+					goto out;
+				}
+				if (uio->uio_rw == UIO_WRITE &&
+				    pmap_page_executable(m))
+					__syncicache(cp, cnt);
+				break;
+			case UIO_SYSSPACE:
+				if (uio->uio_rw == UIO_READ)
+					bcopy(cp, iov->iov_base, cnt);
+				else
+					bcopy(iov->iov_base, cp, cnt);
+				break;
+			case UIO_NOCOPY:
+				break;
 		}
+		sf_buf_free(sf);
 		iov->iov_base = (char *)iov->iov_base + cnt;
 		iov->iov_len -= cnt;
 		uio->uio_resid -= cnt;

==== //depot/projects/ppc-g5/sys/powerpc/aim/uma_machdep.c#2 (text+ko) ====

@@ -35,9 +35,13 @@
 #include <sys/sysctl.h>
 #include <vm/vm.h>
 #include <vm/vm_page.h>
+#include <vm/vm_kern.h>
 #include <vm/vm_pageout.h>
+#include <vm/vm_extern.h>
+#include <vm/uma.h>
 #include <vm/uma.h>
 #include <vm/uma_int.h>
+#include <machine/md_var.h>
 #include <machine/vmparam.h>
 
 static int hw_uma_mdpages;
@@ -51,6 +55,13 @@
 	void *va;
 	vm_page_t m;
 	int pflags;
+	
+	if (!hw_direct_map) {
+		*flags = UMA_SLAB_KMEM;
+		va = (void *)kmem_malloc(kmem_map, bytes, wait);
+	
+		return va;
+	}
 
 	*flags = UMA_SLAB_PRIV;
 	if ((wait & (M_NOWAIT|M_USE_RESERVE)) == M_NOWAIT)
@@ -83,6 +94,12 @@
 {
 	vm_page_t m;
 
+	if (!hw_direct_map) {
+		kmem_free(kmem_map, (vm_offset_t)mem, size);
+
+		return;
+	}
+
 	m = PHYS_TO_VM_PAGE((u_int32_t)mem);
 	m->wire_count--;
 	vm_page_free(m);

==== //depot/projects/ppc-g5/sys/powerpc/aim/vm_machdep.c#2 (text+ko) ====

@@ -101,6 +101,37 @@
 #include <vm/vm_extern.h>
 
 /*
+ * On systems without a direct mapped region (e.g. PPC64),
+ * we use the same code as the Book E implementation. Since
+ * we need to have runtime detection of this, define some machinery
+ * for sf_bufs in this case, and ignore it on systems with direct maps.
+ */
+
+#ifndef NSFBUFS
+#define NSFBUFS         (512 + maxusers * 16)
+#endif
+
+static void sf_buf_init(void *arg);
+SYSINIT(sock_sf, SI_SUB_MBUF, SI_ORDER_ANY, sf_buf_init, NULL);
+ 
+LIST_HEAD(sf_head, sf_buf);
+ 
+/* A hash table of active sendfile(2) buffers */
+static struct sf_head *sf_buf_active;
+static u_long sf_buf_hashmask;
+
+#define SF_BUF_HASH(m)  (((m) - vm_page_array) & sf_buf_hashmask)
+
+static TAILQ_HEAD(, sf_buf) sf_buf_freelist;
+static u_int sf_buf_alloc_want;
+
+/*
+ * A lock used to synchronize access to the hash table and free list
+ */
+static struct mtx sf_buf_lock;
+
+
+/*
  * Finish a fork operation, with process p2 nearly set up.
  * Copy and update the pcb, set up the stack so that the child
  * ready to run and return to user mode.
@@ -202,24 +233,122 @@
 }
 
 /*
- * Allocate an sf_buf for the given vm_page.  On this machine, however, there
- * is no sf_buf object.  Instead, an opaque pointer to the given vm_page is
- * returned.
+ * Allocate a pool of sf_bufs (sendfile(2) or "super-fast" if you prefer. :-))
+ */
+static void
+sf_buf_init(void *arg)
+{
+        struct sf_buf *sf_bufs;
+        vm_offset_t sf_base;
+        int i;
+
+	/* Don't bother on systems with a direct map */

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200808261956.m7QJu09K004108>