Mercurial > flash_v2
diff packages/hal/powerpc/arch/current/src/hal_intr.c @ 2:443894e2e912 ecos-v1_2_1-release
Block commit of eCos version 1.2.1
| author | jlarmour |
|---|---|
| date | Tue, 11 May 1999 12:24:34 +0000 |
| parents | |
| children | 5f5102441818 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/packages/hal/powerpc/arch/current/src/hal_intr.c @@ -0,0 +1,225 @@ +//========================================================================== +// +// hal_intr.c +// +// PowerPC interrupt handlers +// +//========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Cygnus eCos Public License +// Version 1.0 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://sourceware.cygnus.com/ecos +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Cygnus Operating System, released +// September 30, 1998. +// +// The Initial Developer of the Original Code is Cygnus. Portions created +// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jskov +// Contributors: jskov +// Date: 1999-02-20 +// Purpose: PowerPC interrupt handlers +// Description: This file contains code to handle interrupt related issues +// on the PowerPC. +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include <pkgconf/hal.h> + +#include <cyg/hal/ppc_regs.h> + +// These are the Cyg_Interrupt::HANDLED/CALL_DSR values. +#define Cyg_InterruptHANDLED 1 +#define Cyg_InterruptCALL_DSR 2 + +//#include <cyg/hal/hal_intr.inl> // hal_call_isr +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// FIXME: This function should be in hal/common/.../include/hal_intr.inl +// or similar. +#include <cyg/hal/hal_intr.h> // hal_interrupt_x tables + +typedef cyg_uint32 cyg_ISR(cyg_uint32 vector, CYG_ADDRWORD data); + +extern void cyg_interrupt_post_dsr( CYG_ADDRWORD intr_obj ); + +static inline cyg_uint32 +hal_call_isr (cyg_uint32 vector) +{ + cyg_ISR *isr; + CYG_ADDRWORD data; + cyg_uint32 isr_ret; + + isr = (cyg_ISR*) hal_interrupt_handlers[vector]; + data = hal_interrupt_data[vector]; + + isr_ret = (*isr) (vector, data); + +#ifdef CYGFUN_HAL_COMMON_KERNEL_SUPPORT + if (isr_ret & Cyg_InterruptCALL_DSR) { + cyg_interrupt_post_dsr (hal_interrupt_objects[vector]); + } +#endif + + return isr_ret & Cyg_InterruptHANDLED; +} + +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +#ifdef CYG_HAL_POWERPC_MPC860 + +// Since the interrupt sources do not have fixed vectors on the 860 +// SIU, some arbitration is required. + +// More than one interrupt source can be programmed to use the same +// vector, so all sources on the same vector have to be queried to +// find the one raising the interrupt. This functionality has not been +// implemented, but the arbiter functions for each of the SIU +// interrupt sources can be called in sequence without change. + + + +// Timebase interrupt can be caused by match on either reference A +// or B. +// Note: If only one interrupt source is assigned per vector, and only +// reference interrupt A or B is used, this ISR is not +// necessary. Attach the timerbase reference A or B ISR directly to +// the LVLx vector instead. +externC cyg_uint32 +hal_arbitration_isr_tb (CYG_ADDRWORD vector, CYG_ADDRWORD data) +{ + cyg_uint32 isr_ret; + cyg_uint16 tbscr; + + HAL_READ_UINT16 (CYGARC_REG_IMM_TBSCR, tbscr); + if (tbscr & CYGARC_REG_IMM_TBSCR_REFA) { + isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_SIU_TB_A); + + CYG_ASSERT (isr_ret & Cyg_InterruptHANDLED, + "Interrupt not handled"); + +#ifndef CYGSEM_HAL_COMMON_INTERRUPTS_CHECK_ALL_SOURCES + return isr_ret; +#endif + } + + if (tbscr & CYGARC_REG_IMM_TBSCR_REFB) { + isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_SIU_TB_B); + + CYG_ASSERT (isr_ret & Cyg_InterruptHANDLED, + "Interrupt not handled"); + +#ifndef CYGSEM_HAL_COMMON_INTERRUPTS_CHECK_ALL_SOURCES + return isr_ret; +#endif + } + + return 0; +} + +// Periodic interrupt. +// Note: If only one interrupt source is assigned per vector, this ISR +// is not necessary. Attach the periodic interrupt ISR directly to the +// LVLx vector instead. +externC cyg_uint32 +hal_arbitration_isr_pit (CYG_ADDRWORD vector, CYG_ADDRWORD data) +{ + cyg_uint32 isr_ret; + cyg_uint16 piscr; + + HAL_READ_UINT16 (CYGARC_REG_IMM_PISCR, piscr); + if (piscr & CYGARC_REG_IMM_PISCR_PS) { + isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_SIU_PIT); + + CYG_ASSERT (isr_ret & Cyg_InterruptHANDLED, + "Interrupt not handled"); + +#ifndef CYGSEM_HAL_COMMON_INTERRUPTS_CHECK_ALL_SOURCES + return isr_ret; +#endif + } + + return 0; +} + +// Real time clock interrupts can be caused by the alarm or +// once-per-second. +// Note: If only one interrupt source is assigned per vector, and only +// the alarm or once-per-second interrupt is used, this ISR is not +// necessary. Attach the alarm or once-per-second ISR directly to the +// LVLx vector instead. +externC cyg_uint32 +hal_arbitration_isr_rtc (CYG_ADDRWORD vector, CYG_ADDRWORD data) +{ + cyg_uint32 isr_ret; + cyg_uint16 rtcsc; + + HAL_READ_UINT16 (CYGARC_REG_IMM_RTCSC, rtcsc); + if (rtcsc & CYGARC_REG_IMM_RTCSC_SEC) { + isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_SIU_RTC_SEC); + + CYG_ASSERT (isr_ret & Cyg_InterruptHANDLED, + "Interrupt not handled"); + +#ifndef CYGSEM_HAL_COMMON_INTERRUPTS_CHECK_ALL_SOURCES + return isr_ret; +#endif + } + + if (rtcsc & CYGARC_REG_IMM_RTCSC_ALR) { + isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_SIU_RTC_ALR); + + CYG_ASSERT (isr_ret & Cyg_InterruptHANDLED, + "Interrupt not handled"); + +#ifndef CYGSEM_HAL_COMMON_INTERRUPTS_CHECK_ALL_SOURCES + return isr_ret; +#endif + } + + return 0; +} + +// Communication Processor Module interrupt can be caused by any of +// the CPM sources. +externC cyg_uint32 +hal_arbitration_isr_cpm (CYG_ADDRWORD vector, CYG_ADDRWORD data) +{ + cyg_uint32 isr_ret; + cyg_uint16 civr; + + HAL_WRITE_UINT16 (CYGARC_REG_IMM_CIVR, CYGARC_REG_IMM_CIVR_IACK); + HAL_READ_UINT16 (CYGARC_REG_IMM_CIVR, civr); + civr >>= CYGARC_REG_IMM_CIVR_VECTOR_SHIFT; + if (civr) { + isr_ret = hal_call_isr (CYGNUM_HAL_INTERRUPT_CPM_LAST - civr); + + CYG_ASSERT (isr_ret & Cyg_InterruptHANDLED, + "Interrupt not handled"); + +#ifndef CYGSEM_HAL_COMMON_INTERRUPTS_CHECK_ALL_SOURCES + return isr_ret; +#endif + } + + return 0; +} + +#endif // ifdef CYG_HAL_POWERPC_MPC860 + +// ------------------------------------------------------------------------- +// EOF hal_intr.c
