Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm/arm/generic_timer.c
Show First 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | |||||
static struct resource_spec timer_spec[] = { | static struct resource_spec timer_spec[] = { | ||||
{ SYS_RES_IRQ, 0, RF_ACTIVE }, /* Secure */ | { SYS_RES_IRQ, 0, RF_ACTIVE }, /* Secure */ | ||||
{ SYS_RES_IRQ, 1, RF_ACTIVE }, /* Non-secure */ | { SYS_RES_IRQ, 1, RF_ACTIVE }, /* Non-secure */ | ||||
{ SYS_RES_IRQ, 2, RF_ACTIVE | RF_OPTIONAL }, /* Virt */ | { SYS_RES_IRQ, 2, RF_ACTIVE | RF_OPTIONAL }, /* Virt */ | ||||
{ SYS_RES_IRQ, 3, RF_ACTIVE | RF_OPTIONAL }, /* Hyp */ | { SYS_RES_IRQ, 3, RF_ACTIVE | RF_OPTIONAL }, /* Hyp */ | ||||
{ -1, 0 } | { -1, 0 } | ||||
}; | }; | ||||
static uint32_t arm_tmr_fill_vdso_timehands(struct vdso_timehands *vdso_th, | |||||
struct timecounter *tc); | |||||
static void arm_tmr_do_delay(int usec, void *); | |||||
static timecounter_get_t arm_tmr_get_timecount; | static timecounter_get_t arm_tmr_get_timecount; | ||||
static struct timecounter arm_tmr_timecount = { | static struct timecounter arm_tmr_timecount = { | ||||
.tc_name = "ARM MPCore Timecounter", | .tc_name = "ARM MPCore Timecounter", | ||||
.tc_get_timecount = arm_tmr_get_timecount, | .tc_get_timecount = arm_tmr_get_timecount, | ||||
.tc_poll_pps = NULL, | .tc_poll_pps = NULL, | ||||
.tc_counter_mask = ~0u, | .tc_counter_mask = ~0u, | ||||
.tc_frequency = 0, | .tc_frequency = 0, | ||||
.tc_quality = 1000, | .tc_quality = 1000, | ||||
.tc_fill_vdso_timehands = arm_tmr_fill_vdso_timehands, | |||||
}; | }; | ||||
#ifdef __arm__ | #ifdef __arm__ | ||||
#define get_el0(x) cp15_## x ##_get() | #define get_el0(x) cp15_## x ##_get() | ||||
#define get_el1(x) cp15_## x ##_get() | #define get_el1(x) cp15_## x ##_get() | ||||
#define set_el0(x, val) cp15_## x ##_set(val) | #define set_el0(x, val) cp15_## x ##_set(val) | ||||
#define set_el1(x, val) cp15_## x ##_set(val) | #define set_el1(x, val) cp15_## x ##_set(val) | ||||
#else /* __aarch64__ */ | #else /* __aarch64__ */ | ||||
#define get_el0(x) READ_SPECIALREG(x ##_el0) | #define get_el0(x) READ_SPECIALREG(x ##_el0) | ||||
#define get_el1(x) READ_SPECIALREG(x ##_el1) | #define get_el1(x) READ_SPECIALREG(x ##_el1) | ||||
#define set_el0(x, val) WRITE_SPECIALREG(x ##_el0, val) | #define set_el0(x, val) WRITE_SPECIALREG(x ##_el0, val) | ||||
#define set_el1(x, val) WRITE_SPECIALREG(x ##_el1, val) | #define set_el1(x, val) WRITE_SPECIALREG(x ##_el1, val) | ||||
#endif | #endif | ||||
static uint32_t arm_tmr_fill_vdso_timehands(struct vdso_timehands *vdso_th, | |||||
struct timecounter *tc); | |||||
static void arm_tmr_do_delay(int usec, void *); | |||||
static int | static int | ||||
get_freq(void) | get_freq(void) | ||||
{ | { | ||||
return (get_el0(cntfrq)); | return (get_el0(cntfrq)); | ||||
} | } | ||||
static long | static long | ||||
get_cntxct(bool physical) | get_cntxct(bool physical) | ||||
▲ Show 20 Lines • Show All 264 Lines • ▼ Show 20 Lines | for (i = 0; i < 3; i++) { | ||||
error = bus_setup_intr(dev, sc->res[i], INTR_TYPE_CLK, | error = bus_setup_intr(dev, sc->res[i], INTR_TYPE_CLK, | ||||
arm_tmr_intr, NULL, sc, &sc->ihl[i]); | arm_tmr_intr, NULL, sc, &sc->ihl[i]); | ||||
if (error) { | if (error) { | ||||
device_printf(dev, "Unable to alloc int resource.\n"); | device_printf(dev, "Unable to alloc int resource.\n"); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
} | } | ||||
arm_cpu_fill_vdso_timehands = arm_tmr_fill_vdso_timehands; | |||||
arm_tmr_timecount.tc_frequency = sc->clkfreq; | arm_tmr_timecount.tc_frequency = sc->clkfreq; | ||||
tc_init(&arm_tmr_timecount); | tc_init(&arm_tmr_timecount); | ||||
sc->et.et_name = "ARM MPCore Eventtimer"; | sc->et.et_name = "ARM MPCore Eventtimer"; | ||||
sc->et.et_flags = ET_FLAGS_ONESHOT | ET_FLAGS_PERCPU; | sc->et.et_flags = ET_FLAGS_ONESHOT | ET_FLAGS_PERCPU; | ||||
sc->et.et_quality = 1000; | sc->et.et_quality = 1000; | ||||
sc->et.et_frequency = sc->clkfreq; | sc->et.et_frequency = sc->clkfreq; | ||||
▲ Show 20 Lines • Show All 105 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
#endif | #endif | ||||
static uint32_t | static uint32_t | ||||
arm_tmr_fill_vdso_timehands(struct vdso_timehands *vdso_th, | arm_tmr_fill_vdso_timehands(struct vdso_timehands *vdso_th, | ||||
struct timecounter *tc) | struct timecounter *tc) | ||||
{ | { | ||||
vdso_th->th_algo = VDSO_TH_ALGO_ARM_GENTIM; | |||||
vdso_th->th_physical = arm_tmr_sc->physical; | vdso_th->th_physical = arm_tmr_sc->physical; | ||||
bzero(vdso_th->th_res, sizeof(vdso_th->th_res)); | bzero(vdso_th->th_res, sizeof(vdso_th->th_res)); | ||||
return (tc == &arm_tmr_timecount); | return (1); | ||||
} | } |