Author: raj
Date: Thu May 14 16:48:25 2009
New Revision: 192109
URL: http://svn.freebsd.org/changeset/base/192109

Log:
  PowerPC common SMP startup and time base rework.
  
  - make mftb() shared, rewrite in C, provide complementary mttb()
  - adjust SMP startup per the above, additional comments, minor naming
    changes
  - eliminate redundant TB defines, other minor cosmetics
  
  Reviewed by:  marcel, nwhitehorn
  Obtained from:        Freescale, Semihalf

Modified:
  head/sys/powerpc/aim/clock.c
  head/sys/powerpc/booke/clock.c
  head/sys/powerpc/include/cpufunc.h
  head/sys/powerpc/include/md_var.h
  head/sys/powerpc/include/spr.h
  head/sys/powerpc/powerpc/mp_machdep.c

Modified: head/sys/powerpc/aim/clock.c
==============================================================================
--- head/sys/powerpc/aim/clock.c        Thu May 14 16:25:57 2009        
(r192108)
+++ head/sys/powerpc/aim/clock.c        Thu May 14 16:48:25 2009        
(r192109)
@@ -148,22 +148,19 @@ decr_init(void)
        mtmsr(msr);
 }
 
+#ifdef SMP
 void
-decr_tc_init(void)
+decr_ap_init(void)
 {
-       decr_timecounter.tc_frequency = ticks_per_sec;
-       tc_init(&decr_timecounter);
+
 }
+#endif
 
-static __inline u_quad_t
-mftb(void)
+void
+decr_tc_init(void)
 {
-       u_long          scratch;
-       u_quad_t        tb;
-
-       __asm ("1: mftbu %0; mftb %0+1; mftbu %1; cmpw 0,%0,%1; bne 1b"
-             : "=r"(tb), "=r"(scratch));
-       return tb;
+       decr_timecounter.tc_frequency = ticks_per_sec;
+       tc_init(&decr_timecounter);
 }
 
 static unsigned

Modified: head/sys/powerpc/booke/clock.c
==============================================================================
--- head/sys/powerpc/booke/clock.c      Thu May 14 16:25:57 2009        
(r192108)
+++ head/sys/powerpc/booke/clock.c      Thu May 14 16:48:25 2009        
(r192109)
@@ -151,22 +151,6 @@ decr_init (void)
        mtmsr(msr);
 }
 
-static __inline u_quad_t
-mftb (void)
-{
-       u_long          scratch;
-       u_quad_t        tb;
-
-       __asm__ __volatile__(
-           "1: mftbu %0;"
-           "   mftb %0+1;"
-           "   mftbu %1;"
-           "   cmpw 0,%0,%1;"
-           "   bne 1b"
-           : "=r"(tb), "=r"(scratch));
-       return tb;
-}
-
 void
 decr_tc_init(void)
 {

Modified: head/sys/powerpc/include/cpufunc.h
==============================================================================
--- head/sys/powerpc/include/cpufunc.h  Thu May 14 16:25:57 2009        
(r192108)
+++ head/sys/powerpc/include/cpufunc.h  Thu May 14 16:48:25 2009        
(r192109)
@@ -115,13 +115,37 @@ mfdec(void)
 static __inline register_t
 mfpvr(void)
 {
-       register_t      value;
+       register_t value;
 
        __asm __volatile ("mfpvr %0" : "=r"(value));
 
        return (value);
 }
 
+static __inline u_quad_t
+mftb(void)
+{
+       u_quad_t tb;
+       uint32_t *tbup = (uint32_t *)&tb;
+       uint32_t *tblp = tbup + 1;
+
+       do {
+               *tbup = mfspr(TBR_TBU);
+               *tblp = mfspr(TBR_TBL);
+       } while (*tbup != mfspr(TBR_TBU));
+
+       return (tb);
+}
+
+static __inline void
+mttb(u_quad_t time)
+{
+
+       mtspr(TBR_TBWL, 0);
+       mtspr(TBR_TBWU, (uint32_t)(time >> 32));
+       mtspr(TBR_TBWL, (uint32_t)(time & 0xffffffff));
+}
+
 static __inline void
 eieio(void)
 {

Modified: head/sys/powerpc/include/md_var.h
==============================================================================
--- head/sys/powerpc/include/md_var.h   Thu May 14 16:25:57 2009        
(r192108)
+++ head/sys/powerpc/include/md_var.h   Thu May 14 16:48:25 2009        
(r192109)
@@ -56,11 +56,12 @@ int is_physical_memory(vm_offset_t addr)
 int    mem_valid(vm_offset_t addr, int len);
 
 void   decr_init(void);
+void   decr_ap_init(void);
 void   decr_tc_init(void);
 
 void   cpu_setup(u_int);
 
-struct trapframe;
+struct trapframe;
 void   powerpc_interrupt(struct trapframe *);
 
 #endif /* !_MACHINE_MD_VAR_H_ */

Modified: head/sys/powerpc/include/spr.h
==============================================================================
--- head/sys/powerpc/include/spr.h      Thu May 14 16:25:57 2009        
(r192108)
+++ head/sys/powerpc/include/spr.h      Thu May 14 16:48:25 2009        
(r192109)
@@ -129,8 +129,6 @@
 #define        SPR_SPRG7               0x117   /* 4.. SPR General 7 */
 #define        SPR_ASR                 0x118   /* ... Address Space Register 
(PPC64) */
 #define        SPR_EAR                 0x11a   /* .68 External Access Register 
*/
-#define        SPR_TBL                 0x11c   /* 468 Time Base Lower */
-#define        SPR_TBU                 0x11d   /* 468 Time Base Upper */
 #define        SPR_PVR                 0x11f   /* 468 Processor Version 
Register */
 #define          MPC601                  0x0001
 #define          MPC603                  0x0003

Modified: head/sys/powerpc/powerpc/mp_machdep.c
==============================================================================
--- head/sys/powerpc/powerpc/mp_machdep.c       Thu May 14 16:25:57 2009        
(r192108)
+++ head/sys/powerpc/powerpc/mp_machdep.c       Thu May 14 16:48:25 2009        
(r192109)
@@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
+#include <sys/ktr.h>
 #include <sys/bus.h>
 #include <sys/pcpu.h>
 #include <sys/proc.h>
@@ -40,6 +41,7 @@ __FBSDID("$FreeBSD$");
 #include <machine/cpu.h>
 #include <machine/intr_machdep.h>
 #include <machine/platform.h>
+#include <machine/md_var.h>
 #include <machine/smp.h>
 
 #include "pic_if.h"
@@ -47,30 +49,35 @@ __FBSDID("$FreeBSD$");
 extern struct pcpu __pcpu[MAXCPU];
 
 volatile static int ap_awake;
-volatile static u_int ap_state;
+volatile static u_int ap_letgo;
 volatile static uint32_t ap_decr;
-volatile static uint32_t ap_tbl;
+volatile static u_quad_t ap_timebase;
+static u_int ipi_msg_cnt[32];
 
 void
 machdep_ap_bootstrap(void)
 {
 
-       pcpup->pc_awake = 1;
+       PCPU_SET(pir, mfspr(SPR_PIR));
+       PCPU_SET(awake, 1);
+       __asm __volatile("msync; isync");
 
-       while (ap_state == 0)
+       while (ap_letgo == 0)
                ;
 
-       mtspr(SPR_TBL, 0);
-       mtspr(SPR_TBU, 0);
-       mtspr(SPR_TBL, ap_tbl);
+       /* Initialize DEC and TB, sync with the BSP values */
+       decr_ap_init();
+       mttb(ap_timebase);
        __asm __volatile("mtdec %0" :: "r"(ap_decr));
 
-       ap_awake++;
+       atomic_add_int(&ap_awake, 1);
+       CTR1(KTR_SMP, "SMP: AP CPU%d launched", PCPU_GET(cpuid));
 
-       /* Initialize curthread. */
+       /* Initialize curthread */
        PCPU_SET(curthread, PCPU_GET(idlethread));
        PCPU_SET(curpcb, curthread->td_pcb);
 
+       /* Let the DEC and external interrupts go */
        mtmsr(mfmsr() | PSL_EE);
        sched_throw(NULL);
 }
@@ -149,8 +156,7 @@ cpu_mp_start(void)
                pc->pc_cpumask = 1 << pc->pc_cpuid;
                pc->pc_hwref = cpu.cr_hwref;
                all_cpus |= pc->pc_cpumask;
-
- next:
+next:
                error = platform_smp_next_cpu(&cpu);
        }
 }
