From d25c5758ea35b3a5510242ed2943f124cc00de19 Mon Sep 17 00:00:00 2001 From: "Dale S. Rahn" Date: Fri, 7 Jul 2000 13:22:44 +0000 Subject: Since it is possible for the interrupt controller to be configured late in the config cycle, and pci devices as well as mac onboard devices do not use interrupts to probe. It is possible to record that the interrupt is to be configured, but not configure it with the interrupt controller until the interrupt controller configures itself. This is lazy binding of interrupts. If there is a conflicting interrupt or other problem it will be noticed when the interrupt controller configures and collects the data rather than when the device configures. Currently on the openpic interrupt controller supports these pre-configured interrupts. --- sys/arch/powerpc/include/intr.h | 5 ++++- sys/arch/powerpc/mac/openpic.c | 35 +++++++++++++++++++++++++++++++---- sys/arch/powerpc/powerpc/machdep.c | 24 ++++++++++++++++++++---- 3 files changed, 55 insertions(+), 9 deletions(-) (limited to 'sys/arch/powerpc') diff --git a/sys/arch/powerpc/include/intr.h b/sys/arch/powerpc/include/intr.h index f2387c0a9fe..55fe476c175 100644 --- a/sys/arch/powerpc/include/intr.h +++ b/sys/arch/powerpc/include/intr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.h,v 1.6 2000/07/06 15:29:53 ho Exp $ */ +/* $OpenBSD: intr.h,v 1.7 2000/07/07 13:22:42 rahnds Exp $ */ /* * Copyright (c) 1997 Per Fogelstrom, Opsycon AB and RTMX Inc, USA. @@ -162,6 +162,9 @@ struct intrhand { int ih_irq; char *ih_what; }; +extern int ppc_configed_intr_cnt; +#define MAX_PRECONF_INTR 16 +extern struct intrhand ppc_configed_intr[MAX_PRECONF_INTR]; #endif /* _LOCORE */ diff --git a/sys/arch/powerpc/mac/openpic.c b/sys/arch/powerpc/mac/openpic.c index 099648c8af7..1f435ac1e01 100644 --- a/sys/arch/powerpc/mac/openpic.c +++ b/sys/arch/powerpc/mac/openpic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: openpic.c,v 1.3 2000/06/15 03:11:01 rahnds Exp $ */ +/* $OpenBSD: openpic.c,v 1.4 2000/07/07 13:22:42 rahnds Exp $ */ /*- * Copyright (c) 1995 Per Fogelstrom @@ -58,12 +58,12 @@ #include #include -#define ICU_LEN 64 +#define ICU_LEN 128 #define LEGAL_IRQ(x) ((x >= 0) && (x < ICU_LEN)) static int intrtype[ICU_LEN], intrmask[ICU_LEN], intrlevel[ICU_LEN]; static struct intrhand *intrhand[ICU_LEN] = { 0 }; -static int hwirq[ICU_LEN], virq[64]; +static int hwirq[ICU_LEN], virq[ICU_LEN]; unsigned int imen /* = 0xffffffff */; /* XXX */ static int virq_max = 0; @@ -145,6 +145,7 @@ vaddr_t openpic_base; void * openpic_intr_establish( void * lcv, int irq, int type, int level, int (*ih_fun) __P((void *)), void *ih_arg, char *name); void openpic_intr_disestablish( void *lcp, void *arg); +void openpic_collect_preconf_intr(); void openpic_attach(parent, self, aux) @@ -171,6 +172,10 @@ openpic_attach(parent, self, aux) mac_intr_establish_func = openpic_intr_establish; mac_intr_disestablish_func = openpic_intr_disestablish; install_extint(ext_intr_openpic); + +#if 1 + openpic_collect_preconf_intr(); +#endif #if 1 mac_intr_establish(parent, 0x37, IST_LEVEL, @@ -179,6 +184,28 @@ openpic_attach(parent, self, aux) printf("\n"); } +void +openpic_collect_preconf_intr() +{ + int i; + printf("postconfiguring interrupts\n"); + for (i = 0; i < ppc_configed_intr_cnt; i++) { + printf("\t%s irq %d level %d fun %x arg %x\n", + ppc_configed_intr[i].ih_what, + ppc_configed_intr[i].ih_irq, + ppc_configed_intr[i].ih_level, + ppc_configed_intr[i].ih_fun, + ppc_configed_intr[i].ih_arg + ); + openpic_intr_establish(NULL, + ppc_configed_intr[i].ih_irq, + IST_LEVEL, + ppc_configed_intr[i].ih_level, + ppc_configed_intr[i].ih_fun, + ppc_configed_intr[i].ih_arg, + ppc_configed_intr[i].ih_what); + } +} static int prog_switch (void *arg) @@ -419,7 +446,7 @@ mapirq(irq) { int v; - if (irq < 0 || irq >= 64) + if (irq < 0 || irq >= ICU_LEN) panic("invalid irq"); virq_max++; v = virq_max; diff --git a/sys/arch/powerpc/powerpc/machdep.c b/sys/arch/powerpc/powerpc/machdep.c index 7fe2e3727a2..528a77ea4fd 100644 --- a/sys/arch/powerpc/powerpc/machdep.c +++ b/sys/arch/powerpc/powerpc/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.42 2000/06/08 22:25:22 niklas Exp $ */ +/* $OpenBSD: machdep.c,v 1.43 2000/07/07 13:22:43 rahnds Exp $ */ /* $NetBSD: machdep.c,v 1.4 1996/10/16 19:33:11 ws Exp $ */ /* @@ -998,19 +998,35 @@ systype(char *name) */ #include typedef void *(intr_establish_t) __P((void *, pci_intr_handle_t, - int, int (*func)(void *), void *, char *)); + int, int, int (*func)(void *), void *, char *)); typedef void (intr_disestablish_t) __P((void *, void *)); +int ppc_configed_intr_cnt = 0; +struct intrhand ppc_configed_intr[MAX_PRECONF_INTR]; + void * -ppc_intr_establish(lcv, ih, level, func, arg, name) +ppc_intr_establish(lcv, ih, type, level, func, arg, name) void *lcv; pci_intr_handle_t ih; + int type; int level; int (*func) __P((void *)); void *arg; char *name; { - panic("ppc_intr_establish called before interrupt controller configured: driver %s", name); + if (ppc_configed_intr_cnt < MAX_PRECONF_INTR) { + ppc_configed_intr[ppc_configed_intr_cnt].ih_fun = func; + ppc_configed_intr[ppc_configed_intr_cnt].ih_arg = arg; + ppc_configed_intr[ppc_configed_intr_cnt].ih_level = level; + ppc_configed_intr[ppc_configed_intr_cnt].ih_irq = ih; + ppc_configed_intr[ppc_configed_intr_cnt].ih_what = name; + ppc_configed_intr_cnt++; + } else { + panic("ppc_intr_establish called before interrupt controller" + " configured: driver %s too many interrupts\n", name); + } + /* disestablish is going to be tricky to supported for these :-) */ + return (void *)ppc_configed_intr_cnt; } intr_establish_t *intr_establish_func = ppc_intr_establish;; -- cgit v1.2.3