OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [i960/] [kernel/] [ints.c] - Diff between revs 1765 and 1782

Only display areas with differences | Details | Blame | View Log

Rev 1765 Rev 1782
/*
/*
 * linux/arch/i960/kernel/ints.c
 * linux/arch/i960/kernel/ints.c
 *
 *
 * Copyright (C) 1999   Keith Adams     <kma@cse.ogi.edu>
 * Copyright (C) 1999   Keith Adams     <kma@cse.ogi.edu>
 *                      Oregon Graduate Institute
 *                      Oregon Graduate Institute
 *
 *
 * Based on:
 * Based on:
 *
 *
 * linux/arch/i386/kernel/irq.c
 * linux/arch/i386/kernel/irq.c
 *
 *
 * Copyright (C) 1992 Linux Torvalds
 * Copyright (C) 1992 Linux Torvalds
 *
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file COPYING in the main directory of this archive
 * License.  See the file COPYING in the main directory of this archive
 * for more details.
 * for more details.
 *
 *
 * N.B. that we treat "irq" as meaning, the high order four bits of the vector
 * N.B. that we treat "irq" as meaning, the high order four bits of the vector
 * number. Since there seems to be no way to set the low bits to something other
 * number. Since there seems to be no way to set the low bits to something other
 * than 0010, this is good enough for us.
 * than 0010, this is good enough for us.
 */
 */
 
 
#include <linux/types.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/kernel_stat.h>
#include <linux/kernel_stat.h>
#include <linux/errno.h>
#include <linux/errno.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/config.h>
#include <linux/config.h>
#include <linux/ip.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/tcp.h>
 
 
#include <asm/atomic.h>
#include <asm/atomic.h>
#include <asm/system.h>
#include <asm/system.h>
#include <asm/irq.h>
#include <asm/irq.h>
#include <asm/traps.h>
#include <asm/traps.h>
#include <asm/page.h>
#include <asm/page.h>
#include <asm/ptrace.h>
#include <asm/ptrace.h>
#include <asm/machdep.h>
#include <asm/machdep.h>
#include <asm/i960.h>
#include <asm/i960.h>
#include <asm/unistd.h>
#include <asm/unistd.h>
 
 
#if defined(CONFIG_I960JX) || defined(CONFIG_I960VH)
#if defined(CONFIG_I960JX) || defined(CONFIG_I960VH)
#include <asm/i960jx.h>
#include <asm/i960jx.h>
#endif
#endif
 
 
/*
/*
 * device vectors; the *_HO macros are the corresponding indices into the
 * device vectors; the *_HO macros are the corresponding indices into the
 * low-mem isr table
 * low-mem isr table
 */
 */
#define NMI_VEC         248
#define NMI_VEC         248
 
 
#define LED     ((unsigned char*)0xe0040000)
#define LED     ((unsigned char*)0xe0040000)
#define LED_THRESHOLD   (HZ/2)
#define LED_THRESHOLD   (HZ/2)
 
 
#define TMR0_VEC_HO 0xd
#define TMR0_VEC_HO 0xd
#define TMR1_VEC_HO 0xe
#define TMR1_VEC_HO 0xe
#define XINT0_VEC_HO 1
#define XINT0_VEC_HO 1
#define XINT1_VEC_HO 2
#define XINT1_VEC_HO 2
#define XINT2_VEC_HO 3
#define XINT2_VEC_HO 3
#define XINT3_VEC_HO 4
#define XINT3_VEC_HO 4
#define XINT4_VEC_HO 5
#define XINT4_VEC_HO 5
#define XINT5_VEC_HO 6
#define XINT5_VEC_HO 6
#define XINT6_VEC_HO 7
#define XINT6_VEC_HO 7
#define XINT7_VEC_HO 8
#define XINT7_VEC_HO 8
 
 
static char* irq_names[] = {
static char* irq_names[] = {
        0,       /* 0 */
        0,       /* 0 */
        "xint0",
        "xint0",
        "xint1",
        "xint1",
        "xint2",
        "xint2",
        "xint3",
        "xint3",
        "serial",
        "serial",
        "xint5",
        "xint5",
        "xint6",
        "xint6",
        "xint7",
        "xint7",
        0, 0, 0, 0,
        0, 0, 0, 0,
        "timer0",
        "timer0",
        "timer1",
        "timer1",
        0,
        0,
};
};
 
 
#ifdef CONFIG_PROF_IRQ
#ifdef CONFIG_PROF_IRQ
static struct irqstat {
static struct irqstat {
        unsigned long   min;
        unsigned long   min;
        unsigned long   avg;
        unsigned long   avg;
        unsigned long   max;
        unsigned long   max;
} irqstat[16];
} irqstat[16];
#endif
#endif
 
 
static void* pci_dev;
static void* pci_dev;
static const char* pci_name;
static const char* pci_name;
static void (*pci_isr)(int, void *, struct pt_regs *);
static void (*pci_isr)(int, void *, struct pt_regs *);
 
 
#define __VEC(ho)       (((ho) << 4) | 2)
#define __VEC(ho)       (((ho) << 4) | 2)
#define TMR0_VEC __VEC(TMR0_VEC_HO)
#define TMR0_VEC __VEC(TMR0_VEC_HO)
#define TMR1_VEC __VEC(TMR1_VEC_HO)
#define TMR1_VEC __VEC(TMR1_VEC_HO)
#define XINT0_VEC __VEC(XINT0_VEC_HO)
#define XINT0_VEC __VEC(XINT0_VEC_HO)
#define XINT1_VEC __VEC(XINT1_VEC_HO)
#define XINT1_VEC __VEC(XINT1_VEC_HO)
#define XINT2_VEC __VEC(XINT2_VEC_HO)
#define XINT2_VEC __VEC(XINT2_VEC_HO)
#define XINT3_VEC __VEC(XINT3_VEC_HO)
#define XINT3_VEC __VEC(XINT3_VEC_HO)
#define XINT4_VEC __VEC(XINT4_VEC_HO)
#define XINT4_VEC __VEC(XINT4_VEC_HO)
#define SERIAL_VEC XINT4_VEC
#define SERIAL_VEC XINT4_VEC
#define PCI_VEC XINT1_VEC
#define PCI_VEC XINT1_VEC
#define XINT5_VEC __VEC(XINT5_VEC_HO)
#define XINT5_VEC __VEC(XINT5_VEC_HO)
#define XINT6_VEC __VEC(XINT6_VEC_HO)
#define XINT6_VEC __VEC(XINT6_VEC_HO)
#define XINT7_VEC __VEC(XINT7_VEC_HO)
#define XINT7_VEC __VEC(XINT7_VEC_HO)
 
 
 
 
void leave_kernel(struct pt_regs* regs);
void leave_kernel(struct pt_regs* regs);
static void nmi_intr(void);
static void nmi_intr(void);
static void bad_intr(unsigned char vec, struct pt_regs* regs);
static void bad_intr(unsigned char vec, struct pt_regs* regs);
static void xint(unsigned char ho, struct pt_regs* regs);
static void xint(unsigned char ho, struct pt_regs* regs);
void stack_trace(void);
void stack_trace(void);
 
 
extern void intr(void);
extern void intr(void);
static void program_clock(void);
static void program_clock(void);
 
 
#ifdef CONFIG_MON960
#ifdef CONFIG_MON960
#include <asm/i960jx.h>
#include <asm/i960jx.h>
#include <asm/mon960.h>
#include <asm/mon960.h>
 
 
static unsigned long get_mon960_serial_isr(void)
static unsigned long get_mon960_serial_isr(void)
{
{
        prcb_t* prcb = (prcb_t*)get_prcbptr();
        prcb_t* prcb = (prcb_t*)get_prcbptr();
        unsigned long vec = (*(unsigned long*)IMAP1 & 0x0f00) >> 8;
        unsigned long vec = (*(unsigned long*)IMAP1 & 0x0f00) >> 8;
 
 
        /* on cyclone, serial isr is XINT5 */
        /* on cyclone, serial isr is XINT5 */
        return (unsigned long) prcb->pr_intr_tab->i_vectors[vec];
        return (unsigned long) prcb->pr_intr_tab->i_vectors[vec];
}
}
 
 
#endif
#endif
 
 
static void init_syscalls(void)
static void init_syscalls(void)
{
{
        unsigned long** prcb = (unsigned long**)get_prcbptr();
        unsigned long** prcb = (unsigned long**)get_prcbptr();
        unsigned long* syscall_tab = prcb[5];
        unsigned long* syscall_tab = prcb[5];
        extern void syscall(void);
        extern void syscall(void);
        /* we only use syscall 0, which is 12 words from the start of
        /* we only use syscall 0, which is 12 words from the start of
         * the syscall table. The entry type field of 0x2 indicates a call
         * the syscall table. The entry type field of 0x2 indicates a call
         * to supervisor mode.  */
         * to supervisor mode.  */
        syscall_tab[12] = ((unsigned long) syscall) | 0x2;
        syscall_tab[12] = ((unsigned long) syscall) | 0x2;
        return;
        return;
}
}
 
 
/*
/*
 * At entry here, we have a high ipl. We need to establish
 * At entry here, we have a high ipl. We need to establish
 * our isr's, and enable the clock.
 * our isr's, and enable the clock.
 */
 */
