summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/mips/include/clock.h8
-rw-r--r--sys/mips/mips/tick.c5
-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
5 files changed, 53 insertions, 0 deletions
diff --git a/sys/mips/include/clock.h b/sys/mips/include/clock.h
index 62b5112..7dbf4ab 100644
--- a/sys/mips/include/clock.h
+++ b/sys/mips/include/clock.h
@@ -34,6 +34,14 @@ void mips_timer_init_params(uint64_t, int);
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_ */
diff --git a/sys/mips/mips/tick.c b/sys/mips/mips/tick.c
index bf147c5..b83d83f 100644
--- a/sys/mips/mips/tick.c
+++ b/sys/mips/mips/tick.c
@@ -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
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