MFcalloutng:
Switch eventtimers(9) from using struct bintime to sbintime_t. Even before this not a single driver really supported full dynamic range of struct bintime even in theory, not speaking about practical inexpediency. This change legitimates the status quo and cleans up the code.
This commit is contained in:
parent
240074414d
commit
6cf7cc6e4d
@ -1,5 +1,5 @@
|
||||
.\"
|
||||
.\" Copyright (c) 2011 Alexander Motin <mav@FreeBSD.org>
|
||||
.\" Copyright (c) 2011-2013 Alexander Motin <mav@FreeBSD.org>
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
@ -24,7 +24,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd December 14, 2011
|
||||
.Dd February 25, 2013
|
||||
.Dt EVENTTIMERS 9
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -36,7 +36,7 @@
|
||||
struct eventtimer;
|
||||
|
||||
typedef int et_start_t(struct eventtimer *et,
|
||||
struct bintime *first, struct bintime *period);
|
||||
sbintime_t first, sbintime_t period);
|
||||
typedef int et_stop_t(struct eventtimer *et);
|
||||
typedef void et_event_cb_t(struct eventtimer *et, void *arg);
|
||||
typedef int et_deregister_cb_t(struct eventtimer *et, void *arg);
|
||||
@ -53,8 +53,8 @@ struct eventtimer {
|
||||
int et_quality;
|
||||
int et_active;
|
||||
uint64_t et_frequency;
|
||||
struct bintime et_min_period;
|
||||
struct bintime et_max_period;
|
||||
sbintime_t et_min_period;
|
||||
sbintime_t et_max_period;
|
||||
et_start_t *et_start;
|
||||
et_stop_t *et_stop;
|
||||
et_event_cb_t *et_event_cb;
|
||||
@ -75,7 +75,7 @@ struct eventtimer {
|
||||
.Ft int
|
||||
.Fn et_init "struct eventtimer *et" "et_event_cb_t *event" "et_deregister_cb_t *deregister" "void *arg"
|
||||
.Ft int
|
||||
.Fn et_start "struct eventtimer *et" "struct bintime *first" "struct bintime *period"
|
||||
.Fn et_start "struct eventtimer *et" "sbintime_t first" "sbintime_t period"
|
||||
.Ft int
|
||||
.Fn et_stop "struct eventtimer *et"
|
||||
.Ft int
|
||||
|
@ -95,7 +95,7 @@ int a10_timer_get_timerfreq(struct a10_timer_softc *);
|
||||
|
||||
static u_int a10_timer_get_timecount(struct timecounter *);
|
||||
static int a10_timer_timer_start(struct eventtimer *,
|
||||
struct bintime *, struct bintime *);
|
||||
sbintime_t first, sbintime_t period);
|
||||
static int a10_timer_timer_stop(struct eventtimer *);
|
||||
|
||||
static uint64_t timer_read_counter64(void);
|
||||
@ -193,12 +193,8 @@ a10_timer_attach(device_t dev)
|
||||
sc->et.et_name = "a10_timer Eventtimer";
|
||||
sc->et.et_flags = ET_FLAGS_ONESHOT | ET_FLAGS_PERIODIC;
|
||||
sc->et.et_quality = 1000;
|
||||
sc->et.et_min_period.sec = 0;
|
||||
sc->et.et_min_period.frac =
|
||||
((0x00000005LLU << 32) / sc->et.et_frequency) << 32;
|
||||
sc->et.et_max_period.sec = 0xfffffff0U / sc->et.et_frequency;
|
||||
sc->et.et_max_period.frac =
|
||||
((0xfffffffeLLU << 32) / sc->et.et_frequency) << 32;
|
||||
sc->et.et_min_period = (0x00000005LLU << 32) / sc->et.et_frequency;
|
||||
sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
|
||||
sc->et.et_start = a10_timer_timer_start;
|
||||
sc->et.et_stop = a10_timer_timer_stop;
|
||||
sc->et.et_priv = sc;
|
||||
@ -225,8 +221,8 @@ a10_timer_attach(device_t dev)
|
||||
}
|
||||
|
||||
static int
|
||||
a10_timer_timer_start(struct eventtimer *et, struct bintime *first,
|
||||
struct bintime *period)
|
||||
a10_timer_timer_start(struct eventtimer *et, sbintime_t first,
|
||||
sbintime_t period)
|
||||
{
|
||||
struct a10_timer_softc *sc;
|
||||
uint32_t count;
|
||||
@ -234,26 +230,21 @@ a10_timer_timer_start(struct eventtimer *et, struct bintime *first,
|
||||
|
||||
sc = (struct a10_timer_softc *)et->et_priv;
|
||||
|
||||
sc->sc_period = 0;
|
||||
|
||||
if (period != NULL) {
|
||||
sc->sc_period = (sc->et.et_frequency * (period->frac >> 32)) >> 32;
|
||||
sc->sc_period += sc->et.et_frequency * period->sec;
|
||||
}
|
||||
if (first == NULL)
|
||||
if (period != 0)
|
||||
sc->sc_period = ((uint32_t)et->et_frequency * period) >> 32;
|
||||
else
|
||||
sc->sc_period = 0;
|
||||
if (first != 0)
|
||||
count = ((uint32_t)et->et_frequency * first) >> 32;
|
||||
else
|
||||
count = sc->sc_period;
|
||||
else {
|
||||
count = (sc->et.et_frequency * (first->frac >> 32)) >> 32;
|
||||
if (first->sec != 0)
|
||||
count += sc->et.et_frequency * first->sec;
|
||||
}
|
||||
|
||||
/* Update timer values */
|
||||
timer_write_4(sc, SW_TIMER0_INT_VALUE_REG, sc->sc_period);
|
||||
timer_write_4(sc, SW_TIMER0_CUR_VALUE_REG, count);
|
||||
|
||||
val = timer_read_4(sc, SW_TIMER0_CTRL_REG);
|
||||
if (first == NULL) {
|
||||
if (period != 0) {
|
||||
/* periodic */
|
||||
val |= TIMER_AUTORELOAD;
|
||||
} else {
|
||||
|
@ -167,31 +167,23 @@ arm_tmr_get_timecount(struct timecounter *tc)
|
||||
* Always returns 0
|
||||
*/
|
||||
static int
|
||||
arm_tmr_start(struct eventtimer *et, struct bintime *first,
|
||||
struct bintime *period)
|
||||
arm_tmr_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
|
||||
{
|
||||
struct arm_tmr_softc *sc = (struct arm_tmr_softc *)et->et_priv;
|
||||
uint32_t load, count;
|
||||
uint32_t ctrl;
|
||||
|
||||
ctrl = PRV_TIMER_CTRL_IRQ_ENABLE | PRV_TIMER_CTRL_TIMER_ENABLE;
|
||||
|
||||
if (period != NULL) {
|
||||
load = (et->et_frequency * (period->frac >> 32)) >> 32;
|
||||
if (period->sec > 0)
|
||||
load += et->et_frequency * period->sec;
|
||||
if (period != 0) {
|
||||
load = ((uint32_t)et->et_frequency * period) >> 32;
|
||||
ctrl |= PRV_TIMER_CTRL_AUTO_RELOAD;
|
||||
} else {
|
||||
} else
|
||||
load = 0;
|
||||
}
|
||||
|
||||
if (first != NULL) {
|
||||
count = (sc->et.et_frequency * (first->frac >> 32)) >> 32;
|
||||
if (first->sec != 0)
|
||||
count += sc->et.et_frequency * first->sec;
|
||||
} else {
|
||||
if (first != 0)
|
||||
count = ((uint32_t)et->et_frequency * first) >> 32;
|
||||
else
|
||||
count = load;
|
||||
}
|
||||
|
||||
tmr_prv_write_4(PRV_TIMER_LOAD, load);
|
||||
tmr_prv_write_4(PRV_TIMER_COUNT, count);
|
||||
@ -330,12 +322,8 @@ arm_tmr_attach(device_t dev)
|
||||
sc->et.et_quality = 1000;
|
||||
|
||||
sc->et.et_frequency = sc->clkfreq;
|
||||
sc->et.et_min_period.sec = 0;
|
||||
sc->et.et_min_period.frac =
|
||||
((0x00000002LLU << 32) / sc->et.et_frequency) << 32;
|
||||
sc->et.et_max_period.sec = 0xfffffff0U / sc->et.et_frequency;
|
||||
sc->et.et_max_period.frac =
|
||||
((0xfffffffeLLU << 32) / sc->et.et_frequency) << 32;
|
||||
sc->et.et_min_period = (0x00000002LLU << 32) / sc->et.et_frequency;
|
||||
sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
|
||||
sc->et.et_start = arm_tmr_start;
|
||||
sc->et.et_stop = arm_tmr_stop;
|
||||
sc->et.et_priv = sc;
|
||||
|
@ -118,19 +118,16 @@ bcm_systimer_tc_get_timecount(struct timecounter *tc)
|
||||
}
|
||||
|
||||
static int
|
||||
bcm_systimer_start(struct eventtimer *et, struct bintime *first,
|
||||
struct bintime *period)
|
||||
bcm_systimer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
|
||||
{
|
||||
struct systimer *st = et->et_priv;
|
||||
uint32_t clo;
|
||||
uint32_t count;
|
||||
register_t s;
|
||||
|
||||
if (first != NULL) {
|
||||
if (first != 0) {
|
||||
|
||||
count = (st->et.et_frequency * (first->frac >> 32)) >> 32;
|
||||
if (first->sec != 0)
|
||||
count += st->et.et_frequency * first->sec;
|
||||
count = ((uint32_t)et->et_frequency * first) >> 32;
|
||||
|
||||
s = intr_disable();
|
||||
clo = bcm_systimer_tc_read_4(SYSTIMER_CLO);
|
||||
@ -238,12 +235,10 @@ bcm_systimer_attach(device_t dev)
|
||||
sc->st[DEFAULT_TIMER].et.et_flags = ET_FLAGS_ONESHOT;
|
||||
sc->st[DEFAULT_TIMER].et.et_quality = 1000;
|
||||
sc->st[DEFAULT_TIMER].et.et_frequency = sc->sysclk_freq;
|
||||
sc->st[DEFAULT_TIMER].et.et_min_period.sec = 0;
|
||||
sc->st[DEFAULT_TIMER].et.et_min_period.frac =
|
||||
((MIN_PERIOD << 32) / sc->st[DEFAULT_TIMER].et.et_frequency) << 32;
|
||||
sc->st[DEFAULT_TIMER].et.et_max_period.sec = 0xfffffff0U / sc->st[DEFAULT_TIMER].et.et_frequency;
|
||||
sc->st[DEFAULT_TIMER].et.et_max_period.frac =
|
||||
((0xfffffffeLLU << 32) / sc->st[DEFAULT_TIMER].et.et_frequency) << 32;
|
||||
sc->st[DEFAULT_TIMER].et.et_min_period =
|
||||
(MIN_PERIOD << 32) / sc->st[DEFAULT_TIMER].et.et_frequency;
|
||||
sc->st[DEFAULT_TIMER].et.et_max_period =
|
||||
(0xfffffffeLLU << 32) / sc->st[DEFAULT_TIMER].et.et_frequency;
|
||||
sc->st[DEFAULT_TIMER].et.et_start = bcm_systimer_start;
|
||||
sc->st[DEFAULT_TIMER].et.et_stop = bcm_systimer_stop;
|
||||
sc->st[DEFAULT_TIMER].et.et_priv = &sc->st[DEFAULT_TIMER];
|
||||
|
@ -72,8 +72,8 @@ static struct lpc_timer_softc *timer_softc = NULL;
|
||||
static int lpc_timer_initialized = 0;
|
||||
static int lpc_timer_probe(device_t);
|
||||
static int lpc_timer_attach(device_t);
|
||||
static int lpc_timer_start(struct eventtimer *, struct bintime *first,
|
||||
struct bintime *);
|
||||
static int lpc_timer_start(struct eventtimer *,
|
||||
sbintime_t first, sbintime_t period);
|
||||
static int lpc_timer_stop(struct eventtimer *et);
|
||||
static unsigned lpc_get_timecount(struct timecounter *);
|
||||
static int lpc_hardclock(void *);
|
||||
@ -173,12 +173,8 @@ lpc_timer_attach(device_t dev)
|
||||
sc->lt_et.et_name = "LPC32x0 Timer0";
|
||||
sc->lt_et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
|
||||
sc->lt_et.et_quality = 1000;
|
||||
sc->lt_et.et_min_period.sec = 0;
|
||||
sc->lt_et.et_min_period.frac =
|
||||
((0x00000002LLU << 32) / sc->lt_et.et_frequency) << 32;
|
||||
sc->lt_et.et_max_period.sec = 0xfffffff0U / sc->lt_et.et_frequency;
|
||||
sc->lt_et.et_max_period.frac =
|
||||
((0xfffffffeLLU << 32) / sc->lt_et.et_frequency) << 32;
|
||||
sc->lt_et.et_min_period = (0x00000002LLU << 32) / sc->lt_et.et_frequency;
|
||||
sc->lt_et.et_max_period = (0xfffffffeLLU << 32) / sc->lt_et.et_frequency;
|
||||
sc->lt_et.et_start = lpc_timer_start;
|
||||
sc->lt_et.et_stop = lpc_timer_stop;
|
||||
sc->lt_et.et_priv = sc;
|
||||
@ -199,27 +195,23 @@ lpc_timer_attach(device_t dev)
|
||||
}
|
||||
|
||||
static int
|
||||
lpc_timer_start(struct eventtimer *et, struct bintime *first,
|
||||
struct bintime *period)
|
||||
lpc_timer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
|
||||
{
|
||||
struct lpc_timer_softc *sc = (struct lpc_timer_softc *)et->et_priv;
|
||||
uint32_t ticks;
|
||||
|
||||
if (period == NULL)
|
||||
if (period == 0) {
|
||||
sc->lt_oneshot = 1;
|
||||
else {
|
||||
sc->lt_period = 0;
|
||||
} else {
|
||||
sc->lt_oneshot = 0;
|
||||
sc->lt_period = (sc->lt_et.et_frequency * (first->frac >> 32)) >> 32;
|
||||
sc->lt_period += sc->lt_et.et_frequency * first->sec;
|
||||
sc->lt_period = ((uint32_t)et->et_frequency * period) >> 32;
|
||||
}
|
||||
|
||||
if (first == NULL)
|
||||
if (first == 0)
|
||||
ticks = sc->lt_period;
|
||||
else {
|
||||
ticks = (sc->lt_et.et_frequency * (first->frac >> 32)) >> 32;
|
||||
if (first->sec != 0)
|
||||
ticks += sc->lt_et.et_frequency * first->sec;
|
||||
}
|
||||
else
|
||||
ticks = ((uint32_t)et->et_frequency * first) >> 32;
|
||||
|
||||
/* Reset timer */
|
||||
timer0_write_4(sc, LPC_TIMER_TCR, LPC_TIMER_TCR_RESET);
|
||||
|
@ -93,7 +93,7 @@ static void mv_watchdog_enable(void);
|
||||
static void mv_watchdog_disable(void);
|
||||
static void mv_watchdog_event(void *, unsigned int, int *);
|
||||
static int mv_timer_start(struct eventtimer *et,
|
||||
struct bintime *first, struct bintime *period);
|
||||
sbintime_t first, sbintime_t period);
|
||||
static int mv_timer_stop(struct eventtimer *et);
|
||||
static void mv_setup_timers(void);
|
||||
|
||||
@ -168,12 +168,8 @@ mv_timer_attach(device_t dev)
|
||||
sc->et.et_quality = 1000;
|
||||
|
||||
sc->et.et_frequency = MV_CLOCK_SRC;
|
||||
sc->et.et_min_period.sec = 0;
|
||||
sc->et.et_min_period.frac =
|
||||
((0x00000002LLU << 32) / sc->et.et_frequency) << 32;
|
||||
sc->et.et_max_period.sec = 0xfffffff0U / sc->et.et_frequency;
|
||||
sc->et.et_max_period.frac =
|
||||
((0xfffffffeLLU << 32) / sc->et.et_frequency) << 32;
|
||||
sc->et.et_min_period = (0x00000002LLU << 32) / sc->et.et_frequency;
|
||||
sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
|
||||
sc->et.et_start = mv_timer_start;
|
||||
sc->et.et_stop = mv_timer_stop;
|
||||
sc->et.et_priv = sc;
|
||||
@ -394,25 +390,20 @@ mv_watchdog_event(void *arg, unsigned int cmd, int *error)
|
||||
}
|
||||
|
||||
static int
|
||||
mv_timer_start(struct eventtimer *et,
|
||||
struct bintime *first, struct bintime *period)
|
||||
mv_timer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
|
||||
{
|
||||
struct mv_timer_softc *sc;
|
||||
uint32_t val, val1;
|
||||
|
||||
/* Calculate dividers. */
|
||||
sc = (struct mv_timer_softc *)et->et_priv;
|
||||
if (period != NULL) {
|
||||
val = (sc->et.et_frequency * (period->frac >> 32)) >> 32;
|
||||
if (period->sec != 0)
|
||||
val += sc->et.et_frequency * period->sec;
|
||||
} else
|
||||
if (period != 0)
|
||||
val = ((uint32_t)sc->et.et_frequency * period) >> 32;
|
||||
else
|
||||
val = 0;
|
||||
if (first != NULL) {
|
||||
val1 = (sc->et.et_frequency * (first->frac >> 32)) >> 32;
|
||||
if (first->sec != 0)
|
||||
val1 += sc->et.et_frequency * first->sec;
|
||||
} else
|
||||
if (first != 0)
|
||||
val1 = ((uint32_t)sc->et.et_frequency * first) >> 32;
|
||||
else
|
||||
val1 = val;
|
||||
|
||||
/* Apply configuration. */
|
||||
@ -420,7 +411,7 @@ mv_timer_start(struct eventtimer *et,
|
||||
mv_set_timer(0, val1);
|
||||
val = mv_get_timer_control();
|
||||
val |= CPU_TIMER0_EN;
|
||||
if (period != NULL)
|
||||
if (period != 0)
|
||||
val |= CPU_TIMER0_AUTO;
|
||||
else
|
||||
val &= ~CPU_TIMER0_AUTO;
|
||||
|
@ -143,30 +143,24 @@ am335x_dmtimer_tc_get_timecount(struct timecounter *tc)
|
||||
}
|
||||
|
||||
static int
|
||||
am335x_dmtimer_start(struct eventtimer *et, struct bintime *first,
|
||||
struct bintime *period)
|
||||
am335x_dmtimer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
|
||||
{
|
||||
struct am335x_dmtimer *tmr = (struct am335x_dmtimer *)et->et_priv;
|
||||
uint32_t load, count;
|
||||
uint32_t tclr = 0;
|
||||
|
||||
if (period != NULL) {
|
||||
load = (et->et_frequency * (period->frac >> 32)) >> 32;
|
||||
if (period->sec > 0)
|
||||
load += et->et_frequency * period->sec;
|
||||
if (period != 0) {
|
||||
load = ((uint32_t)et->et_frequency * period) >> 32;
|
||||
tclr |= 2; /* autoreload bit */
|
||||
panic("periodic timer not implemented\n");
|
||||
} else {
|
||||
load = 0;
|
||||
}
|
||||
|
||||
if (first != NULL) {
|
||||
count = (tmr->et.et_frequency * (first->frac >> 32)) >> 32;
|
||||
if (first->sec != 0)
|
||||
count += tmr->et.et_frequency * first->sec;
|
||||
} else {
|
||||
if (first != 0)
|
||||
count = ((uint32_t)et->et_frequency * first) >> 32;
|
||||
else
|
||||
count = load;
|
||||
}
|
||||
|
||||
/* Reset Timer */
|
||||
am335x_dmtimer_et_write_4(DMTIMER_TSICR, 2);
|
||||
@ -316,12 +310,10 @@ am335x_dmtimer_attach(device_t dev)
|
||||
sc->t[3].et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
|
||||
sc->t[3].et.et_quality = 1000;
|
||||
sc->t[3].et.et_frequency = sc->sysclk_freq;
|
||||
sc->t[3].et.et_min_period.sec = 0;
|
||||
sc->t[3].et.et_min_period.frac =
|
||||
((0x00000002LLU << 32) / sc->t[3].et.et_frequency) << 32;
|
||||
sc->t[3].et.et_max_period.sec = 0xfffffff0U / sc->t[3].et.et_frequency;
|
||||
sc->t[3].et.et_max_period.frac =
|
||||
((0xfffffffeLLU << 32) / sc->t[3].et.et_frequency) << 32;
|
||||
sc->t[3].et.et_min_period =
|
||||
(0x00000002LLU << 32) / sc->t[3].et.et_frequency;
|
||||
sc->t[3].et.et_max_period =
|
||||
(0xfffffffeLLU << 32) / sc->t[3].et.et_frequency;
|
||||
sc->t[3].et.et_start = am335x_dmtimer_start;
|
||||
sc->t[3].et.et_stop = am335x_dmtimer_stop;
|
||||
sc->t[3].et.et_priv = &sc->t[3];
|
||||
|
@ -120,18 +120,15 @@ sp804_timer_tc_get_timecount(struct timecounter *tc)
|
||||
}
|
||||
|
||||
static int
|
||||
sp804_timer_start(struct eventtimer *et, struct bintime *first,
|
||||
struct bintime *period)
|
||||
sp804_timer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
|
||||
{
|
||||
struct sp804_timer_softc *sc = et->et_priv;
|
||||
uint32_t count, reg;
|
||||
|
||||
if (first != NULL) {
|
||||
if (first != 0) {
|
||||
sc->et_enabled = 1;
|
||||
|
||||
count = (sc->et.et_frequency * (first->frac >> 32)) >> 32;
|
||||
if (first->sec != 0)
|
||||
count += sc->et.et_frequency * first->sec;
|
||||
count = ((uint32_t)et->et_frequency * first) >> 32;
|
||||
|
||||
sp804_timer_tc_write_4(SP804_TIMER2_LOAD, count);
|
||||
reg = TIMER_CONTROL_32BIT | TIMER_CONTROL_INTREN |
|
||||
@ -142,7 +139,7 @@ sp804_timer_start(struct eventtimer *et, struct bintime *first,
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (period != NULL) {
|
||||
if (period != 0) {
|
||||
panic("period");
|
||||
}
|
||||
|
||||
@ -264,12 +261,8 @@ sp804_timer_attach(device_t dev)
|
||||
sc->et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT;
|
||||
sc->et.et_quality = 1000;
|
||||
sc->et.et_frequency = sc->sysclk_freq / DEFAULT_DIVISOR;
|
||||
sc->et.et_min_period.sec = 0;
|
||||
sc->et.et_min_period.frac =
|
||||
((0x00000002LLU << 32) / sc->et.et_frequency) << 32;
|
||||
sc->et.et_max_period.sec = 0xfffffff0U / sc->et.et_frequency;
|
||||
sc->et.et_max_period.frac =
|
||||
((0xfffffffeLLU << 32) / sc->et.et_frequency) << 32;
|
||||
sc->et.et_min_period = (0x00000002LLU << 32) / sc->et.et_frequency;
|
||||
sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
|
||||
sc->et.et_start = sp804_timer_start;
|
||||
sc->et.et_stop = sp804_timer_stop;
|
||||
sc->et.et_priv = sc;
|
||||
|
@ -147,8 +147,7 @@ hpet_disable(struct hpet_softc *sc)
|
||||
}
|
||||
|
||||
static int
|
||||
hpet_start(struct eventtimer *et,
|
||||
struct bintime *first, struct bintime *period)
|
||||
hpet_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
|
||||
{
|
||||
struct hpet_timer *mt = (struct hpet_timer *)et->et_priv;
|
||||
struct hpet_timer *t;
|
||||
@ -156,20 +155,16 @@ hpet_start(struct eventtimer *et,
|
||||
uint32_t fdiv, now;
|
||||
|
||||
t = (mt->pcpu_master < 0) ? mt : &sc->t[mt->pcpu_slaves[curcpu]];
|
||||
if (period != NULL) {
|
||||
if (period != 0) {
|
||||
t->mode = 1;
|
||||
t->div = (sc->freq * (period->frac >> 32)) >> 32;
|
||||
if (period->sec != 0)
|
||||
t->div += sc->freq * period->sec;
|
||||
t->div = (sc->freq * period) >> 32;
|
||||
} else {
|
||||
t->mode = 2;
|
||||
t->div = 0;
|
||||
}
|
||||
if (first != NULL) {
|
||||
fdiv = (sc->freq * (first->frac >> 32)) >> 32;
|
||||
if (first->sec != 0)
|
||||
fdiv += sc->freq * first->sec;
|
||||
} else
|
||||
if (first != 0)
|
||||
fdiv = (sc->freq * first) >> 32;
|
||||
else
|
||||
fdiv = t->div;
|
||||
if (t->irq < 0)
|
||||
bus_write_4(sc->mem_res, HPET_ISR, 1 << t->num);
|
||||
@ -684,12 +679,9 @@ hpet_attach(device_t dev)
|
||||
if ((t->caps & HPET_TCAP_PER_INT) == 0)
|
||||
t->et.et_quality -= 10;
|
||||
t->et.et_frequency = sc->freq;
|
||||
t->et.et_min_period.sec = 0;
|
||||
t->et.et_min_period.frac =
|
||||
(((uint64_t)(HPET_MIN_CYCLES * 2) << 32) / sc->freq) << 32;
|
||||
t->et.et_max_period.sec = 0xfffffffeLLU / sc->freq;
|
||||
t->et.et_max_period.frac =
|
||||
((0xfffffffeLLU << 32) / sc->freq) << 32;
|
||||
t->et.et_min_period =
|
||||
((uint64_t)(HPET_MIN_CYCLES * 2) << 32) / sc->freq;
|
||||
t->et.et_max_period = (0xfffffffeLLU << 32) / sc->freq;
|
||||
t->et.et_start = hpet_start;
|
||||
t->et.et_stop = hpet_stop;
|
||||
t->et.et_priv = &sc->t[i];
|
||||
|
@ -768,8 +768,7 @@ resettodr()
|
||||
#endif
|
||||
|
||||
static int
|
||||
xen_et_start(struct eventtimer *et,
|
||||
struct bintime *first, struct bintime *period)
|
||||
xen_et_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
|
||||
{
|
||||
struct xen_et_state *state = DPCPU_PTR(et_state);
|
||||
struct shadow_time_info *shadow;
|
||||
@ -777,21 +776,16 @@ xen_et_start(struct eventtimer *et,
|
||||
|
||||
__get_time_values_from_xen();
|
||||
|
||||
if (period != NULL) {
|
||||
if (period != 0) {
|
||||
state->mode = MODE_PERIODIC;
|
||||
state->period = (1000000000LL *
|
||||
(uint32_t)(period->frac >> 32)) >> 32;
|
||||
if (period->sec != 0)
|
||||
state->period += 1000000000LL * period->sec;
|
||||
state->period = (1000000000LLU * period) >> 32;
|
||||
} else {
|
||||
state->mode = MODE_ONESHOT;
|
||||
state->period = 0;
|
||||
}
|
||||
if (first != NULL) {
|
||||
fperiod = (1000000000LL * (uint32_t)(first->frac >> 32)) >> 32;
|
||||
if (first->sec != 0)
|
||||
fperiod += 1000000000LL * first->sec;
|
||||
} else
|
||||
if (first != 0)
|
||||
fperiod = (1000000000LLU * first) >> 32;
|
||||
else
|
||||
fperiod = state->period;
|
||||
|
||||
shadow = &per_cpu(shadow_time, smp_processor_id());
|
||||
@ -832,11 +826,9 @@ cpu_initclocks(void)
|
||||
xen_et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT |
|
||||
ET_FLAGS_PERCPU;
|
||||
xen_et.et_quality = 600;
|
||||
xen_et.et_frequency = 0;
|
||||
xen_et.et_min_period.sec = 0;
|
||||
xen_et.et_min_period.frac = 0x00400000LL << 32;
|
||||
xen_et.et_max_period.sec = 2;
|
||||
xen_et.et_max_period.frac = 0;
|
||||
xen_et.et_frequency = 1000000000;
|
||||
xen_et.et_min_period = 0x00400000LL;
|
||||
xen_et.et_max_period = (0xfffffffeLLU << 32) / xen_et.et_frequency;
|
||||
xen_et.et_start = xen_et_start;
|
||||
xen_et.et_stop = xen_et_stop;
|
||||
xen_et.et_priv = NULL;
|
||||
|
@ -105,17 +105,14 @@ ia64_ih_clock(struct thread *td, u_int xiv, struct trapframe *tf)
|
||||
* Event timer start method.
|
||||
*/
|
||||
static int
|
||||
ia64_clock_start(struct eventtimer *et, struct bintime *first,
|
||||
struct bintime *period)
|
||||
ia64_clock_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
|
||||
{
|
||||
u_long itc, load;
|
||||
register_t is;
|
||||
|
||||
if (period != NULL) {
|
||||
if (period != 0) {
|
||||
PCPU_SET(md.clock_mode, CLOCK_ET_PERIODIC);
|
||||
load = (et->et_frequency * (period->frac >> 32)) >> 32;
|
||||
if (period->sec > 0)
|
||||
load += et->et_frequency * period->sec;
|
||||
load = (et->et_frequency * period) >> 32;
|
||||
} else {
|
||||
PCPU_SET(md.clock_mode, CLOCK_ET_ONESHOT);
|
||||
load = 0;
|
||||
@ -123,11 +120,8 @@ ia64_clock_start(struct eventtimer *et, struct bintime *first,
|
||||
|
||||
PCPU_SET(md.clock_load, load);
|
||||
|
||||
if (first != NULL) {
|
||||
load = (et->et_frequency * (first->frac >> 32)) >> 32;
|
||||
if (first->sec > 0)
|
||||
load += et->et_frequency * first->sec;
|
||||
}
|
||||
if (first != 0)
|
||||
load = (et->et_frequency * first) >> 32;
|
||||
|
||||
is = intr_disable();
|
||||
itc = ia64_get_itc();
|
||||
@ -185,10 +179,8 @@ clock_configure(void *dummy)
|
||||
et->et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_ONESHOT | ET_FLAGS_PERCPU;
|
||||
et->et_quality = 1000;
|
||||
et->et_frequency = itc_freq;
|
||||
et->et_min_period.sec = 0;
|
||||
et->et_min_period.frac = (0x8000000000000000ul / (u_long)(10*hz)) << 1;
|
||||
et->et_max_period.sec = 0xffffffff;
|
||||
et->et_max_period.frac = ((0xfffffffeul << 32) / itc_freq) << 32;
|
||||
et->et_min_period = SBT_1S / (10 * hz);
|
||||
et->et_max_period = (0xfffffffeul << 32) / itc_freq;
|
||||
et->et_start = ia64_clock_start;
|
||||
et->et_stop = ia64_clock_stop;
|
||||
et->et_priv = NULL;
|
||||
|
@ -153,6 +153,8 @@ static DPCPU_DEFINE(struct pcpu_state, timerstate);
|
||||
(((uint64_t)0x8000000000000000 + ((bt)->frac >> 2)) / \
|
||||
((bt)->frac >> 1))
|
||||
|
||||
#define SBT2FREQ(sbt) ((SBT_1S + ((sbt) >> 1)) / (sbt))
|
||||
|
||||
/*
|
||||
* Timer broadcast IPI handler.
|
||||
*/
|
||||
@ -442,7 +444,7 @@ loadtimer(struct bintime *now, int start)
|
||||
new.sec, (u_int)(new.frac >> 32));
|
||||
*next = new;
|
||||
bintime_add(next, now);
|
||||
et_start(timer, &new, &timerperiod);
|
||||
et_start(timer, bttosbt(new), bttosbt(timerperiod));
|
||||
}
|
||||
} else {
|
||||
getnextevent(&new);
|
||||
@ -454,7 +456,7 @@ loadtimer(struct bintime *now, int start)
|
||||
if (!eq) {
|
||||
*next = new;
|
||||
bintime_sub(&new, now);
|
||||
et_start(timer, &new, NULL);
|
||||
et_start(timer, bttosbt(new), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -603,13 +605,13 @@ round_freq(struct eventtimer *et, int freq)
|
||||
div = 1 << (flsl(div + div / 2) - 1);
|
||||
freq = (et->et_frequency + div / 2) / div;
|
||||
}
|
||||
if (et->et_min_period.sec > 0)
|
||||
if (et->et_min_period > SBT_1S)
|
||||
panic("Event timer \"%s\" doesn't support sub-second periods!",
|
||||
et->et_name);
|
||||
else if (et->et_min_period.frac != 0)
|
||||
freq = min(freq, BT2FREQ(&et->et_min_period));
|
||||
if (et->et_max_period.sec == 0 && et->et_max_period.frac != 0)
|
||||
freq = max(freq, BT2FREQ(&et->et_max_period));
|
||||
else if (et->et_min_period != 0)
|
||||
freq = min(freq, SBT2FREQ(et->et_min_period));
|
||||
if (et->et_max_period < SBT_1S && et->et_max_period != 0)
|
||||
freq = max(freq, SBT2FREQ(et->et_max_period));
|
||||
return (freq);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2010 Alexander Motin <mav@FreeBSD.org>
|
||||
* Copyright (c) 2010-2013 Alexander Motin <mav@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -62,6 +62,7 @@ et_register(struct eventtimer *et)
|
||||
et->et_quality);
|
||||
}
|
||||
}
|
||||
KASSERT(et->et_start, ("et_register: timer has no start function"));
|
||||
et->et_sysctl = SYSCTL_ADD_NODE(NULL,
|
||||
SYSCTL_STATIC_CHILDREN(_kern_eventtimer_et), OID_AUTO, et->et_name,
|
||||
CTLFLAG_RW, 0, "event timer description");
|
||||
@ -159,43 +160,29 @@ et_init(struct eventtimer *et, et_event_cb_t *event,
|
||||
* period - period of subsequent periodic ticks.
|
||||
*/
|
||||
int
|
||||
et_start(struct eventtimer *et,
|
||||
struct bintime *first, struct bintime *period)
|
||||
et_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
|
||||
{
|
||||
|
||||
if (!et->et_active)
|
||||
return (ENXIO);
|
||||
if (first == NULL && period == NULL)
|
||||
return (EINVAL);
|
||||
if ((et->et_flags & ET_FLAGS_PERIODIC) == 0 &&
|
||||
period != NULL)
|
||||
return (ENODEV);
|
||||
if ((et->et_flags & ET_FLAGS_ONESHOT) == 0 &&
|
||||
period == NULL)
|
||||
return (ENODEV);
|
||||
if (first != NULL) {
|
||||
if (first->sec < et->et_min_period.sec ||
|
||||
(first->sec == et->et_min_period.sec &&
|
||||
first->frac < et->et_min_period.frac))
|
||||
first = &et->et_min_period;
|
||||
if (first->sec > et->et_max_period.sec ||
|
||||
(first->sec == et->et_max_period.sec &&
|
||||
first->frac > et->et_max_period.frac))
|
||||
first = &et->et_max_period;
|
||||
KASSERT(period >= 0, ("et_start: negative period"));
|
||||
KASSERT((et->et_flags & ET_FLAGS_PERIODIC) || period == 0,
|
||||
("et_start: period specified for oneshot-only timer"));
|
||||
KASSERT((et->et_flags & ET_FLAGS_ONESHOT) && period == 0,
|
||||
("et_start: period not specified for periodic-only timer"));
|
||||
if (period != 0) {
|
||||
if (period < et->et_min_period)
|
||||
period = et->et_min_period;
|
||||
else if (period > et->et_max_period)
|
||||
period = et->et_max_period;
|
||||
}
|
||||
if (period != NULL) {
|
||||
if (period->sec < et->et_min_period.sec ||
|
||||
(period->sec == et->et_min_period.sec &&
|
||||
period->frac < et->et_min_period.frac))
|
||||
period = &et->et_min_period;
|
||||
if (period->sec > et->et_max_period.sec ||
|
||||
(period->sec == et->et_max_period.sec &&
|
||||
period->frac > et->et_max_period.frac))
|
||||
period = &et->et_max_period;
|
||||
if (period == 0 || first != 0) {
|
||||
if (first < et->et_min_period)
|
||||
first = et->et_min_period;
|
||||
else if (first > et->et_max_period)
|
||||
first = et->et_max_period;
|
||||
}
|
||||
if (et->et_start)
|
||||
return (et->et_start(et, first, period));
|
||||
return (0);
|
||||
return (et->et_start(et, first, period));
|
||||
}
|
||||
|
||||
/* Stop event timer hardware. */
|
||||
|
@ -217,22 +217,17 @@ DELAY(int n)
|
||||
}
|
||||
|
||||
static int
|
||||
clock_start(struct eventtimer *et,
|
||||
struct bintime *first, struct bintime *period)
|
||||
clock_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
|
||||
{
|
||||
uint32_t fdiv, div, next;
|
||||
|
||||
if (period != NULL) {
|
||||
div = (et->et_frequency * (period->frac >> 32)) >> 32;
|
||||
if (period->sec != 0)
|
||||
div += et->et_frequency * period->sec;
|
||||
if (period != 0) {
|
||||
div = (et->et_frequency * period) >> 32;
|
||||
} else
|
||||
div = 0;
|
||||
if (first != NULL) {
|
||||
fdiv = (et->et_frequency * (first->frac >> 32)) >> 32;
|
||||
if (first->sec != 0)
|
||||
fdiv += et->et_frequency * first->sec;
|
||||
} else
|
||||
if (first != 0)
|
||||
fdiv = (et->et_frequency * first) >> 32;
|
||||
else
|
||||
fdiv = div;
|
||||
DPCPU_SET(cycles_per_tick, div);
|
||||
next = mips_rd_count() + fdiv;
|
||||
@ -361,11 +356,8 @@ clock_attach(device_t dev)
|
||||
ET_FLAGS_PERCPU;
|
||||
sc->et.et_quality = 800;
|
||||
sc->et.et_frequency = counter_freq;
|
||||
sc->et.et_min_period.sec = 0;
|
||||
sc->et.et_min_period.frac = 0x00004000LLU << 32; /* To be safe. */
|
||||
sc->et.et_max_period.sec = 0xfffffffeU / sc->et.et_frequency;
|
||||
sc->et.et_max_period.frac =
|
||||
((0xfffffffeLLU << 32) / sc->et.et_frequency) << 32;
|
||||
sc->et.et_min_period = 0x00004000LLU; /* To be safe. */
|
||||
sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
|
||||
sc->et.et_start = clock_start;
|
||||
sc->et.et_stop = clock_stop;
|
||||
sc->et.et_priv = sc;
|
||||
|
@ -222,22 +222,17 @@ DELAY(int n)
|
||||
}
|
||||
|
||||
static int
|
||||
clock_start(struct eventtimer *et,
|
||||
struct bintime *first, struct bintime *period)
|
||||
clock_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
|
||||
{
|
||||
uint32_t fdiv, div, next;
|
||||
|
||||
if (period != NULL) {
|
||||
div = (et->et_frequency * (period->frac >> 32)) >> 32;
|
||||
if (period->sec != 0)
|
||||
div += et->et_frequency * period->sec;
|
||||
} else
|
||||
if (period != 0)
|
||||
div = (et->et_frequency * period) >> 32;
|
||||
else
|
||||
div = 0;
|
||||
if (first != NULL) {
|
||||
fdiv = (et->et_frequency * (first->frac >> 32)) >> 32;
|
||||
if (first->sec != 0)
|
||||
fdiv += et->et_frequency * first->sec;
|
||||
} else
|
||||
if (first != 0)
|
||||
fdiv = (et->et_frequency * first) >> 32;
|
||||
else
|
||||
fdiv = div;
|
||||
DPCPU_SET(cycles_per_tick, div);
|
||||
next = mips_rd_count() + fdiv;
|
||||
@ -357,11 +352,8 @@ clock_attach(device_t dev)
|
||||
sc->et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_PERCPU;
|
||||
sc->et.et_quality = 800;
|
||||
sc->et.et_frequency = counter_freq;
|
||||
sc->et.et_min_period.sec = 0;
|
||||
sc->et.et_min_period.frac = 0x00004000LLU << 32; /* To be safe. */
|
||||
sc->et.et_max_period.sec = 0xfffffffeU / sc->et.et_frequency;
|
||||
sc->et.et_max_period.frac =
|
||||
((0xfffffffeLLU << 32) / sc->et.et_frequency) << 32;
|
||||
sc->et.et_min_period = 0x00004000LLU; /* To be safe. */
|
||||
sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
|
||||
sc->et.et_start = clock_start;
|
||||
sc->et.et_stop = clock_stop;
|
||||
sc->et.et_priv = sc;
|
||||
|
@ -219,22 +219,17 @@ DELAY(int n)
|
||||
}
|
||||
|
||||
static int
|
||||
clock_start(struct eventtimer *et,
|
||||
struct bintime *first, struct bintime *period)
|
||||
clock_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
|
||||
{
|
||||
uint32_t fdiv, div, next;
|
||||
|
||||
if (period != NULL) {
|
||||
div = (et->et_frequency * (period->frac >> 32)) >> 32;
|
||||
if (period->sec != 0)
|
||||
div += et->et_frequency * period->sec;
|
||||
} else
|
||||
if (period != 0)
|
||||
div = (et->et_frequency * period) >> 32;
|
||||
else
|
||||
div = 0;
|
||||
if (first != NULL) {
|
||||
fdiv = (et->et_frequency * (first->frac >> 32)) >> 32;
|
||||
if (first->sec != 0)
|
||||
fdiv += et->et_frequency * first->sec;
|
||||
} else
|
||||
if (first != 0)
|
||||
fdiv = (et->et_frequency * first) >> 32;
|
||||
else
|
||||
fdiv = div;
|
||||
DPCPU_SET(cycles_per_tick, div);
|
||||
next = mips_rd_count() + fdiv;
|
||||
@ -351,11 +346,8 @@ clock_attach(device_t dev)
|
||||
ET_FLAGS_PERCPU;
|
||||
sc->et.et_quality = 800;
|
||||
sc->et.et_frequency = counter_freq;
|
||||
sc->et.et_min_period.sec = 0;
|
||||
sc->et.et_min_period.frac = 0x00004000LLU << 32; /* To be safe. */
|
||||
sc->et.et_max_period.sec = 0xfffffffeU / sc->et.et_frequency;
|
||||
sc->et.et_max_period.frac =
|
||||
((0xfffffffeLLU << 32) / sc->et.et_frequency) << 32;
|
||||
sc->et.et_min_period = 0x00004000LLU; /* To be safe. */
|
||||
sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
|
||||
sc->et.et_start = clock_start;
|
||||
sc->et.et_stop = clock_stop;
|
||||
sc->et.et_priv = sc;
|
||||
|
@ -85,7 +85,7 @@ static u_long ticks_per_sec = 12500000;
|
||||
static u_long *decr_counts[MAXCPU];
|
||||
|
||||
static int decr_et_start(struct eventtimer *et,
|
||||
struct bintime *first, struct bintime *period);
|
||||
sbintime_t first, sbintime_t period);
|
||||
static int decr_et_stop(struct eventtimer *et);
|
||||
static timecounter_get_t decr_get_timecount;
|
||||
|
||||
@ -195,12 +195,8 @@ decr_tc_init(void)
|
||||
ET_FLAGS_PERCPU;
|
||||
decr_et.et_quality = 1000;
|
||||
decr_et.et_frequency = ticks_per_sec;
|
||||
decr_et.et_min_period.sec = 0;
|
||||
decr_et.et_min_period.frac =
|
||||
((0x00000002LLU << 32) / ticks_per_sec) << 32;
|
||||
decr_et.et_max_period.sec = 0x7fffffffLLU / ticks_per_sec;
|
||||
decr_et.et_max_period.frac =
|
||||
((0x7fffffffLLU << 32) / ticks_per_sec) << 32;
|
||||
decr_et.et_min_period = (0x00000002LLU << 32) / ticks_per_sec;
|
||||
decr_et.et_max_period = (0x7fffffffLLU << 32) / ticks_per_sec;
|
||||
decr_et.et_start = decr_et_start;
|
||||
decr_et.et_stop = decr_et_stop;
|
||||
decr_et.et_priv = NULL;
|
||||
@ -212,24 +208,20 @@ decr_tc_init(void)
|
||||
*/
|
||||
static int
|
||||
decr_et_start(struct eventtimer *et,
|
||||
struct bintime *first, struct bintime *period)
|
||||
sbintime_t first, sbintime_t period)
|
||||
{
|
||||
struct decr_state *s = DPCPU_PTR(decr_state);
|
||||
uint32_t fdiv;
|
||||
|
||||
if (period != NULL) {
|
||||
if (period != 0) {
|
||||
s->mode = 1;
|
||||
s->div = (decr_et.et_frequency * (period->frac >> 32)) >> 32;
|
||||
if (period->sec != 0)
|
||||
s->div += decr_et.et_frequency * period->sec;
|
||||
s->div = (decr_et.et_frequency * period) >> 32;
|
||||
} else {
|
||||
s->mode = 2;
|
||||
s->div = 0x7fffffff;
|
||||
s->div = 0;
|
||||
}
|
||||
if (first != NULL) {
|
||||
fdiv = (decr_et.et_frequency * (first->frac >> 32)) >> 32;
|
||||
if (first->sec != 0)
|
||||
fdiv += decr_et.et_frequency * first->sec;
|
||||
if (first != 0) {
|
||||
fdiv = (decr_et.et_frequency * first) >> 32;
|
||||
} else
|
||||
fdiv = s->div;
|
||||
|
||||
|
@ -88,7 +88,7 @@ static u_long *decr_counts[MAXCPU];
|
||||
#define DIFF19041970 2082844800
|
||||
|
||||
static int decr_et_start(struct eventtimer *et,
|
||||
struct bintime *first, struct bintime *period);
|
||||
sbintime_t first, sbintime_t period);
|
||||
static int decr_et_stop(struct eventtimer *et);
|
||||
static timecounter_get_t decr_get_timecount;
|
||||
|
||||
@ -193,12 +193,8 @@ decr_tc_init(void)
|
||||
ET_FLAGS_PERCPU;
|
||||
decr_et.et_quality = 1000;
|
||||
decr_et.et_frequency = ticks_per_sec;
|
||||
decr_et.et_min_period.sec = 0;
|
||||
decr_et.et_min_period.frac =
|
||||
((0x00000002LLU << 32) / ticks_per_sec) << 32;
|
||||
decr_et.et_max_period.sec = 0xfffffffeLLU / ticks_per_sec;
|
||||
decr_et.et_max_period.frac =
|
||||
((0xfffffffeLLU << 32) / ticks_per_sec) << 32;
|
||||
decr_et.et_min_period = (0x00000002LLU << 32) / ticks_per_sec;
|
||||
decr_et.et_max_period = (0xfffffffeLLU << 32) / ticks_per_sec;
|
||||
decr_et.et_start = decr_et_start;
|
||||
decr_et.et_stop = decr_et_stop;
|
||||
decr_et.et_priv = NULL;
|
||||
@ -209,26 +205,21 @@ decr_tc_init(void)
|
||||
* Event timer start method.
|
||||
*/
|
||||
static int
|
||||
decr_et_start(struct eventtimer *et,
|
||||
struct bintime *first, struct bintime *period)
|
||||
decr_et_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
|
||||
{
|
||||
struct decr_state *s = DPCPU_PTR(decr_state);
|
||||
uint32_t fdiv, tcr;
|
||||
|
||||
if (period != NULL) {
|
||||
if (period != 0) {
|
||||
s->mode = 1;
|
||||
s->div = (decr_et.et_frequency * (period->frac >> 32)) >> 32;
|
||||
if (period->sec != 0)
|
||||
s->div += decr_et.et_frequency * period->sec;
|
||||
s->div = (decr_et.et_frequency * period) >> 32;
|
||||
} else {
|
||||
s->mode = 2;
|
||||
s->div = 0xffffffff;
|
||||
s->div = 0;
|
||||
}
|
||||
if (first != NULL) {
|
||||
fdiv = (decr_et.et_frequency * (first->frac >> 32)) >> 32;
|
||||
if (first->sec != 0)
|
||||
fdiv += decr_et.et_frequency * first->sec;
|
||||
} else
|
||||
if (first != 0)
|
||||
fdiv = (decr_et.et_frequency * first) >> 32;
|
||||
else
|
||||
fdiv = s->div;
|
||||
|
||||
tcr = mfspr(SPR_TCR);
|
||||
|
@ -93,8 +93,8 @@ static timecounter_get_t stick_get_timecount_mp;
|
||||
static timecounter_get_t stick_get_timecount_up;
|
||||
static rd_tick_t stick_rd;
|
||||
static wr_tick_cmpr_t stick_wr_cmpr;
|
||||
static int tick_et_start(struct eventtimer *et, struct bintime *first,
|
||||
struct bintime *period);
|
||||
static int tick_et_start(struct eventtimer *et, sbintime_t first,
|
||||
sbintime_t period);
|
||||
static int tick_et_stop(struct eventtimer *et);
|
||||
#ifdef SMP
|
||||
static timecounter_get_t tick_get_timecount_mp;
|
||||
@ -227,10 +227,8 @@ cpu_initclocks(void)
|
||||
ET_FLAGS_PERCPU;
|
||||
tick_et.et_quality = 1000;
|
||||
tick_et.et_frequency = tick_et_use_stick ? sclock : clock;
|
||||
tick_et.et_min_period.sec = 0;
|
||||
tick_et.et_min_period.frac = 0x00010000LLU << 32; /* To be safe. */
|
||||
tick_et.et_max_period.sec = 3600 * 24; /* No practical limit. */
|
||||
tick_et.et_max_period.frac = 0;
|
||||
tick_et.et_min_period = 0x00010000LLU; /* To be safe. */
|
||||
tick_et.et_max_period = (0xfffffffeLLU << 32) / tick_et.et_frequency;
|
||||
tick_et.et_start = tick_et_start;
|
||||
tick_et.et_stop = tick_et_stop;
|
||||
tick_et.et_priv = NULL;
|
||||
@ -355,23 +353,18 @@ tick_get_timecount_mp(struct timecounter *tc)
|
||||
#endif
|
||||
|
||||
static int
|
||||
tick_et_start(struct eventtimer *et, struct bintime *first,
|
||||
struct bintime *period)
|
||||
tick_et_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
|
||||
{
|
||||
u_long base, div, fdiv;
|
||||
register_t s;
|
||||
|
||||
if (period != NULL) {
|
||||
div = (tick_et.et_frequency * (period->frac >> 32)) >> 32;
|
||||
if (period->sec != 0)
|
||||
div += tick_et.et_frequency * period->sec;
|
||||
} else
|
||||
if (period != 0)
|
||||
div = (tick_et.et_frequency * period) >> 32;
|
||||
else
|
||||
div = 0;
|
||||
if (first != NULL) {
|
||||
fdiv = (tick_et.et_frequency * (first->frac >> 32)) >> 32;
|
||||
if (first->sec != 0)
|
||||
fdiv += tick_et.et_frequency * first->sec;
|
||||
} else
|
||||
if (first != 0)
|
||||
fdiv = (tick_et.et_frequency * first) >> 32;
|
||||
else
|
||||
fdiv = div;
|
||||
PCPU_SET(tickincrement, div);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2010 Alexander Motin <mav@FreeBSD.org>
|
||||
* Copyright (c) 2010-2013 Alexander Motin <mav@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -45,7 +45,7 @@
|
||||
|
||||
struct eventtimer;
|
||||
typedef int et_start_t(struct eventtimer *et,
|
||||
struct bintime *first, struct bintime *period);
|
||||
sbintime_t first, sbintime_t period);
|
||||
typedef int et_stop_t(struct eventtimer *et);
|
||||
typedef void et_event_cb_t(struct eventtimer *et, void *arg);
|
||||
typedef int et_deregister_cb_t(struct eventtimer *et, void *arg);
|
||||
@ -70,8 +70,8 @@ struct eventtimer {
|
||||
int et_active;
|
||||
u_int64_t et_frequency;
|
||||
/* Base frequency in Hz. */
|
||||
struct bintime et_min_period;
|
||||
struct bintime et_max_period;
|
||||
sbintime_t et_min_period;
|
||||
sbintime_t et_max_period;
|
||||
et_start_t *et_start;
|
||||
et_stop_t *et_stop;
|
||||
et_event_cb_t *et_event_cb;
|
||||
@ -93,8 +93,7 @@ int et_deregister(struct eventtimer *et);
|
||||
struct eventtimer *et_find(const char *name, int check, int want);
|
||||
int et_init(struct eventtimer *et, et_event_cb_t *event,
|
||||
et_deregister_cb_t *deregister, void *arg);
|
||||
int et_start(struct eventtimer *et,
|
||||
struct bintime *first, struct bintime *period);
|
||||
int et_start(struct eventtimer *et, sbintime_t first, sbintime_t period);
|
||||
int et_stop(struct eventtimer *et);
|
||||
int et_ban(struct eventtimer *et);
|
||||
int et_free(struct eventtimer *et);
|
||||
|
@ -164,11 +164,10 @@ struct atrtc_softc {
|
||||
};
|
||||
|
||||
static int
|
||||
rtc_start(struct eventtimer *et,
|
||||
struct bintime *first, struct bintime *period)
|
||||
rtc_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
|
||||
{
|
||||
|
||||
atrtc_rate(max(fls((period->frac + (period->frac >> 1)) >> 32) - 17, 1));
|
||||
atrtc_rate(max(fls(period + (period >> 1)) - 17, 1));
|
||||
atrtc_enable_intr();
|
||||
return (0);
|
||||
}
|
||||
@ -277,10 +276,8 @@ atrtc_attach(device_t dev)
|
||||
sc->et.et_flags = ET_FLAGS_PERIODIC | ET_FLAGS_POW2DIV;
|
||||
sc->et.et_quality = 0;
|
||||
sc->et.et_frequency = 32768;
|
||||
sc->et.et_min_period.sec = 0;
|
||||
sc->et.et_min_period.frac = 0x0008LLU << 48;
|
||||
sc->et.et_max_period.sec = 0;
|
||||
sc->et.et_max_period.frac = 0x8000LLU << 48;
|
||||
sc->et.et_min_period = 0x00080000;
|
||||
sc->et.et_max_period = 0x80000000;
|
||||
sc->et.et_start = rtc_start;
|
||||
sc->et.et_stop = rtc_stop;
|
||||
sc->et.et_priv = dev;
|
||||
|
@ -589,18 +589,17 @@ i8254_get_timecount(struct timecounter *tc)
|
||||
}
|
||||
|
||||
static int
|
||||
attimer_start(struct eventtimer *et,
|
||||
struct bintime *first, struct bintime *period)
|
||||
attimer_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
|
||||
{
|
||||
device_t dev = (device_t)et->et_priv;
|
||||
struct attimer_softc *sc = device_get_softc(dev);
|
||||
|
||||
if (period != NULL) {
|
||||
if (period != 0) {
|
||||
sc->mode = MODE_PERIODIC;
|
||||
sc->period = period->frac >> 32;
|
||||
sc->period = period;
|
||||
} else {
|
||||
sc->mode = MODE_ONESHOT;
|
||||
sc->period = first->frac >> 32;
|
||||
sc->period = first;
|
||||
}
|
||||
if (!sc->intr_en) {
|
||||
i8254_intsrc->is_pic->pic_enable_source(i8254_intsrc);
|
||||
@ -755,12 +754,8 @@ attimer_attach(device_t dev)
|
||||
sc->et.et_flags |= ET_FLAGS_ONESHOT;
|
||||
sc->et.et_quality = 100;
|
||||
sc->et.et_frequency = i8254_freq;
|
||||
sc->et.et_min_period.sec = 0;
|
||||
sc->et.et_min_period.frac =
|
||||
((0x0002LLU << 48) / i8254_freq) << 16;
|
||||
sc->et.et_max_period.sec = 0xffff / i8254_freq;
|
||||
sc->et.et_max_period.frac =
|
||||
((0xfffeLLU << 48) / i8254_freq) << 16;
|
||||
sc->et.et_min_period = (0x0002LLU << 32) / i8254_freq;
|
||||
sc->et.et_max_period = (0xfffeLLU << 32) / i8254_freq;
|
||||
sc->et.et_start = attimer_start;
|
||||
sc->et.et_stop = attimer_stop;
|
||||
sc->et.et_priv = dev;
|
||||
|
@ -169,7 +169,7 @@ static void lapic_timer_stop(struct lapic *);
|
||||
static void lapic_timer_set_divisor(u_int divisor);
|
||||
static uint32_t lvt_mode(struct lapic *la, u_int pin, uint32_t value);
|
||||
static int lapic_et_start(struct eventtimer *et,
|
||||
struct bintime *first, struct bintime *period);
|
||||
sbintime_t first, sbintime_t period);
|
||||
static int lapic_et_stop(struct eventtimer *et);
|
||||
|
||||
struct pic lapic_pic = { .pic_resume = lapic_resume };
|
||||
@ -268,10 +268,8 @@ lapic_init(vm_paddr_t addr)
|
||||
}
|
||||
lapic_et.et_frequency = 0;
|
||||
/* We don't know frequency yet, so trying to guess. */
|
||||
lapic_et.et_min_period.sec = 0;
|
||||
lapic_et.et_min_period.frac = 0x00001000LL << 32;
|
||||
lapic_et.et_max_period.sec = 1;
|
||||
lapic_et.et_max_period.frac = 0;
|
||||
lapic_et.et_min_period = 0x00001000LL;
|
||||
lapic_et.et_max_period = SBT_1S;
|
||||
lapic_et.et_start = lapic_et_start;
|
||||
lapic_et.et_stop = lapic_et_stop;
|
||||
lapic_et.et_priv = NULL;
|
||||
@ -487,8 +485,7 @@ lapic_disable_pmc(void)
|
||||
}
|
||||
|
||||
static int
|
||||
lapic_et_start(struct eventtimer *et,
|
||||
struct bintime *first, struct bintime *period)
|
||||
lapic_et_start(struct eventtimer *et, sbintime_t first, sbintime_t period)
|
||||
{
|
||||
struct lapic *la;
|
||||
u_long value;
|
||||
@ -513,28 +510,18 @@ lapic_et_start(struct eventtimer *et,
|
||||
printf("lapic: Divisor %lu, Frequency %lu Hz\n",
|
||||
lapic_timer_divisor, value);
|
||||
et->et_frequency = value;
|
||||
et->et_min_period.sec = 0;
|
||||
et->et_min_period.frac =
|
||||
((0x00000002LLU << 32) / et->et_frequency) << 32;
|
||||
et->et_max_period.sec = 0xfffffffeLLU / et->et_frequency;
|
||||
et->et_max_period.frac =
|
||||
((0xfffffffeLLU << 32) / et->et_frequency) << 32;
|
||||
et->et_min_period = (0x00000002LLU << 32) / et->et_frequency;
|
||||
et->et_max_period = (0xfffffffeLLU << 32) / et->et_frequency;
|
||||
}
|
||||
if (la->la_timer_mode == 0)
|
||||
lapic_timer_set_divisor(lapic_timer_divisor);
|
||||
if (period != NULL) {
|
||||
if (period != 0) {
|
||||
la->la_timer_mode = 1;
|
||||
la->la_timer_period =
|
||||
(et->et_frequency * (period->frac >> 32)) >> 32;
|
||||
if (period->sec != 0)
|
||||
la->la_timer_period += et->et_frequency * period->sec;
|
||||
la->la_timer_period = ((uint32_t)et->et_frequency * period) >> 32;
|
||||
lapic_timer_periodic(la, la->la_timer_period, 1);
|
||||
} else {
|
||||
la->la_timer_mode = 2;
|
||||
la->la_timer_period =
|
||||
(et->et_frequency * (first->frac >> 32)) >> 32;
|
||||
if (first->sec != 0)
|
||||
la->la_timer_period += et->et_frequency * first->sec;
|
||||
la->la_timer_period = ((uint32_t)et->et_frequency * first) >> 32;
|
||||
lapic_timer_oneshot(la, la->la_timer_period, 1);
|
||||
}
|
||||
return (0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user