@@ -176,7 +182,7 @@ static void
 cpu_mp_unleash(void *dummy)
 {
        struct pcpu *pc;
-       int cpus;
+       int cpus, timeout;
 
        if (mp_ncpus <= 1)
                return;
@@ -187,35 +193,47 @@ cpu_mp_unleash(void *dummy)
                cpus++;
                pc->pc_other_cpus = all_cpus & ~pc->pc_cpumask;
                if (!pc->pc_bsp) {
-                       printf("Waking up CPU %d (dev=%x)\n", pc->pc_cpuid,
-                           pc->pc_hwref);
+                       if (bootverbose)
+                               printf("Waking up CPU %d (dev=%x)\n",
+                                   pc->pc_cpuid, pc->pc_hwref);
+
                        platform_smp_start_cpu(pc);
+                       
+                       timeout = 2000; /* wait 2sec for the AP */
+                       while (!pc->pc_awake && --timeout > 0)
+                               DELAY(1000);
+
                } else {
-                       __asm __volatile("mfspr %0,1023" : "=r"(pc->pc_pir));
+                       PCPU_SET(pir, mfspr(SPR_PIR));
                        pc->pc_awake = 1;
                }
-               if (pc->pc_awake)
+               if (pc->pc_awake) {
+                       if (bootverbose)
+                               printf("Adding CPU %d, pir=%x, awake=%x\n",
+                                   pc->pc_cpuid, pc->pc_pir, pc->pc_awake);
                        smp_cpus++;
+               } else
+                       stopped_cpus |= (1 << pc->pc_cpuid);
        }
 
        ap_awake = 1;
 
-       __asm __volatile("mftb %0" : "=r"(ap_tbl));
-       ap_tbl += 10;
+       /* Provide our current DEC and TB values for APs */
        __asm __volatile("mfdec %0" : "=r"(ap_decr));
-       ap_state++;
-       powerpc_sync();
+       ap_timebase = mftb() + 10;
+       __asm __volatile("msync; isync");
+       
+       /* Let APs continue */
+       atomic_store_rel_int(&ap_letgo, 1);
 
-       mtspr(SPR_TBL, 0);
-       mtspr(SPR_TBU, 0);
-       mtspr(SPR_TBL, ap_tbl);
+       mttb(ap_timebase);
 
        while (ap_awake < smp_cpus)
                ;
 
        if (smp_cpus != cpus || cpus != mp_ncpus) {
                printf("SMP: %d CPUs found; %d CPUs usable; %d CPUs woken\n",
-                       mp_ncpus, cpus, smp_cpus);
+                   mp_ncpus, cpus, smp_cpus);
        }
 
        smp_active = 1;
@@ -224,8 +242,6 @@ cpu_mp_unleash(void *dummy)
 
 SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, cpu_mp_unleash, NULL);
 
-static u_int ipi_msg_cnt[32];
-
 int
 powerpc_ipi_handler(void *arg)
 {
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to