Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Oct 2008 00:10:51 GMT
From:      Nathan Whitehorn <nwhitehorn@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 151466 for review
Message-ID:  <200810170010.m9H0Apfm025028@repoman.freebsd.org>

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

Change 151466 by nwhitehorn@nwhitehorn_trantor on 2008/10/17 00:09:58

	Add support for real mode Open Firmware accesses, at least for i
	64-bit machines. This lets us boot a decent way into the IBM
	Mambo simulator and should give us a prayer of support on real
	IBM and Genesi hardware.
	
	MFP4 after:	10 days

Affected files ...

.. //depot/projects/ppc-g5/sys/dev/ofw/openfirm.c#2 edit
.. //depot/projects/ppc-g5/sys/dev/ofw/openfirm.h#2 edit
.. //depot/projects/ppc-g5/sys/powerpc/aim/mmu_oea64.c#6 edit
.. //depot/projects/ppc-g5/sys/powerpc/aim/ofw_machdep.c#5 edit
.. //depot/projects/ppc-g5/sys/sparc64/sparc64/ofw_machdep.c#2 edit

Differences ...

==== //depot/projects/ppc-g5/sys/dev/ofw/openfirm.c#2 (text+ko) ====

@@ -117,7 +117,7 @@
 		1,
 	};
 
-	args.service = (cell_t)name;
+	args.service = openfirm_mapptr(name);
 	if (openfirmware(&args) == -1)
 		return (-1);
 	return (args.missing);
@@ -141,7 +141,7 @@
 
 	va_start(ap, nreturns);
 	args.nreturns = ++nreturns;
-	args.slot[i++] = (cell_t)cmd;
+	args.slot[i++] = openfirm_mapptr(cmd);
 	while (i < 1)
 		args.slot[i++] = va_arg(ap, cell_t);
 	if (openfirmware(&args) == -1) {
@@ -284,7 +284,7 @@
 	};
 
 	args.package = package;
-	args.propname = (cell_t)propname;
+	args.propname = openfirm_mapptr(propname);
 	if (openfirmware(&args) == -1)
 		return (-1);
 	return (args.proplen);
@@ -310,8 +310,8 @@
 	};
 
 	args.package = package;
-	args.propname = (cell_t)propname;
-	args.buf = (cell_t)buf;
+	args.propname = openfirm_mapptr(propname);
+	args.buf = openfirm_mapptr(buf);
 	args.buflen = buflen;
 	if (openfirmware(&args) == -1)
 		return (-1);
@@ -361,8 +361,8 @@
 	};
 
 	args.package = package;
-	args.previous = (cell_t)previous;
-	args.buf = (cell_t)buf;
+	args.previous = openfirm_mapptr(previous);
+	args.buf = openfirm_mapptr(buf);
 	if (openfirmware(&args) == -1)
 		return (-1);
 	return (args.flag);
@@ -389,8 +389,8 @@
 	};
 
 	args.package = package;
-	args.propname = (cell_t)propname;
-	args.buf = (cell_t)buf;
+	args.propname = openfirm_mapptr(propname);
+	args.buf = openfirm_mapptr(buf);
 	args.len = len;
 	if (openfirmware(&args) == -1)
 		return (-1);
@@ -415,8 +415,8 @@
 		1,
 	};
 
-	args.device = (cell_t)device;
-	args.buf = (cell_t)buf;
+	args.device = openfirm_mapptr(device);
+	args.buf = openfirm_mapptr(buf);
 	args.len = len;
 	if (openfirmware(&args) == -1)
 		return (-1);
@@ -439,7 +439,7 @@
 		1,
 	};
 
-	args.device = (cell_t)device;
+	args.device = openfirm_mapptr(device);
 	if (openfirmware(&args) == -1)
 		return (-1);
 	return (args.package);
@@ -464,7 +464,7 @@
 	};
 
 	args.instance = instance;
-	args.buf = (cell_t)buf;
+	args.buf = openfirm_mapptr(buf);
 	args.len = len;
 	if (openfirmware(&args) == -1)
 		return (-1);
