📄 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/VR5500) * * Interrupt controller */#include <basic.h>#include <tk/syslib.h>#include <tk/sysdef.h>/* * Disable/enable interrupt */IMPORT UINT _disint( void );IMPORT void _enaint( UINT imask );#define _DI(imask) ( imask = _disint() )#define _EI(imask) ( _enaint(imask) )/* * Set interrupt mode * Sets the interrupt specified in intvec to the mode * specified in mode. * * mode := (IM_LEVEL || IM_EDGE) | (IM_HI || IM_LOW) * * The following types of intvec can be set. * IRQ 8 - 12 PCI interrupt * IRQ 16 - 19 IOPCI interrupt * GPIO 0 - 31 GPIO interrupt * * For GPIO interrupt, the hold/through select register is * defined as follows. * * For edge trigger hold * For level trigger through */EXPORT void SetIntMode( INTVEC intvec, UINT mode ){ _UW *ppes; UW imask, bit; W i; if ( (i = intvec - IV_GPIO(31)) >= 0 ) { bit = 0x80000000 >> i; _DI(imask); if ( (mode & IM_EDGE) != 0 ) { *(_UW*)GIUINTTYP |= bit; *(_UW*)GIUINTHTSEL |= bit; } else { *(_UW*)GIUINTTYP &= ~bit; *(_UW*)GIUINTHTSEL &= ~bit; } if ( (mode & IM_HI) != 0 ) { *(_UW*)GIUINTALSEL |= bit; } else { *(_UW*)GIUINTALSEL &= ~bit; } _EI(imask); return; } bit = ( (mode & IM_EDGE) != 0 )? 0x00: 0x02; bit |= ( (mode & IM_HI) != 0 )? 0x00: 0x01; if ( (i = intvec - IV_IRQ(12)) >= 0 ) { i = (4 - i) * 2; ppes = (_UW*)INTPPES0; } else if ( (i = intvec - IV_IRQ(19)) >= 0 ) { i = (3 - i) * 2; ppes = (_UW*)INTPPES1; } else return; _DI(imask); *ppes = (*ppes & ~(0x03 << i)) | (bit << i); _EI(imask);}/* * Enable interrupt * Enables the interrupt specified in intvec. * * level is valid only for IRQ. It is ignored for GPIO. * The following values can be specified in level. * Proper operation cannot be guaranteed when the value * specified is invalid. * * level = 0 IP2 CP0 cause register IP * 1 IP3 * 2 IP4 * 3 IP5 * 4 IP6 * 6 NMI * * GPIO interrupt is attached to IRQ26, which is set to * level 2 by default. */EXPORT void EnableInt( INTVEC intvec, INT level ){ _UW *ctrl; UW imask; W i; if ( (i = intvec - IV_GPIO(31)) >= 0 ) { _DI(imask); *(_UW*)GIUINTEN |= 0x80000000 >> i; _EI(imask); return; } if ( (i = intvec - IV_IRQ(7)) >= 0 ) { ctrl = (_UW*)INTCTRL0_L; } else if ( (i = intvec - IV_IRQ(15)) >= 0 ) { ctrl = (_UW*)INTCTRL0_H; } else if ( (i = intvec - IV_IRQ(23)) >= 0 ) { ctrl = (_UW*)INTCTRL1_L; } else if ( (i = intvec - IV_IRQ(31)) >= 0 ) { ctrl = (_UW*)INTCTRL1_H; } else return; i = (7 - i) * 4; _DI(imask); *ctrl = (*ctrl & ~(0x0f << i)) | ((level | 8) << i); _EI(imask);}/* * Disable interrupt * Disables the interrupt specified in intvec. */EXPORT void DisableInt( INTVEC intvec ){ _UW *ctrl; UW imask; W i; if ( (i = intvec - IV_GPIO(31)) >= 0 ) { _DI(imask); *(_UW*)GIUINTEN &= ~(0x80000000 >> i); _EI(imask); return; } if ( (i = intvec - IV_IRQ(7)) >= 0 ) { ctrl = (_UW*)INTCTRL0_L; } else if ( (i = intvec - IV_IRQ(15)) >= 0 ) { ctrl = (_UW*)INTCTRL0_H; } else if ( (i = intvec - IV_IRQ(23)) >= 0 ) { ctrl = (_UW*)INTCTRL1_L; } else if ( (i = intvec - IV_IRQ(31)) >= 0 ) { ctrl = (_UW*)INTCTRL1_H; } else return; _DI(imask); *ctrl &= ~(0x80000000 >> (i * 4)); _EI(imask);}/* * Clear interrupt request * Clears the intvec interrupt request. * Valid for edge trigger only. * For edge trigger, the interrupt must be cleared with the * interrupt handler. */EXPORT void ClearInt( INTVEC intvec ){ W i; if ( (i = intvec - IV_GPIO(31)) >= 0 ) { *(_UW*)GIUINTSTAT = 0x80000000 >> i; } else if ( (i = intvec - IV_IRQ(31)) >= 0 ) { *(_UW*)INTCLR32 = 0x80000000 >> i; }}/* * Check for interrupt requests * Checks for intvec interrupt requests. * If an interrupt request is found, returns TRUE (other than 0). */EXPORT BOOL CheckInt( INTVEC intvec ){ W i; if ( (i = intvec - IV_GPIO(31)) >= 0 ) { return *(_UW*)GIUINTSTAT & (0x80000000 >> i); } if ( (i = intvec - IV_IRQ(31)) >= 0 ) { return (*(_UW*)INT0STAT | *(_UW*)INT1STAT | *(_UW*)INT2STAT | *(_UW*)INT3STAT | *(_UW*)INT4STAT | *(_UW*)NMISTAT) & (0x80000000 >> i); } return FALSE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -