Some fixes to the current RMI interrupt handling, changes in this patch are:
- (cleanup) remove rmi specific 'struct mips_intrhand' - this is no longer needed since 'struct intr_event' have all the required hooks - add xlr_cpu_establish_hardintr, which has args for pre/post ithread and filter hooks, so that the PCI code can add the PCI controller interrupt ack code here - make 'cpu_establish_hardintr' use the above function. - (fix) change type of eirr/eimr from register_t to uint64_t. These have to be 64bit otherwise we cannot handle interrupts from 32. - (fix) use eimr to mask eirr before checking interrupts, so that we will not handle masked interrupts. Obtained from: C. Jayachandran - c.jayachandran@gmail.com
This commit is contained in:
parent
d91c59ee1e
commit
0364c7f075
@ -30,21 +30,7 @@
|
||||
#define _MACHINE_INTR_MACHDEP_H_
|
||||
|
||||
#ifdef TARGET_XLR_XLS
|
||||
/*
|
||||
* XLR/XLS uses its own intr_machdep.c and has
|
||||
* a different number of interupts. This probably
|
||||
* should be placed somewhere else.
|
||||
*/
|
||||
|
||||
struct mips_intrhand {
|
||||
struct intr_event *mih_event;
|
||||
driver_intr_t *mih_disable;
|
||||
volatile long *cntp; /* interrupt counter */
|
||||
};
|
||||
|
||||
extern struct mips_intrhand mips_intr_handlers[];
|
||||
#define XLR_MAX_INTR 64
|
||||
|
||||
#else
|
||||
#define NHARD_IRQS 6
|
||||
#define NSOFT_IRQS 2
|
||||
|
@ -25,7 +25,7 @@
|
||||
* 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.
|
||||
*
|
||||
*__FBSDID("$FreeBSD$")
|
||||
* RMI_BSD */
|
||||
#ifndef _RMI_INTERRUPT_H_
|
||||
#define _RMI_INTERRUPT_H_
|
||||
@ -39,4 +39,14 @@
|
||||
#define IRQ_MSGRING 6
|
||||
#define IRQ_TIMER 7
|
||||
|
||||
/*
|
||||
* XLR needs custom pre and post handlers for PCI/PCI-e interrupts
|
||||
* XXX: maybe follow i386 intsrc model
|
||||
*/
|
||||
void xlr_cpu_establish_hardintr(const char *, driver_filter_t *,
|
||||
driver_intr_t *, void *, int, int, void **, void (*)(void *),
|
||||
void (*)(void *), void (*)(void *), int (*)(void *, u_char));
|
||||
void xlr_mask_hard_irq(void *);
|
||||
void xlr_unmask_hard_irq(void *);
|
||||
|
||||
#endif /* _RMI_INTERRUPT_H_ */
|
||||
|
@ -51,19 +51,19 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
/*#include <machine/intrcnt.h>*/
|
||||
static mips_intrcnt_t mips_intr_counters[XLR_MAX_INTR];
|
||||
struct mips_intrhand mips_intr_handlers[XLR_MAX_INTR];
|
||||
static struct intr_event *mips_intr_events[XLR_MAX_INTR];
|
||||
static int intrcnt_index;
|
||||
|
||||
static void
|
||||
mips_mask_hard_irq(void *source)
|
||||
void
|
||||
xlr_mask_hard_irq(void *source)
|
||||
{
|
||||
uintptr_t irq = (uintptr_t) source;
|
||||
|
||||
write_c0_eimr64(read_c0_eimr64() & ~(1ULL << irq));
|
||||
}
|
||||
|
||||
static void
|
||||
mips_unmask_hard_irq(void *source)
|
||||
void
|
||||
xlr_unmask_hard_irq(void *source)
|
||||
{
|
||||
uintptr_t irq = (uintptr_t) source;
|
||||
|
||||
@ -71,10 +71,11 @@ mips_unmask_hard_irq(void *source)
|
||||
}
|
||||
|
||||
void
|
||||
cpu_establish_hardintr(const char *name, driver_filter_t * filt,
|
||||
void (*handler) (void *), void *arg, int irq, int flags, void **cookiep)
|
||||
xlr_cpu_establish_hardintr(const char *name, driver_filter_t * filt,
|
||||
void (*handler) (void *), void *arg, int irq, int flags, void **cookiep,
|
||||
void (*pre_ithread)(void *), void (*post_ithread)(void *),
|
||||
void (*post_filter)(void *), int (*assign_cpu)(void *, u_char))
|
||||
{
|
||||
struct mips_intrhand *mih; /* descriptor for the IRQ */
|
||||
struct intr_event *ie; /* descriptor for the IRQ */
|
||||
int errcode;
|
||||
|
||||
@ -85,25 +86,33 @@ cpu_establish_hardintr(const char *name, driver_filter_t * filt,
|
||||
* FIXME locking - not needed now, because we do this only on
|
||||
* startup from CPU0
|
||||
*/
|
||||
mih = &mips_intr_handlers[irq];
|
||||
ie = mips_intr_events[irq];
|
||||
/* mih->cntp = &intrcnt[irq]; */
|
||||
ie = mih->mih_event;
|
||||
if (ie == NULL) {
|
||||
errcode = intr_event_create(&ie, (void *)(uintptr_t) irq, 0,
|
||||
irq, mips_mask_hard_irq, mips_unmask_hard_irq,
|
||||
NULL, NULL, "hard intr%d:", irq);
|
||||
irq, pre_ithread, post_ithread, post_filter, assign_cpu,
|
||||
"hard intr%d:", irq);
|
||||
|
||||
if (errcode) {
|
||||
printf("Could not create event for intr %d\n", irq);
|
||||
return;
|
||||
}
|
||||
mips_intr_events[irq] = ie;
|
||||
}
|
||||
|
||||
intr_event_add_handler(ie, name, filt, handler, arg,
|
||||
intr_priority(flags), flags, cookiep);
|
||||
mih->mih_event = ie;
|
||||
mips_unmask_hard_irq((void *)(uintptr_t) irq);
|
||||
xlr_unmask_hard_irq((void *)(uintptr_t) irq);
|
||||
}
|
||||
|
||||
void
|
||||
cpu_establish_hardintr(const char *name, driver_filter_t * filt,
|
||||
void (*handler) (void *), void *arg, int irq, int flags, void **cookiep)
|
||||
{
|
||||
xlr_cpu_establish_hardintr(name, filt, handler, arg, irq,
|
||||
flags, cookiep, xlr_mask_hard_irq, xlr_unmask_hard_irq,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
cpu_establish_softintr(const char *name, driver_filter_t * filt,
|
||||
@ -111,19 +120,25 @@ cpu_establish_softintr(const char *name, driver_filter_t * filt,
|
||||
void **cookiep)
|
||||
{
|
||||
/* we don't separate them into soft/hard like other mips */
|
||||
cpu_establish_hardintr(name, filt, handler, arg, irq, flags, cookiep);
|
||||
xlr_cpu_establish_hardintr(name, filt, handler, arg, irq,
|
||||
flags, cookiep, xlr_mask_hard_irq, xlr_unmask_hard_irq,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
cpu_intr(struct trapframe *tf)
|
||||
{
|
||||
struct mips_intrhand *mih;
|
||||
struct intr_event *ie;
|
||||
register_t eirr;
|
||||
uint64_t eirr, eimr;
|
||||
int i;
|
||||
|
||||
critical_enter();
|
||||
|
||||
/* find a list of enabled interrupts */
|
||||
eirr = read_c0_eirr64();
|
||||
eimr = read_c0_eimr64();
|
||||
eirr &= eimr;
|
||||
|
||||
if (eirr == 0) {
|
||||
critical_exit();
|
||||
return;
|
||||
@ -162,9 +177,8 @@ cpu_intr(struct trapframe *tf)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
mih = &mips_intr_handlers[i];
|
||||
ie = mips_intr_events[i];
|
||||
/* atomic_add_long(mih->cntp, 1); */
|
||||
ie = mih->mih_event;
|
||||
|
||||
write_c0_eirr64(1ULL << i);
|
||||
pic_ack(i, 0);
|
||||
|
Loading…
x
Reference in New Issue
Block a user