Changeset View
Changeset View
Standalone View
Standalone View
sys/powerpc/powerpc/intr_machdep.c
Show First 20 Lines • Show All 81 Lines • ▼ Show 20 Lines | |||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <machine/frame.h> | #include <machine/frame.h> | ||||
#include <machine/intr_machdep.h> | #include <machine/intr_machdep.h> | ||||
#include <machine/md_var.h> | #include <machine/md_var.h> | ||||
#include <machine/smp.h> | #include <machine/smp.h> | ||||
#include <machine/trap.h> | #include <machine/trap.h> | ||||
#include "pic_if.h" | #include "oldpic_if.h" | ||||
#define MAX_STRAY_LOG 5 | #define MAX_STRAY_LOG 5 | ||||
static MALLOC_DEFINE(M_INTR, "intr", "interrupt handler data"); | static MALLOC_DEFINE(M_INTR, "intr", "interrupt handler data"); | ||||
struct powerpc_intr { | struct powerpc_intr { | ||||
struct intr_event *event; | struct intr_event *event; | ||||
long *cntp; | long *cntp; | ||||
▲ Show 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | |||||
smp_intr_init(void *dummy __unused) | smp_intr_init(void *dummy __unused) | ||||
{ | { | ||||
struct powerpc_intr *i; | struct powerpc_intr *i; | ||||
int vector; | int vector; | ||||
for (vector = 0; vector < nvectors; vector++) { | for (vector = 0; vector < nvectors; vector++) { | ||||
i = powerpc_intrs[vector]; | i = powerpc_intrs[vector]; | ||||
if (i != NULL && i->event != NULL && i->pic == root_pic) | if (i != NULL && i->event != NULL && i->pic == root_pic) | ||||
PIC_BIND(i->pic, i->intline, i->pi_cpuset, &i->priv); | OLDPIC_BIND(i->pic, i->intline, i->pi_cpuset, &i->priv); | ||||
} | } | ||||
} | } | ||||
SYSINIT(smp_intr_init, SI_SUB_SMP, SI_ORDER_ANY, smp_intr_init, NULL); | SYSINIT(smp_intr_init, SI_SUB_SMP, SI_ORDER_ANY, smp_intr_init, NULL); | ||||
#endif | #endif | ||||
void | void | ||||
intrcnt_add(const char *name, u_long **countp) | intrcnt_add(const char *name, u_long **countp) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | powerpc_map_irq(struct powerpc_intr *i) | ||||
return (0); | return (0); | ||||
} | } | ||||
static void | static void | ||||
powerpc_intr_eoi(void *arg) | powerpc_intr_eoi(void *arg) | ||||
{ | { | ||||
struct powerpc_intr *i = arg; | struct powerpc_intr *i = arg; | ||||
PIC_EOI(i->pic, i->intline, i->priv); | OLDPIC_EOI(i->pic, i->intline, i->priv); | ||||
} | } | ||||
static void | static void | ||||
powerpc_intr_pre_ithread(void *arg) | powerpc_intr_pre_ithread(void *arg) | ||||
{ | { | ||||
struct powerpc_intr *i = arg; | struct powerpc_intr *i = arg; | ||||
PIC_MASK(i->pic, i->intline, i->priv); | OLDPIC_MASK(i->pic, i->intline, i->priv); | ||||
PIC_EOI(i->pic, i->intline, i->priv); | OLDPIC_EOI(i->pic, i->intline, i->priv); | ||||
} | } | ||||
static void | static void | ||||
powerpc_intr_post_ithread(void *arg) | powerpc_intr_post_ithread(void *arg) | ||||
{ | { | ||||
struct powerpc_intr *i = arg; | struct powerpc_intr *i = arg; | ||||
PIC_UNMASK(i->pic, i->intline, i->priv); | OLDPIC_UNMASK(i->pic, i->intline, i->priv); | ||||
} | } | ||||
static int | static int | ||||
powerpc_assign_intr_cpu(void *arg, int cpu) | powerpc_assign_intr_cpu(void *arg, int cpu) | ||||
{ | { | ||||
#ifdef SMP | #ifdef SMP | ||||
struct powerpc_intr *i = arg; | struct powerpc_intr *i = arg; | ||||
if (cpu == NOCPU) | if (cpu == NOCPU) | ||||
i->pi_cpuset = all_cpus; | i->pi_cpuset = all_cpus; | ||||
else | else | ||||
CPU_SETOF(cpu, &i->pi_cpuset); | CPU_SETOF(cpu, &i->pi_cpuset); | ||||
if (!cold && i->pic != NULL && i->pic == root_pic) | if (!cold && i->pic != NULL && i->pic == root_pic) | ||||
PIC_BIND(i->pic, i->intline, i->pi_cpuset, &i->priv); | OLDPIC_BIND(i->pic, i->intline, i->pi_cpuset, &i->priv); | ||||
return (0); | return (0); | ||||
#else | #else | ||||
return (EOPNOTSUPP); | return (EOPNOTSUPP); | ||||
#endif | #endif | ||||
} | } | ||||
u_int | u_int | ||||
▲ Show 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | for (vector = 0; vector < nvectors; vector++) { | ||||
if (i == NULL) | if (i == NULL) | ||||
continue; | continue; | ||||
error = powerpc_map_irq(i); | error = powerpc_map_irq(i); | ||||
if (error) | if (error) | ||||
continue; | continue; | ||||
if (i->trig == INTR_TRIGGER_INVALID) | if (i->trig == INTR_TRIGGER_INVALID) | ||||
PIC_TRANSLATE_CODE(i->pic, i->intline, i->fwcode, | OLDPIC_TRANSLATE_CODE(i->pic, i->intline, i->fwcode, | ||||
&i->trig, &i->pol); | &i->trig, &i->pol); | ||||
if (i->trig != INTR_TRIGGER_CONFORM || | if (i->trig != INTR_TRIGGER_CONFORM || | ||||
i->pol != INTR_POLARITY_CONFORM) | i->pol != INTR_POLARITY_CONFORM) | ||||
PIC_CONFIG(i->pic, i->intline, i->trig, i->pol); | OLDPIC_CONFIG(i->pic, i->intline, i->trig, i->pol); | ||||
if (i->event != NULL) | if (i->event != NULL) | ||||
PIC_ENABLE(i->pic, i->intline, vector, &i->priv); | OLDPIC_ENABLE(i->pic, i->intline, vector, &i->priv); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
powerpc_setup_intr(const char *name, u_int irq, driver_filter_t filter, | powerpc_setup_intr(const char *name, u_int irq, driver_filter_t filter, | ||||
driver_intr_t handler, void *arg, enum intr_type flags, void **cookiep, | driver_intr_t handler, void *arg, enum intr_type flags, void **cookiep, | ||||
Show All 29 Lines | powerpc_setup_intr(const char *name, u_int irq, driver_filter_t filter, | ||||
intrcnt_setname(i->event->ie_fullname, i->cntindex); | intrcnt_setname(i->event->ie_fullname, i->cntindex); | ||||
mtx_unlock(&intr_table_lock); | mtx_unlock(&intr_table_lock); | ||||
if (!cold) { | if (!cold) { | ||||
error = powerpc_map_irq(i); | error = powerpc_map_irq(i); | ||||
if (!error) { | if (!error) { | ||||
if (i->trig == INTR_TRIGGER_INVALID) | if (i->trig == INTR_TRIGGER_INVALID) | ||||
PIC_TRANSLATE_CODE(i->pic, i->intline, | OLDPIC_TRANSLATE_CODE(i->pic, i->intline, | ||||
i->fwcode, &i->trig, &i->pol); | i->fwcode, &i->trig, &i->pol); | ||||
if (i->trig != INTR_TRIGGER_CONFORM || | if (i->trig != INTR_TRIGGER_CONFORM || | ||||
i->pol != INTR_POLARITY_CONFORM) | i->pol != INTR_POLARITY_CONFORM) | ||||
PIC_CONFIG(i->pic, i->intline, i->trig, i->pol); | OLDPIC_CONFIG(i->pic, i->intline, i->trig, i->pol); | ||||
if (i->pic == root_pic) | if (i->pic == root_pic) | ||||
PIC_BIND(i->pic, i->intline, i->pi_cpuset, &i->priv); | OLDPIC_BIND(i->pic, i->intline, i->pi_cpuset, &i->priv); | ||||
if (enable) | if (enable) | ||||
PIC_ENABLE(i->pic, i->intline, i->vector, | OLDPIC_ENABLE(i->pic, i->intline, i->vector, | ||||
&i->priv); | &i->priv); | ||||
} | } | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
powerpc_teardown_intr(void *cookie) | powerpc_teardown_intr(void *cookie) | ||||
Show All 25 Lines | powerpc_fw_config_intr(int irq, int sense_code) | ||||
if (i == NULL) | if (i == NULL) | ||||
return (ENOMEM); | return (ENOMEM); | ||||
i->trig = INTR_TRIGGER_INVALID; | i->trig = INTR_TRIGGER_INVALID; | ||||
i->pol = INTR_POLARITY_CONFORM; | i->pol = INTR_POLARITY_CONFORM; | ||||
i->fwcode = sense_code; | i->fwcode = sense_code; | ||||
if (!cold && i->pic != NULL) { | if (!cold && i->pic != NULL) { | ||||
PIC_TRANSLATE_CODE(i->pic, i->intline, i->fwcode, &i->trig, | OLDPIC_TRANSLATE_CODE(i->pic, i->intline, i->fwcode, &i->trig, | ||||
&i->pol); | &i->pol); | ||||
PIC_CONFIG(i->pic, i->intline, i->trig, i->pol); | OLDPIC_CONFIG(i->pic, i->intline, i->trig, i->pol); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
powerpc_config_intr(int irq, enum intr_trigger trig, enum intr_polarity pol) | powerpc_config_intr(int irq, enum intr_trigger trig, enum intr_polarity pol) | ||||
{ | { | ||||
struct powerpc_intr *i; | struct powerpc_intr *i; | ||||
i = intr_lookup(irq); | i = intr_lookup(irq); | ||||
if (i == NULL) | if (i == NULL) | ||||
return (ENOMEM); | return (ENOMEM); | ||||
i->trig = trig; | i->trig = trig; | ||||
i->pol = pol; | i->pol = pol; | ||||
if (!cold && i->pic != NULL) | if (!cold && i->pic != NULL) | ||||
PIC_CONFIG(i->pic, i->intline, trig, pol); | OLDPIC_CONFIG(i->pic, i->intline, trig, pol); | ||||
return (0); | return (0); | ||||
} | } | ||||
void | void | ||||
powerpc_dispatch_intr(u_int vector, struct trapframe *tf) | powerpc_dispatch_intr(u_int vector, struct trapframe *tf) | ||||
{ | { | ||||
struct powerpc_intr *i; | struct powerpc_intr *i; | ||||
struct intr_event *ie; | struct intr_event *ie; | ||||
i = powerpc_intrs[vector]; | i = powerpc_intrs[vector]; | ||||
if (i == NULL) | if (i == NULL) | ||||
goto stray; | goto stray; | ||||
(*i->cntp)++; | (*i->cntp)++; | ||||
ie = i->event; | ie = i->event; | ||||
KASSERT(ie != NULL, ("%s: interrupt without an event", __func__)); | KASSERT(ie != NULL, ("%s: interrupt without an event", __func__)); | ||||
/* | /* | ||||
* IPIs are magical and need to be EOI'ed before filtering. | * IPIs are magical and need to be EOI'ed before filtering. | ||||
* This prevents races in IPI handling. | * This prevents races in IPI handling. | ||||
*/ | */ | ||||
if (i->ipi) | if (i->ipi) | ||||
PIC_EOI(i->pic, i->intline, i->priv); | OLDPIC_EOI(i->pic, i->intline, i->priv); | ||||
if (intr_event_handle(ie, tf) != 0) { | if (intr_event_handle(ie, tf) != 0) { | ||||
goto stray; | goto stray; | ||||
} | } | ||||
return; | return; | ||||
stray: | stray: | ||||
stray_count++; | stray_count++; | ||||
if (stray_count <= MAX_STRAY_LOG) { | if (stray_count <= MAX_STRAY_LOG) { | ||||
printf("stray irq %d\n", i ? i->irq : -1); | printf("stray irq %d\n", i ? i->irq : -1); | ||||
if (stray_count >= MAX_STRAY_LOG) { | if (stray_count >= MAX_STRAY_LOG) { | ||||
printf("got %d stray interrupts, not logging anymore\n", | printf("got %d stray interrupts, not logging anymore\n", | ||||
MAX_STRAY_LOG); | MAX_STRAY_LOG); | ||||
} | } | ||||
} | } | ||||
if (i != NULL) | if (i != NULL) | ||||
PIC_MASK(i->pic, i->intline, i->priv); | OLDPIC_MASK(i->pic, i->intline, i->priv); | ||||
} | } | ||||
void | void | ||||
powerpc_intr_mask(u_int irq) | powerpc_intr_mask(u_int irq) | ||||
{ | { | ||||
struct powerpc_intr *i; | struct powerpc_intr *i; | ||||
i = intr_lookup(irq); | i = intr_lookup(irq); | ||||
if (i == NULL || i->pic == NULL) | if (i == NULL || i->pic == NULL) | ||||
return; | return; | ||||
PIC_MASK(i->pic, i->intline, i->priv); | OLDPIC_MASK(i->pic, i->intline, i->priv); | ||||
} | } | ||||
void | void | ||||
powerpc_intr_unmask(u_int irq) | powerpc_intr_unmask(u_int irq) | ||||
{ | { | ||||
struct powerpc_intr *i; | struct powerpc_intr *i; | ||||
i = intr_lookup(irq); | i = intr_lookup(irq); | ||||
if (i == NULL || i->pic == NULL) | if (i == NULL || i->pic == NULL) | ||||
return; | return; | ||||
PIC_UNMASK(i->pic, i->intline, i->priv); | OLDPIC_UNMASK(i->pic, i->intline, i->priv); | ||||
} | } |