📄 irq_init.c
字号:
/* 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.com/license/LICENSE. * * $Id: irq_init.c,v 1.6.2.6 2004/11/10 22:15:00 joel Exp $ */#include <libcpu/io.h>#include <libcpu/spr.h>#include <bsp/pci.h>#include <bsp/residual.h>#include <bsp/openpic.h>#include <bsp/irq.h>#include <bsp.h>#include <libcpu/raw_exception.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;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 , on , off , isOn */ 0, nop_func , 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 */};#elsestatic 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 */};#endifvoid 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}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -