Shuffle the code to be more readable. Simplify.
This commit is contained in:
parent
7ef52537c9
commit
5f93873eda
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: timer_msiiep.c,v 1.15 2005/09/23 23:22:57 uwe Exp $ */
|
||||
/* $NetBSD: timer_msiiep.c,v 1.16 2005/09/24 00:35:08 uwe Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -58,7 +58,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: timer_msiiep.c,v 1.15 2005/09/23 23:22:57 uwe Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: timer_msiiep.c,v 1.16 2005/09/24 00:35:08 uwe Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
|
@ -67,21 +67,98 @@ __KERNEL_RCSID(0, "$NetBSD: timer_msiiep.c,v 1.15 2005/09/23 23:22:57 uwe Exp $"
|
|||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <sparc/sparc/timerreg.h>
|
||||
#include <sparc/sparc/timervar.h>
|
||||
|
||||
#include <sparc/sparc/msiiepreg.h>
|
||||
#include <sparc/sparc/msiiepvar.h>
|
||||
|
||||
static struct intrhand level10;
|
||||
static struct intrhand level14;
|
||||
#include <sparc/sparc/timervar.h>
|
||||
|
||||
|
||||
static int timermatch_msiiep(struct device *, struct cfdata *, void *);
|
||||
static void timerattach_msiiep(struct device *, struct device *, void *);
|
||||
|
||||
CFATTACH_DECL(timer_msiiep, sizeof(struct device),
|
||||
timermatch_msiiep, timerattach_msiiep, NULL, NULL);
|
||||
|
||||
|
||||
static void timer_init_msiiep(void);
|
||||
static int clockintr_msiiep(void *);
|
||||
static int statintr_msiiep(void *);
|
||||
|
||||
static struct intrhand level10 = { .ih_fun = clockintr_msiiep };
|
||||
static struct intrhand level14 = { .ih_fun = statintr_msiiep };
|
||||
|
||||
|
||||
/*
|
||||
* ms-IIep counters tick every 4 CPU clock @100MHz.
|
||||
* ms-IIep counters tick every 4 CPU clocks @100MHz.
|
||||
* counter is reset to 1 when new limit is written.
|
||||
*/
|
||||
#define tmr_ustolimIIep(n) ((n) * 25 + 1)
|
||||
|
||||
|
||||
static int
|
||||
timermatch_msiiep(struct device *parent, struct cfdata *cf, void *aux)
|
||||
{
|
||||
struct msiiep_attach_args *msa = aux;
|
||||
|
||||
return (strcmp(msa->msa_name, "timer") == 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Attach system and processor counters (kernel hard and stat clocks)
|
||||
* for ms-IIep. Counters are part of the PCIC and there's no PROM
|
||||
* node for them.
|
||||
*/
|
||||
static void
|
||||
timerattach_msiiep(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
|
||||
/* Put processor counter in "counter" mode */
|
||||
mspcic_write_1(pcic_pc_ctl, 0); /* stop user timer (just in case) */
|
||||
mspcic_write_1(pcic_pc_cfg, 0); /* timer mode disabled */
|
||||
|
||||
/*
|
||||
* Calibrate delay() by tweaking the magic constant until
|
||||
* delay(100) actually reads (at least) 100 us on the clock.
|
||||
*/
|
||||
for (timerblurb = 1; ; ++timerblurb) {
|
||||
int t;
|
||||
|
||||
mspcic_read_4(pcic_pclr); /* clear the limit bit */
|
||||
mspcic_write_4(pcic_pclr, 0); /* reset to 1, free run */
|
||||
delay(100);
|
||||
t = mspcic_read_4(pcic_pccr);
|
||||
|
||||
if (t < 0) /* limit bit set, cannot happen */
|
||||
panic("delay calibration");
|
||||
|
||||
if (t >= 2501) /* (t - 1) / 25 >= 100 us */
|
||||
break;
|
||||
}
|
||||
printf(": delay constant %d\n", timerblurb);
|
||||
|
||||
timer_init = timer_init_msiiep;
|
||||
|
||||
/*
|
||||
* Set counter interrupt priority assignment:
|
||||
* upper 4 bits are for system counter: level 10
|
||||
* lower 4 bits are for processor counter: level 14
|
||||
*
|
||||
* XXX: ensure that interrupt target mask doesn't mask them?
|
||||
*/
|
||||
mspcic_write_1(pcic_cipar, 0xae);
|
||||
|
||||
/* link interrupt handlers */
|
||||
intr_establish(10, 0, &level10, NULL);
|
||||
intr_establish(14, 0, &level14, NULL);
|
||||
|
||||
/* Establish a soft interrupt at a lower level for schedclock */
|
||||
sched_cookie = softintr_establish(IPL_SCHED, schedintr, NULL);
|
||||
if (sched_cookie == NULL)
|
||||
panic("timerattach: cannot establish schedintr");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Set up the real-time and statistics clocks.
|
||||
* Leave stathz 0 only if no alternative timer is available.
|
||||
|
@ -92,12 +169,11 @@ static void
|
|||
timer_init_msiiep(void)
|
||||
{
|
||||
|
||||
/* ms-IIep kernels support *only* IIep */
|
||||
mspcic_write_4(pcic_sclr, tmr_ustolimIIep(tick));
|
||||
mspcic_write_4(pcic_pclr, tmr_ustolimIIep(statint));
|
||||
/* XXX: ensure interrupt target mask doesn't masks them? */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Level 10 (clock) interrupts from system counter.
|
||||
*/
|
||||
|
@ -105,12 +181,12 @@ static int
|
|||
clockintr_msiiep(void *cap)
|
||||
{
|
||||
|
||||
/* read the limit register to clear the interrupt */
|
||||
mspcic_read_4(pcic_sclr);
|
||||
mspcic_read_4(pcic_sclr); /* clear the interrupt */
|
||||
hardclock((struct clockframe *)cap);
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Level 14 (stat clock) interrupts from processor counter.
|
||||
*/
|
||||
|
@ -120,8 +196,7 @@ statintr_msiiep(void *cap)
|
|||
struct clockframe *frame = cap;
|
||||
u_long newint;
|
||||
|
||||
/* read the limit register to clear the interrupt */
|
||||
mspcic_read_4(pcic_pclr);
|
||||
mspcic_read_4(pcic_pclr); /* clear the interrupt */
|
||||
|
||||
statclock(frame);
|
||||
|
||||
|
@ -131,9 +206,9 @@ statintr_msiiep(void *cap)
|
|||
newint = new_interval();
|
||||
|
||||
/*
|
||||
* Use the `non-resetting' limit register, so we don't
|
||||
* loose the counter ticks that happened since this
|
||||
* interrupt was raised.
|
||||
* Use the `non-resetting' limit register, so that we don't
|
||||
* lose the counter ticks that happened since this interrupt
|
||||
* has been raised.
|
||||
*/
|
||||
mspcic_write_4(pcic_pclr_nr, tmr_ustolimIIep(newint));
|
||||
|
||||
|
@ -157,73 +232,3 @@ statintr_msiiep(void *cap)
|
|||
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
timermatch_msiiep(struct device *parent, struct cfdata *cf, void *aux)
|
||||
{
|
||||
struct msiiep_attach_args *msa = aux;
|
||||
|
||||
return (strcmp(msa->msa_name, "timer") == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
timerattach_msiiep(struct device *parent, struct device *self, void *aux)
|
||||
{
|
||||
|
||||
/*
|
||||
* Attach system and CPU counters (kernel hard and stat clocks)
|
||||
* for ms-IIep. Counters are part of the PCIC and there's no
|
||||
* PROM node for them.
|
||||
*/
|
||||
|
||||
/* Put processor counter in "counter" mode */
|
||||
mspcic_write_1(pcic_pc_ctl, 0); /* stop user timer (just in case) */
|
||||
mspcic_write_1(pcic_pc_cfg, 0); /* timer mode disabled (processor counter) */
|
||||
|
||||
/*
|
||||
* Calibrate delay() by tweaking the magic constant
|
||||
* until a delay(100) actually reads (at least) 100 us on the clock.
|
||||
* Note: ms-IIep clocks ticks every 4 processor cycles.
|
||||
*/
|
||||
for (timerblurb = 1; ; ++timerblurb) {
|
||||
volatile int t;
|
||||
|
||||
/* clear the limit bit */
|
||||
mspcic_read_4(pcic_pclr);
|
||||
mspcic_write_4(pcic_pclr, 0); /* reset counter to 1, free run */
|
||||
delay(100);
|
||||
t = mspcic_read_4(pcic_pccr);
|
||||
|
||||
if (t & TMR_LIMIT) /* cannot happen */
|
||||
panic("delay calibration");
|
||||
|
||||
/* counter ticks -> usec, inverse of tmr_ustolimIIep */
|
||||
t = (t - 1) / 25;
|
||||
if (t >= 100)
|
||||
break;
|
||||
}
|
||||
printf(": delay constant %d\n", timerblurb);
|
||||
|
||||
/*
|
||||
* Set counter interrupt priority assignment:
|
||||
* upper 4 bits are for system counter: level 10
|
||||
* lower 4 bits are for processor counter: level 14
|
||||
*/
|
||||
mspcic_write_1(pcic_cipar, 0xae);
|
||||
|
||||
timer_init = timer_init_msiiep;
|
||||
level10.ih_fun = clockintr_msiiep;
|
||||
level14.ih_fun = statintr_msiiep;
|
||||
|
||||
/* link interrupt handlers */
|
||||
intr_establish(10, 0, &level10, NULL);
|
||||
intr_establish(14, 0, &level14, NULL);
|
||||
|
||||
/* Establish a soft interrupt at a lower level for schedclock */
|
||||
sched_cookie = softintr_establish(IPL_SCHED, schedintr, NULL);
|
||||
if (sched_cookie == NULL)
|
||||
panic("timerattach: cannot establish schedintr");
|
||||
}
|
||||
|
||||
CFATTACH_DECL(timer_msiiep, sizeof(struct device),
|
||||
timermatch_msiiep, timerattach_msiiep, NULL, NULL);
|
||||
|
|
Loading…
Reference in New Issue