forked from Imagelibrary/rtems
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:
@@ -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:
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user