@@ -490,7 +490,7 @@
 	};
 
 	args.package = package;
-	args.buf = (cell_t)buf;
+	args.buf = openfirm_mapptr(buf);
 	args.len = len;
 	if (openfirmware(&args) == -1)
 		return (-1);
@@ -521,7 +521,7 @@
 		return (-1);
 	args.nargs = nargs + 2;
 	args.nreturns = nreturns + 1;
-	args.method = (cell_t)method;
+	args.method = openfirm_mapptr(method);
 	args.instance = instance;
 	va_start(ap, nreturns);
 	for (cp = args.args_n_results + (n = nargs); --n >= 0;)
@@ -556,7 +556,7 @@
 		1,
 	};
 
-	args.device = (cell_t)device;
+	args.device = openfirm_mapptr(device);
 	if (openfirmware(&args) == -1 || args.instance == 0) {
 		return (-1);
 	}
@@ -600,7 +600,7 @@
 	};
 
 	args.instance = instance;
-	args.addr = (cell_t)addr;
+	args.addr = openfirm_mapptr(addr);
 	args.len = len;
 	if (openfirmware(&args) == -1)
 		return (-1);
@@ -627,7 +627,7 @@
 	};
 
 	args.instance = instance;
-	args.addr = (cell_t)addr;
+	args.addr = openfirm_mapptr(addr);
 	args.len = len;
 	if (openfirmware(&args) == -1)
 		return (-1);
@@ -728,7 +728,7 @@
 		1,
 	};
 
-	args.bootspec = (cell_t)bootspec;
+	args.bootspec = openfirm_mapptr(bootspec);
 	openfirmware(&args);
 	for (;;)			/* just in case */
 		;

==== //depot/projects/ppc-g5/sys/dev/ofw/openfirm.h#2 (text+ko) ====

@@ -81,6 +81,7 @@
  */
 void	set_openfirm_callback(int (*)(void *));
 int	openfirmware(void *);
+cell_t	openfirm_mapptr(const void *);
 
 /*
  * This isn't actually an Open Firmware function, but it seemed like the right

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

@@ -271,8 +271,9 @@
  */
 static struct	mem_region *regions;
 static struct	mem_region *pregions;
-extern u_int           phys_avail_count;
-extern int		regions_sz, pregions_sz;
+extern u_int	phys_avail_count;
+extern int	regions_sz, pregions_sz;
+extern int	ofw_real_mode;
 static struct	ofw_map translations[64];
 
 extern struct pmap ofw_pmap;
@@ -697,6 +698,25 @@
 }
 
 static void
