?? portisr.c
字號:
//
// portisr.c
//
// EBS - ERTFS
//
// Copyright EBS Inc , 1993,1994,1995
// All rights reserved.
// This code may not be redistributed in source or linkable object form
// without the consent of its author.
//
//
// Module description:
// This file contains interrupt sevice routines and associated
// HISR mechanisms for RTFS.
//
//
// This is for ERTFS_STAND_ALONE only. Not used in RTIP enviroment
#include <pcdisk.h>
/* These routines are only needed if these sub-systems are included */
#if (USE_ATA || USE_FLOPPY || INCLUDE_PCMCIA)
/* These are pc specific PIC functions.. see below */
void ks_mask_isr_on(int irq);
void ks_mask_isr_off(int irq);
void ks_clear_isr(int irq);
int ks_isr_to_vector(int irq);
/* Define macros to declare an interrupt service routine and to declare
storage to hold the previous value of the interrupt vector that
we are replacing */
#if (defined(POLLOS))
#include <dos.h>
#define KS_INTFN_DECLARE(x) void interrupt KS_FAR x(void)
#define KS_INTFN_POINTER(x) void (interrupt KS_FAR *x)(void)
#elif (defined(RTPX))
#include <dos.h>
#define KS_INTFN_DECLARE(x) void interrupt KS_FAR x(void)
#define KS_INTFN_POINTER(x) void (interrupt KS_FAR *x)(void)
#elif (defined(UCOS))
#define KS_INTFN_DECLARE(x) void KS_FAR x(void)
#define KS_INTFN_POINTER(x) void KS_FAR *x
/* See the provided copy of Ix86L_A.ASM for these routines */
extern void asm_ide_isr_0(void);
extern void asm_ide_isr_1(void);
extern void asm_floppy_isr(void);
#elif (defined(__PSOS__))
#error declare interrupt function types for PSOS
#define KS_INTFN_DECLARE(x) void x(void)
#define KS_INTFN_POINTER(x) void *x
#elif (defined(CMX))
#define KS_INTFN_DECLARE(x) void KS_FAR x(void)
#define KS_INTFN_POINTER(x) void KS_FAR *x
#if (defined(CMXRM))
/* See the provided copy of Ix86L_A.ASM for these routines */
extern void asm_ide_isr_0(void);
extern void asm_ide_isr_1(void);
extern void asm_floppy_isr(void);
#endif
#elif (defined(PLUS))
#define KS_INTFN_DECLARE(x) void KS_FAR x(void)
#define KS_INTFN_POINTER(x) void KS_FAR *x
#if (USE_ATA)
/* ide HISR data */
NU_HISR ide_HISR_Control[2];
char ide_HISR_Stack[2][1024];
void ide_hisr_0(void);
void ide_hisr_1(void);
#endif
#if (USE_FLOPPY)
/* floppy HISR data */
NU_HISR floppy_HISR_Control;
char floppy_HISR_Stack[1024];
void floppy_hisr(void);
#endif
#else
#error - Define KS_INTFN_DECLARE and KS_INTFN_POINTER(x) for your environment
#endif
/* Saved off old values from the interrupt vector table */
KS_INTFN_POINTER(oldint[15]);
#if (USE_ATA)
/* IDE interrupt management package */
/* Signals touched in this file */
/* irq number for ide controllers saved at hook time */
int ide_isr_no[2];
int pcmcia_isr_no;
/* This is the isr function in ide_drv.c */
void ide_isr(int controller_no);
/* This is the interrupt service routine for IDE controller number zero
it calls the ide_isr() routine in ide_drv.c which calls ks_invoke_ide_interrupt(0)
in this file
*/
KS_INTFN_DECLARE(ide_isr_0)
{
#if (defined(RTPX))
px_isr_enter();
#endif
ide_isr(0);
ks_clear_isr(ide_isr_no[0]);
#if (defined(RTPX))
px_isr_exit();
#endif
}
/* This is the interrupt service routine for IDE controller number one
it calls the ide_isr() routine in ide_drv.c which calls ks_invoke_ide_interrupt(0)
in this file
*/
KS_INTFN_DECLARE(ide_isr_1)
{
#if (defined(RTPX))
px_isr_enter();
#endif
ide_isr(1);
ks_clear_isr(ide_isr_no[1]);
#if (defined(RTPX))
px_isr_exit();
#endif
}
/* This is called by the isr to execute the hisr for the interrupt */
void ks_invoke_ide_interrupt(int controller_number)
{
#if (defined(PLUS))
NU_Activate_HISR(&ide_HISR_Control[controller_number]);
#elif (defined(POLLOS)||defined(RTPX)||defined(CMX)||defined(UCOS))
ks_set_ide_signal(controller_number);
#else
#error - Signal ide from ISR for your kernel. Following code may be correct
ks_set_ide_signal(controller_number);
#endif
}
/* This is the routine that hooks the interrupt for the IDE controller */
void hook_ide_interrupt(int irq, int controller_number)
{
int vector_no;
ide_isr_no[controller_number] = irq;
/* Convert irq number to vector number for register lisr */
vector_no = ks_isr_to_vector(irq);
if (controller_number==0)
{
#if (defined(PLUS))
NU_Create_HISR(&ide_HISR_Control[0], "HISR", ide_hisr_0,
2, &ide_HISR_Stack[0][0], 1024);
NU_Register_LISR(vector_no, ide_isr_0, &(oldint[irq]));
#elif (defined(POLLOS))
oldint[irq] = _dos_getvect (vector_no);
_dos_setvect (vector_no, ide_isr_0);
#elif (defined(RTPX))
oldint[irq] = _dos_getvect (vector_no);
_dos_setvect (vector_no, ide_isr_0);
#elif (defined(CMXRM))
/* See the provided copy of Ix86L_A.ASM for these routines */
oldint[irq] = _dos_getvect (vector_no);
_dos_setvect (vector_no, asm_ide_isr_0);
#elif (defined(CMXD860))
// Nothing. done up front
#elif (defined(UCOS))
oldint[irq] = _dos_getvect (vector_no);
_dos_setvect (vector_no, (void (interrupt *)(void))asm_ide_isr_0);
#elif (defined(__PSOS__))
#error implement interrupt hook function for PSOS
#else
#error - Implement hook ide vector for your system
#endif
}
else
{
#if (defined(PLUS))
NU_Create_HISR(&ide_HISR_Control[1], "HISR", ide_hisr_1,
2, &ide_HISR_Stack[1][0], 1024);
NU_Register_LISR(vector_no, ide_isr_1, &(oldint[irq]));
#elif (defined(POLLOS))
oldint[irq] = _dos_getvect (vector_no);
_dos_setvect (vector_no, ide_isr_1);
#elif (defined(RTPX))
oldint[irq] = _dos_getvect (vector_no);
_dos_setvect (vector_no, ide_isr_1);
#elif (defined(CMXRM))
/* See the provided copy of Ix86L_A.ASM for these routines */
oldint[irq] = _dos_getvect (vector_no);
_dos_setvect (vector_no, asm_ide_isr_1);
#elif (defined(CMXD860))
// Nothing. done up front
#elif (defined(UCOS))
oldint[irq] = _dos_getvect (vector_no);
_dos_setvect (vector_no, (void (interrupt *)(void))asm_ide_isr_1);
#elif (defined(__PSOS__))
#error implement interrupt hook function for PSOS
#else
#error - Implement hook ide vector for your system
#endif
}
/* mask on the interrupt 8259. pc specific */
ks_mask_isr_on(irq);
/* clear any stray interrupts */
ks_clear_isr(irq);
}
#endif /* (USE_ATA) */
#if (USE_FLOPPY)
void KS_FAR floppy_isr(int controller_no);
void ks_set_floppy_signal(void);
/* irq number for floppy disk saved at hook time */
int floppy_isr_no;
/* This is the interrupt service routine for IDE controller number zero
it calls the ide_isr() routine in ide_drv.c which calls ks_invoke_ide_interrupt(0)
in this file
*/
KS_INTFN_DECLARE(floppy_isr_0)
{
#if (defined(RTPX))
px_isr_enter();
#endif
floppy_isr(0);
ks_clear_isr(floppy_isr_no);
#if (defined(RTPX))
px_isr_exit();
#endif
}
/* This is called by the isr to execute the hisr for the interrupt */
void ks_invoke_floppy_interrupt(int controller_no)
{
#if (defined(PLUS))
NU_Activate_HISR(&floppy_HISR_Control);
#elif (defined(POLLOS)||defined(RTPX)||defined(CMX)||defined(UCOS))
ks_set_floppy_signal();
#else
#error - Signal floppy from ISR for your kernel. Followin code may be correct
ks_set_floppy_signal();
#endif
}
/* This is the routine that hooks the interrupt for the IDE controller */
void hook_floppy_interrupt(int irq)
{
int vector_no;
floppy_isr_no = irq;
/* Convert irq number to vector number for register lisr */
vector_no = ks_isr_to_vector(irq);
#if (defined(PLUS))
NU_Create_HISR(&floppy_HISR_Control, "HISR", floppy_hisr,
2, &floppy_HISR_Stack[0], 1024);
NU_Register_LISR(vector_no, floppy_isr_0, &(oldint[irq]));
#elif (defined(POLLOS))
oldint[irq] = _dos_getvect (vector_no);
_dos_setvect (vector_no, floppy_isr_0);
#elif (defined(RTPX))
oldint[irq] = _dos_getvect (vector_no);
_dos_setvect (vector_no, floppy_isr_0);
#elif (defined(CMXRM))
/* See the provided copy of Ix86L_A.ASM for these routines */
oldint[irq] = _dos_getvect (vector_no);
_dos_setvect (vector_no, asm_floppy_isr_0);
#elif (defined(CMXD860))
// Nothing. done up front
#elif (defined(UCOS))
oldint[irq] = _dos_getvect (vector_no);
_dos_setvect (vector_no, (void (interrupt *)(void))asm_floppy_isr);
#elif (defined(__PSOS__))
#error implement interrupt hook function for PSOS
#else
#error - Implement hook floppy vector for your system
#endif
/* mask on the interrupt 8259. pc specific */
ks_mask_isr_on(irq);
/* clear any stray interrupts */
ks_clear_isr(irq);
}
#endif /* (USE_FLOPPY) */
#if (INCLUDE_PCMCIA)
/* This section manages the pcmcia management interrupt (see pcmctrl.)
there are no HISRs required so it is a simple LISR hook and
dispatch */
void mgmt_isr(int arg);
#if (defined(PLUS))
void KS_FAR pcmcia_isr(void)
#elif (defined(POLLOS))
void interrupt KS_FAR pcmcia_isr(void)
#elif (defined(RTPX))
void interrupt KS_FAR pcmcia_isr(void)
#elif (defined(CMXRM))
void interrupt KS_FAR pcmcia_isr(void)
#elif (defined(CMXD860))
void KS_FAR pcmcia_isr(void)
#elif (defined(UCOS))
void interrupt KS_FAR pcmcia_isr(void)
#elif (defined(__PSOS__))
#error implement interrupt hook function for PSOS
void pcmcia_isr(void) ????
#else
#error define Interrupt function for IDE
#endif
{
mgmt_isr(0);
ks_clear_isr(pcmcia_isr_no);
}
void hook_pcmcia_interrupt(int irq)
{
int vector_no;
pcmcia_isr_no = irq;
/* Convert irq number to vector number for register lisr */
vector_no = ks_isr_to_vector(irq);
#if (defined(PLUS))
NU_Register_LISR(vector_no, pcmcia_isr, &(oldint[irq]));
#elif (defined(POLLOS))
oldint[irq] = _dos_getvect (vector_no);
_dos_setvect (vector_no, pcmcia_isr);
#elif (defined(RTPX))
oldint[irq] = _dos_getvect (vector_no);
_dos_setvect (vector_no, pcmcia_isr);
#elif (defined(CMXRM))
/* See the provided copy of Ix86L_A.ASM for these routines */
oldint[irq] = _dos_getvect (vector_no);
_dos_setvect (vector_no, pcmcia_isr);
#elif (defined(CMXD860))
// Nothing. done up front
#elif (defined(UCOS))
oldint[irq] = _dos_getvect (vector_no);
_dos_setvect (vector_no, (void (interrupt *)(void))pcmcia_isr);
#elif (defined(__PSOS__))
#error implement interrupt hook function for PSOS
#else
#error - Implement hook pcmcia vector for your system
#endif
/* mask on the interrupt 8259. pc specific */
ks_mask_isr_on(irq);
/* clear any stray interrupts */
ks_clear_isr(irq);
}
#endif /* (USE_ATA) */
/* Common routines */
void ks_restore_vectors()
{
int i;
for (i = 0; i < 15; i++)
{
if (oldint[i])
{
#if (defined(PLUS))
NU_Register_LISR(ks_isr_to_vector(i),oldint[i], &oldint[i]);
#elif (defined(POLLOS))
_dos_setvect (ks_isr_to_vector(i),oldint[i]);
#elif (defined(RTPX))
_dos_setvect (ks_isr_to_vector(i),oldint[i]);
#elif (defined(UCOS))
_dos_setvect (ks_isr_to_vector(i),(void (interrupt *)(void))oldint[i]);
#elif (defined(CMXRM))
_dos_setvect (ks_isr_to_vector(i),(void (interrupt *)(void))oldint[i]);
#elif (defined(CMXD860))
// Nothing. done up front
#else
#error Implement retore vector for your kernel
#endif
}
}
}
#if (IS_NOT_PC_ARCH)
int ks_isr_to_vector(int irq)
{
return(irq);
}
// turn on the interrupt thru 8259 interrupt controller
void ks_mask_isr_on(int irq)
{
}
// turn off the interrupt thru 8259 interrupt controller
void ks_mask_isr_off(int irq)
{
}
/* clear any stray interupts or acknowledge to interrupt controller */
void ks_clear_isr(int irq)
{
}
#elif (IS_PC_ARCH)
/****** Interrupt Controller Registers ******/
#define MR8259A 0x21 /* interrupt controller 1 */
#define IR8259A 0x20
#define MR8259B 0xA1 /* interrupt controller 2 */
#define IR8259B 0xA0
/****** 8259 REGISTER DEFINITIONS ******/
#define EOI 0x20 /* end of interrupt */
#define RIRR 0x0a /* read interrupt request register */
int ks_isr_to_vector(int irq)
{
int vector_no;
/* map the interrupt number to a position in the int table */
if ( irq > 7)
vector_no = 0x70 + ( irq - 8);
else
vector_no = irq + 8;
return(vector_no);
}
// turn on the interrupt thru 8259 interrupt controller
void ks_mask_isr_on(int irq)
{
if ( irq > 7) /* if using second int controller */
{
OUTBYTE(MR8259B, INBYTE(MR8259B) & ~(1 << ( irq - 8)));
}
else
{
OUTBYTE (MR8259A, INBYTE(MR8259A) & ~(1 << irq));
}
}
// turn off the interrupt thru 8259 interrupt controller
void ks_mask_isr_off(int irq)
{
if ( irq > 7) /* if using second int controller */
{
OUTBYTE(MR8259B, INBYTE(MR8259B) | (1 << ( irq - 8)));
}
else
{
OUTBYTE (MR8259A, INBYTE(MR8259A) | (1 << irq));
}
}
/* clear any stray interupts or acknowledge to interrupt controller */
void ks_clear_isr(int irq)
{
if ( irq > 7)
OUTBYTE (IR8259B, EOI);
OUTBYTE (IR8259A, EOI);
}
#else
#error must define ks_isr_to_vector, ks_mask_isr_on(int irq)
#error void ks_mask_isr_off(int irq)
#error void ks_clear_isr(int irq)
#endif
#if (defined(PLUS))
#if (USE_ATA)
/* These are hisr routines for the ide driver. they are scheduled when the
ide interrupt service routine calls ks_invoke_ide_interrupt(controller_number) */
void ide_hisr_0(void)
{
ks_set_ide_signal(0);
}
void ide_hisr_1(void)
{
ks_set_ide_signal(1);
}
#endif
#if (USE_FLOPPY)
/* This is the hisr routines for the floppy driver. It is scheduled when the
floppy interrupt service routine calls floppy_interrupt_signal() */
void floppy_hisr(void)
{
ks_set_floppy_signal();
}
#endif
#endif /* Nucleus */
#endif // (USE_ATA || USE_FLOPPY || INCLUDE_PCMCIA)
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -