📄 int.c
字号:
/* *---------------------------------------------------------------------- * T-Kernel * * Copyright (C) 2004 by Ken Sakamura. All rights reserved. * T-Kernel is distributed under the T-License. *---------------------------------------------------------------------- * * Version: 1.01.00 * Released by T-Engine Forum(http://www.t-engine.org) at 2004/6/28. * *---------------------------------------------------------------------- *//* * @(#)int.c (libtk/S1C38K) * * Interrupt controller */#include <basic.h>#include <tk/syslib.h>#include <tk/sysdef.h>/* * Disable/enable interrupt */Inline UW _disint( void ){ UW imask; Asm(" mrs %0, cpsr \n" " orr ip, %0, %1 \n" " msr cpsr_c, ip " : "=r"(imask) : "i"(PSR_DI) : "ip" ); return imask;}Inline void _enaint( UW imask ){ Asm("msr cpsr_c, %0":: "r"(imask));}#define _DI(imask) ( imask = _disint() )#define _EI(imask) ( _enaint(imask) )/* * Set interrupt mode * * Sets the interrupt specified in 'intveci' to the mode specified * in 'mode'. * FIQ, IRQ, and GPIO interrupt can be specified; FPGA interrupt * cannot. * For FIQ and IRQ, the interrupt controller level register * and polarity register are set. * For GPA and GPB, the GPIO controller Interrupt Type register and * Interrupt Polarity register are set. * * mode := (IM_LEVEL || IM_EDGE) | (IM_HI || IM_LOW) */EXPORT void SetIntMode( INTVEC intvec, UINT mode ){ UW imask; _UW *level, *polar; W i; if ( (i = intvec - IV_GPB(0)) >= 0 ) { level = (_UW*)GPB_LEVEL; polar = (_UW*)GPB_POLAR; mode ^= IM_HI; } else if ( (i = intvec - IV_GPA(0)) >= 0 ) { level = (_UW*)GPA_LEVEL; polar = (_UW*)GPA_POLAR; mode ^= IM_HI; } else if ( (i = intvec - IV_IRQ(0)) >= 0 ) { level = (_UW*)IRQ_LEVEL; polar = (_UW*)IRQ_POLAR; } else if ( (i = intvec - IV_FIQ(0)) >= 0 ) { level = (_UW*)FIQ_LEVEL; polar = (_UW*)FIQ_POLAR; } else return; _DI(imask); if ( (mode & IM_EDGE) != 0 ) { *level |= 1 << i; } else { *level &= ~(1 << i); } if ( (mode & IM_HI) != 0 ) { *polar |= 1 << i; } else { *polar &= ~(1 << i); } _EI(imask);}/* * Enable interrupt * Enables the interrupt specified in intvec. * FIQ, IRQ, GPIO, and FPGA interrupt can be specified. */EXPORT void EnableInt( INTVEC intvec ){ UW imask; W i; _DI(imask); if ( (i = intvec - IV_FPGA2(0)) >= 0 ) { *(_UB*)IRQ_MASK2 |= 1 << i; } else if ( (i = intvec - IV_FPGA1(0)) >= 0 ) { *(_UB*)IRQ_MASK1 |= 1 << i; } else if ( (i = intvec - IV_GPB(0)) >= 0 ) { *(_UW*)GPB_ENA |= 1 << i; } else if ( (i = intvec - IV_GPA(0)) >= 0 ) { *(_UW*)GPA_ENA |= 1 << i; } else if ( (i = intvec - IV_IRQ(0)) >= 0 ) { *(_UW*)IRQ_ENA = 1 << i; } else if ( (i = intvec - IV_FIQ(0)) >= 0 ) { *(_UW*)FIQ_ENA = 1 << i; } _EI(imask);}/* * Disable interrupt * Disables the interrupt specified in intvec. * FIQ, IRQ, GPIO, and FPGA interrupt can be specified. */EXPORT void DisableInt( INTVEC intvec ){ UW imask; W i; _DI(imask); if ( (i = intvec - IV_FPGA2(0)) >= 0 ) { *(_UB*)IRQ_MASK2 &= ~(1 << i); } else if ( (i = intvec - IV_FPGA1(0)) >= 0 ) { *(_UB*)IRQ_MASK1 &= ~(1 << i); } else if ( (i = intvec - IV_GPB(0)) >= 0 ) { *(_UW*)GPB_ENA &= ~(1 << i); } else if ( (i = intvec - IV_GPA(0)) >= 0 ) { *(_UW*)GPA_ENA &= ~(1 << i); } else if ( (i = intvec - IV_IRQ(0)) >= 0 ) { *(_UW*)IRQ_DIS = 1 << i; } else if ( (i = intvec - IV_FIQ(0)) >= 0 ) { *(_UW*)FIQ_DIS = 1 << i; } _EI(imask);}/* * Clear interrupt request * Clears the intvec interrupt request. * Valid only for edge trigger. * For edge trigger, the interrupt must be cleared with an * interrupt handler. * FIQ, IRQ, GPIO, and FPGA interrupt can be specified. */EXPORT void ClearInt( INTVEC intvec ){ W i; if ( (i = intvec - IV_FPGA2(0)) >= 0 ) { *(_UB*)IRQ_STR2 = ~(1 << i); } else if ( (i = intvec - IV_FPGA1(0)) >= 0 ) { *(_UB*)IRQ_STR1 = ~(1 << i); } else if ( (i = intvec - IV_GPB(0)) >= 0 ) { *(_UW*)GPB_STS = 1 << i; } else if ( (i = intvec - IV_GPA(0)) >= 0 ) { *(_UW*)GPA_STS = 1 << i; } else if ( (i = intvec - IV_IRQ(0)) >= 0 ) { *(_UW*)IRQ_CLR = 1 << i; } else if ( (i = intvec - IV_FIQ(0)) >= 0 ) { *(_UW*)FIQ_CLR = 1 << i; }}/* * Check for interrupt requests * Checks for intvec interrupt requests. * If an interrupt request is found, returns TRUE (other than 0). * FIQ, IRQ, GPIO, and FPGA interrupt can be specified. */EXPORT BOOL CheckInt( INTVEC intvec ){ W i; if ( (i = intvec - IV_FPGA2(0)) >= 0 ) { return *(_UB*)IRQ_STR2 & (1 << i); } if ( (i = intvec - IV_FPGA1(0)) >= 0 ) { return *(_UB*)IRQ_STR1 & (1 << i); } if ( (i = intvec - IV_GPB(0)) >= 0 ) { return *(_UW*)GPB_STS & (1 << i); } if ( (i = intvec - IV_GPA(0)) >= 0 ) { return *(_UW*)GPA_STS & (1 << i); } if ( (i = intvec - IV_IRQ(0)) >= 0 ) { return *(_UW*)IRQ_STS & (1 << i); } if ( (i = intvec - IV_FIQ(0)) >= 0 ) { return *(_UW*)FIQ_STS & (1 << i); } return FALSE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -