Author: nwhitehorn
Date: Sat Nov 25 21:59:59 2017
New Revision: 326205
URL: https://svnweb.freebsd.org/changeset/base/326205

Log:
  Whether you can use mttb() or not is more complicated than whether PSL_HV
  is set and the right thing to do may be platform-dependent (it requires
  firmware on PowerNV, for instance). Make it a new platform method called
  platform_smp_timebase_sync().
  
  MFC after:    3 weeks

Modified:
  head/sys/powerpc/aim/mp_cpudep.c
  head/sys/powerpc/include/platform.h
  head/sys/powerpc/mpc85xx/platform_mpc85xx.c
  head/sys/powerpc/powermac/platform_powermac.c
  head/sys/powerpc/powerpc/mp_machdep.c
  head/sys/powerpc/powerpc/platform.c
  head/sys/powerpc/powerpc/platform_if.m

Modified: head/sys/powerpc/aim/mp_cpudep.c
==============================================================================
--- head/sys/powerpc/aim/mp_cpudep.c    Sat Nov 25 21:46:51 2017        
(r326204)
+++ head/sys/powerpc/aim/mp_cpudep.c    Sat Nov 25 21:59:59 2017        
(r326205)
@@ -281,13 +281,8 @@ cpudep_ap_setup()
        vers = mfpvr() >> 16;
 
        /* The following is needed for restoring from sleep. */
-#ifdef __powerpc64__
-       /* Writing to the time base register is hypervisor-privileged */
-       if (mfmsr() & PSL_HV)
-               mttb(0);
-#else
-       mttb(0);
-#endif
+       platform_smp_timebase_sync(0, 1);
+
        switch(vers) {
        case IBM970:
        case IBM970FX:

Modified: head/sys/powerpc/include/platform.h
==============================================================================
--- head/sys/powerpc/include/platform.h Sat Nov 25 21:46:51 2017        
(r326204)
+++ head/sys/powerpc/include/platform.h Sat Nov 25 21:59:59 2017        
(r326205)
@@ -45,6 +45,8 @@ struct mem_region {
        uint64_t        mr_size;
 };
 
+/* Documentation for these functions is in platform_if.m */
+
 void   mem_regions(struct mem_region **, int *, struct mem_region **, int *);
 vm_offset_t platform_real_maxaddr(void);
 
@@ -54,6 +56,7 @@ int   platform_smp_first_cpu(struct cpuref *);
 int    platform_smp_next_cpu(struct cpuref *);
 int    platform_smp_get_bsp(struct cpuref *);
 int    platform_smp_start_cpu(struct pcpu *);
+void   platform_smp_timebase_sync(u_long tb, int ap);
 void   platform_smp_ap_init(void);
   
 const char *installed_platform(void);

Modified: head/sys/powerpc/mpc85xx/platform_mpc85xx.c
==============================================================================
--- head/sys/powerpc/mpc85xx/platform_mpc85xx.c Sat Nov 25 21:46:51 2017        
(r326204)
+++ head/sys/powerpc/mpc85xx/platform_mpc85xx.c Sat Nov 25 21:59:59 2017        
(r326205)
@@ -92,6 +92,7 @@ static int mpc85xx_smp_first_cpu(platform_t, struct cp
 static int mpc85xx_smp_next_cpu(platform_t, struct cpuref *cpuref);
 static int mpc85xx_smp_get_bsp(platform_t, struct cpuref *cpuref);
 static int mpc85xx_smp_start_cpu(platform_t, struct pcpu *cpu);
+static void mpc85xx_smp_timebase_sync(platform_t, u_long tb, int ap);
 static void mpc85xx_idle(platform_t, int cpu);
 static int mpc85xx_idle_wakeup(platform_t plat, int cpu);
 
@@ -107,6 +108,7 @@ static platform_method_t mpc85xx_methods[] = {
        PLATFORMMETHOD(platform_smp_next_cpu,   mpc85xx_smp_next_cpu),
        PLATFORMMETHOD(platform_smp_get_bsp,    mpc85xx_smp_get_bsp),
        PLATFORMMETHOD(platform_smp_start_cpu,  mpc85xx_smp_start_cpu),
+       PLATFORMMETHOD(platform_smp_timebase_sync, mpc85xx_smp_timebase_sync),
 
        PLATFORMMETHOD(platform_reset,          mpc85xx_reset),
        PLATFORMMETHOD(platform_idle,           mpc85xx_idle),
@@ -526,6 +528,13 @@ mpc85xx_reset(platform_t plat)
        printf("Reset failed...\n");
        while (1)
                ;
+}
+
+static void
+mpc85xx_smp_timebase_sync(platform_t plat, u_long tb, int ap)
+{
+
+       mttb(tb);
 }
 
 static void

Modified: head/sys/powerpc/powermac/platform_powermac.c
==============================================================================
--- head/sys/powerpc/powermac/platform_powermac.c       Sat Nov 25 21:46:51 
2017        (r326204)
+++ head/sys/powerpc/powermac/platform_powermac.c       Sat Nov 25 21:59:59 
2017        (r326205)
@@ -64,6 +64,7 @@ static int powermac_smp_first_cpu(platform_t, struct c
 static int powermac_smp_next_cpu(platform_t, struct cpuref *cpuref);
 static int powermac_smp_get_bsp(platform_t, struct cpuref *cpuref);
 static int powermac_smp_start_cpu(platform_t, struct pcpu *cpu);
+static void powermac_smp_timebase_sync(platform_t, u_long tb, int ap);
 static void powermac_reset(platform_t);
 static void powermac_sleep(platform_t);
 
@@ -77,6 +78,7 @@ static platform_method_t powermac_methods[] = {
        PLATFORMMETHOD(platform_smp_next_cpu,   powermac_smp_next_cpu),
        PLATFORMMETHOD(platform_smp_get_bsp,    powermac_smp_get_bsp),
        PLATFORMMETHOD(platform_smp_start_cpu,  powermac_smp_start_cpu),
+       PLATFORMMETHOD(platform_smp_timebase_sync, powermac_smp_timebase_sync),
 
        PLATFORMMETHOD(platform_reset,          powermac_reset),
        PLATFORMMETHOD(platform_sleep,          powermac_sleep),
@@ -387,6 +389,13 @@ powermac_smp_start_cpu(platform_t plat, struct pcpu *p
        /* No SMP support */
        return (ENXIO);
 #endif
+}
+
+static void
+powermac_smp_timebase_sync(platform_t plat, u_long tb, int ap)
+{
+
+       mttb(tb);
 }
 
 static void

Modified: head/sys/powerpc/powerpc/mp_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/mp_machdep.c       Sat Nov 25 21:46:51 2017        
(r326204)
+++ head/sys/powerpc/powerpc/mp_machdep.c       Sat Nov 25 21:59:59 2017        
(r326205)
@@ -81,13 +81,7 @@ machdep_ap_bootstrap(void)
                ;
 
        /* Initialize DEC and TB, sync with the BSP values */
-#ifdef __powerpc64__
-       /* Writing to the time base register is hypervisor-privileged */
-       if (mfmsr() & PSL_HV)
-               mttb(ap_timebase);
-#else
-       mttb(ap_timebase);
-#endif
+       platform_smp_timebase_sync(ap_timebase, 1);
        decr_ap_init();
 
        /* Give platform code a chance to do anything necessary */
@@ -144,7 +138,6 @@ cpu_mp_start(void)
 
        error = platform_smp_get_bsp(&bsp);
        KASSERT(error == 0, ("Don't know BSP"));
-       KASSERT(bsp.cr_cpuid == 0, ("%s: cpuid != 0", __func__));
 
        error = platform_smp_first_cpu(&cpu);
        while (!error) {
@@ -184,7 +177,7 @@ cpu_mp_announce(void)
        struct pcpu *pc;
        int i;
 
-       for (i = 0; i <= mp_maxid; i++) {
+       CPU_FOREACH(i) {
                pc = pcpu_find(i);
                if (pc == NULL)
                        continue;
@@ -246,13 +239,7 @@ 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
+       platform_smp_timebase_sync(ap_timebase, 0);
 
        while (ap_awake < smp_cpus)
                ;

Modified: head/sys/powerpc/powerpc/platform.c
==============================================================================
--- head/sys/powerpc/powerpc/platform.c Sat Nov 25 21:46:51 2017        
(r326204)
+++ head/sys/powerpc/powerpc/platform.c Sat Nov 25 21:59:59 2017        
(r326205)
@@ -266,6 +266,12 @@ platform_cpu_idle(int cpu)
        PLATFORM_IDLE(plat_obj, cpu);
 }
 
+void platform_smp_timebase_sync(u_long tb, int ap)
+{
+
+       PLATFORM_SMP_TIMEBASE_SYNC(plat_obj, tb, ap);
+}
+
 /*
  * Platform install routines. Highest priority wins, using the same
  * algorithm as bus attachment.

Modified: head/sys/powerpc/powerpc/platform_if.m
==============================================================================
--- head/sys/powerpc/powerpc/platform_if.m      Sat Nov 25 21:46:51 2017        
(r326204)
+++ head/sys/powerpc/powerpc/platform_if.m      Sat Nov 25 21:59:59 2017        
(r326205)
@@ -241,3 +241,14 @@ METHOD void sleep {
        platform_t      _plat;
 };
 
+/**
+ * @brief Attempt to synchronize timebase of current CPU with others.
+ * Entered (approximately) simultaneously on all CPUs, including the BSP.
+ * Passed the timebase value on the BSP as of shortly before the call.
+ */
+METHOD void smp_timebase_sync {
+       platform_t      _plat;
+       u_long          _tb;
+       int             _ap;
+};
+
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to