summaryrefslogtreecommitdiffstats
path: root/c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2009-07-03 15:08:54 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2009-07-03 15:08:54 +0000
commitfc5490fe84850d51e7cbfc43377ec6844d793b87 (patch)
tree936bfb0a3056da3936d7ab0867c40f3e130304db /c
parent2009-07-01 Sebastian Huber <sebastian.huber@embedded-brains.de> (diff)
downloadrtems-fc5490fe84850d51e7cbfc43377ec6844d793b87.tar.bz2
2009-07-01 Sebastian Huber <sebastian.huber@embedded-brains.de>
* shared/irq/irq.h, shared/irq/irq.c, shared/irq/irq_init.c: Converted to use generic interrupt support. * shared/irq/irq-config.h: New file.
Diffstat (limited to '')
-rw-r--r--c/src/lib/libbsp/i386/ChangeLog6
-rw-r--r--c/src/lib/libbsp/i386/shared/irq/irq-config.h39
-rw-r--r--c/src/lib/libbsp/i386/shared/irq/irq.c318
-rw-r--r--c/src/lib/libbsp/i386/shared/irq/irq.h1
-rw-r--r--c/src/lib/libbsp/i386/shared/irq/irq_init.c112
5 files changed, 112 insertions, 364 deletions
diff --git a/c/src/lib/libbsp/i386/ChangeLog b/c/src/lib/libbsp/i386/ChangeLog
index c212ac36f3..0e994091a1 100644
--- a/c/src/lib/libbsp/i386/ChangeLog
+++ b/c/src/lib/libbsp/i386/ChangeLog
@@ -1,3 +1,9 @@
+2009-07-01 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+ * shared/irq/irq.h, shared/irq/irq.c, shared/irq/irq_init.c: Converted
+ to use generic interrupt support.
+ * shared/irq/irq-config.h: New file.
+
2009-05-06 Joel Sherrill <joel.sherrill@oarcorp.com>
* shared/comm/i386-stub-glue.c, shared/comm/uart.c, shared/irq/irq.c,
diff --git a/c/src/lib/libbsp/i386/shared/irq/irq-config.h b/c/src/lib/libbsp/i386/shared/irq/irq-config.h
new file mode 100644
index 0000000000..992898e5ea
--- /dev/null
+++ b/c/src/lib/libbsp/i386/shared/irq/irq-config.h
@@ -0,0 +1,39 @@
+/**
+ * @file
+ *
+ * @ingroup bsp_interrupt
+ *
+ * @brief i386 interrupt support configuration.
+ */
+
+/*
+ * Copyright (c) 2009
+ * embedded brains GmbH
+ * Obere Lagerstr. 30
+ * D-82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id$
+ */
+
+#ifndef LIBBSP_I386_SHARED_IRQ_CONFIG_H
+#define LIBBSP_I386_SHARED_IRQ_CONFIG_H
+
+#include <bsp/irq.h>
+
+/**
+ * @brief Minimum vector number.
+ */
+#define BSP_INTERRUPT_VECTOR_MIN BSP_LOWEST_OFFSET
+
+/**
+ * @brief Maximum vector number.
+ */
+#define BSP_INTERRUPT_VECTOR_MAX BSP_MAX_OFFSET
+
+#endif /* LIBBSP_I386_SHARED_IRQ_CONFIG_H */
diff --git a/c/src/lib/libbsp/i386/shared/irq/irq.c b/c/src/lib/libbsp/i386/shared/irq/irq.c
index 325c53b79f..5e546a3309 100644
--- a/c/src/lib/libbsp/i386/shared/irq/irq.c
+++ b/c/src/lib/libbsp/i386/shared/irq/irq.c
@@ -2,6 +2,7 @@
*
* This file contains the implementation of the function described in irq.h
*
+ * Copyright (c) 2009 embedded brains GmbH
* Copyright (C) 1998 valette@crf.canon.fr
*
* The license and distribution terms for this file may be
@@ -16,6 +17,8 @@
#include <bsp.h>
#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
+
#include <stdlib.h>
#include <rtems/score/apiext.h>
@@ -29,17 +32,6 @@
*/
rtems_i8259_masks irq_mask_or_tbl[BSP_IRQ_LINES_NUMBER];
-/*
- * default handler connected on each irq after bsp initialization
- */
-static rtems_irq_connect_data default_rtems_entry;
-
-/*
- * location used to store initial tables used for interrupt
- * management.
- */
-static rtems_irq_global_settings* internal_config;
-rtems_irq_connect_data* rtems_hdl_tbl;
/*-------------------------------------------------------------------------+
| Cache for 1st and 2nd PIC IRQ line's status (enabled or disabled) register.
+--------------------------------------------------------------------------*/
@@ -160,287 +152,83 @@ int BSP_irq_ack_at_i8259s (const rtems_irq_number irqLine)
* ------------------------ RTEMS Irq helper functions ----------------
*/
-/*
- * Caution : this function assumes the variable "internal_config"
- * is already set and that the tables it contains are still valid
- * and accessible.
- */
+static rtems_irq_prio irqPrioTable[BSP_IRQ_LINES_NUMBER]={
+ /*
+ * actual rpiorities for interrupt :
+ * 0 means that only current interrupt is masked
+ * 255 means all other interrupts are masked
+ * The second entry has a priority of 255 because
+ * it is the slave pic entry and is should always remain
+ * unmasked.
+ */
+ 0,0,
+ 255,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
static void compute_i8259_masks_from_prio (void)
{
+ rtems_interrupt_level level;
unsigned int i;
unsigned int j;
+
+ rtems_interrupt_disable(level); /* XXX */
+
/*
* Always mask at least current interrupt to prevent re-entrance
*/
- for (i=0; i < internal_config->irqNb; i++) {
+ for (i=0; i < BSP_IRQ_LINES_NUMBER; i++) {
* ((unsigned short*) &irq_mask_or_tbl[i]) = (1 << i);
- for (j = 0; j < internal_config->irqNb; j++) {
+ for (j = 0; j < BSP_IRQ_LINES_NUMBER; j++) {
/*
* Mask interrupts at i8259 level that have a lower priority
*/
- if (internal_config->irqPrioTbl [i] > internal_config->irqPrioTbl [j]) {
+ if (irqPrioTable [i] > irqPrioTable [j]) {
* ((unsigned short*) &irq_mask_or_tbl[i]) |= (1 << j);
}
}
}
-}
-
-/*
- * This function check that the value given for the irq line
- * is valid.
- */
-
-static int isValidInterrupt(int irq)
-{
- if ( (irq < BSP_LOWEST_OFFSET) || (irq > BSP_MAX_OFFSET))
- return 0;
- return 1;
-}
-
-/*
- * ------------------- RTEMS Shared Irq Handler Mngt Routines ------------
- */
-int BSP_install_rtems_shared_irq_handler (const rtems_irq_connect_data* irq)
-{
- rtems_interrupt_level level;
- rtems_irq_connect_data* vchain;
-
- if (!isValidInterrupt(irq->name)) {
- printk("Invalid interrupt vector %d\n",irq->name);
- return 0;
- }
-
- rtems_interrupt_disable(level);
-
- if ( (int)rtems_hdl_tbl[irq->name].next_handler == -1 ) {
- rtems_interrupt_enable(level);
- printk(
- "IRQ vector %d already connected to an unshared handler\n",
- irq->name
- );
- return 0;
- }
-
- vchain = (rtems_irq_connect_data*)malloc(sizeof(rtems_irq_connect_data));
-
- /* save off topmost handler */
- vchain[0]= rtems_hdl_tbl[irq->name];
-
- /*
- * store the data provided by user
- */
- rtems_hdl_tbl[irq->name] = *irq;
-
- /* link chain to new topmost handler */
- rtems_hdl_tbl[irq->name].next_handler = (void *)vchain;
-
- /*
- * enable_irq_at_pic is supposed to ignore
- * requests to disable interrupts outside
- * of the range handled by the PIC
- */
- BSP_irq_enable_at_i8259s (irq->name);
-
- /*
- * Enable interrupt on device
- */
- if (irq->on)
- irq->on(irq);
rtems_interrupt_enable(level);
-
- return 1;
}
-
-/*
- * --------------- RTEMS Single Irq Handler Mngt Routines ---------------
- */
-
-int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq)
+rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector)
{
- rtems_interrupt_level level;
+ BSP_irq_enable_at_i8259s(vector);
- if (!isValidInterrupt(irq->name)) {
- return 0;
- }
- /*
- * Check if default handler is actually connected. If not issue an error.
- * You must first get the current handler via i386_get_current_idt_entry
- * and then disconnect it using i386_delete_idt_entry.
- * RATIONALE : to always have the same transition by forcing the user
- * to get the previous handler before accepting to disconnect.
- */
- rtems_interrupt_disable(level);
- if (rtems_hdl_tbl[irq->name].hdl != default_rtems_entry.hdl) {
- rtems_interrupt_enable(level);
- return 0;
- }
-
- /*
- * store the data provided by user
- */
- rtems_hdl_tbl[irq->name] = *irq;
- rtems_hdl_tbl[irq->name].next_handler = (void *)-1;
-
- /*
- * Enable interrupt at PIC level
- */
- BSP_irq_enable_at_i8259s (irq->name);
- /*
- * Enable interrupt on device
- */
- if (irq->on)
- irq->on(irq);
-
- rtems_interrupt_enable(level);
-
- return 1;
+ return RTEMS_SUCCESSFUL;
}
-int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* irq)
+rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector)
{
- rtems_interrupt_level level;
+ BSP_irq_disable_at_i8259s(vector);
- if (!isValidInterrupt(irq->name)) {
- return 0;
- }
- rtems_interrupt_disable(level);
- *irq = rtems_hdl_tbl[irq->name];
- rtems_interrupt_enable(level);
- return 1;
+ return RTEMS_SUCCESSFUL;
}
-int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq)
+rtems_status_code bsp_interrupt_facility_initialize(void)
{
- rtems_interrupt_level level;
- rtems_irq_connect_data *pchain= NULL, *vchain = NULL;
-
- if (!isValidInterrupt(irq->name)) {
- return 0;
- }
-
/*
- * Check if default handler is actually connected. If not issue an error.
- * You must first get the current handler via i386_get_current_idt_entry
- * and then disconnect it using i386_delete_idt_entry.
- * RATIONALE : to always have the same transition by forcing the user
- * to get the previous handler before accepting to disconnect.
+ * set up internal tables used by rtems interrupt prologue
*/
- rtems_interrupt_disable(level);
- if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) {
- rtems_interrupt_enable(level);
- return 0;
- }
-
- if ( (int)rtems_hdl_tbl[irq->name].next_handler != -1 ) {
- int found = 0;
-
- for( (pchain= NULL, vchain = &rtems_hdl_tbl[irq->name]);
- (vchain->hdl != default_rtems_entry.hdl);
- (pchain= vchain,
- vchain = (rtems_irq_connect_data*)vchain->next_handler) ) {
- if ( vchain->hdl == irq->hdl ) {
- found = -1;
- break;
- }
- }
-
- if ( !found ) {
- rtems_interrupt_enable(level);
- return 0;
- }
- } else {
- if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) {
- rtems_interrupt_enable(level);
- return 0;
- }
- }
-
- /*
- * disable interrupt at PIC level
- */
- BSP_irq_disable_at_i8259s (irq->name);
+ compute_i8259_masks_from_prio();
/*
- * Disable interrupt on device
+ * must enable slave pic anyway
*/
- if (irq->off)
- irq->off(irq);
+ BSP_irq_enable_at_i8259s(2);
- /*
- * restore the default irq value
- */
- if( !vchain ) {
- /* single handler vector... */
- rtems_hdl_tbl[irq->name] = default_rtems_entry;
- } else {
- if ( pchain ) {
- /* non-first handler being removed */
- pchain->next_handler = vchain->next_handler;
- } else {
- /* first handler isn't malloc'ed, so just overwrite it. Since
- * the contents of vchain are being struct copied, vchain itself
- * goes away
- */
- vchain = vchain->next_handler;
- rtems_hdl_tbl[irq->name]= *vchain;
- }
- free(vchain);
- }
-
-
- rtems_interrupt_enable(level);
-
- return 1;
+ return RTEMS_SUCCESSFUL;
}
-/*
- * ------------------------ RTEMS Global Irq Handler Mngt Routines ----------------
- */
-
-int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config)
+void bsp_interrupt_handler_default(rtems_vector_number vector)
{
- int i;
- rtems_irq_connect_data* vchain;
- rtems_interrupt_level level;
-
- /*
- * Store various code accelerators
- */
- internal_config = config;
- default_rtems_entry = config->defaultEntry;
- rtems_hdl_tbl = config->irqHdlTbl;
-
- rtems_interrupt_disable(level);
- /*
- * set up internal tables used by rtems interrupt prologue
- */
- compute_i8259_masks_from_prio ();
-
- for (i=0; i < internal_config->irqNb; i++) {
- BSP_irq_disable_at_i8259s (i);
- for( vchain = &rtems_hdl_tbl[i];
- ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl);
- vchain = (rtems_irq_connect_data*)vchain->next_handler ) {
- BSP_irq_enable_at_i8259s (i);
- if (vchain->on)
- vchain->on(vchain);
- }
- }
-
- /*
- * must enable slave pic anyway
- */
- BSP_irq_enable_at_i8259s (2);
- rtems_interrupt_enable(level);
- return 1;
+ printk("spurious interrupt: %u\n", vector);
}
-int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** config)
+void C_dispatch_isr(int vector)
{
- *config = internal_config;
- return 0;
+ bsp_interrupt_handler_dispatch(vector);
}
void _ThreadProcessSignalsFromIrq (CPU_Exception_frame* ctx)
@@ -461,29 +249,3 @@ void _ThreadProcessSignalsFromIrq (CPU_Exception_frame* ctx)
* This will include DEBUG session requested from keyboard...
*/
}
-
-void processIrq(unsigned index)
-{
- rtems_hdl_tbl[index].hdl(rtems_hdl_tbl[index].handle);
-}
-
-static inline void
-bsp_irq_dispatch_list(
- rtems_irq_connect_data *tbl,
- unsigned irq,
- rtems_irq_hdl sentinel
-)
-{
- rtems_irq_connect_data* vchain;
- for( vchain = &tbl[irq];
- ((int)vchain != -1 && vchain->hdl != sentinel);
- vchain = (rtems_irq_connect_data*)vchain->next_handler ) {
- vchain->hdl(vchain->handle);
- }
-}
-
-
-void C_dispatch_isr(int irq)
-{
- bsp_irq_dispatch_list(rtems_hdl_tbl, irq, default_rtems_entry.hdl);
-}
diff --git a/c/src/lib/libbsp/i386/shared/irq/irq.h b/c/src/lib/libbsp/i386/shared/irq/irq.h
index ce5b626a27..6ca7e7ab21 100644
--- a/c/src/lib/libbsp/i386/shared/irq/irq.h
+++ b/c/src/lib/libbsp/i386/shared/irq/irq.h
@@ -33,6 +33,7 @@ extern "C" {
#include <rtems.h>
#define BSP_SHARED_HANDLER_SUPPORT 1
#include <rtems/irq.h>
+#include <rtems/irq-extension.h>
/*-------------------------------------------------------------------------+
| Constants
diff --git a/c/src/lib/libbsp/i386/shared/irq/irq_init.c b/c/src/lib/libbsp/i386/shared/irq/irq_init.c
index 5cb63cd425..b5057c4453 100644
--- a/c/src/lib/libbsp/i386/shared/irq/irq_init.c
+++ b/c/src/lib/libbsp/i386/shared/irq/irq_init.c
@@ -3,6 +3,7 @@
* This file contains the implementation of rtems initialization
* related to interrupt handling.
*
+ * Copyright (c) 2009 embedded brains GmbH
* CopyRight (C) 1998 valette@crf.canon.fr
*
* The license and distribution terms for this file may be
@@ -12,10 +13,13 @@
* $Id$
*/
+#include <rtems/bspIo.h>
+
#include <libcpu/cpu.h>
-#include <bsp/irq.h>
+
#include <bsp.h>
-#include <rtems/bspIo.h>
+#include <bsp/irq.h>
+#include <bsp/irq-generic.h>
/*
* rtems prologue generated in irq_asm.S
@@ -60,51 +64,23 @@ static int raw_not_connected(
static rtems_raw_irq_connect_data idtHdl[IDT_SIZE];
-/*
- * default IRQ handler
- */
-static void irq_default_handler(rtems_irq_hdl_param unused)
-{
-}
-
-/*
- * default IRQ on/off function
- */
-static void irq_nop_func(const struct __rtems_irq_connect_data__ *unused)
-{
-}
-
-/*
- * default irq isOn function
- */
-static int irq_not_connected( const struct __rtems_irq_connect_data__ *unused)
-{
- return 0;
-}
-
-
-/*
- * Table used to store rtems managed interrupt handlers.
- * Borrow the table to store raw handler entries at the beginning.
- * The table will be reinitialized before the call to BSP_rtems_irq_mngt_set().
- */
-static rtems_irq_connect_data rtemsIrq[BSP_IRQ_LINES_NUMBER] = {
- {0,(rtems_irq_hdl)rtems_irq_prologue_0},
- {0,(rtems_irq_hdl)rtems_irq_prologue_1},
- {0,(rtems_irq_hdl)rtems_irq_prologue_2},
- {0,(rtems_irq_hdl)rtems_irq_prologue_3},
- {0,(rtems_irq_hdl)rtems_irq_prologue_4},
- {0,(rtems_irq_hdl)rtems_irq_prologue_5},
- {0,(rtems_irq_hdl)rtems_irq_prologue_6},
- {0,(rtems_irq_hdl)rtems_irq_prologue_7},
- {0,(rtems_irq_hdl)rtems_irq_prologue_8},
- {0,(rtems_irq_hdl)rtems_irq_prologue_9},
- {0,(rtems_irq_hdl)rtems_irq_prologue_10},
- {0,(rtems_irq_hdl)rtems_irq_prologue_11},
- {0,(rtems_irq_hdl)rtems_irq_prologue_12},
- {0,(rtems_irq_hdl)rtems_irq_prologue_13},
- {0,(rtems_irq_hdl)rtems_irq_prologue_14},
- {0,(rtems_irq_hdl)rtems_irq_prologue_15}
+static rtems_raw_irq_hdl rtemsIrq[BSP_IRQ_LINES_NUMBER] = {
+ rtems_irq_prologue_0,
+ rtems_irq_prologue_1,
+ rtems_irq_prologue_2,
+ rtems_irq_prologue_3,
+ rtems_irq_prologue_4,
+ rtems_irq_prologue_5,
+ rtems_irq_prologue_6,
+ rtems_irq_prologue_7,
+ rtems_irq_prologue_8,
+ rtems_irq_prologue_9,
+ rtems_irq_prologue_10,
+ rtems_irq_prologue_11,
+ rtems_irq_prologue_12,
+ rtems_irq_prologue_13,
+ rtems_irq_prologue_14,
+ rtems_irq_prologue_15
};
static rtems_raw_irq_connect_data defaultRawIrq = {
@@ -115,32 +91,8 @@ static rtems_raw_irq_connect_data defaultRawIrq = {
raw_not_connected /* isOn */
};
-static rtems_irq_connect_data defaultIrq = {
- 0, /* vectorIdex */
- irq_default_handler, /* hdl */
- 0, /* handle */
- irq_nop_func, /* on */
- irq_nop_func, /* off */
- irq_not_connected /* isOn */
-};
-
-static rtems_irq_prio irqPrioTable[BSP_IRQ_LINES_NUMBER]={
- /*
- * actual rpiorities for interrupt :
- * 0 means that only current interrupt is masked
- * 255 means all other interrupts are masked
- * The second entry has a priority of 255 because
- * it is the slave pic entry and is should always remain
- * unmasked.
- */
- 0,0,
- 255,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
static interrupt_gate_descriptor idtEntry;
-static rtems_irq_global_settings initial_config;
static rtems_raw_irq_global_settings raw_initial_config;
void raw_idt_notify(void)
@@ -191,7 +143,7 @@ void rtems_irq_mngt_init(void)
* with RTEMS prologue.
*/
for (i = 0; i < BSP_IRQ_LINES_NUMBER; i++) {
- create_interrupt_gate_descriptor(&idtEntry,(rtems_raw_irq_hdl) rtemsIrq[i].hdl);
+ create_interrupt_gate_descriptor(&idtEntry, rtemsIrq[i]);
idt_entry_tbl[i + BSP_ASM_IRQ_VECTOR_BASE] = idtEntry;
}
/*
@@ -199,23 +151,11 @@ void rtems_irq_mngt_init(void)
* with raw handlers. We must now initialize the higher level
* interrupt management.
*/
- /*
- * re-init the rtemsIrq table
- */
- for (i = 0; i < BSP_IRQ_LINES_NUMBER; i++) {
- rtemsIrq[i] = defaultIrq;
- rtemsIrq[i].name = i;
- }
+
/*
* Init initial Interrupt management config
*/
- initial_config.irqNb = BSP_IRQ_LINES_NUMBER;
- initial_config.defaultEntry = defaultIrq;
- initial_config.irqHdlTbl = rtemsIrq;
- initial_config.irqBase = BSP_ASM_IRQ_VECTOR_BASE;
- initial_config.irqPrioTbl = irqPrioTable;
-
- if (!BSP_rtems_irq_mngt_set(&initial_config)) {
+ if (bsp_interrupt_initialize() != RTEMS_SUCCESSFUL) {
/*
* put something here that will show the failure...
*/