diff options
-rw-r--r-- | sys/mips/include/clock.h | 8 | ||||
-rw-r--r-- | sys/mips/mips/tick.c | 5 | ||||
-rw-r--r-- | sys/mips/sibyte/sb_machdep.c | 30 | ||||
-rw-r--r-- | sys/mips/sibyte/sb_scd.c | 9 | ||||
-rw-r--r-- | sys/mips/sibyte/sb_scd.h | 1 |
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); |