diff options
author | Till Straumann <strauman@slac.stanford.edu> | 2007-12-02 20:46:00 +0000 |
---|---|---|
committer | Till Straumann <strauman@slac.stanford.edu> | 2007-12-02 20:46:00 +0000 |
commit | a3ae58967fa9e3024a7c7352a1439af6751c8e60 (patch) | |
tree | 05f2f14d533a41cf66686ab9d0092c266c559eaa /c | |
parent | 2007-12-01 Till Straumann <strauman@slac.stanford.edu> (diff) | |
download | rtems-a3ae58967fa9e3024a7c7352a1439af6751c8e60.tar.bz2 |
2007-12-02 Till Straumann <strauman@slac.stanford.edu>
* shared/openpic/openpic.c, shared/openpic/openpic.h:
- eliminated conditional compilation (#ifdef mpc8240)
The difference in register-layout between the EPIC
and the std. openPIC is handled by an offset parameter
which can be set at run-time (initialization) with
a new routine 'openpic_set_src_offset()'.
- allow BSP to define symbol BSP_OPEN_PIC_BIG_ENDIAN
which builds the driver for big-endian register access
(mpc8540).
- openpic_disable_irq() now returns the old state so
that it can be restored later.
Diffstat (limited to 'c')
-rw-r--r-- | c/src/lib/libbsp/powerpc/ChangeLog | 13 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/shared/openpic/openpic.c | 50 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/shared/openpic/openpic.h | 51 |
3 files changed, 82 insertions, 32 deletions
diff --git a/c/src/lib/libbsp/powerpc/ChangeLog b/c/src/lib/libbsp/powerpc/ChangeLog index f88babd37f..ac723d234f 100644 --- a/c/src/lib/libbsp/powerpc/ChangeLog +++ b/c/src/lib/libbsp/powerpc/ChangeLog @@ -1,3 +1,16 @@ +2007-12-02 Till Straumann <strauman@slac.stanford.edu> + * shared/openpic/openpic.c, shared/openpic/openpic.h: + - eliminated conditional compilation (#ifdef mpc8240) + The difference in register-layout between the EPIC + and the std. openPIC is handled by an offset parameter + which can be set at run-time (initialization) with + a new routine 'openpic_set_src_offset()'. + - allow BSP to define symbol BSP_OPEN_PIC_BIG_ENDIAN + which builds the driver for big-endian register access + (mpc8540). + - openpic_disable_irq() now returns the old state so + that it can be restored later. + 2007-12-01 Till Straumann <strauman@slac.stanford.edu> * shared/irq/openpic_i8259_irq.c: diff --git a/c/src/lib/libbsp/powerpc/shared/openpic/openpic.c b/c/src/lib/libbsp/powerpc/shared/openpic/openpic.c index 8c9562310a..f752055cd7 100644 --- a/c/src/lib/libbsp/powerpc/shared/openpic/openpic.c +++ b/c/src/lib/libbsp/powerpc/shared/openpic/openpic.c @@ -39,9 +39,9 @@ volatile struct OpenPIC *OpenPIC = NULL; static unsigned int NumProcessors; static unsigned int NumSources; -#if defined(mpc8240) || defined(mpc8245) static unsigned int openpic_eoi_delay = 0; -#endif +static int openpic_src_offst = 0; +#define SOURCE(irq) Source[ (irq) + openpic_src_offst ] /* * Accesses to the current processor's registers @@ -93,7 +93,11 @@ static inline unsigned int openpic_read(volatile unsigned int *addr) { unsigned int val; +#ifdef BSP_OPEN_PIC_BIG_ENDIAN + val = in_be32(addr); +#else val = in_le32(addr); +#endif #ifdef REGISTER_DEBUG printk("openpic_read(0x%08x) = 0x%08x\n", (unsigned int)addr, val); #endif @@ -105,7 +109,11 @@ static inline void openpic_write(volatile unsigned int *addr, unsigned int val) #ifdef REGISTER_DEBUG printk("openpic_write(0x%08x, 0x%08x)\n", (unsigned int)addr, val); #endif - out_le32(addr, val); +#ifdef BSP_OPEN_PIC_BIG_ENDIAN + out_be32(addr, val); +#else + out_le32(addr, val); +#endif } static inline unsigned int openpic_readfield(volatile unsigned int *addr, unsigned int mask) @@ -321,19 +329,24 @@ unsigned int openpic_irq(unsigned int cpu) void openpic_eoi(unsigned int cpu) { check_arg_cpu(cpu); -#if defined(mpc8240) || defined(mpc8245) if ( openpic_eoi_delay ) rtems_bsp_delay_in_bus_cycles(openpic_eoi_delay); -#endif openpic_write(&OpenPIC->THIS_CPU.EOI, 0); } -#if defined(mpc8240) || defined(mpc8245) -void openpic_set_eoi_delay(unsigned tb_cycles) +unsigned openpic_set_eoi_delay(unsigned tb_cycles) { +unsigned rval = openpic_eoi_delay; openpic_eoi_delay = tb_cycles; + return rval; +} + +int openpic_set_src_offst(int offset) +{ +int rval = openpic_src_offst; + openpic_src_offst = offset; + return rval; } -#endif /* * Get/set the current task priority @@ -452,17 +465,22 @@ void openpic_enable_irq(unsigned int irq) unsigned long flags; check_arg_irq(irq); rtems_interrupt_disable(flags); - openpic_clearfield(&OpenPIC->Source[irq].Vector_Priority, OPENPIC_MASK); + openpic_clearfield(&OpenPIC->SOURCE(irq).Vector_Priority, OPENPIC_MASK); rtems_interrupt_enable(flags); } -void openpic_disable_irq(unsigned int irq) +int openpic_disable_irq(unsigned int irq) { +int rval; unsigned long flags; check_arg_irq(irq); + if ( irq < 0 || irq >=NumSources ) + return -1; rtems_interrupt_disable(flags); - openpic_setfield(&OpenPIC->Source[irq].Vector_Priority, OPENPIC_MASK); + rval = openpic_readfield(&OpenPIC->SOURCE(irq).Vector_Priority, OPENPIC_MASK) ? 0 : 1; + openpic_setfield(&OpenPIC->SOURCE(irq).Vector_Priority, OPENPIC_MASK); rtems_interrupt_enable(flags); + return rval; } /* @@ -485,7 +503,7 @@ void openpic_initirq(unsigned int irq, unsigned int pri, unsigned int vec, int p check_arg_irq(irq); check_arg_pri(pri); check_arg_vec(vec); - openpic_safe_writefield(&OpenPIC->Source[irq].Vector_Priority, + openpic_safe_writefield(&OpenPIC->SOURCE(irq).Vector_Priority, OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK | OPENPIC_SENSE_POLARITY | OPENPIC_SENSE_LEVEL, (pri << OPENPIC_PRIORITY_SHIFT) | vec | @@ -500,7 +518,7 @@ void openpic_initirq(unsigned int irq, unsigned int pri, unsigned int vec, int p void openpic_mapirq(unsigned int irq, unsigned int cpumask) { check_arg_irq(irq); - openpic_write(&OpenPIC->Source[irq].Destination, cpumask); + openpic_write(&OpenPIC->SOURCE(irq).Destination, cpumask); } /* @@ -509,7 +527,7 @@ void openpic_mapirq(unsigned int irq, unsigned int cpumask) unsigned int openpic_get_source_priority(unsigned int irq) { check_arg_irq(irq); - return openpic_readfield(&OpenPIC->Source[irq].Vector_Priority, + return openpic_readfield(&OpenPIC->SOURCE(irq).Vector_Priority, OPENPIC_PRIORITY_MASK) >> OPENPIC_PRIORITY_SHIFT; } @@ -520,7 +538,7 @@ unsigned long flags; check_arg_pri(pri); rtems_interrupt_disable(flags); openpic_writefield( - &OpenPIC->Source[irq].Vector_Priority, + &OpenPIC->SOURCE(irq).Vector_Priority, OPENPIC_PRIORITY_MASK, pri << OPENPIC_PRIORITY_SHIFT); rtems_interrupt_enable(flags); @@ -534,7 +552,7 @@ unsigned long flags; void openpic_set_sense(unsigned int irq, int sense) { check_arg_irq(irq); - openpic_safe_writefield(&OpenPIC->Source[irq].Vector_Priority, + openpic_safe_writefield(&OpenPIC->SOURCE(irq).Vector_Priority, OPENPIC_SENSE_LEVEL, (sense ? OPENPIC_SENSE_LEVEL : 0)); } diff --git a/c/src/lib/libbsp/powerpc/shared/openpic/openpic.h b/c/src/lib/libbsp/powerpc/shared/openpic/openpic.h index 492742188f..b69a37687b 100644 --- a/c/src/lib/libbsp/powerpc/shared/openpic/openpic.h +++ b/c/src/lib/libbsp/powerpc/shared/openpic/openpic.h @@ -40,19 +40,7 @@ /* * OpenPIC supports up to 2048 interrupt sources and up to 32 processors */ - -#if defined(mpc8240) || defined(mpc8245) -#define OPENPIC_MAX_SOURCES (2048 - 16) -/* If the BSP uses the serial interrupt mode / 'multiplexer' then - * EOI must be delayed by at least 16 SRAM_CLK cycles to avoid - * spurious interrupts. - * It is the BSP's responsibility to set up an appropriate delay - * (in timebase-clock cycles) at init time. - */ -extern void openpic_set_eoi_delay(unsigned tb_cycles); -#else #define OPENPIC_MAX_SOURCES 2048 -#endif #define OPENPIC_MAX_PROCESSORS 32 #define OPENPIC_NUM_TIMERS 4 @@ -162,9 +150,6 @@ typedef struct _OpenPIC_Global { OpenPIC_Reg _Timer_Frequency; /* Read/Write */ OpenPIC_Timer Timer[OPENPIC_NUM_TIMERS]; char Pad1[0xee00]; -#if defined(mpc8240) || defined(mpc8245) - char Pad2[0x0200]; -#endif } OpenPIC_Global; /* @@ -306,6 +291,40 @@ extern volatile struct OpenPIC *OpenPIC; * OpenPIC Operations */ +/* + * Handle EPIC differences. Unfortunately, I don't know of an easy + * way to tell an EPIC from a normal PIC at run-time. Therefore, + * the BSP must enable a few quirks if it knows that an EPIC is being + * used: + * - If the BSP uses the serial interrupt mode / 'multiplexer' then + * EOI must be delayed by at least 16 SRAM_CLK cycles to avoid + * spurious interrupts. + * It is the BSP's responsibility to set up an appropriate delay + * (in timebase-clock cycles) at init time using + * 'openpic_set_eoi_delay()'. This is ONLY necessary when using + * an EPIC in serial mode. + * - The EPIC sources start at an offset of 16 in the register + * map, i.e., on an EPIC you'd say Sources[ x + 16 ] where + * on a PIC you would say Sources[ x ]. + * Again, the BSP can set an offset that is used by the + * calls dealing with 'Interrupt Sources' + * openpic_enable_irq() + * openpic_disable_irq() + * openpic_initirq() + * openpic_mapirq() + * openpic_set_sense() + * openpic_get_source_priority() + * openpic_set_source_priority() + * + * The routines 'openpic_set_eoi_delay()' and 'openpic_set_src_offst()' + * return the respective previous values of the affected parameters. + * + * NOTE: openpic_set_src_offst() MUST be called PRIOR to openpic_init() + */ +extern unsigned openpic_set_eoi_delay(unsigned tb_cycles); +extern int openpic_set_src_offst(int offset); + + /* Global Operations */ extern void openpic_init(int,unsigned char *, unsigned char *); extern void openpic_reset(void); @@ -329,7 +348,7 @@ extern void openpic_maptimer(unsigned int timer, unsigned int cpumask); /* Interrupt Sources */ extern void openpic_enable_irq(unsigned int irq); -extern void openpic_disable_irq(unsigned int irq); +extern int openpic_disable_irq(unsigned int irq); extern void openpic_initirq(unsigned int irq, unsigned int pri, unsigned int vector, int polarity, int is_level); extern void openpic_mapirq(unsigned int irq, unsigned int cpumask); |