From fc5490fe84850d51e7cbfc43377ec6844d793b87 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 3 Jul 2009 15:08:54 +0000 Subject: 2009-07-01 Sebastian Huber * 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. --- c/src/lib/libbsp/i386/ChangeLog | 6 + c/src/lib/libbsp/i386/shared/irq/irq-config.h | 39 ++++ c/src/lib/libbsp/i386/shared/irq/irq.c | 318 ++++---------------------- c/src/lib/libbsp/i386/shared/irq/irq.h | 1 + c/src/lib/libbsp/i386/shared/irq/irq_init.c | 112 +++------ 5 files changed, 112 insertions(+), 364 deletions(-) create mode 100644 c/src/lib/libbsp/i386/shared/irq/irq-config.h (limited to 'c/src') 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 + + * 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 * 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 + * + * + * 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 + +/** + * @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 #include +#include + #include #include @@ -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 #define BSP_SHARED_HANDLER_SUPPORT 1 #include +#include /*-------------------------------------------------------------------------+ | 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 + #include -#include + #include -#include +#include +#include /* * 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... */ -- cgit v1.2.3