From ac04bb85ebea019afe4253253945f978661b8fa2 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 12 Mar 2018 16:42:16 +0100 Subject: bsps/powerpc: Move legacy IRQ support This patch is a part of the BSP source reorganization. Update #3285. --- .../libcpu/powerpc/new-exceptions/bspsupport/irq.c | 393 --------------------- 1 file changed, 393 deletions(-) delete mode 100644 c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/irq.c (limited to 'c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/irq.c') diff --git a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/irq.c b/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/irq.c deleted file mode 100644 index 931a9c6074..0000000000 --- a/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/irq.c +++ /dev/null @@ -1,393 +0,0 @@ -/* - * - * This file contains the PIC-independent implementation of the functions described in irq.h - * - * Copyright (C) 1998, 1999 valette@crf.canon.fr - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include - -#include -#include -#include /* for printk */ -#include -#include -#include - -/* - * 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; -static rtems_irq_connect_data* rtems_hdl_tbl; - - -SPR_RW(BOOKE_TSR) -SPR_RW(PPC405_TSR) - -/* legacy mode for bookE DEC exception; - * to avoid the double layer of function calls - * (dec_handler_bookE -> C_dispatch_irq_handler -> user handler) - * it is preferrable for the user to hook the DEC - * exception directly. - * However, the legacy mode works with less modifications - * of user code. - */ -static int C_dispatch_dec_handler_bookE (BSP_Exception_frame *frame, unsigned int excNum) -{ - /* clear interrupt; we must do this - * before C_dispatch_irq_handler() - * re-enables MSR_EE. - * Note that PPC405 uses a different SPR# for TSR - */ - if ( ppc_cpu_is_bookE()==PPC_BOOKE_405) - _write_PPC405_TSR( BOOKE_TSR_DIS ); - else - _write_BOOKE_TSR( BOOKE_TSR_DIS ); - return C_dispatch_irq_handler(frame, ASM_DEC_VECTOR); -} - -/* - * ------------------------ RTEMS Irq helper functions ---------------- - */ - -/* - * This function check that the value given for the irq line - * is valid. - */ - -static int isValidInterrupt(int irq) -{ - if ( (irq < internal_config->irqBase) || (irq >= internal_config->irqBase + internal_config->irqNb)) - 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; - } - - /* pre-allocate memory outside of critical section */ - vchain = (rtems_irq_connect_data*)malloc(sizeof(rtems_irq_connect_data)); - - rtems_interrupt_disable(level); - - if ( (intptr_t)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); - free(vchain); - return 0; - } - - /* 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_enable_irq_at_pic(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_interrupt_level level; - - if (!isValidInterrupt(irq->name)) { - printk("Invalid interrupt vector %d\n",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); - printk("IRQ vector %d already connected\n",irq->name); - return 0; - } - - /* - * store the data provided by user - */ - rtems_hdl_tbl[irq->name] = *irq; - rtems_hdl_tbl[irq->name].next_handler = (void *)-1; - - /* - * enable_irq_at_pic is supposed to ignore - * requests to disable interrupts outside - * of the range handled by the PIC - */ - BSP_enable_irq_at_pic(irq->name); - - /* - * Enable interrupt on device - */ - if (irq->on) - irq->on(irq); - - rtems_interrupt_enable(level); - - return 1; -} - -int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* irq) -{ - rtems_interrupt_level level; - - if (!isValidInterrupt(irq->name)) { - return 0; - } - rtems_interrupt_disable(level); - *irq = rtems_hdl_tbl[irq->name]; - rtems_interrupt_enable(level); - return 1; -} - -int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq) -{ - rtems_irq_connect_data *pchain= NULL, *vchain = NULL; - rtems_interrupt_level level; - - 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 != irq->hdl) { - rtems_interrupt_enable(level); - return 0; - } - - if( (intptr_t)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 on device - */ - if (irq->off) - irq->off(irq); - - /* - * 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; - } - } - - /* Only disable at PIC if we removed the last handler */ - if ( rtems_hdl_tbl[irq->name].hdl == default_rtems_entry.hdl ) { - /* - * disable_irq_at_pic is supposed to ignore - * requests to disable interrupts outside - * of the range handled by the PIC; - */ - BSP_disable_irq_at_pic(irq->name); - } - - rtems_interrupt_enable(level); - - free(vchain); - - return 1; -} - -/* - * Less cumbersome, alternate entry points; - * RETURNS: more traditional, 0 on success, nonzero on error - */ - -static int doit( - int (*p)(const rtems_irq_connect_data*), - rtems_irq_number n, - rtems_irq_hdl hdl, - rtems_irq_hdl_param prm) -{ -rtems_irq_connect_data xx; - xx.name = n; - xx.hdl = hdl; - xx.handle = prm; - xx.on = 0; - xx.off = 0; - xx.isOn = 0; - return ! p(&xx); -} - -int BSP_rtems_int_connect(rtems_irq_number n, rtems_irq_hdl hdl, rtems_irq_hdl_param p) -{ - return doit(BSP_install_rtems_shared_irq_handler, n, hdl, p); -} - -int BSP_rtems_int_disconnect(rtems_irq_number n, rtems_irq_hdl hdl, rtems_irq_hdl_param p) -{ - return doit(BSP_remove_rtems_irq_handler, n, hdl, p); -} - - -/* - * RTEMS Global Interrupt Handler Management Routines - */ - -int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config) -{ - int i; - rtems_interrupt_level level; - rtems_irq_connect_data* vchain; - - /* - * Store various code accelerators - */ - internal_config = config; - default_rtems_entry = config->defaultEntry; - rtems_hdl_tbl = config->irqHdlTbl; - - rtems_interrupt_disable(level); - - if ( !BSP_setup_the_pic(config) ) { - printk("PIC setup failed; leaving IRQs OFF\n"); - return 0; - } - - for ( i = config->irqBase; i < config->irqBase + config->irqNb; i++ ) { - for( vchain = &rtems_hdl_tbl[i]; - ((intptr_t)vchain != -1 && vchain->hdl != default_rtems_entry.hdl); - vchain = (rtems_irq_connect_data*)vchain->next_handler ) - { - if (vchain->on) - vchain->on(vchain); - } - if ( vchain != &rtems_hdl_tbl[i] ) { - /* at least one handler registered */ - BSP_enable_irq_at_pic(i); - } else { -/* Do NOT disable; there might be boards with cascaded - * interrupt controllers where the BSP (incorrectly) does - * not ignore the cascaded interrupts in BSP_disable_irq_at_pic()! - * Instead, we rely on BSP_setup_the_pic() for a good - * initial configuration. - * - BSP_disable_irq_at_pic(i); - */ - } - } - - rtems_interrupt_enable(level); - - { - ppc_exc_set_handler(ASM_EXT_VECTOR, C_dispatch_irq_handler); - - if ( ppc_cpu_is_bookE() ) { - /* bookE decrementer interrupt needs to be cleared BEFORE - * dispatching the user ISR (because the user ISR is called - * with EE enabled) - * We do this so that existing DEC handlers can be used - * with minor modifications. - */ - ppc_exc_set_handler(ASM_BOOKE_DEC_VECTOR, C_dispatch_dec_handler_bookE); - } else { - ppc_exc_set_handler(ASM_DEC_VECTOR, C_dispatch_irq_handler); - } - } - return 1; -} - -int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** config) -{ - *config = internal_config; - return 0; -} -- cgit v1.2.3