svn commit: r210760 - in user/nwhitehorn/ps3/powerpc: aim powerpc ps3

Nathan Whitehorn nwhitehorn at FreeBSD.org
Mon Aug 2 13:00:43 UTC 2010


Author: nwhitehorn
Date: Mon Aug  2 13:00:43 2010
New Revision: 210760
URL: http://svn.freebsd.org/changeset/base/210760

Log:
  Initial SMP support on PS3. The second thread is extraordinarily slow at
  the moment. Maybe some cache initialization or something is needed?

Modified:
  user/nwhitehorn/ps3/powerpc/aim/mmu_oea64.c
  user/nwhitehorn/ps3/powerpc/powerpc/mp_machdep.c
  user/nwhitehorn/ps3/powerpc/ps3/platform_ps3.c

Modified: user/nwhitehorn/ps3/powerpc/aim/mmu_oea64.c
==============================================================================
--- user/nwhitehorn/ps3/powerpc/aim/mmu_oea64.c	Mon Aug  2 12:21:37 2010	(r210759)
+++ user/nwhitehorn/ps3/powerpc/aim/mmu_oea64.c	Mon Aug  2 13:00:43 2010	(r210760)
@@ -1159,10 +1159,6 @@ moea64_late_bootstrap(mmu_t mmup, vm_off
 	    moea64_add_ofw_mappings(mmup, mmu, sz);
 	}
 
-#ifdef SMP
-	TLBSYNC();
-#endif
-
 	/*
 	 * Calculate the last available physical address.
 	 */

Modified: user/nwhitehorn/ps3/powerpc/powerpc/mp_machdep.c
==============================================================================
--- user/nwhitehorn/ps3/powerpc/powerpc/mp_machdep.c	Mon Aug  2 12:21:37 2010	(r210759)
+++ user/nwhitehorn/ps3/powerpc/powerpc/mp_machdep.c	Mon Aug  2 13:00:43 2010	(r210760)
@@ -77,7 +77,13 @@ machdep_ap_bootstrap(void)
 
 	/* Initialize DEC and TB, sync with the BSP values */
 	decr_ap_init();
+#ifdef __powerpc64__
+	/* Writing to the time base register is hypervisor-privileged */
+	if (mfmsr() & PSL_HV)
+		mttb(ap_timebase);
+#else
 	mttb(ap_timebase);
+#endif
 	__asm __volatile("mtdec %0" :: "r"(ap_decr));
 
 	atomic_add_int(&ap_awake, 1);
@@ -242,7 +248,13 @@ cpu_mp_unleash(void *dummy)
 	/* Let APs continue */
 	atomic_store_rel_int(&ap_letgo, 1);
 
+#ifdef __powerpc64__
+	/* Writing to the time base register is hypervisor-privileged */
+	if (mfmsr() & PSL_HV)
+		mttb(ap_timebase);
+#else
 	mttb(ap_timebase);
+#endif
 
 	while (ap_awake < smp_cpus)
 		;

Modified: user/nwhitehorn/ps3/powerpc/ps3/platform_ps3.c
==============================================================================
--- user/nwhitehorn/ps3/powerpc/ps3/platform_ps3.c	Mon Aug  2 12:21:37 2010	(r210759)
+++ user/nwhitehorn/ps3/powerpc/ps3/platform_ps3.c	Mon Aug  2 13:00:43 2010	(r210760)
@@ -54,6 +54,10 @@ __FBSDID("$FreeBSD: user/nwhitehorn/ps3/
 #include "platform_if.h"
 #include "ps3-hvcall.h"
 
+#ifdef SMP
+extern void *ap_pcpu;
+#endif
+
 static int ps3_probe(platform_t);
 static int ps3_attach(platform_t);
 static void ps3_mem_regions(platform_t, struct mem_region **phys, int *physsz,
@@ -141,14 +145,12 @@ static u_long
 ps3_timebase_freq(platform_t plat, struct cpuref *cpuref)
 {
 	uint64_t ticks, node_id, junk;
-	uint64_t lpar_id;
 
-	lv1_get_logical_partition_id(&lpar_id);
-	lv1_get_repository_node_value(lpar_id, PS3_LPAR_ID_PME, 
-	    lv1_repository_string("be") >> 32, 0, 0, &node_id, &junk);
-	lv1_get_repository_node_value(lpar_id, PS3_LPAR_ID_PME,
+	lv1_get_repository_node_value(PS3_LPAR_ID_PME, 
+	    lv1_repository_string("be") >> 32, 0, 0, 0, &node_id, &junk);
+	lv1_get_repository_node_value(PS3_LPAR_ID_PME,
 	    lv1_repository_string("be") >> 32, node_id,
-	    lv1_repository_string("clock"), &ticks, &junk);
+	    lv1_repository_string("clock"), 0, &ticks, &junk);
 
 	return (ticks);
 }
@@ -167,7 +169,13 @@ static int
 ps3_smp_next_cpu(platform_t plat, struct cpuref *cpuref)
 {
 
-	return (ENOENT);
+	if (cpuref->cr_cpuid >= 1)
+		return (ENOENT);
+
+	cpuref->cr_cpuid++;
+	cpuref->cr_hwref = cpuref->cr_cpuid;
+
+	return (0);
 }
 
 static int
@@ -183,7 +191,27 @@ ps3_smp_get_bsp(platform_t plat, struct 
 static int
 ps3_smp_start_cpu(platform_t plat, struct pcpu *pc)
 {
+#ifdef SMP
+	/* loader(8) is spinning on 0x40 == 1 right now */
+	uint32_t *secondary_spin_sem = (uint32_t *)(0x40);
+	int timeout;
 
+	if (pc->pc_hwref != 1)
+		return (ENXIO);
+
+	ap_pcpu = pc;
+	*secondary_spin_sem = 1;
+	powerpc_sync();
+	DELAY(1);
+
+	timeout = 10000;
+	while (!pc->pc_awake && timeout--)
+		DELAY(100);
+
+	return ((pc->pc_awake) ? 0 : EBUSY);
+#else
 	/* No SMP support */
 	return (ENXIO);
+#endif
 }
+


More information about the svn-src-user mailing list