X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=cpu%2Fppc4xx%2Finterrupts.c;h=494bd8c9ef9573b8319a9be3c308c5d8112d23df;hb=33211469f7d7e2afacf103cc55790f734572f7a6;hp=974797f4d56b15710b296b59999236c2f7e04626;hpb=d4ca31c40e8888b36635967522ec7ea03fd7e70b;p=oweals%2Fu-boot.git diff --git a/cpu/ppc4xx/interrupts.c b/cpu/ppc4xx/interrupts.c index 974797f4d5..494bd8c9ef 100644 --- a/cpu/ppc4xx/interrupts.c +++ b/cpu/ppc4xx/interrupts.c @@ -5,6 +5,13 @@ * (C) Copyright 2002 (440 port) * Scott McNutt, Artesyn Communication Producs, smcnutt@artsyncp.com * + * (C) Copyright 2003 (440GX port) + * Travis B. Sawyer, Sandburst Corporation, tsawyer@sandburst.com + * + * (C) Copyright 2008 (PPC440X05 port for Virtex 5 FX) + * Ricardo Ribalda-Universidad Autonoma de Madrid-ricardo.ribalda@uam.es + * Work supported by Qtechnology (htpp://qtec.com) + * * See file CREDITS for list of people who contributed to this * project. * @@ -28,12 +35,12 @@ #include #include #include +#include #include #include #include -#include "vecnum.h" -/****************************************************************************/ +DECLARE_GLOBAL_DATA_PTR; /* * CPM interrupt vector functions. @@ -43,16 +50,8 @@ struct irq_action { void *arg; int count; }; +static struct irq_action irq_vecs[IRQ_MAX]; -static struct irq_action irq_vecs[32]; - -#if defined(CONFIG_440) -static struct irq_action irq_vecs1[32]; /* For UIC1 */ - -void uic1_interrupt( void * parms); /* UIC1 handler */ -#endif - -/****************************************************************************/ #if defined(CONFIG_440) /* SPRN changed in 440 */ @@ -81,12 +80,8 @@ static __inline__ void set_evpr(unsigned long val) } #endif /* defined(CONFIG_440 */ -/****************************************************************************/ - int interrupt_init_cpu (unsigned *decrementer_count) { - DECLARE_GLOBAL_DATA_PTR; - int vec; unsigned long val; @@ -96,15 +91,10 @@ int interrupt_init_cpu (unsigned *decrementer_count) /* * Mark all irqs as free */ - for (vec=0; vec<32; vec++) { + for (vec = 0; vec < IRQ_MAX; vec++) { irq_vecs[vec].handler = NULL; irq_vecs[vec].arg = NULL; irq_vecs[vec].count = 0; -#if defined(CONFIG_440) - irq_vecs1[vec].handler = NULL; - irq_vecs1[vec].arg = NULL; - irq_vecs1[vec].count = 0; -#endif } #ifdef CONFIG_4xx @@ -118,7 +108,7 @@ int interrupt_init_cpu (unsigned *decrementer_count) mtspr( dec, 0 ); /* Prevent exception after TSR clear*/ mtspr( decar, 0 ); /* clear reload */ mtspr( tsr, 0x08000000 ); /* clear DEC status */ - val = gd->bd->bi_intfreq/100; /* 10 msec */ + val = gd->bd->bi_intfreq/1000; /* 1 msec */ mtspr( decar, val ); /* Set auto-reload value */ mtspr( dec, val ); /* Set inital val */ #else @@ -145,202 +135,73 @@ int interrupt_init_cpu (unsigned *decrementer_count) */ set_evpr(0x00000000); -#if defined(CONFIG_440) - /* Install the UIC1 handlers */ - irq_install_handler(VECNUM_UIC1NC, uic1_interrupt, 0); - irq_install_handler(VECNUM_UIC1C, uic1_interrupt, 0); -#endif - - return (0); -} - -/****************************************************************************/ - -/* - * Handle external interrupts - */ -void external_interrupt(struct pt_regs *regs) -{ - ulong uic_msr; - ulong msr_shift; - int vec; - /* - * Read masked interrupt status register to determine interrupt source + * Call uic or xilinx_irq pic_enable */ - uic_msr = mfdcr(uicmsr); - msr_shift = uic_msr; - vec = 0; - - while (msr_shift != 0) { - if (msr_shift & 0x80000000) { - /* - * Increment irq counter (for debug purpose only) - */ - irq_vecs[vec].count++; - - if (irq_vecs[vec].handler != NULL) { - /* call isr */ - (*irq_vecs[vec].handler)(irq_vecs[vec].arg); - } else { - mtdcr(uicer, mfdcr(uicer) & ~(0x80000000 >> vec)); - printf ("Masking bogus interrupt vector 0x%x\n", vec); - } - - /* - * After servicing the interrupt, we have to remove the status indicator. - */ - mtdcr(uicsr, (0x80000000 >> vec)); - } + pic_enable(); - /* - * Shift msr to next position and increment vector - */ - msr_shift <<= 1; - vec++; - } + return (0); } -#if defined(CONFIG_440) -/* Handler for UIC1 interrupt */ -void uic1_interrupt( void * parms) +void timer_interrupt_cpu(struct pt_regs *regs) { - ulong uic1_msr; - ulong msr_shift; - int vec; - - /* - * Read masked interrupt status register to determine interrupt source - */ - uic1_msr = mfdcr(uic1msr); - msr_shift = uic1_msr; - vec = 0; - - while (msr_shift != 0) { - if (msr_shift & 0x80000000) { - /* - * Increment irq counter (for debug purpose only) - */ - irq_vecs1[vec].count++; - - if (irq_vecs1[vec].handler != NULL) { - /* call isr */ - (*irq_vecs1[vec].handler)(irq_vecs1[vec].arg); - } else { - mtdcr(uic1er, mfdcr(uic1er) & ~(0x80000000 >> vec)); - printf ("Masking bogus interrupt vector (uic1) 0x%x\n", vec); - } - - /* - * After servicing the interrupt, we have to remove the status indicator. - */ - mtdcr(uic1sr, (0x80000000 >> vec)); - } - - /* - * Shift msr to next position and increment vector - */ - msr_shift <<= 1; - vec++; - } + /* nothing to do here */ + return; } -#endif /* defined(CONFIG_440) */ - -/****************************************************************************/ - -/* - * Install and free a interrupt handler. - */ -void -irq_install_handler(int vec, interrupt_handler_t *handler, void *arg) +void interrupt_run_handler(int vec) { - struct irq_action *irqa = irq_vecs; - int i = vec; - -#if defined(CONFIG_440) - if (vec > 31) { - i = vec - 32; - irqa = irq_vecs1; - } -#endif - - if (irqa[i].handler != NULL) { - printf ("Interrupt vector %d: handler 0x%x replacing 0x%x\n", - vec, (uint)handler, (uint)irqa[i].handler); + irq_vecs[vec].count++; + + if (irq_vecs[vec].handler != NULL) { + /* call isr */ + (*irq_vecs[vec].handler) (irq_vecs[vec].arg); + } else { + pic_irq_disable(vec); + printf("Masking bogus interrupt vector %d\n", vec); } - irqa[i].handler = handler; - irqa[i].arg = arg; -#if defined(CONFIG_440) - if( vec > 31 ) - mtdcr(uic1er, mfdcr(uic1er) | (0x80000000 >> i)); - else -#endif - mtdcr(uicer, mfdcr(uicer) | (0x80000000 >> i)); -#if 0 - printf ("Install interrupt for vector %d ==> %p\n", vec, handler); -#endif + pic_irq_ack(vec); + return; } -void -irq_free_handler(int vec) +void irq_install_handler(int vec, interrupt_handler_t * handler, void *arg) { - struct irq_action *irqa = irq_vecs; - int i = vec; - -#if defined(CONFIG_440) - if (vec > 31) { - irqa = irq_vecs1; - i = vec - 32; + /* + * Print warning when replacing with a different irq vector + */ + if ((irq_vecs[vec].handler != NULL) && (irq_vecs[vec].handler != handler)) { + printf("Interrupt vector %d: handler 0x%x replacing 0x%x\n", + vec, (uint) handler, (uint) irq_vecs[vec].handler); } -#endif - -#if 0 - printf ("Free interrupt for vector %d ==> %p\n", - vec, irq_vecs[vec].handler); -#endif + irq_vecs[vec].handler = handler; + irq_vecs[vec].arg = arg; -#if defined(CONFIG_440) - if (vec > 31) - mtdcr(uic1er, mfdcr(uic1er) & ~(0x80000000 >> i)); - else -#endif - mtdcr(uicer, mfdcr(uicer) & ~(0x80000000 >> i)); - - irqa[i].handler = NULL; - irqa[i].arg = NULL; + pic_irq_enable(vec); + return; } -/****************************************************************************/ - -void timer_interrupt_cpu (struct pt_regs *regs) +void irq_free_handler(int vec) { - /* nothing to do here */ - return; -} + debug("Free interrupt for vector %d ==> %p\n", + vec, irq_vecs[vec].handler); -/****************************************************************************/ + pic_irq_disable(vec); -#if (CONFIG_COMMANDS & CFG_CMD_IRQ) + irq_vecs[vec].handler = NULL; + irq_vecs[vec].arg = NULL; + return; +} -/******************************************************************************* - * - * irqinfo - print information about PCI devices - * - */ -int -do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +#if defined(CONFIG_CMD_IRQ) +int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { int vec; - printf ("\nInterrupt-Information:\n"); -#if defined(CONFIG_440) - printf ("\nUIC 0\n"); -#endif + printf ("Interrupt-Information:\n"); printf ("Nr Routine Arg Count\n"); - for (vec=0; vec<32; vec++) { + for (vec = 0; vec < IRQ_MAX; vec++) { if (irq_vecs[vec].handler != NULL) { printf ("%02d %08lx %08lx %d\n", vec, @@ -350,21 +211,6 @@ do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } } -#if defined(CONFIG_440) - printf ("\nUIC 1\n"); - printf ("Nr Routine Arg Count\n"); - - for (vec=0; vec<32; vec++) - { - if (irq_vecs1[vec].handler != NULL) - printf ("%02d %08lx %08lx %d\n", - vec+31, (ulong)irq_vecs1[vec].handler, - (ulong)irq_vecs1[vec].arg, irq_vecs1[vec].count); - } - printf("\n"); -#endif return 0; } - - -#endif /* CONFIG_COMMANDS & CFG_CMD_IRQ */ +#endif