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

📄 interrupt.cpp

📁 哈工大的几个人开发的操作系统pyos的部分源码
💻 CPP
字号:
#include "system.h"
#include "interrupt.h"
#include "video.h"
#include "process.h"

struct_pyos_InterruptItem class_pyos_Interrupt::m_Idt[ 256 ] ; // 中断描述符表项
struct_pyos_Idtr class_pyos_Interrupt::m_Idtr ; // 中断描述符

/* 初始化中断控制器 8259A */
void class_pyos_Interrupt::Init8259A()
{
  // 给中断寄存器编程
  // 发送 ICW1 : 使用 ICW4,级联工作
  class_pyos_System::ToPort( 0x20 , 0x11 ) ;
  class_pyos_System::ToPort( 0xa0 , 0x11 ) ;

  // 发送 ICW2,中断起始号从 0x20 开始(第一片)及 0x28开始(第二片)
  class_pyos_System::ToPort( 0x21 , 0x20 ) ; 
  class_pyos_System::ToPort( 0xa1 , 0x28 ) ;

  // 发送 ICW3
  class_pyos_System::ToPort( 0x21 , 0x4 ) ;
  class_pyos_System::ToPort( 0xa1 , 0x2 ) ;

  // 发送 ICW4
  class_pyos_System::ToPort( 0x21 , 0x1 ) ;
  class_pyos_System::ToPort( 0xa1 , 0x1 ) ;

  // 设置中断屏蔽位 OCW1 ,屏蔽所有中断请求 
  class_pyos_System::ToPort( 0x21 , 0xff ) ;
  class_pyos_System::ToPort( 0xa1 , 0xff ) ;
}

/* 初始化中断向量表 */
void class_pyos_Interrupt::InitInterruptTable()
{
  /* 设置中断门描述符,指向一个哑中断,在需要的时候再填写 */ 
  struct_pyos_InterruptItem tmp ;
  tmp.Offset_0_15 = ( unsigned int )pyos_asm_interrupt_handle_for_default ;
  tmp.Offset_16_31 = ( unsigned int )pyos_asm_interrupt_handle_for_default >> 16 ;
  tmp.SegSelector = 0x8 ; // 代码段
  tmp.UnUsed = 0 ;
  tmp.P = 1 ;
  tmp.DPL = 0 ;
  tmp.Saved_1_1_0 = 6 ;
  tmp.Saved_0 = 0 ;
  tmp.D = 1 ;

  for( int i = 0 ; i < 256 ; ++i ){
    m_Idt[ i ] = tmp ;
  }

  m_Idtr.IdtAddr = m_Idt ;
  m_Idtr.IdtLengthLimit = 256 * 8 - 1 ; // 共 256项,每项占8个字节

  // 内嵌汇编,载入 ldt
  __asm__( "lidt %0" : "=m"( m_Idtr ) ) ; //载入GDT表
}

/* 开中断 */
void class_pyos_Interrupt::OpenInterrupt()
{
  __asm__( "sti" ) ;
}

/* 关中断 */
void class_pyos_Interrupt::CloseInterrupt()
{
  __asm__( "cli" ) ;
}

/* 初始化中断服务 */
void class_pyos_Interrupt::Init()
{
  /* 初始化中断向量表 */
  InitInterruptTable() ;

  /* 初始化中断可编程控件器 8259A ,这时屏蔽了所有中断请求*/
  Init8259A() ;  
}

/* 默认中断处理函数 */
extern "C" void pyos_interrupt_handle_for_default()
{  
}

/* 安装中断函数,只负责在中断向量表中安装,而相应中断是否开启,什么时候开启完全由各中断服务类自行决定 */
void class_pyos_Interrupt::InstallInterrupt( unsigned int interrupt_number , void* address_of_handle_function ) 
{
  /* 首先关中断 */
  CloseInterrupt() ;
  if( interrupt_number != 0x20 ){
    /* 根据中断号将中断向量表中相应位置处的中断处理函数换成指定函数 */  
    m_Idt[ interrupt_number ].Offset_0_15 = ( unsigned int )address_of_handle_function ;
    m_Idt[ interrupt_number ].Offset_16_31 = ( unsigned int )address_of_handle_function >> 16 ;  
  }
  else{
    // 0x20 中断是时钟中断,用任务门处理
    struct_pyos_TSSGate *p = ( struct_pyos_TSSGate * )&m_Idt[ 0x20 ] ;
    p->DPL = 0 ;
    p->P = 1 ;
    p->Saved0_0 = 0 ;
    p->TSSSelector = 0x40 ;
    p->Type_0101 = 5 ;
    p->UnUsed0 = 0 ;
    p->UnUsed1 = 0 ;
    p->UnUsed2 = 0 ;    
  }
}

/* 设置中断屏蔽字,自动关中断,但需手动开中断 */
void class_pyos_Interrupt::SetEnableWord( unsigned int irq_number , bool enable )
{
  class_pyos_Interrupt::CloseInterrupt() ;
  if( irq_number < 0 || irq_number > 15 ){
    /* 允许设置的屏蔽中断号在 0~15 之间 */
    return ;
  }
  else{
    unsigned char enable_word ;
    if( irq_number < 8 ){
      /* 设置第一片的中断号 */
      /* 读第一片的中断屏蔽字 */
      enable_word = class_pyos_System::FromPort( 0x21 ) ;
    }
    else{
      /* 读第二片的中断屏蔽字 */
      enable_word = class_pyos_System::FromPort( 0xa1 ) ;
    }
    switch( irq_number ){
      case 0 :
      case 8:
        if( enable ){
          enable_word &= 0xfe ; // 0xfe = 1111 1110
        }
        else{
          enable_word |= 0x01 ; // 0x00 = 0000 0001
        }
        break ;
      case 1 :
      case 9:
        if( enable ){
          enable_word &= 0xfd ; // 0xfd = 1111 1101
        }
        else{
          enable_word |= 0xfe ; // 0x01 = 0000 0010
        }
        break ;
      case 2 :
      case 10:
        if( enable ){
          enable_word &= 0xfb ; // 0xfb = 1111 1011
        }
        else{
          enable_word |= 0x04 ; // 0x04 = 0000 0100
        }
        break ;
      case 3 :
      case 11:
        if( enable ){
          enable_word &= 0xf7 ; // 0xf7 = 1111 0111
        }
        else{
          enable_word |= 0x08 ; // 0x08 = 0000 1000
        }
        break ;
      case 4 :
      case 12:
        if( enable ){
          enable_word &= 0xef ; // 0xef = 1110 1111
        }
        else{
          enable_word |= 0x10 ; // 0x01 = 0001 0000
        }
        break ;
      case 5 :
      case 13:
        if( enable ){
          enable_word &= 0xdf ; // 0xfd = 1101 1111
        }
        else{
          enable_word |= 0xfe ; // 0x20 = 0010 0000
        }
        break ;
      case 6 :
      case 14:
        if( enable ){
          enable_word &= 0xfd ; // 0xbf = 1011 1111
        }
        else{
          enable_word |= 0xfe ; // 0x40 = 0100 0000
        }
        break ;
      case 7 :
      case 15:
        if( enable ){
          enable_word &= 0xfd ; // 0x7f = 0111 1111
        }
        else{
          enable_word |= 0xfe ; // 0x80 = 1000 0000
        }
        break ;
    }
    if( irq_number < 8 ){
      /* 发送到主片 */
      class_pyos_System::ToPort( 0x21 , enable_word ) ;
    }
    else{
      /* 发送到从片 */
      class_pyos_System::ToPort( 0xa1 , enable_word ) ;
    }
  }
}

⌨️ 快捷键说明

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