summaryrefslogtreecommitdiffstats
path: root/sys/mips/sibyte
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2010-03-20 05:49:06 +0000
committerneel <neel@FreeBSD.org>2010-03-20 05:49:06 +0000
commite17e52b7e2dffab4f1200b2f010c3ef8cb1132d7 (patch)
treecacc3b5710d157a71c058bde1ec018801c05c21d /sys/mips/sibyte
parentacca987bde60a7b3b11dabcb24b9870f71e22546 (diff)
downloadFreeBSD-src-e17e52b7e2dffab4f1200b2f010c3ef8cb1132d7.zip
FreeBSD-src-e17e52b7e2dffab4f1200b2f010c3ef8cb1132d7.tar.gz
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.
Diffstat (limited to 'sys/mips/sibyte')
-rw-r--r--sys/mips/sibyte/sb_machdep.c30
-rw-r--r--sys/mips/sibyte/sb_scd.c9
-rw-r--r--sys/mips/sibyte/sb_scd.h1
3 files changed, 40 insertions, 0 deletions
diff --git a/sys/mips/sibyte/sb_machdep.c b/sys/mips/sibyte/sb_machdep.c
index 8f59815..dca2869 100644
--- a/sys/mips/sibyte/sb_machdep.c
+++ b/sys/mips/sibyte/sb_machdep.c
@@ -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, __register_t a1, __register_t a2,
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, __register_t a1, __register_t a2,
mips_init();
mips_timer_init_params(sb_cpu_speed(), 0);
+
+ set_cputicker(sb_zbbus_cycle_count, sb_cpu_speed() / 2, 1);
}
diff --git a/sys/mips/sibyte/sb_scd.c b/sys/mips/sibyte/sb_scd.c
index 007e149..c8fec69 100644
--- a/sys/mips/sibyte/sb_scd.c
+++ b/sys/mips/sibyte/sb_scd.c
@@ -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;
diff --git a/sys/mips/sibyte/sb_scd.h b/sys/mips/sibyte/sb_scd.h
index 03d2681..f8bb6e4 100644
--- a/sys/mips/sibyte/sb_scd.h
+++ b/sys/mips/sibyte/sb_scd.h
@@ -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);
OpenPOWER on IntegriCloud