Implement interrupt to CPU binding. Assign interrupts to CPUs in a
round-robin fashion, starting with the highest priority interrupt on the highest-numbered CPU and cycling downwards.
This commit is contained in:
parent
a29917e075
commit
9280895b48
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=205726
@ -93,7 +93,7 @@ configure_final(void *dummy)
|
|||||||
|
|
||||||
cninit_finish();
|
cninit_finish();
|
||||||
|
|
||||||
ia64_finalize_intr();
|
ia64_enable_intr();
|
||||||
|
|
||||||
cold = 0;
|
cold = 0;
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ ia64_xiv_reserve(u_int xiv, enum ia64_xiv_use what, ia64_ihtype ih)
|
|||||||
return (EBUSY);
|
return (EBUSY);
|
||||||
ia64_xiv[xiv] = what;
|
ia64_xiv[xiv] = what;
|
||||||
ia64_handler[xiv] = (ih == NULL) ? ia64_ih_invalid: ih;
|
ia64_handler[xiv] = (ih == NULL) ? ia64_ih_invalid: ih;
|
||||||
if (1 || bootverbose)
|
if (bootverbose)
|
||||||
printf("XIV %u: use=%u, IH=%p\n", xiv, what, ih);
|
printf("XIV %u: use=%u, IH=%p\n", xiv, what, ih);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -139,7 +139,7 @@ ia64_xiv_alloc(u_int prio, enum ia64_xiv_use what, ia64_ihtype ih)
|
|||||||
|
|
||||||
xiv0 = IA64_NXIVS - (hwprio + 1) * 16;
|
xiv0 = IA64_NXIVS - (hwprio + 1) * 16;
|
||||||
|
|
||||||
KASSERT(xiv0 > IA64_MIN_XIV, ("%s: min XIV", __func__));
|
KASSERT(xiv0 >= IA64_MIN_XIV, ("%s: min XIV", __func__));
|
||||||
KASSERT(xiv0 < IA64_NXIVS, ("%s: max XIV", __func__));
|
KASSERT(xiv0 < IA64_NXIVS, ("%s: max XIV", __func__));
|
||||||
|
|
||||||
xiv = xiv0;
|
xiv = xiv0;
|
||||||
@ -281,10 +281,24 @@ ia64_teardown_intr(void *cookie)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ia64_finalize_intr(void)
|
ia64_bind_intr(void)
|
||||||
{
|
{
|
||||||
|
struct ia64_intr *i;
|
||||||
|
struct pcpu *pc;
|
||||||
|
u_int xiv;
|
||||||
|
int cpu;
|
||||||
|
|
||||||
ia64_enable_intr();
|
cpu = MAXCPU;
|
||||||
|
for (xiv = IA64_NXIVS - 1; xiv >= IA64_MIN_XIV; xiv--) {
|
||||||
|
if (ia64_xiv[xiv] != IA64_XIV_IRQ)
|
||||||
|
continue;
|
||||||
|
i = ia64_intrs[xiv];
|
||||||
|
do {
|
||||||
|
cpu = (cpu == 0) ? MAXCPU - 1 : cpu - 1;
|
||||||
|
pc = cpuid_to_pcpu[cpu];
|
||||||
|
} while (pc == NULL || !pc->pc_md.awake);
|
||||||
|
sapic_bind_intr(i->irq, pc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -382,6 +382,12 @@ cpu_mp_unleash(void *dummy)
|
|||||||
|
|
||||||
smp_active = 1;
|
smp_active = 1;
|
||||||
smp_started = 1;
|
smp_started = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now that all CPUs are up and running, bind interrupts to each of
|
||||||
|
* them.
|
||||||
|
*/
|
||||||
|
ia64_bind_intr();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
#include <machine/bus.h>
|
#include <machine/bus.h>
|
||||||
#include <sys/rman.h>
|
#include <sys/rman.h>
|
||||||
#include <sys/interrupt.h>
|
#include <sys/interrupt.h>
|
||||||
|
#include <sys/pcpu.h>
|
||||||
|
|
||||||
#include <vm/vm.h>
|
#include <vm/vm.h>
|
||||||
#include <vm/pmap.h>
|
#include <vm/pmap.h>
|
||||||
@ -101,6 +102,7 @@ static int nexus_set_resource(device_t, device_t, int, int, u_long, u_long);
|
|||||||
static int nexus_get_resource(device_t, device_t, int, int, u_long *,
|
static int nexus_get_resource(device_t, device_t, int, int, u_long *,
|
||||||
u_long *);
|
u_long *);
|
||||||
static void nexus_delete_resource(device_t, device_t, int, int);
|
static void nexus_delete_resource(device_t, device_t, int, int);
|
||||||
|
static int nexus_bind_intr(device_t, device_t, struct resource *, int);
|
||||||
static int nexus_config_intr(device_t, int, enum intr_trigger,
|
static int nexus_config_intr(device_t, int, enum intr_trigger,
|
||||||
enum intr_polarity);
|
enum intr_polarity);
|
||||||
|
|
||||||
@ -129,6 +131,7 @@ static device_method_t nexus_methods[] = {
|
|||||||
DEVMETHOD(bus_set_resource, nexus_set_resource),
|
DEVMETHOD(bus_set_resource, nexus_set_resource),
|
||||||
DEVMETHOD(bus_get_resource, nexus_get_resource),
|
DEVMETHOD(bus_get_resource, nexus_get_resource),
|
||||||
DEVMETHOD(bus_delete_resource, nexus_delete_resource),
|
DEVMETHOD(bus_delete_resource, nexus_delete_resource),
|
||||||
|
DEVMETHOD(bus_bind_intr, nexus_bind_intr),
|
||||||
DEVMETHOD(bus_config_intr, nexus_config_intr),
|
DEVMETHOD(bus_config_intr, nexus_config_intr),
|
||||||
|
|
||||||
/* Clock interface */
|
/* Clock interface */
|
||||||
@ -461,6 +464,17 @@ nexus_config_intr(device_t dev, int irq, enum intr_trigger trig,
|
|||||||
return (sapic_config_intr(irq, trig, pol));
|
return (sapic_config_intr(irq, trig, pol));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
nexus_bind_intr(device_t dev, device_t child, struct resource *irq, int cpu)
|
||||||
|
{
|
||||||
|
struct pcpu *pc;
|
||||||
|
|
||||||
|
pc = cpuid_to_pcpu[cpu];
|
||||||
|
if (pc == NULL)
|
||||||
|
return (EINVAL);
|
||||||
|
return (sapic_bind_intr(rman_get_start(irq), pc));
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nexus_gettime(device_t dev, struct timespec *ts)
|
nexus_gettime(device_t dev, struct timespec *ts)
|
||||||
{
|
{
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include <sys/bus.h>
|
#include <sys/bus.h>
|
||||||
#include <sys/lock.h>
|
#include <sys/lock.h>
|
||||||
#include <sys/mutex.h>
|
#include <sys/mutex.h>
|
||||||
|
#include <sys/pcpu.h>
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
|
|
||||||
#include <machine/intr.h>
|
#include <machine/intr.h>
|
||||||
@ -171,6 +172,26 @@ sapic_lookup(u_int irq, u_int *vecp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
sapic_bind_intr(u_int irq, struct pcpu *pc)
|
||||||
|
{
|
||||||
|
struct sapic_rte rte;
|
||||||
|
struct sapic *sa;
|
||||||
|
|
||||||
|
sa = sapic_lookup(irq, NULL);
|
||||||
|
if (sa == NULL)
|
||||||
|
return (EINVAL);
|
||||||
|
|
||||||
|
mtx_lock_spin(&sa->sa_mtx);
|
||||||
|
sapic_read_rte(sa, irq - sa->sa_base, &rte);
|
||||||
|
rte.rte_destination_id = (pc->pc_md.lid >> 24) & 255;
|
||||||
|
rte.rte_destination_eid = (pc->pc_md.lid >> 16) & 255;
|
||||||
|
rte.rte_delivery_mode = SAPIC_DELMODE_FIXED;
|
||||||
|
sapic_write_rte(sa, irq - sa->sa_base, &rte);
|
||||||
|
mtx_unlock_spin(&sa->sa_mtx);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
sapic_config_intr(u_int irq, enum intr_trigger trig, enum intr_polarity pol)
|
sapic_config_intr(u_int irq, enum intr_trigger trig, enum intr_polarity pol)
|
||||||
{
|
{
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
#define IA64_MAX_HWPRIO 14
|
#define IA64_MAX_HWPRIO 14
|
||||||
|
|
||||||
|
struct pcpu;
|
||||||
struct sapic;
|
struct sapic;
|
||||||
struct thread;
|
struct thread;
|
||||||
struct trapframe;
|
struct trapframe;
|
||||||
@ -65,7 +66,7 @@ typedef u_int (ia64_ihtype)(struct thread *, u_int, struct trapframe *);
|
|||||||
|
|
||||||
extern struct ia64_pib *ia64_pib;
|
extern struct ia64_pib *ia64_pib;
|
||||||
|
|
||||||
void ia64_finalize_intr(void);
|
void ia64_bind_intr(void);
|
||||||
void ia64_handle_intr(struct trapframe *);
|
void ia64_handle_intr(struct trapframe *);
|
||||||
int ia64_setup_intr(const char *, int, driver_filter_t, driver_intr_t,
|
int ia64_setup_intr(const char *, int, driver_filter_t, driver_intr_t,
|
||||||
void *, enum intr_type, void **);
|
void *, enum intr_type, void **);
|
||||||
@ -76,6 +77,7 @@ u_int ia64_xiv_alloc(u_int, enum ia64_xiv_use, ia64_ihtype);
|
|||||||
int ia64_xiv_free(u_int, enum ia64_xiv_use);
|
int ia64_xiv_free(u_int, enum ia64_xiv_use);
|
||||||
int ia64_xiv_reserve(u_int, enum ia64_xiv_use, ia64_ihtype);
|
int ia64_xiv_reserve(u_int, enum ia64_xiv_use, ia64_ihtype);
|
||||||
|
|
||||||
|
int sapic_bind_intr(u_int, struct pcpu *);
|
||||||
int sapic_config_intr(u_int, enum intr_trigger, enum intr_polarity);
|
int sapic_config_intr(u_int, enum intr_trigger, enum intr_polarity);
|
||||||
struct sapic *sapic_create(u_int, u_int, uint64_t);
|
struct sapic *sapic_create(u_int, u_int, uint64_t);
|
||||||
int sapic_enable(struct sapic *, u_int, u_int);
|
int sapic_enable(struct sapic *, u_int, u_int);
|
||||||
|
Loading…
Reference in New Issue
Block a user