void init_IRQ(void)
void init_IRQ(void)
{
{
        unsigned long   *dram = 0;
        unsigned long   *dram = 0;
        int     ii;
        int     ii;
 
 
        /* set up the following layout in low RAM for our 15 vectors:
        /* set up the following layout in low RAM for our 15 vectors:
         * 0:           NMI (we have no choice about this)
         * 0:           NMI (we have no choice about this)
         * 1-8:         XINT0-7
         * 1-8:         XINT0-7
         * 9-12:        Invalid
         * 9-12:        Invalid
         * 13:          Timer0. Note that Timer1 is disabled.
         * 13:          Timer0. Note that Timer1 is disabled.
         * 14-15:       Invalid.
         * 14-15:       Invalid.
         *
         *
         * This works out nicely, since the vector number-1 is the
         * This works out nicely, since the vector number-1 is the
         * corresponding bit in IMSK; see disable_irq below.
         * corresponding bit in IMSK; see disable_irq below.
         */
         */
        atmod((void*)IMAP0, 0xffff, 0x4321);            /* xint 0-3 */
        atmod((void*)IMAP0, 0xffff, 0x4321);            /* xint 0-3 */
        atmod((void*)IMAP1, 0xffff, 0x8756);            /* xint 4-7 */
        atmod((void*)IMAP1, 0xffff, 0x8756);            /* xint 4-7 */
        atmod((void*)IMAP2, 0xff<<16, 0xed << 16);      /* Timer 0, Timer 1 */
        atmod((void*)IMAP2, 0xff<<16, 0xed << 16);      /* Timer 0, Timer 1 */
 
 
        /* we vector all interrupts through intr */
        /* we vector all interrupts through intr */
        for (ii=0; ii < 16; ii++)
        for (ii=0; ii < 16; ii++)
                dram[ii] = (unsigned long)intr;
                dram[ii] = (unsigned long)intr;
 
 
#ifdef CONFIG_MON960
#ifdef CONFIG_MON960
        /* reset the XINT5 interrupt handler from software */
        /* reset the XINT5 interrupt handler from software */
        dram[XINT5_VEC_HO] = get_mon960_serial_isr();
        dram[XINT5_VEC_HO] = get_mon960_serial_isr();
#endif
#endif
 
 
        program_clock();
        program_clock();
        /* set 13th bit of ICON; enable vector caching */
        /* set 13th bit of ICON; enable vector caching */
        atmod((void*)ICON, 1<<13, 1<<13);
        atmod((void*)ICON, 1<<13, 1<<13);
        /*
        /*
         * XXX: what to mask is somewhat board dependent; we leave XINT4
         * XXX: what to mask is somewhat board dependent; we leave XINT4
         * masked because Cyclone needs it to always be masked.
         * masked because Cyclone needs it to always be masked.
         */
         */
        atmod((void*)IPND, ~0, 0);
        atmod((void*)IPND, ~0, 0);
        atmod((void*)IMSK, 0x30ef, 0x30ef);
        atmod((void*)IMSK, 0x30ef, 0x30ef);
 
 
        /* Now set up syscalls */
        /* Now set up syscalls */
        init_syscalls();
        init_syscalls();
}
}
 
 
#define TRR0    (volatile unsigned long*)0xff000300
#define TRR0    (volatile unsigned long*)0xff000300
#define TCR0    (volatile unsigned long*)0xff000304
#define TCR0    (volatile unsigned long*)0xff000304
#define TMR0    (volatile unsigned long*)0xff000308
#define TMR0    (volatile unsigned long*)0xff000308
 
 
#define TRR1    (volatile unsigned long*)0xff000310
#define TRR1    (volatile unsigned long*)0xff000310
#define TCR1    (volatile unsigned long*)0xff000314
#define TCR1    (volatile unsigned long*)0xff000314
#define TMR1    (volatile unsigned long*)0xff000318
#define TMR1    (volatile unsigned long*)0xff000318
/* some helper macros for programming the mode register, TMR0 */
/* some helper macros for programming the mode register, TMR0 */
 
 
/* the clock may decrement once per cpu cycle, once every two cycles, ...
/* the clock may decrement once per cpu cycle, once every two cycles, ...
 * up to eight; set the appropriate bits in TMR0
 * up to eight; set the appropriate bits in TMR0
 */
 */