+moea64_bridge_cpu_bootstrap(int ap)
+{
+	int i = 0;
+
+	/*
+	 * Initialize segment registers and MMU
+	 */
+
+	mtmsr(mfmsr() & ~PSL_DR & ~PSL_IR); isync();
+	for (i = 0; i < 16; i++) {
+		mtsrin(i << ADDR_SR_SHFT, kernel_pmap->pm_sr[i]);
+	}
+	__asm __volatile ("sync; mtsdr1 %0; isync"
+	    :: "r"((u_int)moea64_pteg_table 
+		     | (32 - cntlzw(moea64_pteg_mask >> 11))));
+	tlbia();
+}
+
+static void
 moea64_bridge_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
 {
 	ihandle_t	mmui;
@@ -766,10 +786,9 @@
 	moea64_pteg_count >>= 1;
 #endif /* PTEGCOUNT */
 
-
 	size = moea64_pteg_count * sizeof(struct lpteg);
-	CTR2(KTR_PMAP, "moea64_bootstrap: %d PTEGs, %d bytes", moea64_pteg_count,
-	    size);
+	CTR2(KTR_PMAP, "moea64_bootstrap: %d PTEGs, %d bytes", 
+	    moea64_pteg_count, size);
 
 	/* We now need to allocate memory. This memory, to be allocated,
 	   has to reside in a page table. The page table we are about to
@@ -867,31 +886,32 @@
 		moea64_kenter(mmup, pa, pa);
 	ENABLE_TRANS(msr);
 
-	/*
-	 * Set up the Open Firmware pmap and add it's mappings.
-	 */
+	if (!ofw_real_mode) {
+	    /*
+	     * Set up the Open Firmware pmap and add its mappings.
+	     */
 
-	moea64_pinit(mmup, &ofw_pmap);
-	ofw_pmap.pm_sr[KERNEL_SR] = kernel_pmap->pm_sr[KERNEL_SR];
-	ofw_pmap.pm_sr[KERNEL2_SR] = kernel_pmap->pm_sr[KERNEL2_SR];
+	    moea64_pinit(mmup, &ofw_pmap);
+	    ofw_pmap.pm_sr[KERNEL_SR] = kernel_pmap->pm_sr[KERNEL_SR];
+	    ofw_pmap.pm_sr[KERNEL2_SR] = kernel_pmap->pm_sr[KERNEL2_SR];
 
-	if ((chosen = OF_finddevice("/chosen")) == -1)
+	    if ((chosen = OF_finddevice("/chosen")) == -1)
 		panic("moea64_bootstrap: can't find /chosen");
-	OF_getprop(chosen, "mmu", &mmui, 4);
-	if ((mmu = OF_instance_to_package(mmui)) == -1)
+	    OF_getprop(chosen, "mmu", &mmui, 4);
+	    if ((mmu = OF_instance_to_package(mmui)) == -1)
 		panic("moea64_bootstrap: can't get mmu package");
-	if ((sz = OF_getproplen(mmu, "translations")) == -1)
+	    if ((sz = OF_getproplen(mmu, "translations")) == -1)
 		panic("moea64_bootstrap: can't get ofw translation count");
 
-	bzero(translations, sz);
-	if (OF_getprop(mmu, "translations", translations, sz) == -1)
+	    bzero(translations, sz);
+	    if (OF_getprop(mmu, "translations", translations, sz) == -1)
 		panic("moea64_bootstrap: can't get ofw translations");
 
-	CTR0(KTR_PMAP, "moea64_bootstrap: translations");
-	sz /= sizeof(*translations);
-	qsort(translations, sz, sizeof (*translations), om_cmp);
+	    CTR0(KTR_PMAP, "moea64_bootstrap: translations");
+	    sz /= sizeof(*translations);
+	    qsort(translations, sz, sizeof (*translations), om_cmp);
 
-	for (i = 0, ofw_mappings = 0; i < sz; i++) {
+	    for (i = 0, ofw_mappings = 0; i < sz; i++) {
 		CTR3(KTR_PMAP, "translation: pa=%#x va=%#x len=%#x",
 		    (uint32_t)(translations[i].om_pa_lo), translations[i].om_va,
 		    translations[i].om_len);
@@ -940,6 +960,7 @@
 
 		PMAP_UNLOCK(kernel_pmap);
 		PMAP_UNLOCK(&ofw_pmap);
+	    }
 	}
 
 #ifdef SMP
@@ -954,15 +975,9 @@
 	Maxmem = powerpc_btop(phys_avail[i + 1]);
 
 	/*
-	 * Initialize segment registers and MMU
+	 * Initialize MMU
 	 */
-	mtmsr(mfmsr() & ~PSL_DR & ~PSL_IR); isync();
-	for (i = 0; i < 16; i++) {
-		mtsrin(i << ADDR_SR_SHFT, kernel_pmap->pm_sr[i]);
-	}
-	__asm __volatile ("sync; mtsdr1 %0; isync"
-	    :: "r"((u_int)moea64_pteg_table | (32 - cntlzw(moea64_pteg_mask >> 11))));
-	tlbia();
+	moea64_bridge_cpu_bootstrap(0);
 	mtmsr(mfmsr() | PSL_DR | PSL_IR); isync();
 	pmap_bootstrapped++;
 

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

@@ -71,6 +71,7 @@
 extern register_t ofmsr[5];
 extern struct	pmap ofw_pmap;
 static int	(*ofwcall)(void *);
+int		ofw_real_mode;
 
 /*
  * Saved SPRG0-3 from OpenFirmware. Will be restored prior to the callback.
@@ -147,21 +148,43 @@
 	int asz, msz, fsz;
 	int i, j;
 	int still_merging;
+
+	asz = msz = 0;
 	
 	/*
 	 * Get memory.
 	 */
 	if ((phandle = OF_finddevice("/memory")) == -1
 	    || (asz = OF_getprop(phandle, "available",
-			  OFavail, sizeof OFavail[0] * OFMEM_REGIONS))
-	       <= 0)
-		panic("no memory?");
+		  OFavail, sizeof OFavail[0] * OFMEM_REGIONS)) <= 0)
+	{
+		if (ofw_real_mode) {
+			/* XXX MAMBO */
+			printf("Physical memory unknown -- guessing 128 MB\n");
+
+			/* Leave the first 0xA000000 bytes for the kernel */
+			OFavail[0].mr_start = 0xA00000;
+			OFavail[0].mr_size = 0x75FFFFF;
+			asz = sizeof(OFavail[0]);
+		} else {
+			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");
+	    if ((phandle == -1) || (msz = OF_getprop(phandle, "reg",
+			  OFmem64, sizeof OFmem64[0] * OFMEM_REGIONS)) <= 0) {
+		if (ofw_real_mode) {
+			/* XXX MAMBO */
+			OFmem64[0].mr_start_hi = 0;
+			OFmem64[0].mr_start_lo = 0x0;
+			OFmem64[0].mr_size = 0x7FFFFFF;
+			msz = sizeof(OFmem64[0]);
+		} else {
+			panic("Physical memory map not found");
+		}
+	    }
 
 	    for (i = 0; i < msz/sizeof(OFmem64[0]); i++) {
 		if (OFmem64[i].mr_start_hi == 0) {
@@ -220,10 +243,23 @@
 void
 set_openfirm_callback(int (*openfirm)(void *))
 {
+	if (ofmsr[0] & PSL_DR)
+		ofw_real_mode = 0;
+	else
+		ofw_real_mode = 1;
 
 	ofwcall = openfirm;
 }
 
+cell_t
+openfirm_mapptr(const void *arg)
+{
+	if (ofw_real_mode && pmap_bootstrapped)
+		return ((cell_t)pmap_kextract((vm_offset_t)arg));
+
+	return ((cell_t)arg);
+}
+
 int
 openfirmware(void *args)
 {
@@ -232,6 +268,9 @@
 	u_int	srsave[16];
 	u_int   i;
 
+	if (pmap_bootstrapped && ofw_real_mode)
+		args = (void *)pmap_kextract((vm_offset_t)args);
+
 	__asm __volatile(	"\t"
 		"sync\n\t"
 		"mfmsr  %0\n\t"
@@ -243,7 +282,7 @@
 
 	ofw_sprg_prepare();
 
-	if (pmap_bootstrapped) {
+	if (pmap_bootstrapped && !ofw_real_mode) {
 		/*
 		 * Swap the kernel's address space with Open Firmware's
 		 */
@@ -264,7 +303,7 @@
 
        	result = ofwcall(args);
 
-	if (pmap_bootstrapped) {
+	if (pmap_bootstrapped && !ofw_real_mode) {
 		/*
 		 * Restore the kernel's addr space. The isync() doesn;t
 		 * work outside the loop unless mtsrin() is open-coded
@@ -458,3 +497,4 @@
 
 	return (EFAULT);
 }
+

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

@@ -268,4 +268,15 @@
 		return (0);
 	}
 	return (ENXIO);
+} 
+
+/*
+ * Map a pointer from kernel address space to OFW address space. Since OFW
+ * lives in the same address space, do nothing.
+ */
+
+cell_t
+openfirm_mapptr(const void *arg)
+{
+	return ((cell_t)arg);
 }



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