diff options
author | Jennifer Averett <jennifer.averett@OARcorp.com> | 2012-04-04 08:39:46 -0500 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@oarcorp.com> | 2012-04-04 08:43:08 -0500 |
commit | 0c0181dee26d64835f0cd4f47ef81f681ea553e8 (patch) | |
tree | 2f8aef096fa1ed345176328b805d9bb8394fd2f8 /c/src/lib/libbsp/mips/shared | |
parent | bsp/mpc55xx: Add and use chip features (diff) | |
download | rtems-0c0181dee26d64835f0cd4f47ef81f681ea553e8.tar.bz2 |
PR 1993 - Convert MIPS to PIC IRQ model
Diffstat (limited to 'c/src/lib/libbsp/mips/shared')
-rw-r--r-- | c/src/lib/libbsp/mips/shared/clock/clockdrv.c | 62 | ||||
-rw-r--r-- | c/src/lib/libbsp/mips/shared/clock/mips_timer.S | 45 | ||||
-rw-r--r-- | c/src/lib/libbsp/mips/shared/irq/i8259.c | 331 | ||||
-rw-r--r-- | c/src/lib/libbsp/mips/shared/irq/i8259.h | 205 | ||||
-rw-r--r-- | c/src/lib/libbsp/mips/shared/irq/interruptmask.c | 31 | ||||
-rw-r--r-- | c/src/lib/libbsp/mips/shared/irq/interruptmask_TX49.c | 31 | ||||
-rw-r--r-- | c/src/lib/libbsp/mips/shared/irq/irq.c | 100 | ||||
-rw-r--r-- | c/src/lib/libbsp/mips/shared/irq/maxvectors.c | 22 | ||||
-rw-r--r-- | c/src/lib/libbsp/mips/shared/irq/vectorexceptions.c | 118 |
9 files changed, 945 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/mips/shared/clock/clockdrv.c b/c/src/lib/libbsp/mips/shared/clock/clockdrv.c new file mode 100644 index 0000000000..f5ae23cc32 --- /dev/null +++ b/c/src/lib/libbsp/mips/shared/clock/clockdrv.c @@ -0,0 +1,62 @@ +/* + * COPYRIGHT (c) 1989-2011. + * On-Line Applications Research Corporation (OAR). + * + * 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: clockdrv.c,v 1.2 2012/02/06 14:17:28 jennifer Exp $ + */ + +#include <bsp.h> +#include <bsp/irq.h> +#include <bspopts.h> + +/* XXX convert to macros? Move to score/cpu? */ +void mips_set_timer(uint32_t timer_clock_interval); +uint32_t mips_get_timer(void); +uint32_t bsp_clock_nanoseconds_since_last_tick(void); + +/* XXX move to BSP.h or irq.h?? */ +#define EXT_INT5 0x8000 /* external interrupt 5 */ +#define CLOCK_VECTOR_MASK EXT_INT5 +#define CLOCK_VECTOR (MIPS_INTERRUPT_BASE+0x7) + +extern uint32_t bsp_clicks_per_microsecond; + +static uint32_t mips_timer_rate = 0; + +/* refresh the internal CPU timer */ +#define Clock_driver_support_at_tick() \ + mips_set_timer( mips_timer_rate ); + +#define Clock_driver_support_install_isr( _new, _old ) \ + do { \ + rtems_interrupt_handler_install(CLOCK_VECTOR, \ + "PIT clock",0, _new, NULL); \ + } while(0) + +#define Clock_driver_support_initialize_hardware() \ + do { \ + mips_timer_rate = rtems_configuration_get_microseconds_per_tick() * \ + bsp_clicks_per_microsecond; \ + mips_set_timer( mips_timer_rate ); \ + printk("Clock_mask: %x\n", CLOCK_VECTOR_MASK ); \ + mips_enable_in_interrupt_mask(CLOCK_VECTOR_MASK); \ + } while(0) + +uint32_t bsp_clock_nanoseconds_since_last_tick(void) +{ + return 0; +} + +#define Clock_driver_nanoseconds_since_last_tick \ + bsp_clock_nanoseconds_since_last_tick + +#define Clock_driver_support_shutdown_hardware() \ + do { \ + mips_disable_in_interrupt_mask(CLOCK_VECTOR_MASK); \ + } while (0) + +#include "../../../shared/clockdrv_shell.h" diff --git a/c/src/lib/libbsp/mips/shared/clock/mips_timer.S b/c/src/lib/libbsp/mips/shared/clock/mips_timer.S new file mode 100644 index 0000000000..3ff3ad13ef --- /dev/null +++ b/c/src/lib/libbsp/mips/shared/clock/mips_timer.S @@ -0,0 +1,45 @@ +/* clock.s + * + * This file contains the assembly code for the IDT 4650 clock driver. + * + * Author: Craig Lebakken <craigl@transition.com> + * + * COPYRIGHT (c) 1996 by Transition Networks Inc. + * + * To anyone who acknowledges that this file is provided "AS IS" + * without any express or implied warranty: + * permission to use, copy, modify, and distribute this file + * for any purpose is hereby granted without fee, provided that + * the above copyright notice and this notice appears in all + * copies, and that the name of Transition Networks not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * Transition Networks makes no representations about the suitability + * of this software for any purpose. + * + * $Id: mips_timer.S,v 1.1 2011/12/09 18:06:08 joel Exp $ + */ +/* @(#)clock.S 08/20/96 1.2 */ + +#include <rtems/mips/iregdef.h> +#include <rtems/mips/idtcpu.h> +#include <rtems/asm.h> + +FRAME(mips_set_timer,sp,0,ra) + .set noreorder + mfc0 t0,C0_COUNT + nop + addu t0,a0,t0 + mtc0 t0,C0_COMPARE + j ra + nop + .set reorder +ENDFRAME(mips_set_timer) + +FRAME(mips_get_timer,sp,0,ra) + .set noreorder + mfc0 v0,C0_COUNT + j ra + nop + .set reorder +ENDFRAME(mips_get_timer) diff --git a/c/src/lib/libbsp/mips/shared/irq/i8259.c b/c/src/lib/libbsp/mips/shared/irq/i8259.c new file mode 100644 index 0000000000..df0a2e4e2f --- /dev/null +++ b/c/src/lib/libbsp/mips/shared/irq/i8259.c @@ -0,0 +1,331 @@ +/** + * @file + * + * This file was based upon the powerpc and the i386. + */ + +/* + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + * + * 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. + */ + +/* + * Copyright (C) 1998, 1999 valette@crf.canon.fr + */ + +#include <bsp.h> +#include <bsp/irq.h> +#include <bsp/i8259.h> +#include <bsp/pci.h> +#include <bsp/irq-generic.h> + + +#define DEBUG_8259 1 + +#define ValidateIrqLine( _irq ) \ + if ( ((int)_irq < 0) ||((int)_irq > 16)) return 1; + +/*-------------------------------------------------------------------------+ +| 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; + + ValidateIrqLine(irqLine); + + rtems_interrupt_disable(level); + + /* Recalculate the value */ + mask = 1 << irqLine; + rval = i8259s_cache & mask ? 0 : 1; + i8259s_cache |= mask; + + /* Determine which chip and write the value. */ + if (irqLine < 8) { + simple_out_8( + BSP_8259_BASE_ADDRESS, + PIC_MASTER_IMR_IO_PORT, + i8259s_cache & 0xff + ); + } else { + simple_out_8( + BSP_8259_BASE_ADDRESS, + 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; + + ValidateIrqLine( irqLine ); + + rtems_interrupt_disable(level); + + /* Calculate the value */ + mask = ~(1 << irqLine); + i8259s_cache &= mask; + + /* Determine which chip and write the value */ + if (irqLine < 8) { + simple_out_8( + BSP_8259_BASE_ADDRESS, + PIC_MASTER_IMR_IO_PORT, + i8259s_cache & 0xff + ); + } else { + simple_out_8( + BSP_8259_BASE_ADDRESS, + 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; + + ValidateIrqLine( irqLine ); + + 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) { + simple_out_8( + BSP_8259_BASE_ADDRESS, + PIC_MASTER_COMMAND_IO_PORT, + SLAVE_PIC_EOSI + ); + simple_out_8( + BSP_8259_BASE_ADDRESS, + PIC_SLAVE_COMMAND_IO_PORT, + (PIC_EOSI | (irqLine - 8)) + ); + }else { + simple_out_8( + BSP_8259_BASE_ADDRESS, + PIC_MASTER_COMMAND_IO_PORT, + (PIC_EOSI | irqLine) + ); + } + + return 0; + +} /* ackIRQ */ + +void BSP_i8259s_init(void) +{ + volatile uint32_t i; + + simple_out_8(BSP_8259_BASE_ADDRESS, PIC_MASTER_IMR_IO_PORT, 0xff ); + simple_out_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_IMR_IO_PORT, 0xff ); + + + /* + * init master 8259 interrupt controller + */ + + /* Start init sequence */ + simple_out_8( + BSP_8259_BASE_ADDRESS, + PIC_MASTER_COMMAND_IO_PORT, + 0x11 + ); + /* Vector base = 0 */ + simple_out_8( + BSP_8259_BASE_ADDRESS, + PIC_MASTER_IMR_IO_PORT, + 0x00 + ); + + /* edge tiggered, Cascade (slave) on IRQ2 */ + simple_out_8( + BSP_8259_BASE_ADDRESS, + PIC_MASTER_IMR_IO_PORT, + 0x04 + ); + + /* Select 8086 mode */ + simple_out_8( + BSP_8259_BASE_ADDRESS, + PIC_MASTER_IMR_IO_PORT, + 0x01 + ); + + /* + * init slave interrupt controller + */ + + /* Start init sequence */ + simple_out_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_COMMAND_IO_PORT, 0x11); + + /* Vector base = 8 */ + simple_out_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_IMR_IO_PORT, 0x08); + + /* edge triggered, Cascade (slave) on IRQ2 */ + simple_out_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_IMR_IO_PORT, 0x02); + + /* Select 8086 mode */ + simple_out_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_IMR_IO_PORT, 0x01); + + /* Mask all except cascade */ + simple_out_8(BSP_8259_BASE_ADDRESS, PIC_MASTER_IMR_IO_PORT, 0xFB); + + /* Mask all */ + simple_out_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_IMR_IO_PORT, 0xFF); + + /* + * Enable all interrupts in debug mode. + */ + + if ( DEBUG_8259 ) { + i8259s_cache = 0x0101; + } + + simple_out_8( + BSP_8259_BASE_ADDRESS, + PIC_MASTER_IMR_IO_PORT, + i8259s_cache & 0xff + ); + simple_out_8( + BSP_8259_BASE_ADDRESS, + PIC_SLAVE_IMR_IO_PORT, + ((i8259s_cache & 0xff00) >> 8) + ); + + for (i=0; i<10000; i++); +} + +#define PCI__GEN(bus, off, num) (((off)^((bus) << 7))+((num) << 4)) +#define PCI_INTR_ACK(bus) PCI__GEN(bus, 0x0c34, 0) + +volatile uint8_t master; +volatile uint8_t slave; +volatile uint8_t temp; + +void bsp_show_interrupt_regs(void); +void bsp_show_interrupt_regs() { + unsigned int sr; + unsigned int cause; + unsigned int pending; + + mips_get_sr( sr ); + mips_get_cause( cause ); + pending = (cause & sr & 0xff00) >> CAUSE_IPSHIFT; + + master = simple_in_8(BSP_8259_BASE_ADDRESS, PIC_MASTER_COMMAND_IO_PORT); + slave = simple_in_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_COMMAND_IO_PORT); + + printk("sr: 0x%x cause: 0x%x pending: 0x%x master: 0x%x slave: 0x%x\n", + sr, cause, pending, master, slave + ); +} + +int BSP_i8259s_int_process() +{ + uint8_t irq; + volatile uint32_t temp; + + /* Get the Interrupt */ + irq = simple_in_le32(BSP_PCI_BASE_ADDRESS, PCI_INTR_ACK(0) ); + + /* + * Mask interrupts + * + Mask all except cascade on master + * + Mask all on slave + */ + simple_out_8(BSP_8259_BASE_ADDRESS, PIC_MASTER_IMR_IO_PORT, 0xFB); + simple_out_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_IMR_IO_PORT, 0xFF); + + /* Call the Handler */ + temp = irq + MALTA_SB_IRQ_0; + bsp_interrupt_handler_dispatch( temp ); + + /* Reset the interrupt on the 8259 either the master or the slave chip */ + if (irq & 8) { + temp = simple_in_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_IMR_IO_PORT); + + /* Mask all */ + simple_out_8(BSP_8259_BASE_ADDRESS, PIC_SLAVE_IMR_IO_PORT, 0xFF); + simple_out_8( + BSP_8259_BASE_ADDRESS, + PIC_SLAVE_COMMAND_IO_PORT, + (PIC_EOSI + (irq&7)) + ); + simple_out_8( + BSP_8259_BASE_ADDRESS, + PIC_MASTER_COMMAND_IO_PORT, + SLAVE_PIC_EOSI + ); + } else { + temp = simple_in_8(BSP_8259_BASE_ADDRESS, PIC_MASTER_IMR_IO_PORT); + /* Mask all except cascade */ + simple_out_8(BSP_8259_BASE_ADDRESS, PIC_MASTER_IMR_IO_PORT, 0xFB); + simple_out_8( + BSP_8259_BASE_ADDRESS, + PIC_MASTER_COMMAND_IO_PORT, + (PIC_EOSI+irq) + ); + } + + /* Restore the interrupts */ + simple_out_8(BSP_8259_BASE_ADDRESS,PIC_MASTER_IMR_IO_PORT,i8259s_cache&0xff); + simple_out_8( + BSP_8259_BASE_ADDRESS, + PIC_SLAVE_IMR_IO_PORT, + ((i8259s_cache & 0xff00) >> 8) + ); + + return 0; +} diff --git a/c/src/lib/libbsp/mips/shared/irq/i8259.h b/c/src/lib/libbsp/mips/shared/irq/i8259.h new file mode 100644 index 0000000000..7fd2a61d6b --- /dev/null +++ b/c/src/lib/libbsp/mips/shared/irq/i8259.h @@ -0,0 +1,205 @@ +/* irq.h + * + * This include file describe the data structure and the functions implemented + * by RTEMS to control the i8259 chip. + * + * Copyright (C) 1999 valette@crf.canon.fr + * + * This code is heavilly inspired by the public specification of STREAM V2 + * that can be found at : + * + * <http://www.chorus.com/Documentation/index.html> by following + * the STREAM API Specification Document link. + * + * 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: i8259.h,v 1.1 2012/02/06 14:19:07 jennifer Exp $ + */ + +#ifndef I8259_H +#define I8259_H + +/* + * 8259 edge/level control definitions at VIA + */ +#if 1 +#define ISA8259_M_ELCR 0x4d0 +#define ISA8259_S_ELCR 0x4d1 +#endif + +#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 + +/* + * 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 + +/* + * rtems_irq_number Definitions + */ +#if 0 +/* + * ISA IRQ handler related definitions + */ +#define BSP_ISA_IRQ_NUMBER (16) +#define BSP_ISA_IRQ_LOWEST_OFFSET (0) +#define BSP_ISA_IRQ_MAX_OFFSET (BSP_ISA_IRQ_LOWEST_OFFSET + BSP_ISA_IRQ_NUMBER - 1) + +#ifndef qemu +#define BSP_PCI_IRQ_NUMBER (16) +#else +#define BSP_PCI_IRQ_NUMBER (0) +#endif +#define BSP_PCI_IRQ_LOWEST_OFFSET (BSP_ISA_IRQ_NUMBER) +#define 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 + */ +#define BSP_PROCESSOR_IRQ_NUMBER (1) +#define BSP_PROCESSOR_IRQ_LOWEST_OFFSET (BSP_PCI_IRQ_MAX_OFFSET + 1) +#define BSP_PROCESSOR_IRQ_MAX_OFFSET (BSP_PROCESSOR_IRQ_LOWEST_OFFSET + BSP_PROCESSOR_IRQ_NUMBER - 1) +/* Misc vectors for OPENPIC irqs (IPI, timers) + */ +#ifndef qemu +#define BSP_MISC_IRQ_NUMBER (8) +#else +#define BSP_MISC_IRQ_NUMBER (0) +#endif + +#define BSP_MISC_IRQ_LOWEST_OFFSET (BSP_PROCESSOR_IRQ_MAX_OFFSET + 1) +#define BSP_MISC_IRQ_MAX_OFFSET (BSP_MISC_IRQ_LOWEST_OFFSET + BSP_MISC_IRQ_NUMBER - 1) +/* + * Summary + */ +#define BSP_IRQ_NUMBER (BSP_MISC_IRQ_MAX_OFFSET + 1) +#define BSP_LOWEST_OFFSET (BSP_ISA_IRQ_LOWEST_OFFSET) +#define BSP_MAX_OFFSET (BSP_MISC_IRQ_MAX_OFFSET) +/* + * Some ISA IRQ symbolic name definition + */ +#define BSP_ISA_PERIODIC_TIMER (0) +#define BSP_ISA_KEYBOARD (1) +#define BSP_ISA_UART_COM2_IRQ (3) +#define BSP_ISA_UART_COM1_IRQ (4) +#define BSP_ISA_RT_TIMER1 (8) +#define BSP_ISA_RT_TIMER3 (10) +/* + * Some PCI IRQ symbolic name definition + */ +#define BSP_PCI_IRQ0 (BSP_PCI_IRQ_LOWEST_OFFSET) +#if BSP_PCI_IRQ_NUMBER > 0 +#define BSP_PCI_ISA_BRIDGE_IRQ (BSP_PCI_IRQ0) +#endif + +#if defined(mvme2100) +#define BSP_DEC21143_IRQ (BSP_PCI_IRQ_LOWEST_OFFSET + 1) +#define BSP_PMC_PCMIP_TYPE1_SLOT0_IRQ (BSP_PCI_IRQ_LOWEST_OFFSET + 2) +#define BSP_PCMIP_TYPE1_SLOT1_IRQ (BSP_PCI_IRQ_LOWEST_OFFSET + 3) +#define BSP_PCMIP_TYPE2_SLOT0_IRQ (BSP_PCI_IRQ_LOWEST_OFFSET + 4) +#define BSP_PCMIP_TYPE2_SLOT1_IRQ (BSP_PCI_IRQ_LOWEST_OFFSET + 5) +#define BSP_PCI_INTA_UNIVERSE_LINT0_IRQ (BSP_PCI_IRQ_LOWEST_OFFSET + 7) +#define BSP_PCI_INTB_UNIVERSE_LINT1_IRQ (BSP_PCI_IRQ_LOWEST_OFFSET + 8) +#define BSP_PCI_INTC_UNIVERSE_LINT2_IRQ (BSP_PCI_IRQ_LOWEST_OFFSET + 9) +#define BSP_PCI_INTD_UNIVERSE_LINT3_IRQ (BSP_PCI_IRQ_LOWEST_OFFSET + 10) +#define BSP_UART_COM1_IRQ (BSP_PCI_IRQ_LOWEST_OFFSET + 13) +#define BSP_FRONT_PANEL_ABORT_IRQ (BSP_PCI_IRQ_LOWEST_OFFSET + 14) +#define BSP_RTC_IRQ (BSP_PCI_IRQ_LOWEST_OFFSET + 15) +#else +#define BSP_UART_COM1_IRQ BSP_ISA_UART_COM1_IRQ +#define BSP_UART_COM2_IRQ BSP_ISA_UART_COM2_IRQ +#endif + +/* + * Some Processor execption handled as RTEMS IRQ symbolic name definition + */ +#define BSP_DECREMENTER (BSP_PROCESSOR_IRQ_LOWEST_OFFSET) +#endif + +/* + * Type definition for RTEMS managed interrupts + */ +typedef unsigned short rtems_i8259_masks; +extern volatile rtems_i8259_masks i8259s_cache; + +/*-------------------------------------------------------------------------+ +| Function Prototypes. ++--------------------------------------------------------------------------*/ +/* + * ------------------------ Intel 8259 (or emulation) Mngt Routines ------- + */ +void BSP_i8259s_init(void); + +/* + * 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 + * + * RETURNS: 1/0 if the interrupt was enabled/disabled originally or + * a value < 0 on error. + */ +int BSP_irq_disable_at_i8259s (const rtems_irq_number 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_number 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_number irqLine); +/* + * function to check if a particular irq is enabled at 8259 level. After calling + */ +int BSP_irq_enabled_at_i8259s (const rtems_irq_number irqLine); + +int BSP_i8259s_int_process(void); + +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/mips/shared/irq/interruptmask.c b/c/src/lib/libbsp/mips/shared/irq/interruptmask.c new file mode 100644 index 0000000000..f4e384180b --- /dev/null +++ b/c/src/lib/libbsp/mips/shared/irq/interruptmask.c @@ -0,0 +1,31 @@ +/** + * @file + * + */ + +/* + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + * + * 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 <rtems.h> + +/* + * This function returns a mask value which is used to select the bits + * in the processor status register that can be set to enable interrupts. + * The mask value should not include the 2 software interrupt enable bits. + */ + +uint32_t mips_interrupt_mask( void ) +{ + uint32_t interrupt_mask; + + interrupt_mask = 0x0000fc00; + return(interrupt_mask); +} diff --git a/c/src/lib/libbsp/mips/shared/irq/interruptmask_TX49.c b/c/src/lib/libbsp/mips/shared/irq/interruptmask_TX49.c new file mode 100644 index 0000000000..72f270c50b --- /dev/null +++ b/c/src/lib/libbsp/mips/shared/irq/interruptmask_TX49.c @@ -0,0 +1,31 @@ +/** + * @file + * + */ + +/* + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + * + * 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 <rtems.h> + +/* + * This function returns a mask value which is used to select the bits + * in the processor status register that can be set to enable interrupts. + * The mask value should not include the 2 software interrupt enable bits. + */ + +uint32_t mips_interrupt_mask( void ) +{ + uint32_t interrupt_mask; + + interrupt_mask = 0x00000400; /* Toshiba TX49 processors have a non-standard interrupt mask */ + return(interrupt_mask); +} diff --git a/c/src/lib/libbsp/mips/shared/irq/irq.c b/c/src/lib/libbsp/mips/shared/irq/irq.c new file mode 100644 index 0000000000..e2db163b1f --- /dev/null +++ b/c/src/lib/libbsp/mips/shared/irq/irq.c @@ -0,0 +1,100 @@ +/** + * @file + * + * @ingroup bsp_interrupt + * + * @brief Interrupt support. + */ + +/* + * Copyright (c) 2005 by Cogent Computer Systems + * Written by Jay Monkman <jtm@lopingdog.com> + * + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + * + * 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 <bsp.h> +#include <bsp/irq.h> +#include <bsp/irq-generic.h> +#include <libcpu/isr_entries.h> + +static const char *const cause_strings[32] = { + /* 0 */ "Int", + /* 1 */ "TLB Mods", + /* 2 */ "TLB Load", + /* 3 */ "TLB Store", + /* 4 */ "Address Load", + /* 5 */ "Address Store", + /* 6 */ "Instruction Bus Error", + /* 7 */ "Data Bus Error", + /* 8 */ "Syscall", + /* 9 */ "Breakpoint", + /* 10 */ "Reserved Instruction", + /* 11 */ "Coprocessor Unuseable", + /* 12 */ "Overflow", + /* 13 */ "Trap", + /* 14 */ "Instruction Virtual Coherency Error", + /* 15 */ "FP Exception", + /* 16 */ "Reserved 16", + /* 17 */ "Reserved 17", + /* 18 */ "Reserved 18", + /* 19 */ "Reserved 19", + /* 20 */ "Reserved 20", + /* 21 */ "Reserved 21", + /* 22 */ "Reserved 22", + /* 23 */ "Watch", + /* 24 */ "Reserved 24", + /* 25 */ "Reserved 25", + /* 26 */ "Reserved 26", + /* 27 */ "Reserved 27", + /* 28 */ "Reserved 28", + /* 29 */ "Reserved 29", + /* 30 */ "Reserved 30", + /* 31 */ "Data Virtual Coherency Error" +}; + +static inline bool bsp_irq_is_valid(rtems_vector_number vector) +{ + return vector <= BSP_INTERRUPT_VECTOR_MAX; +} + +rtems_status_code bsp_interrupt_vector_enable(rtems_vector_number vector) +{ + return RTEMS_SUCCESSFUL; +} + +rtems_status_code bsp_interrupt_vector_disable(rtems_vector_number vector) +{ + return RTEMS_SUCCESSFUL; +} + +rtems_status_code bsp_interrupt_facility_initialize(void) +{ + mips_install_isr_entries(); + return RTEMS_SUCCESSFUL; +} + +void bsp_interrupt_handler_default(rtems_vector_number vector) +{ + uint32_t sr; + uint32_t cause; + + mips_get_sr( sr ); + mips_get_cause( cause ); + + printk( "Unhandled exception %d\n", vector ); + printk( "sr: 0x%08x cause: 0x%08x --> %s\n", sr, cause, + cause_strings[(cause >> 2) &0x1f] ); + #if 0 + mips_dump_exception_frame( frame ); + #endif + rtems_fatal_error_occurred(1); +} diff --git a/c/src/lib/libbsp/mips/shared/irq/maxvectors.c b/c/src/lib/libbsp/mips/shared/irq/maxvectors.c new file mode 100644 index 0000000000..17f7a25ec7 --- /dev/null +++ b/c/src/lib/libbsp/mips/shared/irq/maxvectors.c @@ -0,0 +1,22 @@ +/** + * @file + * + * This file contains the maximum number of vectors. This can not + * be determined without knowing the RTEMS CPU model. + */ + +/* + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + * + * 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 <rtems.h> +#include <bsp/irq.h> + +unsigned int mips_interrupt_number_of_vectors = BSP_INTERRUPT_VECTOR_MAX; diff --git a/c/src/lib/libbsp/mips/shared/irq/vectorexceptions.c b/c/src/lib/libbsp/mips/shared/irq/vectorexceptions.c new file mode 100644 index 0000000000..475527e941 --- /dev/null +++ b/c/src/lib/libbsp/mips/shared/irq/vectorexceptions.c @@ -0,0 +1,118 @@ +/** + * @file + * + * Common Code for Vectoring MIPS Exceptions + * + * The actual decoding of the cause register and vector number assignment + * is CPU model specific. + */ + +/* + * COPYRIGHT (c) 1989-2012. + * On-Line Applications Research Corporation (OAR). + * + * 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 <rtems.h> +#include <stdlib.h> +#include <string.h> +#include <rtems/mips/iregdef.h> +#include <rtems/mips/idtcpu.h> +#include <rtems/bspIo.h> +#include <bsp/irq-generic.h> + +void mips_vector_exceptions( CPU_Interrupt_frame *frame ); + +static const char *cause_strings[32] = +{ + /* 0 */ "Int", + /* 1 */ "TLB Mods", + /* 2 */ "TLB Load", + /* 3 */ "TLB Store", + /* 4 */ "Address Load", + /* 5 */ "Address Store", + /* 6 */ "Instruction Bus Error", + /* 7 */ "Data Bus Error", + /* 8 */ "Syscall", + /* 9 */ "Breakpoint", + /* 10 */ "Reserved Instruction", + /* 11 */ "Coprocessor Unuseable", + /* 12 */ "Overflow", + /* 13 */ "Trap", + /* 14 */ "Instruction Virtual Coherency Error", + /* 15 */ "FP Exception", + /* 16 */ "Reserved 16", + /* 17 */ "Reserved 17", + /* 18 */ "Reserved 18", + /* 19 */ "Reserved 19", + /* 20 */ "Reserved 20", + /* 21 */ "Reserved 21", + /* 22 */ "Reserved 22", + /* 23 */ "Watch", + /* 24 */ "Reserved 24", + /* 25 */ "Reserved 25", + /* 26 */ "Reserved 26", + /* 27 */ "Reserved 27", + /* 28 */ "Reserved 28", + /* 29 */ "Reserved 29", + /* 30 */ "Reserved 30", + /* 31 */ "Data Virtual Coherency Error" +}; + +struct regdef +{ + int offset; + char *name; +}; + +static const struct regdef dumpregs[]= { + { R_RA, "R_RA" }, { R_V0, "R_V0" }, { R_V1, "R_V1" }, + { R_A0, "R_A0" }, { R_A1, "R_A1" }, { R_A2, "R_A2" }, + { R_A3, "R_A3" }, { R_T0, "R_T0" }, { R_T1, "R_T1" }, + { R_T2, "R_T2" }, { R_T3, "R_T3" }, { R_T4, "R_T4" }, + { R_T5, "R_T5" }, { R_T6, "R_T6" }, { R_T7, "R_T7" }, + { R_T8, "R_T8" }, { R_MDLO, "R_MDLO" }, { R_MDHI, "R_MDHI" }, + { R_GP, "R_GP" }, { R_FP, "R_FP" }, { R_AT, "R_AT" }, + { R_EPC,"R_EPC"}, { -1, NULL } +}; + +static void mips_dump_exception_frame( CPU_Interrupt_frame *frame ) +{ + uint32_t *frame_u32; + int i, j; + + frame_u32 = (uint32_t *)frame; + for(i=0; dumpregs[i].offset > -1; i++) + { + printk(" %s", dumpregs[i].name); + for(j=0; j< 7-strlen(dumpregs[i].name); j++) printk(" "); +#if (__mips == 1 ) || (__mips == 32) + printk(" %08X%c", frame_u32[dumpregs[i].offset], (i%3) ? '\t' : '\n' ); +#elif __mips == 3 + printk(" %08X", frame_u32[2 * dumpregs[i].offset + 1] ); + printk("%08X%c", frame_u32[2 * dumpregs[i].offset], (i%2) ? '\t' : '\n' ); +#endif + } + printk( "\n" ); +} + +/* + * There are constants defined for these but they should basically + * all be close to the same set. + */ + +void mips_vector_exceptions( CPU_Interrupt_frame *frame ) +{ + uint32_t cause; + uint32_t exc; + + mips_get_cause( cause ); + exc = (cause >> 2) & 0x1f; + + bsp_interrupt_handler_dispatch( exc ); +} |