#define CLOCKSHIFT 4
#define CLOCKSHIFT 4
#define CLOCKDIV(x)     (x << CLOCKSHIFT)
#define CLOCKDIV(x)     (x << CLOCKSHIFT)
#define CLOCKDIV1 CLOCKDIV(0)
#define CLOCKDIV1 CLOCKDIV(0)
#define CLOCKDIV2 CLOCKDIV(1)
#define CLOCKDIV2 CLOCKDIV(1)
#define CLOCKDIV4 CLOCKDIV(2)
#define CLOCKDIV4 CLOCKDIV(2)
#define CLOCKDIV8 CLOCKDIV(3)
#define CLOCKDIV8 CLOCKDIV(3)
 
 
#define CLOCK_ENABLE            2       /* set for clock to work */
#define CLOCK_ENABLE            2       /* set for clock to work */
#define CLOCK_AUTO_RELOAD       4       /* reload from TRR0 when we reach 0 */
#define CLOCK_AUTO_RELOAD       4       /* reload from TRR0 when we reach 0 */
#define CLOCK_SUPER_ONLY        8       /* don't let users reprogram clocks */
#define CLOCK_SUPER_ONLY        8       /* don't let users reprogram clocks */
 
 
/*
/*
 * Set up timer 0 to interrupt us every so many clocks. Assumes
 * Set up timer 0 to interrupt us every so many clocks. Assumes
 * interrupts are disabled.
 * interrupts are disabled.
 */
 */
static void
static void
program_clock(void)
program_clock(void)
{
{
        /* 33Mhz PCI Bus assumed */
        /* 33Mhz PCI Bus assumed */
#define CYCLES_PER_HZ   (33 * 1000* 1000) / HZ
#define CYCLES_PER_HZ   (33 * 1000* 1000) / HZ
        *TRR0 = *TCR0 = CYCLES_PER_HZ;
        *TRR0 = *TCR0 = CYCLES_PER_HZ;
        *TMR0 = CLOCKDIV1 | CLOCK_ENABLE | CLOCK_AUTO_RELOAD | CLOCK_SUPER_ONLY;
        *TMR0 = CLOCKDIV1 | CLOCK_ENABLE | CLOCK_AUTO_RELOAD | CLOCK_SUPER_ONLY;
 
 
#ifdef CONFIG_PROF_IRQ
#ifdef CONFIG_PROF_IRQ
        disable_irq(TMR1_VEC_HO);
        disable_irq(TMR1_VEC_HO);
#endif
#endif
}
}
 
 
irq_node_t *new_irq_node(void)
irq_node_t *new_irq_node(void)
{
{
        /* XXX: write me */
        /* XXX: write me */
        return NULL;
        return NULL;
}
}
 
 
int request_irq(unsigned int irq,
int request_irq(unsigned int irq,
                void (*handler)(int, void *, struct pt_regs *),
                void (*handler)(int, void *, struct pt_regs *),
                unsigned long flags, const char *devname, void *dev_id)
                unsigned long flags, const char *devname, void *dev_id)
{
{
        /* XXX: this is a stopgap; we only can handle one pci device */
        /* XXX: this is a stopgap; we only can handle one pci device */
        if (pci_dev)
        if (pci_dev)
                return -1;
                return -1;
 
 
        pci_dev = dev_id;
        pci_dev = dev_id;
        pci_name = devname;
        pci_name = devname;
        pci_isr = handler;
        pci_isr = handler;
        return 0;
        return 0;
}
}
 
 
void free_irq(unsigned int irq, void *dev_id)
void free_irq(unsigned int irq, void *dev_id)
{
{
        pci_dev = 0;
        pci_dev = 0;
}
}
 
 
/*
/*
 * Do we need these probe functions on the i960?
 * Do we need these probe functions on the i960?
 */
 */
unsigned long probe_irq_on (void)
unsigned long probe_irq_on (void)
{
{
        return 0;
        return 0;
}
}
 
 
int probe_irq_off (unsigned long irqs)
int probe_irq_off (unsigned long irqs)
{
{
        return 0;
        return 0;
}
}
 
 
void disable_irq(unsigned int irq)
void disable_irq(unsigned int irq)
{
{
        if (irq && irq < SYS_IRQS)
        if (irq && irq < SYS_IRQS)
                atmod((void*)IMSK, 1<<(irq-1), 0);
                atmod((void*)IMSK, 1<<(irq-1), 0);
}
}
 
 
void enable_irq(unsigned int irq)
void enable_irq(unsigned int irq)
{
{
        if (irq && irq < SYS_IRQS)
        if (irq && irq < SYS_IRQS)
                atmod((void*)IMSK, 1<<(irq-1), 1<<(irq-1));
                atmod((void*)IMSK, 1<<(irq-1), 1<<(irq-1));
}
}
 
 
#ifdef CONFIG_PROF_IRQ
#ifdef CONFIG_PROF_IRQ
#define SAMPLE_BITS     7
#define SAMPLE_BITS     7
static inline void
static inline void
update_prof_timers(int vec, unsigned long ticks)
update_prof_timers(int vec, unsigned long ticks)
{
{
        struct irqstat* irq;
        struct irqstat* irq;
        vec = vec >> 4;
        vec = vec >> 4;
        irq = irqstat + vec;
        irq = irqstat + vec;
 
 
        if (!irq->avg)  {
        if (!irq->avg)  {
                irq->max = ticks;
                irq->max = ticks;
                irq->min = ticks;
                irq->min = ticks;
                irq->avg = ticks;
                irq->avg = ticks;
                return;
                return;
        }
        }
 
 
        if (ticks < irq->min)
        if (ticks < irq->min)
                irq->min = ticks;
                irq->min = ticks;
        if (ticks > irq->max)
        if (ticks > irq->max)
                irq->max = ticks;
                irq->max = ticks;
        irq->avg -= irq->avg >> SAMPLE_BITS;
        irq->avg -= irq->avg >> SAMPLE_BITS;
        irq->avg += ticks >> SAMPLE_BITS;
        irq->avg += ticks >> SAMPLE_BITS;
}
}
#endif
#endif
 
 
/*
/*
 * Interrupt service routine. N.B. that XINT0, which is really a system call,
 * Interrupt service routine. N.B. that XINT0, which is really a system call,
 * is never routed to cintr; it ends up in syscall instead.
 * is never routed to cintr; it ends up in syscall instead.
 */
 */
extern void do_signal(void);
extern void do_signal(void);
asmlinkage void cintr(unsigned char vec, struct pt_regs* regs)
asmlinkage void cintr(unsigned char vec, struct pt_regs* regs)
{
{
        extern void timer_interrupt(struct pt_regs* regs);
        extern void timer_interrupt(struct pt_regs* regs);
        static int ticks;
        static int ticks;
#ifdef CONFIG_PROF_IRQ
#ifdef CONFIG_PROF_IRQ
        unsigned long clocks;
        unsigned long clocks;
        *TCR1 = CYCLES_PER_HZ * HZ;
        *TCR1 = CYCLES_PER_HZ * HZ;
        *TMR1 = CLOCKDIV1 | CLOCK_ENABLE;
        *TMR1 = CLOCKDIV1 | CLOCK_ENABLE;
#endif
#endif
        atomic_inc(&intr_count);
        atomic_inc(&intr_count);
 
 
        kstat.interrupts[vec >> 4]++;
        kstat.interrupts[vec >> 4]++;
        switch(vec) {
        switch(vec) {
                case    NMI_VEC:
                case    NMI_VEC:
                        nmi_intr();
                        nmi_intr();
                        break;
                        break;
 
 
                case    XINT1_VEC:
                case    XINT1_VEC:
                case    XINT0_VEC:
                case    XINT0_VEC:
                case    XINT2_VEC:
                case    XINT2_VEC:
                case    XINT3_VEC:
                case    XINT3_VEC:
                case    XINT4_VEC:
                case    XINT4_VEC:
                case    XINT5_VEC:
                case    XINT5_VEC:
                case    XINT6_VEC:
                case    XINT6_VEC:
                case    XINT7_VEC:
                case    XINT7_VEC:
                        xint(vec, regs);
                        xint(vec, regs);
                        break;
                        break;
 
 
                case    TMR0_VEC:
                case    TMR0_VEC:
                        if ((++ticks) >= LED_THRESHOLD) {
                        if ((++ticks) >= LED_THRESHOLD) {
                                static char nm = 0;
                                static char nm = 0;
                                *LED = ~ (1 << (nm++ % 8));
                                *LED = ~ (1 << (nm++ % 8));
                                ticks = 0;
                                ticks = 0;
                        }
                        }
                        timer_interrupt(regs);
                        timer_interrupt(regs);
                        break;
                        break;
 
 
                default:
                default:
                        bad_intr(vec, regs);
                        bad_intr(vec, regs);
                        break;
                        break;
        }
        }
        atomic_dec(&intr_count);
        atomic_dec(&intr_count);
 
 
        if (!intr_count)
        if (!intr_count)
                leave_kernel(regs);
                leave_kernel(regs);
 
 
#ifdef CONFIG_PROF_IRQ
#ifdef CONFIG_PROF_IRQ
        clocks = CYCLES_PER_HZ*HZ - *TCR1;
        clocks = CYCLES_PER_HZ*HZ - *TCR1;
        update_prof_timers(vec, clocks);
        update_prof_timers(vec, clocks);
#endif
#endif
        return;
        return;
}
}
 
 
/*
/*
 * Common code to interrupt and syscall paths. When leaving the kernel, and not
 * Common code to interrupt and syscall paths. When leaving the kernel, and not
 * returning to an interrupt context, do a whole bunch of processing.
 * returning to an interrupt context, do a whole bunch of processing.
 *
 *
 * Note that if we're called from cintr, we're running at high ipl.
 * Note that if we're called from cintr, we're running at high ipl.
 *
 *
 * Run the bottom half, check if scheduling is needed, and deliver signals to
 * Run the bottom half, check if scheduling is needed, and deliver signals to
 * the current process, just as in every other architecture.
 * the current process, just as in every other architecture.
 */
 */
void leave_kernel(struct pt_regs* regs)
void leave_kernel(struct pt_regs* regs)
{
{
bh:
bh:
        if (bh_mask & bh_active) {
        if (bh_mask & bh_active) {
                atomic_inc(&intr_count);
                atomic_inc(&intr_count);
                do_bottom_half();
                do_bottom_half();
                atomic_dec(&intr_count);
                atomic_dec(&intr_count);
        }
        }
        sti();
        sti();
 
 
        if (user_mode(regs)) {
        if (user_mode(regs)) {
                if (need_resched) {
                if (need_resched) {
                        schedule();
                        schedule();
                        goto bh;
                        goto bh;
                }
                }
 
 
 
 
                if (current->signal & ~current->blocked) {
                if (current->signal & ~current->blocked) {
                        do_signal();
                        do_signal();
                }
                }
        }
        }
}
}
 
 
static void nmi_intr(void)
static void nmi_intr(void)
{
{
        /* XXX: write me */
        /* XXX: write me */
}
}
 
 
static void bad_intr(unsigned char vec, struct pt_regs* regs)
static void bad_intr(unsigned char vec, struct pt_regs* regs)
{
{
        /* XXX: write me */
        /* XXX: write me */
        printk("whoah! bad intr: %x\n", vec);
        printk("whoah! bad intr: %x\n", vec);
}
}
 
 
static void xint(unsigned char vec, struct pt_regs* regs)
static void xint(unsigned char vec, struct pt_regs* regs)
{
{
        /*
        /*
         * This basically shouldn't happen
         * This basically shouldn't happen
         */
         */
#ifdef CONFIG_MON960_CONSOLE
#ifdef CONFIG_MON960_CONSOLE
        if (vec == SERIAL_VEC) {
        if (vec == SERIAL_VEC) {
                extern void do_16552_intr(void);
                extern void do_16552_intr(void);
                do_16552_intr();
                do_16552_intr();
                return;
                return;
        }
        }
#endif
#endif
 
 
#ifdef CONFIG_PCI
#ifdef CONFIG_PCI
        if (vec == PCI_VEC && pci_dev) {
        if (vec == PCI_VEC && pci_dev) {
                pci_isr(0, pci_dev, regs);
                pci_isr(0, pci_dev, regs);
                return;
                return;
        }
        }
#endif
#endif
        printk("EEP: xint %x\n", vec);
        printk("EEP: xint %x\n", vec);
        stack_trace();
        stack_trace();
}
}
 
 
int get_irq_list(char *buf)
int get_irq_list(char *buf)
{
{
        int     len = 0;
        int     len = 0;
        int     ii;
        int     ii;
 
 
        for (ii=0; ii < 16; ii++) {
        for (ii=0; ii < 16; ii++) {
                if (irq_names[ii]) {
                if (irq_names[ii]) {
#ifdef CONFIG_PROF_IRQ
#ifdef CONFIG_PROF_IRQ
                        len += sprintf(buf+len, "%d\t%s\t(%08x, %08x, %08x)\n",
                        len += sprintf(buf+len, "%d\t%s\t(%08x, %08x, %08x)\n",
                                       kstat.interrupts[ii],
                                       kstat.interrupts[ii],
                                       (ii==2 && pci_dev)
                                       (ii==2 && pci_dev)
                                       ? pci_name
                                       ? pci_name
                                       : irq_names[ii],
                                       : irq_names[ii],
                                       irqstat[ii].min, irqstat[ii].avg,
                                       irqstat[ii].min, irqstat[ii].avg,
                                       irqstat[ii].max);
                                       irqstat[ii].max);
#else
#else
                        len += sprintf(buf+len, "%d\t%s\n",
                        len += sprintf(buf+len, "%d\t%s\n",
                                       kstat.interrupts[ii],
                                       kstat.interrupts[ii],
                                       (ii==2 && pci_dev)
                                       (ii==2 && pci_dev)
                                       ? pci_name
                                       ? pci_name
                                       : irq_names[ii]);
                                       : irq_names[ii]);
#endif
#endif
                }
                }
        }
        }
        return len;
        return len;
}
}
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.