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

📄 irq.c

📁 The main purpose of this project is to add a new scheduling algorithm to GeekOS and to implement a s
💻 C
字号:
/* * This is the device-driver interface to the interrupt system. * Copyright (c) 2001,2003 David H. Hovemeyer <daveho@cs.umd.edu> * $Revision: 1.12 $ *  * This is free software.  You are permitted to use, * redistribute, and modify it as specified in the file "COPYING". */#include <geekos/kassert.h>#include <geekos/idt.h>#include <geekos/io.h>#include <geekos/irq.h>/* ---------------------------------------------------------------------- * Private functions and data * ---------------------------------------------------------------------- *//* * Current IRQ mask. * This should be kept up to date with setup.asm * (which does the initial programming of the PICs). */static ushort_t s_irqMask = 0xfffb;/* * Get the master and slave parts of an IRQ mask. */#define MASTER(mask) ((mask) & 0xff)#define SLAVE(mask) (((mask)>>8) & 0xff)/* ---------------------------------------------------------------------- * Public functions * ---------------------------------------------------------------------- *//* * Install a handler for given IRQ. * Note that we don't unmask the IRQ. */void Install_IRQ(int irq, Interrupt_Handler handler){    Install_Interrupt_Handler(irq + FIRST_EXTERNAL_INT, handler);}/* * Get current IRQ mask.  Each bit position represents * one of the 16 IRQ lines. */ushort_t Get_IRQ_Mask(void){    return s_irqMask;}/* * Set the IRQ mask. */void Set_IRQ_Mask(ushort_t mask){    uchar_t oldMask, newMask;    oldMask = MASTER(s_irqMask);    newMask = MASTER(mask);    if (newMask != oldMask) {	Out_Byte(0x21, newMask);    }    oldMask = SLAVE(s_irqMask);    newMask = SLAVE(mask);    if (newMask != oldMask) {	Out_Byte(0xA1, newMask);    }    s_irqMask = mask;}/* * Enable given IRQ. */void Enable_IRQ(int irq){    bool iflag = Begin_Int_Atomic();    KASSERT(irq >= 0 && irq < 16);    ushort_t mask = Get_IRQ_Mask();    mask &= ~(1 << irq);    Set_IRQ_Mask(mask);    End_Int_Atomic(iflag);}/* * Disable given IRQ. */void Disable_IRQ(int irq){    bool iflag = Begin_Int_Atomic();    KASSERT(irq >= 0 && irq < 16);    ushort_t mask = Get_IRQ_Mask();    mask |= (1 << irq);    Set_IRQ_Mask(mask);    End_Int_Atomic(iflag);}/* * Called by an IRQ handler to begin the interrupt. * Currently a no-op. */void Begin_IRQ(struct Interrupt_State* state){}/* * Called by an IRQ handler to end the interrupt. * Sends an EOI command to the appropriate PIC(s). */void End_IRQ(struct Interrupt_State* state){    int irq = state->intNum - FIRST_EXTERNAL_INT;    uchar_t command = 0x60 | (irq & 0x7);    if (irq < 8) {	/* Specific EOI to master PIC */	Out_Byte(0x20, command);    }    else {	/* Specific EOI to slave PIC, then to master (cascade line) */	Out_Byte(0xA0, command);	Out_Byte(0x20, 0x62);    }}

⌨️ 快捷键说明

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