diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-23 09:50:39 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-04-23 15:18:44 +0200 |
commit | 8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708 (patch) | |
tree | 5dc76f7a4527b0a500fbf5ee91486b2780e47a1a /c/src/lib/libbsp/powerpc/shared | |
parent | bsps: Move SPI drivers to bsps (diff) | |
download | rtems-8f8ccee0d9e1c3adfb1de484f26f6d9f6ff08708.tar.bz2 |
bsps: Move interrupt controller support to bsps
This patch is a part of the BSP source reorganization.
Update #3285.
Diffstat (limited to 'c/src/lib/libbsp/powerpc/shared')
-rw-r--r-- | c/src/lib/libbsp/powerpc/shared/irq/i8259.c | 149 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/shared/irq/irq_init.c | 364 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/shared/irq/openpic_i8259_irq.c | 331 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/shared/openpic/openpic.c | 622 |
4 files changed, 0 insertions, 1466 deletions
diff --git a/c/src/lib/libbsp/powerpc/shared/irq/i8259.c b/c/src/lib/libbsp/powerpc/shared/irq/i8259.c deleted file mode 100644 index 7363e87ba0..0000000000 --- a/c/src/lib/libbsp/powerpc/shared/irq/i8259.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * This file contains the implementation of the function described in irq.h - * related to Intel 8259 Programmable Interrupt controller. - * - * 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 <bsp.h> -#include <bsp/irq.h> - -/*-------------------------------------------------------------------------+ -| Cache for 1st and 2nd PIC IRQ line's status (enabled or disabled) register. -+--------------------------------------------------------------------------*/ -/* - * lower byte is interrupt mask on the master PIC. - * while upper bits are interrupt on the slave PIC. - */ -volatile rtems_i8259_masks i8259s_cache = 0xfffb; - -/*-------------------------------------------------------------------------+ -| Function: BSP_irq_disable_at_i8259s -| Description: Mask IRQ line in appropriate PIC chip. -| Global Variables: i8259s_cache -| Arguments: vector_offset - number of IRQ line to mask. -| Returns: original state or -1 on error. -+--------------------------------------------------------------------------*/ -int BSP_irq_disable_at_i8259s (const rtems_irq_number irqLine) -{ - unsigned short mask; - rtems_interrupt_level level; - int rval; - - if ( ((int)irqLine < BSP_ISA_IRQ_LOWEST_OFFSET) || - ((int)irqLine > BSP_ISA_IRQ_MAX_OFFSET) - ) - return -1; - - rtems_interrupt_disable(level); - - mask = 1 << irqLine; - rval = i8259s_cache & mask ? 0 : 1; - i8259s_cache |= mask; - - if (irqLine < 8) - { - outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff); - } - else - { - outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8)); - } - rtems_interrupt_enable(level); - - return rval; -} - -/*-------------------------------------------------------------------------+ -| Function: BSP_irq_enable_at_i8259s -| Description: Unmask IRQ line in appropriate PIC chip. -| Global Variables: i8259s_cache -| Arguments: irqLine - number of IRQ line to mask. -| Returns: Nothing. -+--------------------------------------------------------------------------*/ -int BSP_irq_enable_at_i8259s (const rtems_irq_number irqLine) -{ - unsigned short mask; - rtems_interrupt_level level; - - if ( ((int)irqLine < BSP_ISA_IRQ_LOWEST_OFFSET) || - ((int)irqLine > BSP_ISA_IRQ_MAX_OFFSET ) - ) - return 1; - - rtems_interrupt_disable(level); - - mask = ~(1 << irqLine); - i8259s_cache &= mask; - - if (irqLine < 8) - { - outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff); - } - else - { - outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8)); - } - rtems_interrupt_enable(level); - - return 0; -} /* mask_irq */ - -int BSP_irq_enabled_at_i8259s (const rtems_irq_number irqLine) -{ - unsigned short mask; - - if ( ((int)irqLine < BSP_ISA_IRQ_LOWEST_OFFSET) || - ((int)irqLine > BSP_ISA_IRQ_MAX_OFFSET) - ) - return 1; - - mask = (1 << irqLine); - return (~(i8259s_cache & mask)); -} - -/*-------------------------------------------------------------------------+ -| Function: BSP_irq_ack_at_i8259s -| Description: Signal generic End Of Interrupt (EOI) to appropriate PIC. -| Global Variables: None. -| Arguments: irqLine - number of IRQ line to acknowledge. -| Returns: Nothing. -+--------------------------------------------------------------------------*/ -int BSP_irq_ack_at_i8259s (const rtems_irq_number irqLine) -{ - if (irqLine >= 8) { - outport_byte(PIC_MASTER_COMMAND_IO_PORT, SLAVE_PIC_EOSI); - outport_byte(PIC_SLAVE_COMMAND_IO_PORT, (PIC_EOSI | (irqLine - 8))); - } - else { - outport_byte(PIC_MASTER_COMMAND_IO_PORT, (PIC_EOSI | irqLine)); - } - - return 0; - -} /* ackIRQ */ - -void BSP_i8259s_init(void) -{ - /* - * init master 8259 interrupt controller - */ - outport_byte(PIC_MASTER_COMMAND_IO_PORT, 0x11); /* Start init sequence */ - outport_byte(PIC_MASTER_IMR_IO_PORT, 0x00);/* Vector base = 0 */ - outport_byte(PIC_MASTER_IMR_IO_PORT, 0x04);/* edge tiggered, Cascade (slave) on IRQ2 */ - outport_byte(PIC_MASTER_IMR_IO_PORT, 0x01);/* Select 8086 mode */ - outport_byte(PIC_MASTER_IMR_IO_PORT, 0xFB); /* Mask all except cascade */ - /* - * init slave interrupt controller - */ - outport_byte(PIC_SLAVE_COMMAND_IO_PORT, 0x11); /* Start init sequence */ - outport_byte(PIC_SLAVE_IMR_IO_PORT, 0x08);/* Vector base = 8 */ - outport_byte(PIC_SLAVE_IMR_IO_PORT, 0x02);/* edge triggered, Cascade (slave) on IRQ2 */ - outport_byte(PIC_SLAVE_IMR_IO_PORT, 0x01); /* Select 8086 mode */ - outport_byte(PIC_SLAVE_IMR_IO_PORT, 0xFF); /* Mask all */ - -} diff --git a/c/src/lib/libbsp/powerpc/shared/irq/irq_init.c b/c/src/lib/libbsp/powerpc/shared/irq/irq_init.c deleted file mode 100644 index 1a44992a5b..0000000000 --- a/c/src/lib/libbsp/powerpc/shared/irq/irq_init.c +++ /dev/null @@ -1,364 +0,0 @@ -/* 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 <jskulpin@eng01.gdds.com> - * to make it valid for MVME2300 Motorola boards. - * - * Till Straumann <strauman@slac.stanford.edu>, 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.org/license/LICENSE. - */ - -#include <libcpu/io.h> -#include <libcpu/spr.h> -#include <bsp/pci.h> -#include <bsp/residual.h> -#include <bsp/irq.h> -#if BSP_PCI_IRQ_NUMBER > 0 -#include <bsp/openpic.h> -#endif -#include <bsp/irq_supp.h> -#include <bsp.h> -#include <bsp/motorola.h> -#include <rtems/bspIo.h> - -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; -#ifndef qemu -static pci_isa_bridge_device bridge; -#endif - -/* - * default methods - */ -static void nop_hdl(rtems_irq_hdl_param ignored) -{ -} - -static void nop_irq_enable(const struct __rtems_irq_connect_data__*ignored) -{ -} - -static int irq_is_connected(const struct __rtems_irq_connect_data__*ignored) -{ - return 0; -} - - -static rtems_irq_connect_data rtemsIrq[BSP_IRQ_NUMBER]; -static rtems_irq_global_settings initial_config; -static rtems_irq_connect_data defaultIrq = { - 0, /* vector */ - nop_hdl, /* hdl */ - NULL, /* handle */ - nop_irq_enable, /* on */ - nop_irq_enable, /* off */ - irq_is_connected /* isOn */ -#ifdef BSP_SHARED_HANDLER_SUPPORT - , NULL /* next_handler */ -#endif -}; -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, -#if BSP_PCI_IRQ_NUMBER > 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... */ -#endif - /* - * Processor exceptions handled as interrupts - */ - 0 -}; - -#if BSP_PCI_IRQ_NUMBER > 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 -#endif - -#if BSP_ISA_IRQ_NUMBER > 0 && !defined(qemu) -void VIA_isa_bridge_interrupts_setup(void) -{ - pci_isa_bridge_device pci_dev; - uint32_t temp; - unsigned char tmp; - unsigned char maxBus; - unsigned found = 0; - - maxBus = pci_bus_count(); - 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) rtems_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 - } -} -#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 BSP_ISA_IRQ_NUMBER > 0 && !defined(mvme2100) - int known_cpi_isa_bridge = 0; -#endif - 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 - /* EPIC sources don't start at the regular place; define appropriate offset - * prior to initializing the PIC. - */ - openpic_init(1, mvme2100_openpic_initpolarities, mvme2100_openpic_initsenses, 16, 16, BSP_bus_frequency); -#else -#if BSP_PCI_IRQ_NUMBER > 0 -#ifdef TRACE_IRQ_INIT - printk("Going to initialize raven interrupt controller (openpic compliant)\n"); -#endif - openpic_init(1, mcp750_openpic_initpolarities, mcp750_openpic_initsenses, 0, 0, 0); -#ifdef TRACE_IRQ_INIT - printk("Going to initialize the PCI/ISA bridge IRQ related setting (VIA 82C586)\n"); -#endif -#endif - -#if BSP_ISA_IRQ_NUMBER > 0 - if ( currentBoard == MESQUITE ) { -#ifndef qemu - VIA_isa_bridge_interrupts_setup(); -#endif - 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 - -#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_LOWEST_OFFSET; - initial_config.irqPrioTbl = irqPrioTable; - - if (!BSP_rtems_irq_mngt_set(&initial_config)) { - /* - * put something here that will show the failure... - */ - rtems_panic("Unable to initialize RTEMS interrupt Management!!! System locked\n"); - } - -#ifdef TRACE_IRQ_INIT - printk("RTEMS IRQ management is now operational\n"); -#endif -} diff --git a/c/src/lib/libbsp/powerpc/shared/irq/openpic_i8259_irq.c b/c/src/lib/libbsp/powerpc/shared/irq/openpic_i8259_irq.c deleted file mode 100644 index 4a9c393f7f..0000000000 --- a/c/src/lib/libbsp/powerpc/shared/irq/openpic_i8259_irq.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * - * This file contains the i8259/openpic-specific 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 the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#include <stdlib.h> - -#include <bsp.h> -#include <bsp/irq.h> -#include <bsp/irq_supp.h> -#ifndef BSP_HAS_NO_VME -#include <bsp/VMEConfig.h> -#endif -#if BSP_PCI_IRQ_NUMBER > 0 -#include <bsp/openpic.h> -#endif -#include <libcpu/io.h> -#include <bsp/vectors.h> -#include <stdlib.h> - -#include <rtems/bspIo.h> /* for printk */ - -#ifndef qemu -#define RAVEN_INTR_ACK_REG 0xfeff0030 -#else -#define RAVEN_INTR_ACK_REG 0xbffffff0 -#endif - -#if BSP_ISA_IRQ_NUMBER > 0 -/* - * pointer to the mask representing the additionnal irq vectors - * that must be disabled when a particular entry is activated. - * They will be dynamically computed from the priority table given - * in BSP_rtems_irq_mngt_set(); - * CAUTION : this table is accessed directly by interrupt routine - * prologue. - */ -rtems_i8259_masks irq_mask_or_tbl[BSP_IRQ_NUMBER]; -#endif - -/* - * default handler connected on each irq after bsp initialization - */ -static rtems_irq_connect_data default_rtems_entry; - -static rtems_irq_connect_data* rtems_hdl_tbl; - -#if BSP_ISA_IRQ_NUMBER > 0 -/* - * Check if IRQ is an ISA IRQ - */ -static inline int is_isa_irq(const rtems_irq_number irqLine) -{ - return (((int) irqLine <= BSP_ISA_IRQ_MAX_OFFSET) && - ((int) irqLine >= BSP_ISA_IRQ_LOWEST_OFFSET) - ); -} -#endif - -#if BSP_PCI_IRQ_NUMBER > 0 -/* - * Check if IRQ is an OPENPIC IRQ - */ -static inline int is_pci_irq(const rtems_irq_number irqLine) -{ - return OpenPIC && (((int) irqLine <= BSP_PCI_IRQ_MAX_OFFSET) && - ((int) irqLine >= BSP_PCI_IRQ_LOWEST_OFFSET) - ); -} -#endif - -/* - * ------------------------ RTEMS Irq helper functions ---------------- - */ - -#if BSP_ISA_IRQ_NUMBER > 0 -/* - * Caution : this function assumes the variable "*config" - * is already set and that the tables it contains are still valid - * and accessible. - */ -static void compute_i8259_masks_from_prio (rtems_irq_global_settings* config) -{ - int i; - int j; - /* - * Always mask at least current interrupt to prevent re-entrance - */ - for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) { - * ((unsigned short*) &irq_mask_or_tbl[i]) = (1 << i); - for (j = BSP_ISA_IRQ_LOWEST_OFFSET; j < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; j++) { - /* - * Mask interrupts at i8259 level that have a lower priority - */ - if (config->irqPrioTbl [i] > config->irqPrioTbl [j]) { - * ((unsigned short*) &irq_mask_or_tbl[i]) |= (1 << j); - } - } - } -} -#endif - -void -BSP_enable_irq_at_pic(const rtems_irq_number name) -{ -#if BSP_ISA_IRQ_NUMBER > 0 - if (is_isa_irq(name)) { - /* - * Enable interrupt at PIC level - */ - BSP_irq_enable_at_i8259s ((int) name - BSP_ISA_IRQ_LOWEST_OFFSET); - } -#endif - -#if BSP_PCI_IRQ_NUMBER > 0 - if (is_pci_irq(name)) { - /* - * Enable interrupt at OPENPIC level - */ - openpic_enable_irq ((int) name - BSP_PCI_IRQ_LOWEST_OFFSET); - } -#endif -} - -int -BSP_disable_irq_at_pic(const rtems_irq_number name) -{ -#if BSP_ISA_IRQ_NUMBER > 0 - if (is_isa_irq(name)) { - /* - * disable interrupt at PIC level - */ - return BSP_irq_disable_at_i8259s ((int) name - BSP_ISA_IRQ_LOWEST_OFFSET); - } -#endif -#if BSP_PCI_IRQ_NUMBER > 0 - if (is_pci_irq(name)) { - /* - * disable interrupt at OPENPIC level - */ - return openpic_disable_irq ((int) name - BSP_PCI_IRQ_LOWEST_OFFSET); - } -#endif - return -1; -} - -/* - * RTEMS Global Interrupt Handler Management Routines - */ -int BSP_setup_the_pic(rtems_irq_global_settings* config) -{ - int i; - /* - * Store various code accelerators - */ - default_rtems_entry = config->defaultEntry; - rtems_hdl_tbl = config->irqHdlTbl; - - /* - * set up internal tables used by rtems interrupt prologue - */ - -#if BSP_ISA_IRQ_NUMBER > 0 - /* - * start with ISA IRQ - */ - compute_i8259_masks_from_prio (config); - - for (i=BSP_ISA_IRQ_LOWEST_OFFSET; i < BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER; i++) { - if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) { - BSP_irq_enable_at_i8259s (i); - } - else { - BSP_irq_disable_at_i8259s (i); - } - } - - if ( BSP_ISA_IRQ_NUMBER > 0 ) { - /* - * must enable slave pic anyway - */ - BSP_irq_enable_at_i8259s (2); - } -#endif - -#if BSP_PCI_IRQ_NUMBER > 0 - if ( ! OpenPIC ) - return 1; - /* - * continue with PCI IRQ - */ - for (i=BSP_PCI_IRQ_LOWEST_OFFSET; i < BSP_PCI_IRQ_LOWEST_OFFSET + BSP_PCI_IRQ_NUMBER ; i++) { - /* - * Note that openpic_set_priority() sets the TASK priority of the PIC - */ - openpic_set_source_priority(i - BSP_PCI_IRQ_LOWEST_OFFSET, - config->irqPrioTbl[i]); - if (rtems_hdl_tbl[i].hdl != default_rtems_entry.hdl) { - openpic_enable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET); - } - else { - openpic_disable_irq ((int) i - BSP_PCI_IRQ_LOWEST_OFFSET); - } - } - -#ifdef BSP_PCI_ISA_BRIDGE_IRQ - /* - * Must enable PCI/ISA bridge IRQ - */ - openpic_enable_irq (BSP_PCI_ISA_BRIDGE_IRQ); -#endif -#endif - - return 1; -} - -int _BSP_vme_bridge_irq = -1; - -unsigned BSP_spuriousIntr = 0; - -/* - * High level IRQ handler called from shared_raw_irq_code_entry - */ -int C_dispatch_irq_handler (BSP_Exception_frame *frame, unsigned int excNum) -{ - register unsigned int irq; -#if BSP_ISA_IRQ_NUMBER > 0 - register unsigned isaIntr; /* boolean */ - register unsigned oldMask = 0; /* old isa pic masks */ - register unsigned newMask; /* new isa pic masks */ -#endif - - if (excNum == ASM_DEC_VECTOR) { - - bsp_irq_dispatch_list(rtems_hdl_tbl, BSP_DECREMENTER, default_rtems_entry.hdl); - - return 0; - - } - -#if BSP_PCI_IRQ_NUMBER > 0 - if ( OpenPIC ) { - irq = openpic_irq(0); - if (irq == OPENPIC_VEC_SPURIOUS) { - ++BSP_spuriousIntr; - return 0; - } - - /* some BSPs might want to use a different numbering... */ - irq = irq - OPENPIC_VEC_SOURCE + BSP_PCI_IRQ_LOWEST_OFFSET; - } else { -#if BSP_ISA_IRQ_NUMBER > 0 -#ifdef BSP_PCI_ISA_BRIDGE_IRQ - irq = BSP_PCI_ISA_BRIDGE_IRQ; -#else -#error "Configuration Error -- BSP with ISA + PCI IRQs MUST define BSP_PCI_ISA_BRIDGE_IRQ" -#endif -#else - rtems_panic("MUST have an OpenPIC if BSP has PCI IRQs but no ISA IRQs"); - /* rtems_panic() never returns but the 'return' statement silences - * a compiler warning about 'irq' possibly being used w/o initialization. - */ - return -1; -#endif - } -#endif - -#if BSP_ISA_IRQ_NUMBER > 0 -#ifdef BSP_PCI_ISA_BRIDGE_IRQ -#if 0 == BSP_PCI_IRQ_NUMBER -#error "Configuration Error -- BSP w/o PCI IRQs MUST NOT define BSP_PCI_ISA_BRIDGE_IRQ" -#endif - isaIntr = (irq == BSP_PCI_ISA_BRIDGE_IRQ); -#else - isaIntr = 1; -#endif - if (isaIntr) { - /* - * Acknowledge and read 8259 vector - */ - irq = (unsigned int) (*(unsigned char *) RAVEN_INTR_ACK_REG); - /* - * store current PIC mask - */ - oldMask = i8259s_cache; - newMask = oldMask | irq_mask_or_tbl [irq]; - i8259s_cache = newMask; - outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff); - outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8)); - BSP_irq_ack_at_i8259s (irq); -#if BSP_PCI_IRQ_NUMBER > 0 - if ( OpenPIC ) - openpic_eoi(0); -#endif - } -#endif - - /* dispatch handlers */ - bsp_irq_dispatch_list(rtems_hdl_tbl, irq, default_rtems_entry.hdl); - -#if BSP_ISA_IRQ_NUMBER > 0 - if (isaIntr) { - i8259s_cache = oldMask; - outport_byte(PIC_MASTER_IMR_IO_PORT, i8259s_cache & 0xff); - outport_byte(PIC_SLAVE_IMR_IO_PORT, ((i8259s_cache & 0xff00) >> 8)); - } - else -#endif - { -#if BSP_PCI_IRQ_NUMBER > 0 -#ifdef BSP_PCI_VME_DRIVER_DOES_EOI - /* leave it to the VME bridge driver to do EOI, so - * it can re-enable the openpic while handling - * VME interrupts (-> VME priorities in software) - */ - if (_BSP_vme_bridge_irq != irq && OpenPIC) -#endif - openpic_eoi(0); -#else - do {} while (0); -#endif - } - return 0; -} diff --git a/c/src/lib/libbsp/powerpc/shared/openpic/openpic.c b/c/src/lib/libbsp/powerpc/shared/openpic/openpic.c deleted file mode 100644 index 556014964b..0000000000 --- a/c/src/lib/libbsp/powerpc/shared/openpic/openpic.c +++ /dev/null @@ -1,622 +0,0 @@ -/* - * openpic.c -- OpenPIC Interrupt Handling - * - * Copyright (C) 1997 Geert Uytterhoeven - * - * Modified to compile in RTEMS development environment - * by Eric Valette - * - * Copyright (C) 1999 Eric Valette. 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. - */ - -/* - * Note: Interprocessor Interrupt (IPI) and Timer support is incomplete - */ - -#include <rtems.h> -#include <bsp.h> -#include <rtems/bspIo.h> -#include <bsp/openpic.h> -#include <rtems/pci.h> -#include <libcpu/io.h> -#include <libcpu/byteorder.h> -#include <rtems/bspIo.h> -#include <inttypes.h> - -#ifndef NULL -#define NULL 0 -#endif -#define REGISTER_DEBUG -#undef REGISTER_DEBUG - -volatile struct OpenPIC *OpenPIC = NULL; - -static unsigned int NumProcessors; -static unsigned int NumSources; - -static unsigned int openpic_eoi_delay = 0; -static int openpic_src_offst = 0; -#define SOURCE(irq) Source[ (irq) + openpic_src_offst ] - - /* - * Accesses to the current processor's registers - */ - -#define THIS_CPU Processor[cpu] -#define CHECK_THIS_CPU check_arg_cpu(cpu) - - /* - * Sanity checks - */ - -#if 1 -/* This software deliberately uses non-zero values to the method - * __builtin_return_address() and we want to avoid the GCC warning. - */ -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wframe-address" -#define check_arg_ipi(ipi) \ - if (ipi < 0 || ipi >= OPENPIC_NUM_IPI) \ - printk("openpic.c:%d: illegal ipi %d\n", __LINE__, ipi); -#define check_arg_timer(timer) \ - if (timer < 0 || timer >= OPENPIC_NUM_TIMERS) \ - printk("openpic.c:%d: illegal timer %d\n", __LINE__, timer); -#define check_arg_vec(vec) \ - if (vec < 0 || vec >= OPENPIC_NUM_VECTORS) \ - printk("openpic.c:%d: illegal vector %d\n", __LINE__, vec); -#define check_arg_pri(pri) \ - if (pri < 0 || pri >= OPENPIC_NUM_PRI) \ - printk("openpic.c:%d: illegal priority %d\n", __LINE__, pri); -#define check_arg_irq(irq) \ - if (irq < 0 || irq >= NumSources) \ - printk("openpic.c:%d: illegal irq %d from 0x%08" PRIxPTR ",[0x%08" PRIxPTR "],[[0x%08" PRIxPTR "]]\n", \ - __LINE__, irq, (uintptr_t) __builtin_return_address(0), \ - (uintptr_t) __builtin_return_address(1), (uintptr_t) __builtin_return_address(2) \ - ); -#define check_arg_cpu(cpu) \ - if (cpu < 0 || cpu >= NumProcessors) \ - printk("openpic.c:%d: illegal cpu %d\n", __LINE__, cpu); -#else -#define check_arg_ipi(ipi) do {} while (0) -#define check_arg_timer(timer) do {} while (0) -#define check_arg_vec(vec) do {} while (0) -#define check_arg_pri(pri) do {} while (0) -#define check_arg_irq(irq) do {} while (0) -#define check_arg_cpu(cpu) do {} while (0) -#endif - - /* - * I/O functions - */ - -static inline unsigned int openpic_read(volatile unsigned int *addr) -{ - unsigned int val; - -#ifdef BSP_OPEN_PIC_BIG_ENDIAN - val = in_be32((volatile uint32_t *)addr); -#else - val = in_le32((volatile uint32_t *)addr); -#endif -#ifdef REGISTER_DEBUG - printk("openpic_read(0x%08x) = 0x%08x\n", (unsigned int)addr, val); -#endif - return val; -} - -static inline void openpic_write(volatile unsigned int *addr, unsigned int val) -{ -#ifdef REGISTER_DEBUG - printk("openpic_write(0x%08x, 0x%08x)\n", (unsigned int)addr, val); -#endif -#ifdef BSP_OPEN_PIC_BIG_ENDIAN - out_be32((volatile uint32_t *)addr, val); -#else - out_le32((volatile uint32_t *)addr, val); -#endif -} - -static inline unsigned int openpic_readfield(volatile unsigned int *addr, unsigned int mask) -{ - unsigned int val = openpic_read(addr); - return val & mask; -} - -static inline void openpic_writefield(volatile unsigned int *addr, unsigned int mask, - unsigned int field) -{ - unsigned int val = openpic_read(addr); - openpic_write(addr, (val & ~mask) | (field & mask)); -} - -static inline void openpic_clearfield(volatile unsigned int *addr, unsigned int mask) -{ - openpic_writefield(addr, mask, 0); -} - -static inline void openpic_setfield(volatile unsigned int *addr, unsigned int mask) -{ - openpic_writefield(addr, mask, mask); -} - - /* - * Update a Vector/Priority register in a safe manner. The interrupt will - * be disabled. - */ - -static void openpic_safe_writefield(volatile unsigned int *addr, unsigned int mask, - unsigned int field) -{ - openpic_setfield(addr, OPENPIC_MASK); - /* wait until it's not in use */ - while (openpic_read(addr) & OPENPIC_ACTIVITY); - openpic_writefield(addr, mask | OPENPIC_MASK, field | OPENPIC_MASK); -} - -/* -------- Global Operations ---------------------------------------------- */ - - /* - * Initialize the OpenPIC - * - * Add some kludge to use the Motorola Raven OpenPIC which does not - * report vendor and device id, and gets the wrong number of interrupts. - * (Motorola did a great job on that one!) - * - * T. Straumann, 12/20/2001: polarities and senses are now passed as - * parameters, eliminated global vars. - * IRQ0 is no longer treated specially. - */ - -void openpic_init(int main_pic, unsigned char *polarities, unsigned char *senses, int num_sources, int source_offset, unsigned long epic_freq) -{ - unsigned int t, i; - unsigned int vendorid, devid, stepping, timerfreq; - const char *version, *vendor, *device; - - if (!OpenPIC) - rtems_panic("No OpenPIC found"); - - t = openpic_read(&OpenPIC->Global.Feature_Reporting0); - switch (t & OPENPIC_FEATURE_VERSION_MASK) { - case 1: - version = "1.0"; - break; - case 2: - version = "1.2"; - break; - default: - version = "?"; - break; - } - NumProcessors = ((t & OPENPIC_FEATURE_LAST_PROCESSOR_MASK) >> - OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT) + 1; - NumSources = ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK) >> - OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1; - t = openpic_read(&OpenPIC->Global.Vendor_Identification); - - vendorid = t & OPENPIC_VENDOR_ID_VENDOR_ID_MASK; - devid = (t & OPENPIC_VENDOR_ID_DEVICE_ID_MASK) >> - OPENPIC_VENDOR_ID_DEVICE_ID_SHIFT; - stepping = (t & OPENPIC_VENDOR_ID_STEPPING_MASK) >> - OPENPIC_VENDOR_ID_STEPPING_SHIFT; - - /* Kludge for the Raven */ -/* - pci_read_config_dword(0, 0, 0, 0, &t); -*/ - if (t == PCI_VENDOR_ID_MOTOROLA + (PCI_DEVICE_ID_MOTOROLA_RAVEN<<16)) { - vendor = "Motorola"; - device = "Raven"; - NumSources += 1; - } - else if (t == PCI_VENDOR_ID_MOTOROLA + (PCI_DEVICE_ID_MOTOROLA_HAWK<<16)) { - vendor = "Motorola"; - device = "Hawk"; - NumSources += 1; - } else { - switch (vendorid) { - case OPENPIC_VENDOR_ID_APPLE: - vendor = "Apple"; - break; - default: - vendor = "Unknown"; - break; - } - switch (devid) { - case OPENPIC_DEVICE_ID_APPLE_HYDRA: - device = "Hydra"; - break; - default: - device = "Unknown"; - break; - } - } - printk("OpenPIC Version %s (%d CPUs and %d IRQ sources) at 0x%08" PRIuPTR "\n", version, - NumProcessors, NumSources, (uintptr_t) OpenPIC); - - printk("OpenPIC Vendor %d (%s), Device %d (%s), Stepping %d\n", vendorid, - vendor, devid, device, stepping); - - /* Override if they desire */ - if ( num_sources ) { - if ( NumSources != num_sources ) - printk("Overriding NumSources (%i) from configuration with %i\n", - NumSources, num_sources); - NumSources = num_sources; - } - - openpic_src_offst = source_offset; - - timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency); - printk("OpenPIC timer frequency is "); - if (timerfreq) - printk("%d Hz\n", timerfreq); - else - printk("not set\n"); - - if ( main_pic ) - { - /* Initialize timer interrupts */ - for (i = 0; i < OPENPIC_NUM_TIMERS; i++) { - /* Disabled, Priority 0 */ - openpic_inittimer(i, 0, OPENPIC_VEC_TIMER+i); - /* No processor */ - openpic_maptimer(i, 0); - } - - /* Initialize IPI interrupts */ - for (i = 0; i < OPENPIC_NUM_IPI; i++) { - /* Disabled, Priority 0 */ - openpic_initipi(i, 0, OPENPIC_VEC_IPI+i); - } - - /* Initialize external interrupts */ - for (i = 0; i < NumSources; i++) { - /* Enabled, Priority 8 */ - openpic_initirq(i, 8, OPENPIC_VEC_SOURCE+i, - polarities ? polarities[i] : 0, - senses ? senses[i] : 1); - /* Processor 0 */ - openpic_mapirq(i, 1<<0); - } - - /* Initialize the spurious interrupt */ - openpic_set_spurious(OPENPIC_VEC_SPURIOUS); -#if 0 - if (request_irq(IRQ_8259_CASCADE, no_action, SA_INTERRUPT, - "82c59 cascade", NULL)) - printk("Unable to get OpenPIC IRQ 0 for cascade\n"); -#endif - openpic_set_priority(0, 0); - openpic_disable_8259_pass_through(); - } - if ( epic_freq ) { - /* Speed up the serial interface; if it is too slow then we might get spurious - * interrupts: - * After an ISR clears the interrupt condition at the source/device, the wire - * remains asserted during the propagation delay introduced by the serial interface - * (something really stupid). If the ISR returns while the wire is not released - * yet, then a spurious interrupt happens. - * The book says we should be careful if the serial clock is > 33MHz. - * Empirically, it seems that running it at 33MHz is fast enough. Otherwise, - * we should introduce a delay in openpic_eoi(). - * The maximal delay are 16 (serial) clock cycles. If the divisor is 8 - * [power-up default] then the lag is 2us [66MHz SDRAM clock; I assume this - * is equal to the bus frequency]. - * FIXME: This should probably be a EPIC-specific piece in 'openpic.c' - * Unfortunately, there is no easy way of figuring out if the - * device is an EPIC or not. - */ - uint32_t eicr_val, ratio; - /* On the 8240 this is the EICR register */ - eicr_val = in_le32( (volatile uint32_t *)&OpenPIC->Global.Global_Configuration1 ) & ~(7<<28); - if ( (1<<27) & eicr_val ) { - /* serial interface mode enabled */ - - /* round to nearest integer: - * round(Bus_freq/33000000) = floor( 2*(Bus_freq/33e6) + 1 ) / 2 - */ - ratio = epic_freq / 16500000 + 1; - ratio >>= 2; /* EICR value is half actual divisor */ - if ( 0==ratio ) - ratio = 1; - out_le32((volatile uint32_t *)&OpenPIC->Global.Global_Configuration1, eicr_val | ((ratio &7) << 28)); - /* Delay in TB cycles (assuming TB runs at 1/4 of the bus frequency) */ - openpic_set_eoi_delay( 16 * (2*ratio) / 4 ); - } - } -} - - /* - * Reset the OpenPIC - */ - -void openpic_reset(void) -{ - openpic_setfield(&OpenPIC->Global.Global_Configuration0, - OPENPIC_CONFIG_RESET); -} - - /* - * Enable/disable 8259 Pass Through Mode - */ - -void openpic_enable_8259_pass_through(void) -{ - openpic_clearfield(&OpenPIC->Global.Global_Configuration0, - OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE); -} - -void openpic_disable_8259_pass_through(void) -{ - openpic_setfield(&OpenPIC->Global.Global_Configuration0, - OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE); -} - - /* - * Find out the current interrupt - */ - -unsigned int openpic_irq(unsigned int cpu) -{ - unsigned int vec; - - check_arg_cpu(cpu); - vec = openpic_readfield(&OpenPIC->THIS_CPU.Interrupt_Acknowledge, - OPENPIC_VECTOR_MASK); - return vec; -} - - /* - * Signal end of interrupt (EOI) processing - */ - -void openpic_eoi(unsigned int cpu) -{ - check_arg_cpu(cpu); - if ( openpic_eoi_delay ) - rtems_bsp_delay_in_bus_cycles(openpic_eoi_delay); - openpic_write(&OpenPIC->THIS_CPU.EOI, 0); -} - -unsigned openpic_set_eoi_delay(unsigned tb_cycles) -{ -unsigned rval = openpic_eoi_delay; - openpic_eoi_delay = tb_cycles; - return rval; -} - - /* - * Get/set the current task priority - */ - -unsigned int openpic_get_priority(unsigned int cpu) -{ - CHECK_THIS_CPU; - return openpic_readfield(&OpenPIC->THIS_CPU.Current_Task_Priority, - OPENPIC_CURRENT_TASK_PRIORITY_MASK); -} - -void openpic_set_priority(unsigned int cpu, unsigned int pri) -{ - CHECK_THIS_CPU; - check_arg_pri(pri); - openpic_writefield(&OpenPIC->THIS_CPU.Current_Task_Priority, - OPENPIC_CURRENT_TASK_PRIORITY_MASK, pri); -} - - /* - * Get/set the spurious vector - */ - -unsigned int openpic_get_spurious(void) -{ - return openpic_readfield(&OpenPIC->Global.Spurious_Vector, - OPENPIC_VECTOR_MASK); -} - -void openpic_set_spurious(unsigned int vec) -{ - check_arg_vec(vec); - openpic_writefield(&OpenPIC->Global.Spurious_Vector, OPENPIC_VECTOR_MASK, - vec); -} - - /* - * Initialize one or more CPUs - */ - -void openpic_init_processor(unsigned int cpumask) -{ - openpic_write(&OpenPIC->Global.Processor_Initialization, cpumask); -} - -/* -------- Interprocessor Interrupts -------------------------------------- */ - - /* - * Initialize an interprocessor interrupt (and disable it) - * - * ipi: OpenPIC interprocessor interrupt number - * pri: interrupt source priority - * vec: the vector it will produce - */ - -void openpic_initipi(unsigned int ipi, unsigned int pri, unsigned int vec) -{ - check_arg_timer(ipi); - check_arg_pri(pri); - check_arg_vec(vec); - openpic_safe_writefield(&OpenPIC->Global.IPI_Vector_Priority(ipi), - OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK, - (pri << OPENPIC_PRIORITY_SHIFT) | vec); -} - - /* - * Send an IPI to one or more CPUs - */ - -void openpic_cause_IPI(unsigned int cpu, unsigned int ipi, unsigned int cpumask) -{ - CHECK_THIS_CPU; - check_arg_ipi(ipi); - openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), cpumask); -} - -/* -------- Timer Interrupts ----------------------------------------------- */ - - /* - * Initialize a timer interrupt (and disable it) - * - * timer: OpenPIC timer number - * pri: interrupt source priority - * vec: the vector it will produce - */ - -void openpic_inittimer(unsigned int timer, unsigned int pri, unsigned int vec) -{ - check_arg_timer(timer); - check_arg_pri(pri); - check_arg_vec(vec); - openpic_safe_writefield(&OpenPIC->Global.Timer[timer].Vector_Priority, - OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK, - (pri << OPENPIC_PRIORITY_SHIFT) | vec); -} - - /* - * Map a timer interrupt to one or more CPUs - */ - -void openpic_maptimer(unsigned int timer, unsigned int cpumask) -{ - check_arg_timer(timer); - openpic_write(&OpenPIC->Global.Timer[timer].Destination, cpumask); -} - - /* - * Set base count and / or enable / disable interrupt. - */ - - -void openpic_settimer(unsigned int timer, unsigned int base_count, int irq_enable) -{ - check_arg_timer(timer); - if ( base_count ) - openpic_write(&OpenPIC->Global.Timer[timer].Base_Count, base_count); - if ( irq_enable ) - openpic_clearfield(&OpenPIC->Global.Timer[timer].Vector_Priority, OPENPIC_MASK); - else - openpic_setfield(&OpenPIC->Global.Timer[timer].Vector_Priority, OPENPIC_MASK); -} - -unsigned int openpic_gettimer(unsigned int timer) -{ - check_arg_timer(timer); - return (openpic_read(&OpenPIC->Global.Timer[timer].Current_Count) & ~OPENPIC_MASK); -} - -/* -------- Interrupt Sources ---------------------------------------------- */ - - /* - * Enable/disable an interrupt source - */ - -void openpic_enable_irq(unsigned int irq) -{ -unsigned long flags; - check_arg_irq(irq); - rtems_interrupt_disable(flags); - openpic_clearfield(&OpenPIC->SOURCE(irq).Vector_Priority, OPENPIC_MASK); - rtems_interrupt_enable(flags); -} - -int openpic_disable_irq(unsigned int irq) -{ -int rval; -unsigned long flags; - check_arg_irq(irq); - if ( irq < 0 || irq >=NumSources ) - return -1; - rtems_interrupt_disable(flags); - rval = openpic_readfield(&OpenPIC->SOURCE(irq).Vector_Priority, OPENPIC_MASK) ? 0 : 1; - openpic_setfield(&OpenPIC->SOURCE(irq).Vector_Priority, OPENPIC_MASK); - rtems_interrupt_enable(flags); - return rval; -} - - /* - * Initialize an interrupt source (and disable it!) - * - * irq: OpenPIC interrupt number - * pri: interrupt source priority - * vec: the vector it will produce - * pol: polarity (1 for positive, 0 for negative) - * sense: 1 for level, 0 for edge - */ - -void openpic_initirq(unsigned int irq, unsigned int pri, unsigned int vec, int pol, int sense) -{ -#if 0 - printk("openpic_initirq: irq=%d pri=%d vec=%d pol=%d sense=%d\n", - irq, pri, vec, pol, sense); -#endif - - check_arg_irq(irq); - check_arg_pri(pri); - check_arg_vec(vec); - openpic_safe_writefield(&OpenPIC->SOURCE(irq).Vector_Priority, - OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK | - OPENPIC_SENSE_POLARITY | OPENPIC_SENSE_LEVEL, - (pri << OPENPIC_PRIORITY_SHIFT) | vec | - (pol ? OPENPIC_SENSE_POLARITY : 0) | - (sense ? OPENPIC_SENSE_LEVEL : 0)); -} - - /* - * Map an interrupt source to one or more CPUs - */ - -void openpic_mapirq(unsigned int irq, unsigned int cpumask) -{ - check_arg_irq(irq); - openpic_write(&OpenPIC->SOURCE(irq).Destination, cpumask); -} - - /* - * Get the current priority of an external interrupt - */ -unsigned int openpic_get_source_priority(unsigned int irq) -{ - check_arg_irq(irq); - return openpic_readfield(&OpenPIC->SOURCE(irq).Vector_Priority, - OPENPIC_PRIORITY_MASK) >> OPENPIC_PRIORITY_SHIFT; -} - -void openpic_set_source_priority(unsigned int irq, unsigned int pri) -{ -unsigned long flags; - check_arg_irq(irq); - check_arg_pri(pri); - rtems_interrupt_disable(flags); - openpic_writefield( - &OpenPIC->SOURCE(irq).Vector_Priority, - OPENPIC_PRIORITY_MASK, - pri << OPENPIC_PRIORITY_SHIFT); - rtems_interrupt_enable(flags); -} - /* - * Set the sense for an interrupt source (and disable it!) - * - * sense: 1 for level, 0 for edge - */ - -void openpic_set_sense(unsigned int irq, int sense) -{ - check_arg_irq(irq); - openpic_safe_writefield(&OpenPIC->SOURCE(irq).Vector_Priority, - OPENPIC_SENSE_LEVEL, - (sense ? OPENPIC_SENSE_LEVEL : 0)); -} |