diff options
author | bde <bde@FreeBSD.org> | 1999-04-14 14:26:36 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1999-04-14 14:26:36 +0000 |
commit | 9a10a11b66e26366ada864a1edeada684470293b (patch) | |
tree | 3a8da958b77f97c012ad1400922dbf4e9b00b3c1 /sys/i386/isa | |
parent | 4f58b315f5310677e623e6da86f7720169a5dc1d (diff) | |
download | FreeBSD-src-9a10a11b66e26366ada864a1edeada684470293b.zip FreeBSD-src-9a10a11b66e26366ada864a1edeada684470293b.tar.gz |
Generate intrnames[] dynamically. This should be new-bus friendly.
Old version reviewed by: se
Diffstat (limited to 'sys/i386/isa')
-rw-r--r-- | sys/i386/isa/apic_vector.s | 44 | ||||
-rw-r--r-- | sys/i386/isa/atpic_vector.s | 35 | ||||
-rw-r--r-- | sys/i386/isa/icu_vector.s | 35 | ||||
-rw-r--r-- | sys/i386/isa/intr_machdep.c | 145 | ||||
-rw-r--r-- | sys/i386/isa/nmi.c | 145 | ||||
-rw-r--r-- | sys/i386/isa/vector.s | 20 |
6 files changed, 182 insertions, 242 deletions
diff --git a/sys/i386/isa/apic_vector.s b/sys/i386/isa/apic_vector.s index 10c412f..822375d 100644 --- a/sys/i386/isa/apic_vector.s +++ b/sys/i386/isa/apic_vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: apic_vector.s,v 1.34 1998/09/06 22:41:41 tegge Exp $ + * $Id: apic_vector.s,v 1.35 1999/04/10 19:19:02 tegge Exp $ */ @@ -997,46 +997,4 @@ CNAME(cpustop_restartfunc): _apic_pin_trigger: .long 0 - -/* - * Interrupt counters and names. The format of these and the label names - * must agree with what vmstat expects. The tables are indexed by device - * ids so that we don't have to move the names around as devices are - * attached. - */ -#include "vector.h" - .globl _intrcnt, _eintrcnt -_intrcnt: - .space (NR_DEVICES + ICU_LEN) * 4 -_eintrcnt: - - .globl _intrnames, _eintrnames -_intrnames: - .ascii DEVICE_NAMES - .asciz "stray irq0" - .asciz "stray irq1" - .asciz "stray irq2" - .asciz "stray irq3" - .asciz "stray irq4" - .asciz "stray irq5" - .asciz "stray irq6" - .asciz "stray irq7" - .asciz "stray irq8" - .asciz "stray irq9" - .asciz "stray irq10" - .asciz "stray irq11" - .asciz "stray irq12" - .asciz "stray irq13" - .asciz "stray irq14" - .asciz "stray irq15" - .asciz "stray irq16" - .asciz "stray irq17" - .asciz "stray irq18" - .asciz "stray irq19" - .asciz "stray irq20" - .asciz "stray irq21" - .asciz "stray irq22" - .asciz "stray irq23" -_eintrnames: - .text diff --git a/sys/i386/isa/atpic_vector.s b/sys/i386/isa/atpic_vector.s index 042614b..2dcda02 100644 --- a/sys/i386/isa/atpic_vector.s +++ b/sys/i386/isa/atpic_vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: icu_vector.s,v 1.8 1998/08/11 15:08:12 bde Exp $ + * $Id: icu_vector.s,v 1.9 1998/08/11 17:01:32 bde Exp $ */ /* @@ -214,37 +214,4 @@ imasks: /* masks for interrupt handlers */ .long 0, 0, 0, 0 .long 0, 0, SWI_CLOCK_MASK, SWI_AST_MASK -/* - * Interrupt counters and names. The format of these and the label names - * must agree with what vmstat expects. The tables are indexed by device - * ids so that we don't have to move the names around as devices are - * attached. - */ -#include "vector.h" - .globl _intrcnt, _eintrcnt -_intrcnt: - .space (NR_DEVICES + ICU_LEN) * 4 -_eintrcnt: - - .globl _intrnames, _eintrnames -_intrnames: - .ascii DEVICE_NAMES - .asciz "stray irq0" - .asciz "stray irq1" - .asciz "stray irq2" - .asciz "stray irq3" - .asciz "stray irq4" - .asciz "stray irq5" - .asciz "stray irq6" - .asciz "stray irq7" - .asciz "stray irq8" - .asciz "stray irq9" - .asciz "stray irq10" - .asciz "stray irq11" - .asciz "stray irq12" - .asciz "stray irq13" - .asciz "stray irq14" - .asciz "stray irq15" -_eintrnames: - .text diff --git a/sys/i386/isa/icu_vector.s b/sys/i386/isa/icu_vector.s index 042614b..2dcda02 100644 --- a/sys/i386/isa/icu_vector.s +++ b/sys/i386/isa/icu_vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: icu_vector.s,v 1.8 1998/08/11 15:08:12 bde Exp $ + * $Id: icu_vector.s,v 1.9 1998/08/11 17:01:32 bde Exp $ */ /* @@ -214,37 +214,4 @@ imasks: /* masks for interrupt handlers */ .long 0, 0, 0, 0 .long 0, 0, SWI_CLOCK_MASK, SWI_AST_MASK -/* - * Interrupt counters and names. The format of these and the label names - * must agree with what vmstat expects. The tables are indexed by device - * ids so that we don't have to move the names around as devices are - * attached. - */ -#include "vector.h" - .globl _intrcnt, _eintrcnt -_intrcnt: - .space (NR_DEVICES + ICU_LEN) * 4 -_eintrcnt: - - .globl _intrnames, _eintrnames -_intrnames: - .ascii DEVICE_NAMES - .asciz "stray irq0" - .asciz "stray irq1" - .asciz "stray irq2" - .asciz "stray irq3" - .asciz "stray irq4" - .asciz "stray irq5" - .asciz "stray irq6" - .asciz "stray irq7" - .asciz "stray irq8" - .asciz "stray irq9" - .asciz "stray irq10" - .asciz "stray irq11" - .asciz "stray irq12" - .asciz "stray irq13" - .asciz "stray irq14" - .asciz "stray irq15" -_eintrnames: - .text diff --git a/sys/i386/isa/intr_machdep.c b/sys/i386/isa/intr_machdep.c index 0254195..944eb4e 100644 --- a/sys/i386/isa/intr_machdep.c +++ b/sys/i386/isa/intr_machdep.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.15 1998/12/04 22:54:46 archie Exp $ + * $Id: intr_machdep.c,v 1.16 1999/01/08 19:17:48 bde Exp $ */ #include "opt_auto_eoi.h" @@ -61,7 +61,6 @@ #include <i386/isa/isa.h> #endif #include <i386/isa/icu.h> -#include "vector.h" #include <i386/isa/intr_machdep.h> #include <sys/interrupt.h> @@ -86,6 +85,8 @@ #define AUTO_EOI_1 1 #endif +#define NR_INTRNAMES (1 + ICU_LEN + 2 * ICU_LEN) + u_long *intr_countp[ICU_LEN]; inthand2_t *intr_handler[ICU_LEN]; u_int intr_mask[ICU_LEN]; @@ -264,9 +265,9 @@ isa_strayintr(vcookiep) * must be done before sending an EOI so it can't be done if * we are using AUTO_EOI_1. */ - if (intrcnt[NR_DEVICES + intr] <= 5) + if (intrcnt[1 + intr] <= 5) log(LOG_ERR, "stray irq %d\n", intr); - if (intrcnt[NR_DEVICES + intr] == 5) + if (intrcnt[1 + intr] == 5) log(LOG_CRIT, "too many stray irq %d's; not logging any more\n", intr); } @@ -315,74 +316,88 @@ update_intr_masks(void) return (n); } -/* - * The find_device_id function is only required because of the way the - * device names are currently stored for reporting in systat or vmstat. - * In fact, those programs should be modified to use the sysctl interface - * to obtain a list of driver names by traversing intreclist_head[irq]. - */ -static int -find_device_id(int irq) +static const char * +isa_get_nameunit(int id) { - char buf[16]; - char *cp; - int free_id, id; - - snprintf(buf, sizeof(buf), "pci irq%d", irq); - cp = intrnames; - /* default to 0, which corresponds to clk0 */ - free_id = 0; - - for (id = 0; id < NR_DEVICES; id++) { - if (strcmp(cp, buf) == 0) - return (id); - if (free_id == 0 && strcmp(cp, "pci irqnn") == 0) - free_id = id; - while (*cp++ != '\0'); - } -#if 0 - if (free_id == 0) { - /* - * All pci irq counters are in use, perhaps because config - * is old so there aren't any. Abuse the clk0 counter. - */ - printf("\tcounting shared irq%d as clk0 irq\n", irq); - } -#endif - return (free_id); + static char buf[32]; + struct isa_device *dp; + + if (id == -1) + return ("pci"); /* XXX may also be eisa */ + if (id == 0) + return ("clk0"); /* XXX may also be sloppy driver */ + if (id == 1) + return ("rtc0"); + for (dp = isa_devtab_bio; dp->id_driver != NULL; dp++) + if (dp->id_id == id) + goto found_device; + for (dp = isa_devtab_cam; dp->id_driver != NULL; dp++) + if (dp->id_id == id) + goto found_device; + for (dp = isa_devtab_net; dp->id_driver != NULL; dp++) + if (dp->id_id == id) + goto found_device; + for (dp = isa_devtab_null; dp->id_driver != NULL; dp++) + if (dp->id_id == id) + goto found_device; + for (dp = isa_devtab_tty; dp->id_driver != NULL; dp++) + if (dp->id_id == id) + goto found_device; + return "???"; + +found_device: + snprintf(buf, sizeof(buf), "%s%d", dp->id_driver->name, dp->id_unit); + return (buf); } void update_intrname(int intr, int device_id) { - char *cp; - int id; - - if (device_id == -1) - device_id = find_device_id(intr); - - if ((u_int)device_id >= NR_DEVICES) - return; - - intr_countp[intr] = &intrcnt[device_id]; - - for (cp = intrnames, id = 0; id <= device_id; id++) - while (*cp++ != '\0') - ; - if (cp > eintrnames) - return; - if (intr < 10) { - cp[-3] = intr + '0'; - cp[-2] = ' '; - } else if (intr < 20) { - cp[-3] = '1'; - cp[-2] = intr - 10 + '0'; - } else { - cp[-3] = '2'; - cp[-2] = intr - 20 + '0'; + char buf[32]; + char *cp; + const char *name; + int name_index, off, strayintr; + + /* + * Initialise strings for bitbucket and stray interrupt counters. + * These have statically allocated indices 0 and 1 through ICU_LEN. + */ + if (intrnames[0] == '\0') { + off = sprintf(intrnames, "???") + 1; + for (strayintr = 0; strayintr < ICU_LEN; strayintr++) + off += sprintf(intrnames + off, "stray irq%d", + strayintr) + 1; + } + + name = isa_get_nameunit(device_id); + if (snprintf(buf, sizeof(buf), "%s irq%d", name, intr) >= sizeof(buf)) + goto use_bitbucket; + + /* + * Search for `buf' in `intrnames'. In the usual case when it is + * not found, append it to the end if there is enough space (the \0 + * terminator for the previous string, if any, becomes a separator). + */ + for (cp = intrnames, name_index = 0; + cp != eintrnames && name_index < NR_INTRNAMES; + cp += strlen(cp) + 1, name_index++) { + if (*cp == '\0') { + if (strlen(buf) >= eintrnames - cp) + break; + strcpy(cp, buf); + goto found; + } + if (strcmp(cp, buf) == 0) + goto found; } -} +use_bitbucket: + printf("update_intrname: counting %s irq%d as %s\n", name, intr, + intrnames); + name_index = 0; +found: + intr_countp[intr] = &intrcnt[name_index]; +} int icu_setup(int intr, inthand2_t *handler, void *arg, u_int *maskptr, int flags) @@ -479,7 +494,7 @@ icu_unset(intr, handler) INTRDIS(1 << intr); ef = read_eflags(); disable_intr(); - intr_countp[intr] = &intrcnt[NR_DEVICES + intr]; + intr_countp[intr] = &intrcnt[1 + intr]; intr_handler[intr] = isa_strayintr; intr_mptr[intr] = NULL; intr_mask[intr] = HWI_MASK | SWI_MASK; diff --git a/sys/i386/isa/nmi.c b/sys/i386/isa/nmi.c index 0254195..944eb4e 100644 --- a/sys/i386/isa/nmi.c +++ b/sys/i386/isa/nmi.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 - * $Id: intr_machdep.c,v 1.15 1998/12/04 22:54:46 archie Exp $ + * $Id: intr_machdep.c,v 1.16 1999/01/08 19:17:48 bde Exp $ */ #include "opt_auto_eoi.h" @@ -61,7 +61,6 @@ #include <i386/isa/isa.h> #endif #include <i386/isa/icu.h> -#include "vector.h" #include <i386/isa/intr_machdep.h> #include <sys/interrupt.h> @@ -86,6 +85,8 @@ #define AUTO_EOI_1 1 #endif +#define NR_INTRNAMES (1 + ICU_LEN + 2 * ICU_LEN) + u_long *intr_countp[ICU_LEN]; inthand2_t *intr_handler[ICU_LEN]; u_int intr_mask[ICU_LEN]; @@ -264,9 +265,9 @@ isa_strayintr(vcookiep) * must be done before sending an EOI so it can't be done if * we are using AUTO_EOI_1. */ - if (intrcnt[NR_DEVICES + intr] <= 5) + if (intrcnt[1 + intr] <= 5) log(LOG_ERR, "stray irq %d\n", intr); - if (intrcnt[NR_DEVICES + intr] == 5) + if (intrcnt[1 + intr] == 5) log(LOG_CRIT, "too many stray irq %d's; not logging any more\n", intr); } @@ -315,74 +316,88 @@ update_intr_masks(void) return (n); } -/* - * The find_device_id function is only required because of the way the - * device names are currently stored for reporting in systat or vmstat. - * In fact, those programs should be modified to use the sysctl interface - * to obtain a list of driver names by traversing intreclist_head[irq]. - */ -static int -find_device_id(int irq) +static const char * +isa_get_nameunit(int id) { - char buf[16]; - char *cp; - int free_id, id; - - snprintf(buf, sizeof(buf), "pci irq%d", irq); - cp = intrnames; - /* default to 0, which corresponds to clk0 */ - free_id = 0; - - for (id = 0; id < NR_DEVICES; id++) { - if (strcmp(cp, buf) == 0) - return (id); - if (free_id == 0 && strcmp(cp, "pci irqnn") == 0) - free_id = id; - while (*cp++ != '\0'); - } -#if 0 - if (free_id == 0) { - /* - * All pci irq counters are in use, perhaps because config - * is old so there aren't any. Abuse the clk0 counter. - */ - printf("\tcounting shared irq%d as clk0 irq\n", irq); - } -#endif - return (free_id); + static char buf[32]; + struct isa_device *dp; + + if (id == -1) + return ("pci"); /* XXX may also be eisa */ + if (id == 0) + return ("clk0"); /* XXX may also be sloppy driver */ + if (id == 1) + return ("rtc0"); + for (dp = isa_devtab_bio; dp->id_driver != NULL; dp++) + if (dp->id_id == id) + goto found_device; + for (dp = isa_devtab_cam; dp->id_driver != NULL; dp++) + if (dp->id_id == id) + goto found_device; + for (dp = isa_devtab_net; dp->id_driver != NULL; dp++) + if (dp->id_id == id) + goto found_device; + for (dp = isa_devtab_null; dp->id_driver != NULL; dp++) + if (dp->id_id == id) + goto found_device; + for (dp = isa_devtab_tty; dp->id_driver != NULL; dp++) + if (dp->id_id == id) + goto found_device; + return "???"; + +found_device: + snprintf(buf, sizeof(buf), "%s%d", dp->id_driver->name, dp->id_unit); + return (buf); } void update_intrname(int intr, int device_id) { - char *cp; - int id; - - if (device_id == -1) - device_id = find_device_id(intr); - - if ((u_int)device_id >= NR_DEVICES) - return; - - intr_countp[intr] = &intrcnt[device_id]; - - for (cp = intrnames, id = 0; id <= device_id; id++) - while (*cp++ != '\0') - ; - if (cp > eintrnames) - return; - if (intr < 10) { - cp[-3] = intr + '0'; - cp[-2] = ' '; - } else if (intr < 20) { - cp[-3] = '1'; - cp[-2] = intr - 10 + '0'; - } else { - cp[-3] = '2'; - cp[-2] = intr - 20 + '0'; + char buf[32]; + char *cp; + const char *name; + int name_index, off, strayintr; + + /* + * Initialise strings for bitbucket and stray interrupt counters. + * These have statically allocated indices 0 and 1 through ICU_LEN. + */ + if (intrnames[0] == '\0') { + off = sprintf(intrnames, "???") + 1; + for (strayintr = 0; strayintr < ICU_LEN; strayintr++) + off += sprintf(intrnames + off, "stray irq%d", + strayintr) + 1; + } + + name = isa_get_nameunit(device_id); + if (snprintf(buf, sizeof(buf), "%s irq%d", name, intr) >= sizeof(buf)) + goto use_bitbucket; + + /* + * Search for `buf' in `intrnames'. In the usual case when it is + * not found, append it to the end if there is enough space (the \0 + * terminator for the previous string, if any, becomes a separator). + */ + for (cp = intrnames, name_index = 0; + cp != eintrnames && name_index < NR_INTRNAMES; + cp += strlen(cp) + 1, name_index++) { + if (*cp == '\0') { + if (strlen(buf) >= eintrnames - cp) + break; + strcpy(cp, buf); + goto found; + } + if (strcmp(cp, buf) == 0) + goto found; } -} +use_bitbucket: + printf("update_intrname: counting %s irq%d as %s\n", name, intr, + intrnames); + name_index = 0; +found: + intr_countp[intr] = &intrcnt[name_index]; +} int icu_setup(int intr, inthand2_t *handler, void *arg, u_int *maskptr, int flags) @@ -479,7 +494,7 @@ icu_unset(intr, handler) INTRDIS(1 << intr); ef = read_eflags(); disable_intr(); - intr_countp[intr] = &intrcnt[NR_DEVICES + intr]; + intr_countp[intr] = &intrcnt[1 + intr]; intr_handler[intr] = isa_strayintr; intr_mptr[intr] = NULL; intr_mask[intr] = HWI_MASK | SWI_MASK; diff --git a/sys/i386/isa/vector.s b/sys/i386/isa/vector.s index 1fc5668..608f135 100644 --- a/sys/i386/isa/vector.s +++ b/sys/i386/isa/vector.s @@ -1,6 +1,6 @@ /* * from: vector.s, 386BSD 0.1 unknown origin - * $Id: vector.s,v 1.2 1997/05/24 17:05:26 smp Exp smp $ + * $Id: vector.s,v 1.30 1997/05/26 17:58:27 fsmp Exp $ */ /* @@ -41,6 +41,24 @@ _intr_nesting_level: .byte 0 .space 3 +/* + * Interrupt counters and names for export to vmstat(8) and friends. + * + * XXX this doesn't really belong here; everything except the labels + * for the endpointers is almost machine-independent. + */ +#define NR_INTRNAMES (1 + ICU_LEN + 2 * ICU_LEN) + + .globl _intrcnt, _eintrcnt +_intrcnt: + .space NR_INTRNAMES * 4 +_eintrcnt: + + .globl _intrnames, _eintrnames +_intrnames: + .space NR_INTRNAMES * 16 +_eintrnames: + .text /* |