summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i386/shared/irq/irq.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/src/lib/libbsp/i386/shared/irq/irq.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 'c/src/lib/libbsp/i386/shared/irq/irq.c')
-rw-r--r--c/src/lib/libbsp/i386/shared/irq/irq.c318
1 files changed, 40 insertions, 278 deletions
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);
-}