summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorTill Straumann <strauman@slac.stanford.edu>2007-12-02 20:46:00 +0000
committerTill Straumann <strauman@slac.stanford.edu>2007-12-02 20:46:00 +0000
commita3ae58967fa9e3024a7c7352a1439af6751c8e60 (patch)
tree05f2f14d533a41cf66686ab9d0092c266c559eaa /c
parent2007-12-01 Till Straumann <strauman@slac.stanford.edu> (diff)
downloadrtems-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/ChangeLog13
-rw-r--r--c/src/lib/libbsp/powerpc/shared/openpic/openpic.c50
-rw-r--r--c/src/lib/libbsp/powerpc/shared/openpic/openpic.h51
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);