📄 tp4_isr.c
字号:
/***************************************************************************
** File name : tp4_isr.c
** Author : x.cheng
** Create date :
**
** Comment:
** Interrupt manager...
**
** Revisions:
** $Log: tp4_isr.c,v $
** Revision 1.1 2005/08/04 08:32:13 x.cheng
** add into repositories
**
**
***************************************************************************/
#include "const.h"
#include "type.h"
#include "stdarg.h"
#include "..\..\Inc\i386\system.h"
#include "..\..\Inc\i386\io.h"
#include "..\..\Inc\i386\x86.h"
#include "..\..\Inc\i386\interrupt.h"
#include "..\..\Inc\pmm.h"
#include "..\..\Inc\tui.h"
#include "..\..\Inc\debug.h"
/* debug preprocessor instrument
#ifdef _DEBUG_ISR__
#endif
***************************/
/************local function prototype**************/
static inline void Tp4EnableIrq( unsigned char ucIrq );
static inline void Tp4DisableIrq( unsigned char ucIrq );
static inline void Tp4MaskAndAckIrq( unsigned char ucIrq );
static inline void Tp4EndOfIrq( unsigned char ucIrq );
static void Tp4UnhandleInterrupt( ts_IrqContext* pstContext );
static inline void Tp4IsrDumpRegisters( ts_IrqContext* pstContext );
/***************global variable*******************/
//the PIC irq mask
static unsigned short g_uiIrqMask = 0xffff;
// The PIC irq mask for the master controller.
#define g_ucIrqMasterMask ( ((unsigned char *)&(g_uiIrqMask))[0] )
// The PIC irq mask for the slave controller.
#define g_ucIrqSlaveMask ( ((unsigned char *)&(g_uiIrqMask))[1] )
// A table for hardware interrupt handlers only.
static ts_InterruptHandler g_astIrqHandler[ HW_IRQ_NR ] __attribute__ ((aligned(16))) =
{
[ 0 ... HW_IRQ_NR-1 ] = { .fpIrqHandler = Tp4UnhandleInterrupt }
};
/****************extern variable*******************/
// in file tp2_interrupt.asm
//extern void irq_Timer, irq_Keyb, irq_Com2, irq_Com1, irq_Lpt2, irq_Floppy, irq_Lpt1;
//extern void irq_Rtc, irq_PicMaster, irq_Reserved1, irq_Reserved2, irq_Ps2, irq_80x87, irq_IdeChn0, irq_IdeChn1;
//extern void irq_Unhandled;
extern void irq_Timer, irq_Keyb, irq_Com2, irq_Com1, irq_Lpt2, irq_Floppy, irq_Lpt1;
extern void irq_Rtc, irq_PicMaster, irq_Reserved1, irq_Reserved2, irq_Ps2, irq_80x87, irq_IdeChn0, irq_IdeChn1;
extern void irq_Unhandled;
/************************************************************
*************************************************************
** Function Name: DefaultInterruptHandler
** Author: x.cheng
**
** Comment:
** This is the default interrupt handler. It is invoked
** every time an interrupt occurs.
** Send the end of interrupt to the PICs.
**
** List of parameters:
** pstContext - The context of the current task after the interrupt.
**
** Return value:
** no
**
** Revisions:
**
*************************************************************
*************************************************************/
void DefaultInterruptHandler(ts_IrqContext * pstContext)
{
Tp4MaskAndAckIrq( pstContext->ulIrqNb );
// Tp4IsrDumpRegisters( pstContext );
if ( (pstContext->ulIrqNb-HW_PIC_INTR_START) < HW_IRQ_NR ) {
g_astIrqHandler[ pstContext->ulIrqNb - HW_PIC_INTR_START ].fpIrqHandler( pstContext );
//PANIC();
} else {
Tp4UnhandleInterrupt( pstContext );
}
Tp4EndOfIrq( pstContext->ulIrqNb );
vDbgDummy();
// if ( pstContext->ulIrqNb != HWM_TIMER_IRQ0)
// Tp4IsrDumpRegisters( pstContext );
// PANIC();
}
/************************************************************
*************************************************************
** Function Name: Tp4IsrInitialize
** Author: x.cheng
**
** Comment:
**
**
** List of parameters:
** no
**
** Return value:
** no
**
** Revisions:
**
*************************************************************
*************************************************************/
void Tp4IsrInitialize(void)
{
unsigned int iCnt;
for (iCnt=0x20; iCnt<0xFF; iCnt++)
vSetIntrGate(iCnt, &irq_Unhandled);
vSetIntrGate( HWM_TIMER_IRQ0, &irq_Timer );
vSetTrapGate( HWM_KEYB_IRQ1, &irq_Keyb );
//vSetTrapGate( , & );
vSetTrapGate( HWM_COM2_IRQ3, &irq_Com2 );
vSetTrapGate( HWM_COM1_IRQ4, &irq_Com1 );
vSetTrapGate( HWM_LPT2_IRQ5, &irq_Lpt2 );
vSetTrapGate( HWM_FLOPPY_IRQ6, &irq_Floppy );
vSetTrapGate( HWM_LPT1_IRQ7, &irq_Lpt1 );
vSetTrapGate( HWM_RTC_IRQ8, &irq_Rtc );
vSetTrapGate( HWM_PICMASTER_IRQ9, &irq_PicMaster );
vSetTrapGate( HWM_RESERVED_IRQa, &irq_Reserved1 );
vSetTrapGate( HWM_RESERVED_IRQb, &irq_Reserved2 );
vSetTrapGate( HWM_PS2_IRQc, &irq_Ps2 );
vSetTrapGate( HWM_80x87_IRQd, &irq_80x87 );
vSetIntrGate( HWM_IDE_CHN0_IRQe, &irq_IdeChn0 );
vSetIntrGate( HWM_IDE_CHN1_IRQf, &irq_IdeChn1 );
}
/************************************************************
*************************************************************
** Function Name: Tp4IsrInstallHandler
** Author: x.cheng
**
** Comment:
** Install an IRQ handler routine.
**
** This is valid only for hardware interrupts. You cannot
** install a software interrupt handler in this way.
**
** List of parameters:
** no
**
** Return value:
** no
**
** Revisions:
**
*************************************************************
*************************************************************/
void Tp4IsrInstallHandler( unsigned char ucIrq, void *pvHandler )
{
unsigned long ulFlags;
if ( (ucIrq - HW_PIC_INTR_START) > HW_IRQ_NR )
return;
SaveEflagsAndCli( ulFlags );
g_astIrqHandler[ ucIrq - HW_PIC_INTR_START ].fpIrqHandler = pvHandler;
RestoreEflags( ulFlags ); //和下面得Tp4EnableIrq的顺序颠倒是不行的!
#ifdef _DEBUG_ISR__
POSITION();
vDbgDummy();
#endif
Tp4EnableIrq( ucIrq );
return;
}
//----------------------------------------------------------------------------------
//==============================local function======================================
//----------------------------------------------------------------------------------
/************************************************************
*************************************************************
** Function Name: Tp4EnableIrq
** Author: x.cheng
**
** Comment:
** Enable an IRQ line.
** 如果要enable从片控制的中断的话,先要enable主片的
** irq2.
**
** List of parameters:
** ucIrq - The IRQ line to enable.
**
** Return value:
** no
**
** Revisions:
**
*************************************************************
*************************************************************/
static inline void Tp4EnableIrq( unsigned char ucIrq )
{
unsigned short uiMask = ~(1 << (ucIrq -= HW_PIC_INTR_START));
unsigned long ulFlags;
if ( ucIrq & 0x08 ) // 主片的HWM_SLAVE_IRQ2是控制从片的
uiMask &= ~0x04;
SaveEflagsAndCli(ulFlags);
g_uiIrqMask &= uiMask;
#ifdef _DEBUG_ISR__
POSITION();
kprintf("ucIrq= %d, uiMask= %d, g_uiIrqMask= %d\n", ucIrq, uiMask, g_uiIrqMask);
kprintf("gucIrqSlaveMask= %d, g_ucIrqMasterMask= %d\n", g_ucIrqSlaveMask, g_ucIrqMasterMask);
#endif
if ( ucIrq & 0x8 ) { //( ((unsigned char *)&(g_uiIrqMask))[0] )
vOutPort( PORT_8259A_MINOR+1, g_ucIrqSlaveMask );
} else {
vOutPort( PORT_8259A_MAJOR+1, g_ucIrqMasterMask );
}
RestoreEflags(ulFlags);
}
/************************************************************
*************************************************************
** Function Name: Tp4DisableIrq
** Author: x.cheng
**
** Comment:
** Disable an IRQ line.
**
** List of parameters:
** ucIrq - The IRQ line to enable.
**
** Return value:
** no
**
** Revisions:
**
*************************************************************
*************************************************************/
static inline void Tp4DisableIrq( unsigned char ucIrq )
{
unsigned short uiMask = 1 << (ucIrq -= HW_PIC_INTR_START);
unsigned long ulFlags;
SaveEflagsAndCli(ulFlags);
g_uiIrqMask |= uiMask;
if ( ucIrq & 0x8 ) {
vOutPort( PORT_8259A_MINOR+1, g_ucIrqSlaveMask );
} else {
vOutPort( PORT_8259A_MAJOR+1, g_ucIrqMasterMask );
}
RestoreEflags(ulFlags);
}
/************************************************************
*************************************************************
** Function Name: Tp4EndOfIrq
** Author: x.cheng
**
** Comment:
**
**
** List of parameters:
** ucIrq - The IRQ line to enable.
**
** Return value:
** no
**
** Revisions:
**
*************************************************************
*************************************************************/
static inline void Tp4EndOfIrq(unsigned char ucIrq)
{
// Simply re-enable the irq line.
Tp4EnableIrq( ucIrq );
}
/************************************************************
*************************************************************
** Function Name: Tp4MaskAndAckIrq
** Author: x.cheng
**
** Comment:
** Acknowledge the irq line.
**
** List of parameters:
** ucIrq - The IRQ line to enable.
**
** Return value:
** no
**
** Revisions:
**
*************************************************************
*************************************************************/
static inline void Tp4MaskAndAckIrq( unsigned char ucIrq )
{
unsigned short uiMask = 1 << (ucIrq -= HW_PIC_INTR_START);
unsigned long ulFlags;
SaveEflagsAndCli(ulFlags);
g_uiIrqMask |= uiMask;
#ifdef _DEBUG_ISR__
POSITION();
kprintf("\nucIrq= %d, uiMask= %d, g_uiIrqMask= %d\n", ucIrq, uiMask, g_uiIrqMask);
kprintf("gucIrqSlaveMask= %d, g_ucIrqMasterMask= %d\n", g_ucIrqSlaveMask, g_ucIrqMasterMask);
#endif
if ( ucIrq & 0x8) {
// Dummy operation (but required).
(void)ucInPort( PORT_8259A_MINOR+1 );
// Mask the irq on the slave.
vOutPort( PORT_8259A_MINOR+1, g_ucIrqSlaveMask );
// Acknowledge the irq sending a EOI.
vOutPort( PORT_8259A_MINOR, EOI );
vOutPort( PORT_8259A_MAJOR, EOI );
}
else
{
// Dummy operation (but required).
(void)ucInPort( PORT_8259A_MAJOR+1 );
// Mask the irq on the master.
vOutPort( PORT_8259A_MAJOR+1, g_ucIrqMasterMask );
// Acknowledge the irq sending a EOI.
vOutPort( PORT_8259A_MAJOR, EOI );
}
RestoreEflags(ulFlags);
}
/************************************************************
*************************************************************
** Function Name: Tp4UnhandleInterrupt
** Author: x.cheng
**
** Comment:
** Manage an unhandled interrupt..
**
** List of parameters:
** ucIrq - The IRQ line to enable.
**
** Return value:
** no
**
** Revisions:
**
*************************************************************
*************************************************************/
static void Tp4UnhandleInterrupt( ts_IrqContext* pstContext )
{
kprintf("%s(): unexpected IRQ number %ld!\n", __FUNCTION__, pstContext->ulIrqNb);
}
/************************************************************
*************************************************************
** Function Name: Tp4IsrDumpRegisters
** Author: x.cheng
**
** Comment:
** Dump the CPU registers.
**
** List of parameters:
** pstContext - The context of the current task after an exception.
**
** Return value:
** no
**
** Revisions:
**
*************************************************************
*************************************************************/
static inline void Tp4IsrDumpRegisters( ts_IrqContext* pstContext )
{
register unsigned short uiSs;
register unsigned long ulCr0, ulCr2, ulCr3, ulCr4;
register unsigned short uiFs, uiGs;
// Save stack segment register.
__asm__ __volatile__ ("movw %%ss, %0" : "=&r"(uiSs) : );
// Save %fs and %gs registers.
__asm__ __volatile__ ("movw %%fs, %0" : "=m"(uiFs) :);
__asm__ __volatile__ ("movw %%gs, %0" : "=m"(uiGs) :);
// Save control registers.
__asm__ __volatile__ ("movl %%cr0, %0" : "=&r"(ulCr0) : );
__asm__ __volatile__ ("movl %%cr2, %0" : "=&r"(ulCr2) : );
__asm__ __volatile__ ("movl %%cr3, %0" : "=&r"(ulCr3) : );
__asm__ __volatile__ ("movl %%cr2, %0" : "=&r"(ulCr4) : );
// Dump registers.
kprintf("\neax = %#010x ds = %#010x cr0 = %#010x esp = %#010x", pstContext->ulEax, (unsigned short)(pstContext->ulDs), ulCr0, pstContext);
kprintf("\nebx = %#010x es = %#010x cr2 = %#010x ebp = %#010x", pstContext->ulEbx, (unsigned short)(pstContext->ulEs), ulCr2, pstContext->ulEbp);
kprintf("\necx = %#010x fs = %#010x cr3 = %#010x eip = %#010x", pstContext->ulEcx, (unsigned short)(uiFs), ulCr3, pstContext->ulEip);
kprintf("\nedx = %#010x gs = %#010x cr4 = %#010x eflags = %#010x", pstContext->ulEdx, (unsigned short)(uiGs), ulCr4, pstContext->ulEflags);
kprintf("\nesi = %#010x ss = %#010x irq = %#010x", pstContext->ulEsi, (unsigned short)(uiSs), pstContext->ulIrqNb);
kprintf("\nedi = %#010x cs = %#010x\n", pstContext->ulEdi, (unsigned short)(pstContext->ulCs) );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -