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.
This commit is contained in:
Till Straumann
2007-12-02 20:46:00 +00:00
parent f2783292a6
commit a3ae58967f
3 changed files with 82 additions and 32 deletions

View File

@@ -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:

View File

@@ -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));
}

View File

@@ -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);