📄 int.c
字号:
/* *---------------------------------------------------------------------- * T-Kernel * * Copyright (C) 2004-2006 by Ken Sakamura. All rights reserved. * T-Kernel is distributed under the T-License. *---------------------------------------------------------------------- * * Version: 1.02.02 * Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/9. * *---------------------------------------------------------------------- *//* * @(#)int.c (libtk/MB87Q1100) * * Interrupt controller operation * * Operation functions of interrupt controller support IRQ, CPLD, FPGA * interrupts. Some functions treat part of those interrupts. */#include <basic.h>#include <tk/syslib.h>#include <tk/sysdef.h>/* * Interrupt disable/enable */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 enable level * Disable IRQ interrupts which level is less then or equal to specified * 'level'. 'level' must be '0'-'15'. * If '15' is specified, all level IRQ interrupts are enable. * If '0' is specified, all level IRQ interrupts are disable. * 'level' is set to the ILM register of interrupt controller. * Initial value is '15'. * This function returns the interrupt enable level before being changed. */EXPORT INT SetIntLevel( INT level ){ INT oldlevel; UW imask; _DI(imask); oldlevel = *(_UW*)AILM & 0x0000000fU; *(_UW*)AILM = level; *(_UW*)AIRQF = 0; _EI(imask); return oldlevel;}/* * Set interrupt mode * Set accept mode to 'mode' regarding interrupt specified by 'intvec'. * If 'mode' is not correct value, operation is not guaranteed. * * mode := (IM_LEVEL || IM_EDGE) | (IM_HI || IM_LOW) */EXPORT void SetIntMode( INTVEC intvec, UINT mode ){ INT n, i; UW m; UW imask; if ( (n = (INT)intvec - IV_IRQ(10)) >= 0 ) { /* INT_A0 - A3 */ i = 0; } else if ( (n = (INT)intvec - IV_IRQ(6)) >= 0 ) { /* INT_A4 - A7 */ i = 1; } else { return; } mode ^= mode >> 1; m = 1 << n; _DI(imask); *(_UW*)AEILVL(i) = (*(_UW*)AEILVL(i) & ~(0x00000003U << n*2)) | (mode << n*2); *(_UW*)AEIREQ(i) = ~m; *(_UW*)AEIENB(i) |= m; _EI(imask);}/* * Enable interrupt * Enable interrupt specified by 'intvec'. * * For IRQ, level := '0'-'14'. * level=14 means lowest priority level, level=0 means highest. * If 'level' is outside this range, operation is not guaranteed. * Set the ICRn register with the value 'level'. * * For FPGA / CPLD, 'level' is ignored. */EXPORT void EnableInt( INTVEC intvec, INT level ){ INT n; UW imask; if ( (n = (INT)intvec - IV_FPGA2(7)) >= 0 ) { /* FPGA2 */ _DI(imask); *(_UB*)IRQ_MASK2 |= 0x80 >> n; _EI(imask); } else if ( (n = (INT)intvec - IV_FPGA1(7)) >= 0 ) { /* FPGA1 */ _DI(imask); *(_UB*)IRQ_MASK1 |= 0x80 >> n; _EI(imask); } else if ( (n = (INT)intvec - IV_CPLD(7)) >= 0 ) { /* CPLD */ _DI(imask); *(_UB*)TINT_MSK &= ~(0x80U >> n); _EI(imask); } else if ( (n = (INT)intvec - IV_IRQ(0)) >= 0 ) { /* IRQ */ *(_UW*)AICR(n) = level; }}/* * Disable interrupt * Disable interrupt specified by 'intvec'. */EXPORT void DisableInt( INTVEC intvec ){ INT n; UW imask; if ( (n = (INT)intvec - IV_FPGA2(7)) >= 0 ) { /* FPGA2 */ _DI(imask); *(_UB*)IRQ_MASK2 &= ~(0x80U >> n); _EI(imask); } else if ( (n = (INT)intvec - IV_FPGA1(7)) >= 0 ) { /* FPGA1 */ _DI(imask); *(_UB*)IRQ_MASK1 &= ~(0x80U >> n); _EI(imask); } else if ( (n = (INT)intvec - IV_CPLD(7)) >= 0 ) { /* CPLD */ _DI(imask); *(_UB*)TINT_MSK |= 0x80U >> n; _EI(imask); } else if ( (n = (INT)intvec - IV_IRQ(0)) >= 0 ) { /* IRQ */ *(_UW*)AICR(n) = 15; }}/* * Clear interrupt request * Clear interrupt request specified by 'intvec'. */EXPORT void ClearInt( INTVEC intvec ){ INT n; if ( (n = (INT)intvec - IV_FPGA2(7)) >= 0 ) { /* FPGA2 */ *(_UB*)IRQ_STR2 = ~(0x80U >> n); *(_UW*)AEIREQ(0) = ~0x00000001U; /* IRQ10 */ } else if ( (n = (INT)intvec - IV_FPGA1(7)) >= 0 ) { /* FPGA1 */ *(_UB*)IRQ_STR1 = ~(0x80U >> n); *(_UW*)AEIREQ(0) = ~0x00000001U; /* IRQ10 */ } else if ( (n = (INT)intvec - IV_CPLD(7)) >= 0 ) { /* CPLD */ *(_UB*)TINT_STS = ~(0x80U >> n); *(_UW*)AEIREQ(0) = ~0x00000002U; /* IRQ11 */ } else if ( (n = (INT)intvec - IV_IRQ(10)) >= 0 ) { /* INT_A0 - A3 */ *(_UW*)AEIREQ(0) = ~(0x00000001U << n); } else if ( (n = (INT)intvec - IV_IRQ(6)) >= 0 ) { /* INT_A4 - A7 */ *(_UW*)AEIREQ(1) = ~(0x00000001U << n); }}/* * End of interrupt */EXPORT void EndOfInt( INTVEC intvec ){ *(_UW*)AIRQF = 0;}/* * Check interrupt request * Check interrupt request specified by 'intvec'. * If interrupt request occurs, returns TRUE (nonzero). */EXPORT BOOL CheckInt( INTVEC intvec ){ INT n; if ( (n = (INT)intvec - IV_FPGA2(7)) >= 0 ) { /* FPGA2 */ return (BOOL)((*(_UB*)IRQ_STR2 >> (7-n)) & 0x01U); } else if ( (n = (INT)intvec - IV_FPGA1(7)) >= 0 ) { /* FPGA1 */ return (BOOL)((*(_UB*)IRQ_STR1 >> (7-n)) & 0x01U); } else if ( (n = (INT)intvec - IV_CPLD(7)) >= 0 ) { /* CPLD */ return (BOOL)((*(_UB*)TINT_STS >> (7-n)) & 0x01U); } else if ( (n = (INT)intvec - IV_IRQ(10)) >= 0 ) { /* INT_A0 - A3 */ return (BOOL)((*(_UW*)AEIREQ(0) >> n) & 0x01U); } else if ( (n = (INT)intvec - IV_IRQ(6)) >= 0 ) { /* INT_A4 - A7 */ return (BOOL)((*(_UW*)AEIREQ(1) >> n) & 0x01U); } return FALSE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -