Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 20 Mar 2010 05:49:07 +0000 (UTC)
From:      Neel Natu <neel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r205364 - in head/sys/mips: include mips sibyte
Message-ID:  <201003200549.o2K5n7QZ083111@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: neel
Date: Sat Mar 20 05:49:06 2010
New Revision: 205364
URL: http://svn.freebsd.org/changeset/base/205364

Log:
  Sibyte provides a 64-bit read-only counter that counts at half the processor
  frequency. This counter can be accessed coherently from both cores.
  
  Use this as the preferred timecounter for the SWARM kernels.
  
  The CP0 COUNT register is unusable as the timecounter on SMP platforms because
  the COUNT registers on different CPUs are not guaranteed to be in sync.

Modified:
  head/sys/mips/include/clock.h
  head/sys/mips/mips/tick.c
  head/sys/mips/sibyte/sb_machdep.c
  head/sys/mips/sibyte/sb_scd.c
  head/sys/mips/sibyte/sb_scd.h

Modified: head/sys/mips/include/clock.h
==============================================================================
--- head/sys/mips/include/clock.h	Sat Mar 20 05:21:14 2010	(r205363)
+++ head/sys/mips/include/clock.h	Sat Mar 20 05:49:06 2010	(r205364)
@@ -34,6 +34,14 @@ void	mips_timer_init_params(uint64_t, in
 extern uint64_t	counter_freq;
 extern int	clocks_running;
 
+/*
+ * The 'platform_timecounter' pointer may be used to register a
+ * platform-specific timecounter.
+ *
+ * A default timecounter based on the CP0 COUNT register is always registered.
+ */
+extern struct timecounter *platform_timecounter;
+
 #endif
 
 #endif /* !_MACHINE_CLOCK_H_ */

Modified: head/sys/mips/mips/tick.c
==============================================================================
--- head/sys/mips/mips/tick.c	Sat Mar 20 05:21:14 2010	(r205363)
+++ head/sys/mips/mips/tick.c	Sat Mar 20 05:49:06 2010	(r205364)
@@ -54,6 +54,8 @@ __FBSDID("$FreeBSD$");
 
 uint64_t counter_freq;
 
+struct timecounter *platform_timecounter;
+
 static uint64_t cycles_per_tick;
 static uint64_t cycles_per_usec;
 static uint64_t cycles_per_hz, cycles_per_stathz, cycles_per_profhz;
@@ -103,6 +105,9 @@ platform_initclocks(void)
 {
 
 	tc_init(&counter_timecounter);
+
+	if (platform_timecounter != NULL)
+		tc_init(platform_timecounter);
 }
 
 static uint64_t

Modified: head/sys/mips/sibyte/sb_machdep.c
==============================================================================
--- head/sys/mips/sibyte/sb_machdep.c	Sat Mar 20 05:21:14 2010	(r205363)
+++ head/sys/mips/sibyte/sb_machdep.c	Sat Mar 20 05:49:06 2010	(r205364)
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/sysent.h>
 #include <sys/sysproto.h>
 #include <sys/user.h>
+#include <sys/timetc.h>
 
 #include <vm/vm.h>
 #include <vm/vm_object.h>
@@ -364,6 +365,32 @@ platform_start_ap(int cpuid)
 }
 #endif	/* SMP */
 
+static u_int
+sb_get_timecount(struct timecounter *tc)
+{
+
+	return ((u_int)sb_zbbus_cycle_count());
+}
+
+static void
+sb_timecounter_init(void)
+{
+	static struct timecounter sb_timecounter = {
+		sb_get_timecount,
+		NULL,
+		~0u,
+		0,
+		"sibyte_zbbus_counter",
+		2000
+	};
+
+	/*
+	 * The ZBbus cycle counter runs at half the cpu frequency.
+	 */
+	sb_timecounter.tc_frequency = sb_cpu_speed() / 2;
+	platform_timecounter = &sb_timecounter;
+}
+
 void
 platform_start(__register_t a0, __register_t a1, __register_t a2,
 	       __register_t a3)
@@ -378,6 +405,7 @@ platform_start(__register_t a0, __regist
 	mips_postboot_fixup();
 
 	sb_intr_init(0);
+	sb_timecounter_init();
 
 	/* Initialize pcpu stuff */
 	mips_pcpu0_init();
@@ -400,4 +428,6 @@ platform_start(__register_t a0, __regist
 	mips_init();
 
 	mips_timer_init_params(sb_cpu_speed(), 0);
+
+	set_cputicker(sb_zbbus_cycle_count, sb_cpu_speed() / 2, 1);
 }

Modified: head/sys/mips/sibyte/sb_scd.c
==============================================================================
--- head/sys/mips/sibyte/sb_scd.c	Sat Mar 20 05:21:14 2010	(r205363)
+++ head/sys/mips/sibyte/sb_scd.c	Sat Mar 20 05:49:06 2010	(r205364)
@@ -56,6 +56,8 @@ extern uint64_t	sb_load64(uint32_t addr)
 #define	SYSCFG_ADDR		MIPS_PHYS_TO_KSEG1(0x10020008)
 #define SYSCFG_PLLDIV(x)	GET_VAL_64((x), 7, 5)
 
+#define	ZBBUS_CYCLE_COUNT_ADDR	MIPS_PHYS_TO_KSEG1(0x10030000)
+
 #define	INTSRC_MASK_ADDR(cpu)	\
 	(MIPS_PHYS_TO_KSEG1(0x10020028) | ((cpu) << 13))
 
@@ -83,6 +85,13 @@ sb_write_syscfg(uint64_t val)
 }
 
 uint64_t
+sb_zbbus_cycle_count(void)
+{
+
+	return (sb_load64(ZBBUS_CYCLE_COUNT_ADDR));
+}
+
+uint64_t
 sb_cpu_speed(void)
 {
 	int plldiv;

Modified: head/sys/mips/sibyte/sb_scd.h
==============================================================================
--- head/sys/mips/sibyte/sb_scd.h	Sat Mar 20 05:21:14 2010	(r205363)
+++ head/sys/mips/sibyte/sb_scd.h	Sat Mar 20 05:49:06 2010	(r205364)
@@ -31,6 +31,7 @@
 
 #define	NUM_INTSRC		64	/* total number of interrupt sources */
 
+uint64_t	sb_zbbus_cycle_count(void);
 uint64_t	sb_cpu_speed(void);
 void		sb_system_reset(void);
 



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