From 5f93873eda852fe81fc7dd5fa5de407f157ed23e Mon Sep 17 00:00:00 2001 From: uwe Date: Sat, 24 Sep 2005 00:35:08 +0000 Subject: [PATCH] Shuffle the code to be more readable. Simplify. --- sys/arch/sparc/sparc/timer_msiiep.c | 179 ++++++++++++++-------------- 1 file changed, 92 insertions(+), 87 deletions(-) diff --git a/sys/arch/sparc/sparc/timer_msiiep.c b/sys/arch/sparc/sparc/timer_msiiep.c index aa27644a3e63..0781a69c9b5f 100644 --- a/sys/arch/sparc/sparc/timer_msiiep.c +++ b/sys/arch/sparc/sparc/timer_msiiep.c @@ -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 -__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 #include @@ -67,21 +67,98 @@ __KERNEL_RCSID(0, "$NetBSD: timer_msiiep.c,v 1.15 2005/09/23 23:22:57 uwe Exp $" #include -#include -#include - #include #include -static struct intrhand level10; -static struct intrhand level14; +#include + + +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);