⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 portisr.c

📁 ertfs文件系统里面既有完整ucos程序
💻 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)





















⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -