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>
|
2007-12-01 Till Straumann <strauman@slac.stanford.edu>
|
||||||
|
|
||||||
* shared/irq/openpic_i8259_irq.c:
|
* shared/irq/openpic_i8259_irq.c:
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ volatile struct OpenPIC *OpenPIC = NULL;
|
|||||||
static unsigned int NumProcessors;
|
static unsigned int NumProcessors;
|
||||||
static unsigned int NumSources;
|
static unsigned int NumSources;
|
||||||
|
|
||||||
#if defined(mpc8240) || defined(mpc8245)
|
|
||||||
static unsigned int openpic_eoi_delay = 0;
|
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
|
* Accesses to the current processor's registers
|
||||||
@@ -93,7 +93,11 @@ static inline unsigned int openpic_read(volatile unsigned int *addr)
|
|||||||
{
|
{
|
||||||
unsigned int val;
|
unsigned int val;
|
||||||
|
|
||||||
|
#ifdef BSP_OPEN_PIC_BIG_ENDIAN
|
||||||
|
val = in_be32(addr);
|
||||||
|
#else
|
||||||
val = in_le32(addr);
|
val = in_le32(addr);
|
||||||
|
#endif
|
||||||
#ifdef REGISTER_DEBUG
|
#ifdef REGISTER_DEBUG
|
||||||
printk("openpic_read(0x%08x) = 0x%08x\n", (unsigned int)addr, val);
|
printk("openpic_read(0x%08x) = 0x%08x\n", (unsigned int)addr, val);
|
||||||
#endif
|
#endif
|
||||||
@@ -105,7 +109,11 @@ static inline void openpic_write(volatile unsigned int *addr, unsigned int val)
|
|||||||
#ifdef REGISTER_DEBUG
|
#ifdef REGISTER_DEBUG
|
||||||
printk("openpic_write(0x%08x, 0x%08x)\n", (unsigned int)addr, val);
|
printk("openpic_write(0x%08x, 0x%08x)\n", (unsigned int)addr, val);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef BSP_OPEN_PIC_BIG_ENDIAN
|
||||||
|
out_be32(addr, val);
|
||||||
|
#else
|
||||||
out_le32(addr, val);
|
out_le32(addr, val);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned int openpic_readfield(volatile unsigned int *addr, unsigned int mask)
|
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)
|
void openpic_eoi(unsigned int cpu)
|
||||||
{
|
{
|
||||||
check_arg_cpu(cpu);
|
check_arg_cpu(cpu);
|
||||||
#if defined(mpc8240) || defined(mpc8245)
|
|
||||||
if ( openpic_eoi_delay )
|
if ( openpic_eoi_delay )
|
||||||
rtems_bsp_delay_in_bus_cycles(openpic_eoi_delay);
|
rtems_bsp_delay_in_bus_cycles(openpic_eoi_delay);
|
||||||
#endif
|
|
||||||
openpic_write(&OpenPIC->THIS_CPU.EOI, 0);
|
openpic_write(&OpenPIC->THIS_CPU.EOI, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(mpc8240) || defined(mpc8245)
|
unsigned openpic_set_eoi_delay(unsigned tb_cycles)
|
||||||
void openpic_set_eoi_delay(unsigned tb_cycles)
|
|
||||||
{
|
{
|
||||||
|
unsigned rval = openpic_eoi_delay;
|
||||||
openpic_eoi_delay = tb_cycles;
|
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
|
* Get/set the current task priority
|
||||||
@@ -452,17 +465,22 @@ void openpic_enable_irq(unsigned int irq)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
check_arg_irq(irq);
|
check_arg_irq(irq);
|
||||||
rtems_interrupt_disable(flags);
|
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);
|
rtems_interrupt_enable(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void openpic_disable_irq(unsigned int irq)
|
int openpic_disable_irq(unsigned int irq)
|
||||||
{
|
{
|
||||||
|
int rval;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
check_arg_irq(irq);
|
check_arg_irq(irq);
|
||||||
|
if ( irq < 0 || irq >=NumSources )
|
||||||
|
return -1;
|
||||||
rtems_interrupt_disable(flags);
|
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);
|
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_irq(irq);
|
||||||
check_arg_pri(pri);
|
check_arg_pri(pri);
|
||||||
check_arg_vec(vec);
|
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_PRIORITY_MASK | OPENPIC_VECTOR_MASK |
|
||||||
OPENPIC_SENSE_POLARITY | OPENPIC_SENSE_LEVEL,
|
OPENPIC_SENSE_POLARITY | OPENPIC_SENSE_LEVEL,
|
||||||
(pri << OPENPIC_PRIORITY_SHIFT) | vec |
|
(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)
|
void openpic_mapirq(unsigned int irq, unsigned int cpumask)
|
||||||
{
|
{
|
||||||
check_arg_irq(irq);
|
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)
|
unsigned int openpic_get_source_priority(unsigned int irq)
|
||||||
{
|
{
|
||||||
check_arg_irq(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;
|
OPENPIC_PRIORITY_MASK) >> OPENPIC_PRIORITY_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,7 +538,7 @@ unsigned long flags;
|
|||||||
check_arg_pri(pri);
|
check_arg_pri(pri);
|
||||||
rtems_interrupt_disable(flags);
|
rtems_interrupt_disable(flags);
|
||||||
openpic_writefield(
|
openpic_writefield(
|
||||||
&OpenPIC->Source[irq].Vector_Priority,
|
&OpenPIC->SOURCE(irq).Vector_Priority,
|
||||||
OPENPIC_PRIORITY_MASK,
|
OPENPIC_PRIORITY_MASK,
|
||||||
pri << OPENPIC_PRIORITY_SHIFT);
|
pri << OPENPIC_PRIORITY_SHIFT);
|
||||||
rtems_interrupt_enable(flags);
|
rtems_interrupt_enable(flags);
|
||||||
@@ -534,7 +552,7 @@ unsigned long flags;
|
|||||||
void openpic_set_sense(unsigned int irq, int sense)
|
void openpic_set_sense(unsigned int irq, int sense)
|
||||||
{
|
{
|
||||||
check_arg_irq(irq);
|
check_arg_irq(irq);
|
||||||
openpic_safe_writefield(&OpenPIC->Source[irq].Vector_Priority,
|
openpic_safe_writefield(&OpenPIC->SOURCE(irq).Vector_Priority,
|
||||||
OPENPIC_SENSE_LEVEL,
|
OPENPIC_SENSE_LEVEL,
|
||||||
(sense ? OPENPIC_SENSE_LEVEL : 0));
|
(sense ? OPENPIC_SENSE_LEVEL : 0));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,19 +40,7 @@
|
|||||||
/*
|
/*
|
||||||
* OpenPIC supports up to 2048 interrupt sources and up to 32 processors
|
* 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
|
#define OPENPIC_MAX_SOURCES 2048
|
||||||
#endif
|
|
||||||
#define OPENPIC_MAX_PROCESSORS 32
|
#define OPENPIC_MAX_PROCESSORS 32
|
||||||
|
|
||||||
#define OPENPIC_NUM_TIMERS 4
|
#define OPENPIC_NUM_TIMERS 4
|
||||||
@@ -162,9 +150,6 @@ typedef struct _OpenPIC_Global {
|
|||||||
OpenPIC_Reg _Timer_Frequency; /* Read/Write */
|
OpenPIC_Reg _Timer_Frequency; /* Read/Write */
|
||||||
OpenPIC_Timer Timer[OPENPIC_NUM_TIMERS];
|
OpenPIC_Timer Timer[OPENPIC_NUM_TIMERS];
|
||||||
char Pad1[0xee00];
|
char Pad1[0xee00];
|
||||||
#if defined(mpc8240) || defined(mpc8245)
|
|
||||||
char Pad2[0x0200];
|
|
||||||
#endif
|
|
||||||
} OpenPIC_Global;
|
} OpenPIC_Global;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -306,6 +291,40 @@ extern volatile struct OpenPIC *OpenPIC;
|
|||||||
* OpenPIC Operations
|
* 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 */
|
/* Global Operations */
|
||||||
extern void openpic_init(int,unsigned char *, unsigned char *);
|
extern void openpic_init(int,unsigned char *, unsigned char *);
|
||||||
extern void openpic_reset(void);
|
extern void openpic_reset(void);
|
||||||
@@ -329,7 +348,7 @@ extern void openpic_maptimer(unsigned int timer, unsigned int cpumask);
|
|||||||
|
|
||||||
/* Interrupt Sources */
|
/* Interrupt Sources */
|
||||||
extern void openpic_enable_irq(unsigned int irq);
|
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,
|
extern void openpic_initirq(unsigned int irq, unsigned int pri, unsigned int vector, int polarity,
|
||||||
int is_level);
|
int is_level);
|
||||||
extern void openpic_mapirq(unsigned int irq, unsigned int cpumask);
|
extern void openpic_mapirq(unsigned int irq, unsigned int cpumask);
|
||||||
|
|||||||
Reference in New Issue
Block a user