From 2608c9a9f698fe6575c84676c982427fa0ea84e7 Mon Sep 17 00:00:00 2001 From: Jennifer Averett Date: Thu, 28 Apr 2005 17:47:10 +0000 Subject: 2005-04-28 Jennifer Averett * Add/move files for the Update to new exception model. NOTE: These modifications have not been tested on hardware. * irq/FPGA.c, irq/irq.c, irq/irq.h, irq/irq_init.c: New files. * startup/FPGA.c: Removed. --- c/src/lib/libbsp/powerpc/score603e/ChangeLog | 7 + c/src/lib/libbsp/powerpc/score603e/irq/FPGA.c | 164 ++++++++ c/src/lib/libbsp/powerpc/score603e/irq/irq.c | 451 ++++++++++++++++++++++ c/src/lib/libbsp/powerpc/score603e/irq/irq.h | 350 +++++++++++++++++ c/src/lib/libbsp/powerpc/score603e/irq/irq_init.c | 364 +++++++++++++++++ c/src/lib/libbsp/powerpc/score603e/startup/FPGA.c | 164 -------- 6 files changed, 1336 insertions(+), 164 deletions(-) create mode 100644 c/src/lib/libbsp/powerpc/score603e/irq/FPGA.c create mode 100644 c/src/lib/libbsp/powerpc/score603e/irq/irq.c create mode 100644 c/src/lib/libbsp/powerpc/score603e/irq/irq.h create mode 100644 c/src/lib/libbsp/powerpc/score603e/irq/irq_init.c delete mode 100644 c/src/lib/libbsp/powerpc/score603e/startup/FPGA.c (limited to 'c') diff --git a/c/src/lib/libbsp/powerpc/score603e/ChangeLog b/c/src/lib/libbsp/powerpc/score603e/ChangeLog index 34a4c70d0e..23ffc116e8 100644 --- a/c/src/lib/libbsp/powerpc/score603e/ChangeLog +++ b/c/src/lib/libbsp/powerpc/score603e/ChangeLog @@ -1,3 +1,10 @@ +2005-04-28 Jennifer Averett + + * Add/move files for the Update to new exception model. + NOTE: These modifications have not been tested on hardware. + * irq/FPGA.c, irq/irq.c, irq/irq.h, irq/irq_init.c: New files. + * startup/FPGA.c: Removed. + 2005-04-15 Jennifer Averett * clock/clock.c: Fix multiple defined warning diff --git a/c/src/lib/libbsp/powerpc/score603e/irq/FPGA.c b/c/src/lib/libbsp/powerpc/score603e/irq/FPGA.c new file mode 100644 index 0000000000..46c012f2ae --- /dev/null +++ b/c/src/lib/libbsp/powerpc/score603e/irq/FPGA.c @@ -0,0 +1,164 @@ +/* FPGA.c -- Bridge for second and subsequent generations + * + * COPYRIGHT (c) 1989-2001. + * On-Line Applications Research Corporation (OAR). + * + * The license and distribution terms for this file may in + * the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id: + */ + +#include +#include +#include +#include + +#include +#include + +/* + * initialize FPGA + */ +void initialize_PCI_bridge () +{ +#if (!SCORE603E_USE_DINK) + uint16_t mask, shift, data; + + shift = SCORE603E_85C30_0_IRQ - Score_IRQ_First; + mask = 1 << shift; + + shift = SCORE603E_85C30_1_IRQ - Score_IRQ_First; + mask = mask & (1 << shift); + + data = *SCORE603E_FPGA_MASK_DATA; + data = ~mask; + + *SCORE603E_FPGA_MASK_DATA = data; +#endif + +} + +void set_irq_mask( + uint16_t value +) +{ + uint16_t *loc; + + loc = (uint16_t*)SCORE603E_FPGA_MASK_DATA; + + *loc = value; +} + +uint16_t get_irq_mask() +{ + uint16_t *loc; + uint16_t value; + + loc = (uint16_t*)SCORE603E_FPGA_MASK_DATA; + + value = *loc; + + return value; +} + +void unmask_irq( + uint16_t irq_idx +) +{ + uint16_t value; + uint32_t mask_idx = irq_idx; + + value = get_irq_mask(); + +#if (HAS_PMC_PSC8) + switch (irq_idx + Score_IRQ_First ) { + case SCORE603E_85C30_4_IRQ: + case SCORE603E_85C30_2_IRQ: + case SCORE603E_85C30_5_IRQ: + case SCORE603E_85C30_3_IRQ: + mask_idx = SCORE603E_PCI_IRQ_0 - Score_IRQ_First; + break; + default: + break; + } +#endif + + value &= (~(0x1 << mask_idx)); + set_irq_mask( value ); +} + +void init_irq_data_register() +{ + uint32_t index; + uint32_t i; + +#if (SCORE603E_USE_DINK) + set_irq_mask( 0xffff ); +#endif + + /* + * Clear any existing interupts from the vector data register. + */ + for (i=0; i<20; i++) { + index = (*SCORE603E_FPGA_VECT_DATA); + if ( (index&0x10) != 0x10 ) + break; + } +} + +uint16_t read_and_clear_PMC_irq( + uint16_t irq +) +{ + uint16_t status_word = irq; + + status_word = (*BSP_PMC_STATUS_ADDRESS); + + return status_word; +} + +rtems_boolean Is_PMC_IRQ( + uint32_t pmc_irq, + uint16_t status_word +) +{ + rtems_boolean result= FALSE; + + switch(pmc_irq) { + case SCORE603E_85C30_4_IRQ: + result = Is_PMC_85C30_4_IRQ( status_word ); + break; + case SCORE603E_85C30_2_IRQ: + result = Is_PMC_85C30_2_IRQ( status_word ); + break; + case SCORE603E_85C30_5_IRQ: + result = Is_PMC_85C30_5_IRQ( status_word ); + break; + case SCORE603E_85C30_3_IRQ: + result = Is_PMC_85C30_3_IRQ( status_word ); + break; + default: + assert( 0 ); + break; + } + + return result; +} + +uint16_t read_and_clear_irq() +{ + uint16_t irq; + + irq = (*SCORE603E_FPGA_VECT_DATA); + + if ((irq & 0xffff0) != 0x10) { + DEBUG_puts( "ERROR:: no irq data\n"); + return (irq | 0x80); + } + + irq &=0xf; + + return irq; +} diff --git a/c/src/lib/libbsp/powerpc/score603e/irq/irq.c b/c/src/lib/libbsp/powerpc/score603e/irq/irq.c new file mode 100644 index 0000000000..d743bcc962 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/score603e/irq/irq.c @@ -0,0 +1,451 @@ +/* + * + * This file contains the implementation of the function described in irq.h + * + * Copyright (C) 1998, 1999 valette@crf.canon.fr + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#include + +#include +#include +#include +#include /* for post ISR signal processing */ +#include +#include +#include +#include +#include /* for printk */ + +/* + * 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; + +/* + * Check if IRQ is an ISA IRQ + */ +static inline int is_isa_irq(const rtems_irq_symbolic_name irqLine) +{ + return (((int) irqLine <= BSP_ISA_IRQ_MAX_OFFSET) & + ((int) irqLine >= BSP_ISA_IRQ_LOWEST_OFFSET) + ); +} + +/* + * Check if IRQ is an pci IRQ + */ +static inline int is_pci_irq(const rtems_irq_symbolic_name irqLine) +{ + return (((int) irqLine <= BSP_PCI_IRQ_MAX_OFFSET) & + ((int) irqLine >= BSP_PCI_IRQ_LOWEST_OFFSET) + ); +} + +/* + * Check if IRQ is a Processor IRQ + */ +static inline int is_processor_irq(const rtems_irq_symbolic_name irqLine) +{ + return (((int) irqLine <= BSP_PROCESSOR_IRQ_MAX_OFFSET) & + ((int) irqLine >= BSP_PROCESSOR_IRQ_LOWEST_OFFSET) + ); +} + +/* + * ------------------------ RTEMS Irq helper functions ---------------- + */ + +/* + * 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) +{ + unsigned int level; + rtems_irq_connect_data* vchain; + + if (!isValidInterrupt(irq->name)) { + printk("Invalid interrupt vector %d\n",irq->name); + return 0; + } + + _CPU_ISR_Disable(level); + + if ( (int)rtems_hdl_tbl[irq->name].next_handler == -1 ) { + _CPU_ISR_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; + + /* + * XXX FIX ME + */ + if (is_pci_irq(irq->name)) { + } + + if (is_processor_irq(irq->name)) { + /* + * Enable exception at processor level + */ + } + /* + * Enable interrupt on device + */ + irq->on(irq); + + _CPU_ISR_Enable(level); + + return 1; +} + +/* + * ------------------------ RTEMS Single Irq Handler Mngt Routines ---------------- + */ + +int BSP_install_rtems_irq_handler (const rtems_irq_connect_data* irq) +{ + unsigned int 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. + */ + _CPU_ISR_Disable(level); + if (rtems_hdl_tbl[irq->name].hdl != default_rtems_entry.hdl) { + _CPU_ISR_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; + + /* XXX -FIX ME !! */ + if (is_pci_irq(irq->name)) { + /* + * Enable interrupt + */ + } + + if (is_processor_irq(irq->name)) { + /* + * Enable exception at processor level + */ + } + /* + * Enable interrupt on device + */ + irq->on(irq); + + _CPU_ISR_Enable(level); + + return 1; +} + +int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* irq) +{ + unsigned int level; + + if (!isValidInterrupt(irq->name)) { + return 0; + } + _CPU_ISR_Disable(level); + *irq = rtems_hdl_tbl[irq->name]; + _CPU_ISR_Enable(level); + return 1; +} + +int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data* irq) +{ + rtems_irq_connect_data *pchain= NULL, *vchain = NULL; + unsigned int 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. + */ + _CPU_ISR_Disable(level); + if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) { + _CPU_ISR_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 ) + { + _CPU_ISR_Enable(level); + return 0; + } + } + else + { + if (rtems_hdl_tbl[irq->name].hdl != irq->hdl) + { + _CPU_ISR_Enable(level); + return 0; + } + } + + /* XXX - FIX ME !! */ + if (is_pci_irq(irq->name)) { + /* + * disable interrupt + */ + } + if (is_processor_irq(irq->name)) { + /* + * disable exception at processor level + */ + } + + /* + * Disable interrupt on device + */ + 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 */ + rtems_hdl_tbl[irq->name]= *vchain; + } + free(vchain); + } + + _CPU_ISR_Enable(level); + + return 1; +} + +/* + * RTEMS Global Interrupt Handler Management Routines + */ + +int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config) +{ + int i; + unsigned int level; + /* + * Store various code accelerators + */ + internal_config = config; + default_rtems_entry = config->defaultEntry; + rtems_hdl_tbl = config->irqHdlTbl; + + _CPU_ISR_Disable(level); + /* + * set up internal tables used by rtems interrupt prologue + */ + + /* + * XXX - FIX ME !!! + */ + for (i=BSP_PCI_IRQ_LOWEST_OFFSET; i < BSP_PCI_IRQ_LOWEST_OFFSET + BSP_PCI_IRQ_NUMBER ; i++) { + if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) { + { + rtems_irq_connect_data* vchain; + for( vchain = &rtems_hdl_tbl[i]; + ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl); + vchain = (rtems_irq_connect_data*)vchain->next_handler ) + { + vchain->on(vchain); + } + } + + } + else { + /* rtems_hdl_tbl[i].off(&rtems_hdl_tbl[i]); */ + { + rtems_irq_connect_data* vchain; + for( vchain = &rtems_hdl_tbl[i]; + ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl); + vchain = (rtems_irq_connect_data*)vchain->next_handler ) + { + vchain->off(vchain); + } + } + } + } + /* + * finish with Processor exceptions handled like IRQ + */ + for (i=BSP_PROCESSOR_IRQ_LOWEST_OFFSET; i < BSP_PROCESSOR_IRQ_LOWEST_OFFSET+BSP_PROCESSOR_IRQ_NUMBER; i++){ + if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) { + { + rtems_irq_connect_data* vchain; + for( vchain = &rtems_hdl_tbl[i]; + ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl); + vchain = (rtems_irq_connect_data*)vchain->next_handler ) + { + vchain->on(vchain); + } + } + + } + else { + { + rtems_irq_connect_data* vchain; + for( vchain = &rtems_hdl_tbl[i]; + ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl); + vchain = (rtems_irq_connect_data*)vchain->next_handler ) + { + vchain->off(vchain); + } + } + + } + } + _CPU_ISR_Enable(level); + return 1; +} + +int BSP_rtems_irq_mngt_get(rtems_irq_global_settings** config) +{ + *config = internal_config; + return 0; +} + +int _BSP_vme_bridge_irq = -1; + +unsigned BSP_spuriousIntr = 0; +/* + * High level IRQ handler called from shared_raw_irq_code_entry + */ +void C_dispatch_irq_handler (CPU_Interrupt_frame *frame, unsigned int excNum) +{ + register unsigned int irq; + register unsigned msr; + register unsigned new_msr; + + if (excNum == ASM_DEC_VECTOR) { + _CPU_MSR_GET(msr); + new_msr = msr | MSR_EE; + _CPU_MSR_SET(new_msr); + + rtems_hdl_tbl[BSP_DECREMENTER].hdl(rtems_hdl_tbl[BSP_DECREMENTER].handle); + + _CPU_MSR_SET(msr); + return; + + } + irq = read_and_clear_irq(); + _CPU_MSR_GET(msr); + new_msr = msr | MSR_EE; + _CPU_MSR_SET(new_msr); + + /* rtems_hdl_tbl[irq].hdl(rtems_hdl_tbl[irq].handle); */ + { + rtems_irq_connect_data* vchain; + for( vchain = &rtems_hdl_tbl[irq]; + ((int)vchain != -1 && vchain->hdl != default_rtems_entry.hdl); + vchain = (rtems_irq_connect_data*)vchain->next_handler ) + { + vchain->hdl(vchain->handle); + } + } + + _CPU_MSR_SET(msr); + +} + +void _ThreadProcessSignalsFromIrq (BSP_Exception_frame* ctx) +{ + /* + * Process pending signals that have not already been + * processed by _Thread_Displatch. This happens quite + * unfrequently : the ISR must have posted an action + * to the current running thread. + */ + if ( _Thread_Do_post_task_switch_extension || + _Thread_Executing->do_post_task_switch_extension ) { + _Thread_Executing->do_post_task_switch_extension = FALSE; + _API_extensions_Run_postswitch(); + } + /* + * I plan to process other thread related events here. + * This will include DEBUG session requested from keyboard... + */ +} diff --git a/c/src/lib/libbsp/powerpc/score603e/irq/irq.h b/c/src/lib/libbsp/powerpc/score603e/irq/irq.h new file mode 100644 index 0000000000..93dcf9d3c4 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/score603e/irq/irq.h @@ -0,0 +1,350 @@ +/* irq.h + * + * This include file describe the data structure and the functions implemented + * by RTEMS to write interrupt handlers. + * + * Copyright (C) 1999 valette@crf.canon.fr + * + * This code is heavilly inspired by the public specification of STREAM V2 + * that can be found at : + * + * by following + * the STREAM API Specification Document link. + * + * The license and distribution terms for this file may be + * found in found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + * + * $Id$ + */ + +#ifndef LIBBSP_POWERPC_MCP750_IRQ_IRQ_H +#define LIBBSP_POWERPC_MCP750_IRQ_IRQ_H + +/* + * 8259 edge/level control definitions at VIA + */ +#define ISA8259_M_ELCR 0x4d0 +#define ISA8259_S_ELCR 0x4d1 + +#define ELCRS_INT15_LVL 0x80 +#define ELCRS_INT14_LVL 0x40 +#define ELCRS_INT13_LVL 0x20 +#define ELCRS_INT12_LVL 0x10 +#define ELCRS_INT11_LVL 0x08 +#define ELCRS_INT10_LVL 0x04 +#define ELCRS_INT9_LVL 0x02 +#define ELCRS_INT8_LVL 0x01 +#define ELCRM_INT7_LVL 0x80 +#define ELCRM_INT6_LVL 0x40 +#define ELCRM_INT5_LVL 0x20 +#define ELCRM_INT4_LVL 0x10 +#define ELCRM_INT3_LVL 0x8 +#define ELCRM_INT2_LVL 0x4 +#define ELCRM_INT1_LVL 0x2 +#define ELCRM_INT0_LVL 0x1 + +#define BSP_ASM_IRQ_VECTOR_BASE 0x0 + /* PIC's command and mask registers */ +#define PIC_MASTER_COMMAND_IO_PORT 0x20 /* Master PIC command register */ +#define PIC_SLAVE_COMMAND_IO_PORT 0xa0 /* Slave PIC command register */ +#define PIC_MASTER_IMR_IO_PORT 0x21 /* Master PIC Interrupt Mask Register */ +#define PIC_SLAVE_IMR_IO_PORT 0xa1 /* Slave PIC Interrupt Mask Register */ + + /* Command for specific EOI (End Of Interrupt): Interrupt acknowledge */ +#define PIC_EOSI 0x60 /* End of Specific Interrupt (EOSI) */ +#define SLAVE_PIC_EOSI 0x62 /* End of Specific Interrupt (EOSI) for cascade */ +#define PIC_EOI 0x20 /* Generic End of Interrupt (EOI) */ + +#ifndef ASM + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Symbolic IRQ names and related definitions + */ + +typedef enum { + /* Base vector for our ISA IRQ handlers. */ + BSP_ISA_IRQ_VECTOR_BASE = BSP_ASM_IRQ_VECTOR_BASE, + /* + * ISA IRQ handler related definitions + */ + BSP_ISA_IRQ_NUMBER = 16, + BSP_ISA_IRQ_LOWEST_OFFSET = 0, + BSP_ISA_IRQ_MAX_OFFSET = BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER - 1, + /* + * PCI IRQ handlers related definitions + * CAUTION : BSP_PCI_IRQ_LOWEST_OFFSET should be equal to OPENPIC_VEC_SOURCE + */ + BSP_PCI_IRQ_NUMBER = 16, + BSP_PCI_IRQ_LOWEST_OFFSET = BSP_ISA_IRQ_NUMBER, + BSP_PCI_IRQ_MAX_OFFSET = BSP_PCI_IRQ_LOWEST_OFFSET + BSP_PCI_IRQ_NUMBER - 1, + /* + * PowerPC exceptions handled as interrupt where an RTEMS managed interrupt + * handler might be connected + */ + BSP_PROCESSOR_IRQ_NUMBER = 1, + BSP_PROCESSOR_IRQ_LOWEST_OFFSET = BSP_PCI_IRQ_MAX_OFFSET + 1, + BSP_PROCESSOR_IRQ_MAX_OFFSET = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER - 1, + /* Misc vectors for OPENPIC irqs (IPI, timers) + */ + BSP_MISC_IRQ_NUMBER = 8, + BSP_MISC_IRQ_LOWEST_OFFSET = BSP_PROCESSOR_IRQ_MAX_OFFSET + 1, + BSP_MISC_IRQ_MAX_OFFSET = BSP_MISC_IRQ_LOWEST_OFFSET + BSP_MISC_IRQ_NUMBER - 1, + /* + * Summary + */ + BSP_IRQ_NUMBER = BSP_MISC_IRQ_MAX_OFFSET + 1, + BSP_LOWEST_OFFSET = BSP_ISA_IRQ_LOWEST_OFFSET, + BSP_MAX_OFFSET = BSP_MISC_IRQ_MAX_OFFSET, + /* + * Some ISA IRQ symbolic name definition + */ + BSP_ISA_PERIODIC_TIMER = 0, + BSP_ISA_KEYBOARD = 1, + BSP_ISA_UART_COM2_IRQ = 3, + BSP_ISA_UART_COM1_IRQ = 4, + BSP_ISA_RT_TIMER1 = 8, + BSP_ISA_RT_TIMER3 = 10, + /* + * Some PCI IRQ symbolic name definition + */ + BSP_PCI_IRQ0 = BSP_PCI_IRQ_LOWEST_OFFSET, + BSP_PCI_ISA_BRIDGE_IRQ = BSP_PCI_IRQ0, + +#if defined(mvme2100) + BSP_DEC21143_IRQ = BSP_PCI_IRQ_LOWEST_OFFSET + 1, + BSP_PMC_PCMIP_TYPE1_SLOT0_IRQ = BSP_PCI_IRQ_LOWEST_OFFSET + 2, + BSP_PCMIP_TYPE1_SLOT1_IRQ = BSP_PCI_IRQ_LOWEST_OFFSET + 3, + BSP_PCMIP_TYPE2_SLOT0_IRQ = BSP_PCI_IRQ_LOWEST_OFFSET + 4, + BSP_PCMIP_TYPE2_SLOT1_IRQ = BSP_PCI_IRQ_LOWEST_OFFSET + 5, + BSP_PCI_INTA_UNIVERSE_LINT0_IRQ = BSP_PCI_IRQ_LOWEST_OFFSET + 7, + BSP_PCI_INTB_UNIVERSE_LINT1_IRQ = BSP_PCI_IRQ_LOWEST_OFFSET + 8, + BSP_PCI_INTC_UNIVERSE_LINT2_IRQ = BSP_PCI_IRQ_LOWEST_OFFSET + 9, + BSP_PCI_INTD_UNIVERSE_LINT3_IRQ = BSP_PCI_IRQ_LOWEST_OFFSET + 10, + BSP_UART_COM1_IRQ = BSP_PCI_IRQ_LOWEST_OFFSET + 13, + BSP_FRONT_PANEL_ABORT_IRQ = BSP_PCI_IRQ_LOWEST_OFFSET + 14, + BSP_RTC_IRQ = BSP_PCI_IRQ_LOWEST_OFFSET + 15, +#endif + + /* + * Some Processor execption handled as RTEMS IRQ symbolic name definition + */ + BSP_DECREMENTER = BSP_PROCESSOR_IRQ_LOWEST_OFFSET + +} rtems_irq_symbolic_name; + +/* + * Type definition for RTEMS managed interrupts + */ +typedef unsigned char rtems_irq_prio; +typedef unsigned short rtems_i8259_masks; + +extern volatile rtems_i8259_masks i8259s_cache; + +struct __rtems_irq_connect_data__; /* forward declaratiuon */ + +typedef void *rtems_irq_hdl_param; +typedef void (*rtems_irq_hdl) (rtems_irq_hdl_param); +typedef void (*rtems_irq_enable) (const struct __rtems_irq_connect_data__*); +typedef void (*rtems_irq_disable) (const struct __rtems_irq_connect_data__*); +typedef int (*rtems_irq_is_enabled) (const struct __rtems_irq_connect_data__*); + +typedef struct __rtems_irq_connect_data__ { + /* + * IRQ line + */ + rtems_irq_symbolic_name name; + /* + * handler. See comment on handler properties below in function prototype. + */ + rtems_irq_hdl hdl; + /* + * Handler handle to store private data + */ + rtems_irq_hdl_param handle; + /* + * function for enabling interrupts at device level (ONLY!). + * The BSP code will automatically enable it at i8259s level and openpic level. + * RATIONALE : anyway such code has to exist in current driver code. + * It is usually called immediately AFTER connecting the interrupt handler. + * RTEMS may well need such a function when restoring normal interrupt + * processing after a debug session. + * + */ + rtems_irq_enable on; + /* + * function for disabling interrupts at device level (ONLY!). + * The code will disable it at i8259s level. RATIONALE : anyway + * such code has to exist for clean shutdown. It is usually called + * BEFORE disconnecting the interrupt. RTEMS may well need such + * a function when disabling normal interrupt processing for + * a debug session. May well be a NOP function. + */ + rtems_irq_disable off; + /* + * function enabling to know what interrupt may currently occur + * if someone manipulates the i8259s interrupt mask without care... + */ + rtems_irq_is_enabled isOn; + /* + * Set to -1 for vectors forced to have only 1 handler + */ + void *next_handler; + +}rtems_irq_connect_data; + +typedef struct { + /* + * size of all the table fields (*Tbl) described below. + */ + unsigned int irqNb; + /* + * Default handler used when disconnecting interrupts. + */ + rtems_irq_connect_data defaultEntry; + /* + * Table containing initials/current value. + */ + rtems_irq_connect_data* irqHdlTbl; + /* + * actual value of BSP_ISA_IRQ_VECTOR_BASE... + */ + rtems_irq_symbolic_name irqBase; + /* + * software priorities associated with interrupts. + * if (*irqPrio [i] > intrPrio [j] it means that + * interrupt handler hdl connected for interrupt name i + * will not be interrupted by the handler connected for interrupt j + * The interrupt source will be physically masked at i8259 level. + */ + rtems_irq_prio* irqPrioTbl; +}rtems_irq_global_settings; + +/*-------------------------------------------------------------------------+ +| Function Prototypes. ++--------------------------------------------------------------------------*/ +/* + * ------------------------ Intel 8259 (or emulation) Mngt Routines ------- + */ + +/* + * function to disable a particular irq at 8259 level. After calling + * this function, even if the device asserts the interrupt line it will + * not be propagated further to the processor + */ +int BSP_irq_disable_at_i8259s (const rtems_irq_symbolic_name irqLine); +/* + * function to enable a particular irq at 8259 level. After calling + * this function, if the device asserts the interrupt line it will + * be propagated further to the processor + */ +int BSP_irq_enable_at_i8259s (const rtems_irq_symbolic_name irqLine); +/* + * function to acknowledge a particular irq at 8259 level. After calling + * this function, if a device asserts an enabled interrupt line it will + * be propagated further to the processor. Mainly usefull for people + * writing raw handlers as this is automagically done for RTEMS managed + * handlers. + */ +int BSP_irq_ack_at_i8259s (const rtems_irq_symbolic_name irqLine); +/* + * function to check if a particular irq is enabled at 8259 level. After calling + */ +int BSP_irq_enabled_at_i8259s (const rtems_irq_symbolic_name irqLine); +/* + * ------------------------ RTEMS Single Irq Handler Mngt Routines ---------------- + */ +/* + * function to connect a particular irq handler. This hanlder will NOT be called + * directly as the result of the corresponding interrupt. Instead, a RTEMS + * irq prologue will be called that will : + * + * 1) save the C scratch registers, + * 2) switch to a interrupt stack if the interrupt is not nested, + * 3) store the current i8259s' interrupt masks + * 4) modify them to disable the current interrupt at 8259 level (and may + * be others depending on software priorities) + * 5) acknowledge the i8259s', + * 6) demask the processor, + * 7) call the application handler + * + * As a result the hdl function provided + * + * a) can perfectly be written is C, + * b) may also well directly call the part of the RTEMS API that can be + * used from interrupt level, + * c) It only responsible for handling the jobs that need to be done at + * the device level including (aknowledging/re-enabling the interrupt + * at device, level, getting the data,...) + * + * When returning from the function, the following will be performed by + * the RTEMS irq epilogue: + * + * 1) masks the interrupts again, + * 2) restore the original i8259s' interrupt masks + * 3) switch back on the orinal stack if needed, + * 4) perform rescheduling when necessary, + * 5) restore the C scratch registers... + * 6) restore initial execution flow + */ +int BSP_install_rtems_irq_handler (const rtems_irq_connect_data*); +int BSP_install_rtems_shared_irq_handler (const rtems_irq_connect_data*); + +#define BSP_SHARED_HANDLER_SUPPORT 1 + +/* + * function to get the current RTEMS irq handler for ptr->name. It enables to + * define hanlder chain... + */ +int BSP_get_current_rtems_irq_handler (rtems_irq_connect_data* ptr); +/* + * function to get disconnect the RTEMS irq handler for ptr->name. + * This function checks that the value given is the current one for safety + * reasons. + * The user can use the previous function to get it. + */ +int BSP_remove_rtems_irq_handler (const rtems_irq_connect_data*); + +/* + * ------------------------ RTEMS Global Irq Handler Mngt Routines ---------------- + */ +/* + * (Re) Initialize the RTEMS interrupt management. + * + * The result of calling this function will be the same as if each individual + * handler (config->irqHdlTbl[i].hdl) different from "config->defaultEntry.hdl" + * has been individualy connected via + * BSP_install_rtems_irq_handler(&config->irqHdlTbl[i]) + * And each handler currently equal to config->defaultEntry.hdl + * has been previously disconnected via + * BSP_remove_rtems_irq_handler (&config->irqHdlTbl[i]) + * + * This is to say that all information given will be used and not just + * only the space. + * + * CAUTION : the various table address contained in config will be used + * directly by the interrupt mangement code in order to save + * data size so they must stay valid after the call => they should + * not be modified or declared on a stack. + */ + +int BSP_rtems_irq_mngt_set(rtems_irq_global_settings* config); +/* + * (Re) get info on current RTEMS interrupt management. + */ +int BSP_rtems_irq_mngt_get(rtems_irq_global_settings**); + +extern void BSP_rtems_irq_mng_init(unsigned cpuId); +extern void BSP_i8259s_init(void); + +#ifdef __cplusplus +} +#endif + +#endif + +#endif diff --git a/c/src/lib/libbsp/powerpc/score603e/irq/irq_init.c b/c/src/lib/libbsp/powerpc/score603e/irq/irq_init.c new file mode 100644 index 0000000000..492e902da2 --- /dev/null +++ b/c/src/lib/libbsp/powerpc/score603e/irq/irq_init.c @@ -0,0 +1,364 @@ +/* irq_init.c + * + * This file contains the implementation of rtems initialization + * related to interrupt handling. + * + * CopyRight (C) 1999 valette@crf.canon.fr + * + * Enhanced by Jay Kulpinski + * to make it valid for MVME2300 Motorola boards. + * + * Till Straumann , 12/20/2001: + * Use the new interface to openpic_init + * + * 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$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct { + unsigned char bus; /* few chance the PCI/ISA bridge is not on first bus but ... */ + unsigned char device; + unsigned char function; +} pci_isa_bridge_device; + +pci_isa_bridge_device* via_82c586 = 0; +static pci_isa_bridge_device bridge; + +extern unsigned int external_exception_vector_prolog_code_size[]; +extern void external_exception_vector_prolog_code(); +extern unsigned int decrementer_exception_vector_prolog_code_size[]; +extern void decrementer_exception_vector_prolog_code(); + +/* + * default on/off function + */ +static void nop_func(){} +/* + * default isOn function + */ +static int not_connected() {return 0;} +/* + * default possible isOn function + */ +static int connected() {return 1;} + +static rtems_irq_connect_data rtemsIrq[BSP_IRQ_NUMBER]; +static rtems_irq_global_settings initial_config; +static rtems_irq_connect_data defaultIrq = { + /* vectorIdex, hdl , handle , on , off , isOn */ + 0, nop_func , NULL , nop_func , nop_func , not_connected +}; +static rtems_irq_prio irqPrioTable[BSP_IRQ_NUMBER]={ + /* + * actual priorities for interrupt : + * 0 means that only current interrupt is masked + * 255 means all other interrupts are masked + */ + /* + * ISA interrupts. + * The second entry has a priority of 255 because + * it is the slave pic entry and should always remain + * unmasked. + */ + 0,0, + 255, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* + * PCI Interrupts + */ + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, /* for raven prio 0 means unactive... */ + /* + * Processor exceptions handled as interrupts + */ + 0 +}; + +#if defined(mvme2100) +static unsigned char mvme2100_openpic_initpolarities[16] = { + 0, /* Not used - should be disabled */ + 0, /* DEC21143 Controller */ + 0, /* PMC/PC-MIP Type I Slot 0 */ + 0, /* PC-MIP Type I Slot 1 */ + 0, /* PC-MIP Type II Slot 0 */ + 0, /* PC-MIP Type II Slot 1 */ + 0, /* Not used - should be disabled */ + 0, /* PCI Expansion Interrupt A/Universe II (LINT0) */ + 0, /* PCI Expansion Interrupt B/Universe II (LINT1) */ + 0, /* PCI Expansion Interrupt C/Universe II (LINT2) */ + 0, /* PCI Expansion Interrupt D/Universe II (LINT3) */ + 0, /* Not used - should be disabled */ + 0, /* Not used - should be disabled */ + 1, /* 16550 UART */ + 0, /* Front panel Abort Switch */ + 0, /* RTC IRQ */ +}; + +static unsigned char mvme2100_openpic_initsenses[] = { + 0, /* Not used - should be disabled */ + 1, /* DEC21143 Controller */ + 1, /* PMC/PC-MIP Type I Slot 0 */ + 1, /* PC-MIP Type I Slot 1 */ + 1, /* PC-MIP Type II Slot 0 */ + 1, /* PC-MIP Type II Slot 1 */ + 0, /* Not used - should be disabled */ + 1, /* PCI Expansion Interrupt A/Universe II (LINT0) */ + 1, /* PCI Expansion Interrupt B/Universe II (LINT1) */ + 1, /* PCI Expansion Interrupt C/Universe II (LINT2) */ + 1, /* PCI Expansion Interrupt D/Universe II (LINT3) */ + 0, /* Not used - should be disabled */ + 0, /* Not used - should be disabled */ + 1, /* 16550 UART */ + 0, /* Front panel Abort Switch */ + 1, /* RTC IRQ */ +}; +#else +static unsigned char mcp750_openpic_initpolarities[16] = { + 1, /* 8259 cascade */ + 0, /* all the rest of them */ +}; + +static unsigned char mcp750_openpic_initsenses[] = { + 1, /* MCP750_INT_PCB(8259) */ + 0, /* MCP750_INT_FALCON_ECC_ERR */ + 1, /* MCP750_INT_PCI_ETHERNET */ + 1, /* MCP750_INT_PCI_PMC */ + 1, /* MCP750_INT_PCI_WATCHDOG_TIMER1 */ + 1, /* MCP750_INT_PCI_PRST_SIGNAL */ + 1, /* MCP750_INT_PCI_FALL_SIGNAL */ + 1, /* MCP750_INT_PCI_DEG_SIGNAL */ + 1, /* MCP750_INT_PCI_BUS1_INTA */ + 1, /* MCP750_INT_PCI_BUS1_INTB */ + 1, /* MCP750_INT_PCI_BUS1_INTC */ + 1, /* MCP750_INT_PCI_BUS1_INTD */ + 1, /* MCP750_INT_PCI_BUS2_INTA */ + 1, /* MCP750_INT_PCI_BUS2_INTB */ + 1, /* MCP750_INT_PCI_BUS2_INTC */ + 1, /* MCP750_INT_PCI_BUS2_INTD */ +}; +#endif + +void VIA_isa_bridge_interrupts_setup(void) +{ + pci_isa_bridge_device pci_dev; + unsigned int temp; + unsigned char tmp; + unsigned char maxBus; + unsigned found = 0; + + maxBus = BusCountPCI(); + pci_dev.function = 0; /* Assumes the bidge is the first function */ + + for (pci_dev.bus = 0; pci_dev.bus < maxBus; pci_dev.bus++) { +#ifdef SCAN_PCI_PRINT + printk("isa_bridge_interrupts_setup: Scanning bus %d\n", pci_dev.bus); +#endif + for (pci_dev.device = 0; pci_dev.device < PCI_MAX_DEVICES; pci_dev.device++) { +#ifdef SCAN_PCI_PRINT + printk("isa_bridge_interrupts_setup: Scanning device %d\n", pci_dev.device); +#endif + pci_read_config_dword(pci_dev.bus, pci_dev.device, pci_dev.function, + PCI_VENDOR_ID, &temp); +#ifdef SCAN_PCI_PRINT + printk("Vendor/device = %x\n", temp); +#endif + if ((temp == (((unsigned short) PCI_VENDOR_ID_VIA) | (PCI_DEVICE_ID_VIA_82C586_0 << 16))) + ) { + bridge = pci_dev; + via_82c586 = &bridge; +#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS + /* + * Should print : bus = 0, device = 11, function = 0 on a MCP750. + */ + printk("Via PCI/ISA bridge found at bus = %d, device = %d, function = %d\n", + via_82c586->bus, + via_82c586->device, + via_82c586->function); +#endif + found = 1; + goto loop_exit; + + } + } + } +loop_exit: + if (!found) BSP_panic("VIA_82C586 PCI/ISA bridge not found!n"); + + tmp = inb(0x810); + if ( !(tmp & 0x2)) { +#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS + printk("This is a second generation MCP750 board\n"); + printk("We must reprogram the PCI/ISA bridge...\n"); +#endif + pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function, + 0x47, &tmp); +#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS + printk(" PCI ISA bridge control2 = %x\n", (unsigned) tmp); +#endif + /* + * Enable 4D0/4D1 ISA interrupt level/edge config registers + */ + tmp |= 0x20; + pci_write_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function, + 0x47, tmp); + /* + * Now program the ISA interrupt edge/level + */ + tmp = ELCRS_INT9_LVL | ELCRS_INT10_LVL | ELCRS_INT11_LVL; + outb(tmp, ISA8259_S_ELCR); + tmp = ELCRM_INT5_LVL; + outb(tmp, ISA8259_M_ELCR);; + /* + * Set the Interrupt inputs to non-inverting level interrupt + */ + pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function, + 0x54, &tmp); +#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS + printk(" PCI ISA bridge PCI/IRQ Edge/Level Select = %x\n", (unsigned) tmp); +#endif + tmp = 0; + pci_write_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function, + 0x54, tmp); + } + else { +#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS + printk("This is a first generation MCP750 board\n"); + printk("We just show the actual value used by PCI/ISA bridge\n"); +#endif + pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function, + 0x47, &tmp); +#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS + printk(" PCI ISA bridge control2 = %x\n", (unsigned) tmp); +#endif + /* + * Show the Interrupt inputs inverting/non-inverting level status + */ + pci_read_config_byte(via_82c586->bus, via_82c586->device, via_82c586->function, + 0x54, &tmp); +#ifdef SHOW_ISA_PCI_BRIDGE_SETTINGS + printk(" PCI ISA bridge PCI/IRQ Edge/Level Select = %x\n", (unsigned) tmp); +#endif + } +} + + /* + * This code assumes the exceptions management setup has already + * been done. We just need to replace the exceptions that will + * be handled like interrupt. On mcp750/mpc750 and many PPC processors + * this means the decrementer exception and the external exception. + */ +void BSP_rtems_irq_mng_init(unsigned cpuId) +{ +#if !defined(mvme2100) + int known_cpi_isa_bridge = 0; +#endif + rtems_raw_except_connect_data vectorDesc; + int i; + + /* + * First initialize the Interrupt management hardware + */ +#if defined(mvme2100) +#ifdef TRACE_IRQ_INIT + printk("Going to initialize EPIC interrupt controller (openpic compliant)\n"); +#endif + openpic_init(1, mvme2100_openpic_initpolarities, mvme2100_openpic_initsenses); +#else +#ifdef TRACE_IRQ_INIT + printk("Going to initialize raven interrupt controller (openpic compliant)\n"); +#endif + openpic_init(1, mcp750_openpic_initpolarities, mcp750_openpic_initsenses); +#endif + +#if !defined(mvme2100) +#ifdef TRACE_IRQ_INIT + printk("Going to initialize the PCI/ISA bridge IRQ related setting (VIA 82C586)\n"); +#endif + if ( currentBoard == MESQUITE ) { + VIA_isa_bridge_interrupts_setup(); + known_cpi_isa_bridge = 1; + } + if ( currentBoard == MVME_2300 ) { + /* nothing to do for W83C553 bridge */ + known_cpi_isa_bridge = 1; + } + if ( currentBoard == MTX_WO_PP || currentBoard == MTX_W_PP ) { + /* W83C554, don't to anything at the moment. gregm 11/6/2002 */ + known_cpi_isa_bridge = 1; + } + + if (!known_cpi_isa_bridge) { + printk("Please add code for PCI/ISA bridge init to libbsp/powerpc/shared/irq/irq_init.c\n"); + printk("If your card works correctly please add a test and set known_cpi_isa_bridge to true\n"); + printk("currentBoard = %i\n", currentBoard); + } +#ifdef TRACE_IRQ_INIT + printk("Going to initialize the ISA PC legacy IRQ management hardware\n"); +#endif + BSP_i8259s_init(); +#endif + + /* + * Initialize RTEMS management interrupt table + */ + /* + * re-init the rtemsIrq table + */ + for (i = 0; i < BSP_IRQ_NUMBER; i++) { + rtemsIrq[i] = defaultIrq; + rtemsIrq[i].name = i; + } + /* + * Init initial Interrupt management config + */ + initial_config.irqNb = BSP_IRQ_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)) { + /* + * put something here that will show the failure... + */ + BSP_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n"); + } + + /* + * We must connect the raw irq handler for the two + * expected interrupt sources : decrementer and external interrupts. + */ + vectorDesc.exceptIndex = ASM_DEC_VECTOR; + vectorDesc.hdl.vector = ASM_DEC_VECTOR; + vectorDesc.hdl.raw_hdl = decrementer_exception_vector_prolog_code; + vectorDesc.hdl.raw_hdl_size = (unsigned) decrementer_exception_vector_prolog_code_size; + vectorDesc.on = nop_func; + vectorDesc.off = nop_func; + vectorDesc.isOn = connected; + if (!mpc60x_set_exception (&vectorDesc)) { + BSP_panic("Unable to initialize RTEMS decrementer raw exception\n"); + } + vectorDesc.exceptIndex = ASM_EXT_VECTOR; + vectorDesc.hdl.vector = ASM_EXT_VECTOR; + vectorDesc.hdl.raw_hdl = external_exception_vector_prolog_code; + vectorDesc.hdl.raw_hdl_size = (unsigned) external_exception_vector_prolog_code_size; + if (!mpc60x_set_exception (&vectorDesc)) { + BSP_panic("Unable to initialize RTEMS external raw exception\n"); + } +#ifdef TRACE_IRQ_INIT + printk("RTEMS IRQ management is now operational\n"); +#endif +} diff --git a/c/src/lib/libbsp/powerpc/score603e/startup/FPGA.c b/c/src/lib/libbsp/powerpc/score603e/startup/FPGA.c deleted file mode 100644 index 46c012f2ae..0000000000 --- a/c/src/lib/libbsp/powerpc/score603e/startup/FPGA.c +++ /dev/null @@ -1,164 +0,0 @@ -/* FPGA.c -- Bridge for second and subsequent generations - * - * COPYRIGHT (c) 1989-2001. - * On-Line Applications Research Corporation (OAR). - * - * The license and distribution terms for this file may in - * the file LICENSE in this distribution or at - * http://www.rtems.com/license/LICENSE. - * - * $Id: - */ - -#include -#include -#include -#include - -#include -#include - -/* - * initialize FPGA - */ -void initialize_PCI_bridge () -{ -#if (!SCORE603E_USE_DINK) - uint16_t mask, shift, data; - - shift = SCORE603E_85C30_0_IRQ - Score_IRQ_First; - mask = 1 << shift; - - shift = SCORE603E_85C30_1_IRQ - Score_IRQ_First; - mask = mask & (1 << shift); - - data = *SCORE603E_FPGA_MASK_DATA; - data = ~mask; - - *SCORE603E_FPGA_MASK_DATA = data; -#endif - -} - -void set_irq_mask( - uint16_t value -) -{ - uint16_t *loc; - - loc = (uint16_t*)SCORE603E_FPGA_MASK_DATA; - - *loc = value; -} - -uint16_t get_irq_mask() -{ - uint16_t *loc; - uint16_t value; - - loc = (uint16_t*)SCORE603E_FPGA_MASK_DATA; - - value = *loc; - - return value; -} - -void unmask_irq( - uint16_t irq_idx -) -{ - uint16_t value; - uint32_t mask_idx = irq_idx; - - value = get_irq_mask(); - -#if (HAS_PMC_PSC8) - switch (irq_idx + Score_IRQ_First ) { - case SCORE603E_85C30_4_IRQ: - case SCORE603E_85C30_2_IRQ: - case SCORE603E_85C30_5_IRQ: - case SCORE603E_85C30_3_IRQ: - mask_idx = SCORE603E_PCI_IRQ_0 - Score_IRQ_First; - break; - default: - break; - } -#endif - - value &= (~(0x1 << mask_idx)); - set_irq_mask( value ); -} - -void init_irq_data_register() -{ - uint32_t index; - uint32_t i; - -#if (SCORE603E_USE_DINK) - set_irq_mask( 0xffff ); -#endif - - /* - * Clear any existing interupts from the vector data register. - */ - for (i=0; i<20; i++) { - index = (*SCORE603E_FPGA_VECT_DATA); - if ( (index&0x10) != 0x10 ) - break; - } -} - -uint16_t read_and_clear_PMC_irq( - uint16_t irq -) -{ - uint16_t status_word = irq; - - status_word = (*BSP_PMC_STATUS_ADDRESS); - - return status_word; -} - -rtems_boolean Is_PMC_IRQ( - uint32_t pmc_irq, - uint16_t status_word -) -{ - rtems_boolean result= FALSE; - - switch(pmc_irq) { - case SCORE603E_85C30_4_IRQ: - result = Is_PMC_85C30_4_IRQ( status_word ); - break; - case SCORE603E_85C30_2_IRQ: - result = Is_PMC_85C30_2_IRQ( status_word ); - break; - case SCORE603E_85C30_5_IRQ: - result = Is_PMC_85C30_5_IRQ( status_word ); - break; - case SCORE603E_85C30_3_IRQ: - result = Is_PMC_85C30_3_IRQ( status_word ); - break; - default: - assert( 0 ); - break; - } - - return result; -} - -uint16_t read_and_clear_irq() -{ - uint16_t irq; - - irq = (*SCORE603E_FPGA_VECT_DATA); - - if ((irq & 0xffff0) != 0x10) { - DEBUG_puts( "ERROR:: no irq data\n"); - return (irq | 0x80); - } - - irq &=0xf; - - return irq; -} -- cgit v1.2.3