Wire up most of the interrupt handling infrastructure. Not sure it works
right yet but its enough for the ATA probe to work. The SCSI probes which follow are broken though.
This commit is contained in:
parent
ae0d75fe5f
commit
7a7029581c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=84541
@ -94,41 +94,46 @@ typedef struct /* PLATFORM INTERRUPT SOURCE */
|
||||
static void
|
||||
parse_interrupt_override(INTERRUPT_SOURCE_OVERRIDE *override)
|
||||
{
|
||||
printf("\t\tBus=%d, Source=%d, Irq=0x%x\n",
|
||||
override->Bus,
|
||||
override->Source,
|
||||
override->GlobalSystemInterrupt);
|
||||
if (bootverbose)
|
||||
printf("\t\tBus=%d, Source=%d, Irq=0x%x\n",
|
||||
override->Bus,
|
||||
override->Source,
|
||||
override->GlobalSystemInterrupt);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_io_sapic(IO_SAPIC *sapic)
|
||||
{
|
||||
printf("\t\tId=0x%x, Vector=0x%x, Address=0x%lx\n",
|
||||
sapic->IoSapicId,
|
||||
sapic->Vector,
|
||||
sapic->IoSapicAddress);
|
||||
if (bootverbose)
|
||||
printf("\t\tId=0x%x, Vector=0x%x, Address=0x%lx\n",
|
||||
sapic->IoSapicId,
|
||||
sapic->Vector,
|
||||
sapic->IoSapicAddress);
|
||||
sapic_create(sapic->IoSapicId, sapic->Vector, sapic->IoSapicAddress);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_local_sapic(LOCAL_SAPIC *sapic)
|
||||
{
|
||||
printf("\t\tProcessorId=0x%x, Id=0x%x, Eid=0x%x\n",
|
||||
sapic->ProcessorId,
|
||||
sapic->LocalSapicId,
|
||||
sapic->LocalSapicEid);
|
||||
if (bootverbose)
|
||||
printf("\t\tProcessorId=0x%x, Id=0x%x, Eid=0x%x\n",
|
||||
sapic->ProcessorId,
|
||||
sapic->LocalSapicId,
|
||||
sapic->LocalSapicEid);
|
||||
}
|
||||
|
||||
static void
|
||||
parse_platform_interrupt(PLATFORM_INTERRUPT_SOURCE *source)
|
||||
{
|
||||
printf("\t\tPolarity=%d, TriggerMode=%d, Id=0x%x, "
|
||||
"Eid=0x%x, Vector=0x%x, Irq=%d\n",
|
||||
source->Polarity,
|
||||
source->TriggerMode,
|
||||
source->ProcessorId,
|
||||
source->ProcessorEid,
|
||||
source->IoSapicVector,
|
||||
source->GlobalSystemInterrupt);
|
||||
if (bootverbose)
|
||||
printf("\t\tPolarity=%d, TriggerMode=%d, Id=0x%x, "
|
||||
"Eid=0x%x, Vector=0x%x, Irq=%d\n",
|
||||
source->Polarity,
|
||||
source->TriggerMode,
|
||||
source->ProcessorId,
|
||||
source->ProcessorEid,
|
||||
source->IoSapicVector,
|
||||
source->GlobalSystemInterrupt);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -144,7 +149,8 @@ parse_madt(APIC_TABLE *madt)
|
||||
for (p = (char *) (madt + 1); p < end; ) {
|
||||
APIC_HEADER *head = (APIC_HEADER *) p;
|
||||
|
||||
printf("\t");
|
||||
if (bootverbose)
|
||||
printf("\t");
|
||||
switch (head->Type) {
|
||||
case APIC_PROC:
|
||||
if (bootverbose)
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#include <sys/bus.h>
|
||||
@ -53,6 +54,7 @@
|
||||
#include <machine/reg.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/intr.h>
|
||||
#include <machine/sapicvar.h>
|
||||
|
||||
#ifdef EVCNT_COUNTERS
|
||||
struct evcnt clock_intr_evcnt; /* event counter for clock intrs. */
|
||||
@ -82,12 +84,23 @@ void
|
||||
interrupt(u_int64_t vector, struct trapframe *framep)
|
||||
{
|
||||
struct thread *td;
|
||||
volatile struct ia64_interrupt_block *ib = IA64_INTERRUPT_BLOCK;
|
||||
|
||||
td = curthread;
|
||||
atomic_add_int(&td->td_intr_nesting_level, 1);
|
||||
switch (vector) {
|
||||
case 240: /* clock interrupt */
|
||||
CTR0(KTR_INTR, "clock interrupt");
|
||||
|
||||
/*
|
||||
* Handle ExtINT interrupts by generating an INTA cycle to
|
||||
* read the vector.
|
||||
*/
|
||||
if (vector == 0) {
|
||||
vector = ib->ib_inta;
|
||||
printf("ExtINT interrupt: vector=%ld\n", vector);
|
||||
goto out; /* XXX */
|
||||
}
|
||||
|
||||
if (vector == 240) {/* clock interrupt */
|
||||
/* CTR0(KTR_INTR, "clock interrupt"); */
|
||||
|
||||
cnt.v_intr++;
|
||||
#ifdef EVCNT_COUNTERS
|
||||
@ -100,17 +113,14 @@ interrupt(u_int64_t vector, struct trapframe *framep)
|
||||
/* divide hz (1024) by 8 to get stathz (128) */
|
||||
if((++schedclk2 & 0x7) == 0)
|
||||
statclock((struct clockframe *)framep);
|
||||
break;
|
||||
|
||||
default:
|
||||
mtx_lock(&Giant);
|
||||
panic("unexpected interrupt: vec %ld\n", vector);
|
||||
/* NOTREACHED */
|
||||
} else {
|
||||
ia64_dispatch_intr(framep, vector);
|
||||
}
|
||||
|
||||
out:
|
||||
atomic_subtract_int(&td->td_intr_nesting_level, 1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
badaddr(addr, size)
|
||||
void *addr;
|
||||
@ -127,3 +137,165 @@ badaddr_read(addr, size, rptr)
|
||||
{
|
||||
return (1); /* XXX implement */
|
||||
}
|
||||
|
||||
/*
|
||||
* Hardware irqs have vectors starting at this offset.
|
||||
*/
|
||||
#define IA64_HARDWARE_IRQ_BASE 0x20
|
||||
|
||||
struct ia64_intr {
|
||||
struct ithd *ithd; /* interrupt thread */
|
||||
volatile long *cntp; /* interrupt counter */
|
||||
};
|
||||
|
||||
static struct sapic *ia64_sapics[16]; /* XXX make this resizable */
|
||||
static int ia64_sapic_count;
|
||||
static struct mtx ia64_intrs_lock;
|
||||
static struct ia64_intr *ia64_intrs[256];
|
||||
|
||||
static void ithds_init(void *dummy);
|
||||
|
||||
static void
|
||||
ithds_init(void *dummy)
|
||||
{
|
||||
|
||||
mtx_init(&ia64_intrs_lock, "ithread table lock", MTX_SPIN);
|
||||
}
|
||||
SYSINIT(ithds_init, SI_SUB_INTR, SI_ORDER_SECOND, ithds_init, NULL);
|
||||
|
||||
void
|
||||
ia64_add_sapic(struct sapic *sa)
|
||||
{
|
||||
ia64_sapics[ia64_sapic_count++] = sa;
|
||||
}
|
||||
|
||||
static void
|
||||
ia64_enable(int vector)
|
||||
{
|
||||
int irq, i;
|
||||
|
||||
irq = vector - IA64_HARDWARE_IRQ_BASE;
|
||||
for (i = 0; i < ia64_sapic_count; i++) {
|
||||
struct sapic *sa = ia64_sapics[i];
|
||||
if (irq >= sa->sa_base && irq <= sa->sa_limit)
|
||||
sapic_enable(sa, irq - sa->sa_base, vector,
|
||||
(irq < 16
|
||||
? SAPIC_TRIGGER_EDGE
|
||||
: SAPIC_TRIGGER_LEVEL),
|
||||
(irq < 16
|
||||
? SAPIC_POLARITY_HIGH
|
||||
: SAPIC_POLARITY_LOW));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ia64_send_eoi(int vector)
|
||||
{
|
||||
int irq, i;
|
||||
|
||||
irq = vector - IA64_HARDWARE_IRQ_BASE;
|
||||
for (i = 0; i < ia64_sapic_count; i++) {
|
||||
struct sapic *sa = ia64_sapics[i];
|
||||
if (irq >= sa->sa_base && irq <= sa->sa_limit)
|
||||
sapic_eoi(sa, vector);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ia64_setup_intr(const char *name, int irq, driver_intr_t handler, void *arg,
|
||||
enum intr_type flags, void **cookiep, volatile long *cntp)
|
||||
{
|
||||
struct ia64_intr *i;
|
||||
int errcode;
|
||||
int vector = irq + IA64_HARDWARE_IRQ_BASE;
|
||||
|
||||
/*
|
||||
* XXX - Can we have more than one device on a vector? If so, we have
|
||||
* a race condition here that needs to be worked around similar to
|
||||
* the fashion done in the i386 inthand_add() function.
|
||||
*/
|
||||
|
||||
/* First, check for an existing hash table entry for this vector. */
|
||||
mtx_lock_spin(&ia64_intrs_lock);
|
||||
i = ia64_intrs[vector];
|
||||
mtx_unlock_spin(&ia64_intrs_lock);
|
||||
|
||||
if (i == NULL) {
|
||||
/* None was found, so create an entry. */
|
||||
i = malloc(sizeof(struct ia64_intr), M_DEVBUF, M_NOWAIT);
|
||||
if (i == NULL)
|
||||
return ENOMEM;
|
||||
i->cntp = cntp;
|
||||
errcode = ithread_create(&i->ithd, vector, 0, 0,
|
||||
ia64_send_eoi, "intr:");
|
||||
if (errcode) {
|
||||
free(i, M_DEVBUF);
|
||||
return errcode;
|
||||
}
|
||||
|
||||
mtx_lock_spin(&ia64_intrs_lock);
|
||||
ia64_intrs[vector] = i;
|
||||
mtx_unlock_spin(&ia64_intrs_lock);
|
||||
}
|
||||
|
||||
/* Second, add this handler. */
|
||||
errcode = ithread_add_handler(i->ithd, name, handler, arg,
|
||||
ithread_priority(flags), flags, cookiep);
|
||||
if (errcode)
|
||||
return errcode;
|
||||
|
||||
ia64_enable(vector);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ia64_teardown_intr(void *cookie)
|
||||
{
|
||||
|
||||
return (ithread_remove_handler(cookie));
|
||||
}
|
||||
|
||||
void
|
||||
ia64_dispatch_intr(void *frame, unsigned long vector)
|
||||
{
|
||||
struct ia64_intr *i;
|
||||
struct ithd *ithd; /* our interrupt thread */
|
||||
struct intrhand *ih;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Find the interrupt thread for this vector.
|
||||
*/
|
||||
i = ia64_intrs[vector];
|
||||
if (i == NULL)
|
||||
return; /* no ithread for this vector */
|
||||
|
||||
ithd = i->ithd;
|
||||
KASSERT(ithd != NULL, ("interrupt vector without a thread"));
|
||||
|
||||
/*
|
||||
* As an optomization, if an ithread has no handlers, don't
|
||||
* schedule it to run.
|
||||
*/
|
||||
if (TAILQ_EMPTY(&ithd->it_handlers))
|
||||
return;
|
||||
|
||||
if (i->cntp)
|
||||
atomic_add_long(i->cntp, 1);
|
||||
|
||||
/*
|
||||
* Handle a fast interrupt if there is no actual thread for this
|
||||
* interrupt by calling the handler directly without Giant. Note
|
||||
* that this means that any fast interrupt handler must be MP safe.
|
||||
*/
|
||||
ih = TAILQ_FIRST(&ithd->it_handlers);
|
||||
if ((ih->ih_flags & IH_FAST) != 0) {
|
||||
ih->ih_handler(ih->ih_argument);
|
||||
ia64_send_eoi(vector);
|
||||
return;
|
||||
}
|
||||
|
||||
error = ithread_schedule(ithd, 0); /* XXX:no preemption for now */
|
||||
KASSERT(error == 0, ("got an impossible stray interrupt"));
|
||||
}
|
||||
|
||||
|
@ -59,6 +59,7 @@
|
||||
#include <machine/resource.h>
|
||||
|
||||
#include <isa/isavar.h>
|
||||
#include <isa/isareg.h>
|
||||
#include <sys/rtprio.h>
|
||||
|
||||
static MALLOC_DEFINE(M_NEXUSDEV, "nexusdev", "Nexus device");
|
||||
@ -163,7 +164,7 @@ nexus_probe(device_t dev)
|
||||
irq_rman.rm_start = 0;
|
||||
irq_rman.rm_type = RMAN_ARRAY;
|
||||
irq_rman.rm_descr = "Interrupt request lines";
|
||||
irq_rman.rm_end = 15;
|
||||
irq_rman.rm_end = 63;
|
||||
if (rman_init(&irq_rman)
|
||||
|| rman_manage_region(&irq_rman,
|
||||
irq_rman.rm_start, irq_rman.rm_end))
|
||||
@ -211,6 +212,12 @@ nexus_probe(device_t dev)
|
||||
static int
|
||||
nexus_attach(device_t dev)
|
||||
{
|
||||
/*
|
||||
* Mask the legacy PICs - we will use the I/O SAPIC for interrupt.
|
||||
*/
|
||||
outb(IO_ICU1+1, 0xff);
|
||||
outb(IO_ICU2+1, 0xff);
|
||||
|
||||
bus_generic_attach(dev);
|
||||
return 0;
|
||||
}
|
||||
@ -472,10 +479,8 @@ nexus_setup_intr(device_t bus, device_t child, struct resource *irq,
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
#if 0
|
||||
error = inthand_add(device_get_nameunit(child), irq->r_start,
|
||||
ihand, arg, flags, cookiep);
|
||||
#endif
|
||||
error = ia64_setup_intr(device_get_nameunit(child), irq->r_start,
|
||||
ihand, arg, flags, cookiep, 0);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
@ -29,9 +29,30 @@
|
||||
#ifndef _MACHINE_INTR_H_
|
||||
#define _MACHINE_INTR_H_
|
||||
|
||||
int alpha_setup_intr(int vector, driver_intr_t *intr, void *arg,
|
||||
void **cookiep, volatile long *cntp);
|
||||
int alpha_teardown_intr(void *cookie);
|
||||
void alpha_dispatch_intr(void *frame, unsigned long vector);
|
||||
/*
|
||||
* Layout of the Processor Interrupt Block.
|
||||
*/
|
||||
struct ia64_interrupt_block
|
||||
{
|
||||
u_int64_t ib_ipi[0x20000]; /* 1Mb of IPI interrupts */
|
||||
u_int8_t ib_reserved1[0xe0000];
|
||||
u_int8_t ib_inta; /* Generate INTA cycle */
|
||||
u_int8_t ib_reserved2[7];
|
||||
u_int8_t ib_xtp; /* XTP cycle */
|
||||
u_int8_t ib_reserved3[7];
|
||||
u_int8_t ib_reserved4[0x1fff0];
|
||||
};
|
||||
|
||||
#define IA64_INTERRUPT_BLOCK \
|
||||
(struct ia64_interrupt_block *)IA64_PHYS_TO_RR6(0xfee00000)
|
||||
|
||||
struct sapic;
|
||||
|
||||
void ia64_add_sapic(struct sapic *sa);
|
||||
int ia64_setup_intr(const char *name, int irq, driver_intr_t handler,
|
||||
void *arg, enum intr_type flags, void **cookiep,
|
||||
volatile long *cntp);
|
||||
int ia64_teardown_intr(void *cookie);
|
||||
void ia64_dispatch_intr(void *frame, unsigned long vector);
|
||||
|
||||
#endif /* !_MACHINE_INTR_H_ */
|
||||
|
48
sys/ia64/include/sapicreg.h
Normal file
48
sys/ia64/include/sapicreg.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*-
|
||||
* Copyright (c) 2001 Doug Rabson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_SAPICREG_H_
|
||||
#define _MACHINE_SAPICREG_H_
|
||||
|
||||
/*
|
||||
* Offsets from the SAPIC base in memory. Most registers are accessed
|
||||
* by indexing using the SAPIC_IO_SELECT register.
|
||||
*/
|
||||
#define SAPIC_IO_SELECT 0x00
|
||||
#define SAPIC_IO_WINDOW 0x10
|
||||
#define SAPIC_APIC_EOI 0x40
|
||||
|
||||
/*
|
||||
* Indexed registers.
|
||||
*/
|
||||
#define SAPIC_ID 0x00
|
||||
#define SAPIC_VERSION 0x01
|
||||
#define SAPIC_ARBITRATION_ID 0x02
|
||||
#define SAPIC_RTE_BASE 0x10
|
||||
|
||||
#endif /* ! _MACHINE_SAPICREG_H_ */
|
50
sys/ia64/include/sapicvar.h
Normal file
50
sys/ia64/include/sapicvar.h
Normal file
@ -0,0 +1,50 @@
|
||||
/*-
|
||||
* Copyright (c) 2001 Doug Rabson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_SAPICVAR_H_
|
||||
#define _MACHINE_SAPICVAR_H_
|
||||
|
||||
struct sapic {
|
||||
int sa_id; /* I/O SAPIC Id */
|
||||
int sa_base; /* ACPI vector base */
|
||||
int sa_limit; /* last ACPI vector handled here */
|
||||
vm_offset_t sa_registers; /* virtual address of sapic */
|
||||
};
|
||||
|
||||
#define SAPIC_TRIGGER_EDGE 0
|
||||
#define SAPIC_TRIGGER_LEVEL 1
|
||||
|
||||
#define SAPIC_POLARITY_HIGH 0
|
||||
#define SAPIC_POLARITY_LOW 1
|
||||
|
||||
struct sapic *sapic_create(int id, int base, u_int64_t address);
|
||||
void sapic_enable(struct sapic *sa, int input, int vector,
|
||||
int trigger_mode, int polarity);
|
||||
void sapic_eoi(struct sapic *sa, int vector);
|
||||
|
||||
#endif /* ! _MACHINE_SAPICVAR_H_ */
|
Loading…
Reference in New Issue
Block a user