📄 init-idt.c
字号:
/* ============================================================ */
/* File: INIT-IDT.C */
/* */
/* Copyright (C) 2001, Daniel W. Lewis and Prentice-Hall */
/* */
/* Called by INIT-CPU.ASM. */
/* */
/* Purpose: Interrupt system initialization. Establishes an */
/* Interrtupt Vector Table (IVT) for an initial set of */
/* Interrupt Service Routines (ISRs). */
/* */
/* Interrupts: Already disabled; remain disabled. */
/* */
/* Designed for use with the DJGPP port of the GNU C/C++ */
/* protected mode 386 compiler. */
/* */
/* Modification History: */
/* */
/* ============================================================ */
#include "libepc.h"
#define _HW_INT_BASE (256-16) /* Use last 16 vectors */
/* ------------------------------------------------------------ */
/* Format of an entry in the Interrupt Descriptor Table (IDT). */
/* Note: Not needed if you use SetISR (see below). */
/* ------------------------------------------------------------ */
typedef struct IDT_DESCRIPTOR
{
WORD16 offset_0 ; /* Offset, bits 15-0 */
WORD16 selector ; /* Selector value */
BYTE8 not_used ; /* Must be set to 0's */
BYTE8 flags ; /* Access rights, etc. */
WORD16 offset_16; /* Offset, bits 31-16 */
} __attribute__((packed)) IDT_DESCRIPTOR ;
/* ------------------------------------------------------------ */
/* Operand used by the LIDT instruction. */
/* Note: Not needed if you use SetISR (see below). */
/* ------------------------------------------------------------ */
typedef struct IDT_INFO
{
WORD16 limit ;
DWORD32 addrs ;
} __attribute__((packed)) IDT_INFO ;
extern WORD16 code_selector __asm__("code_selector") ;
#define INTEL_INT(n) (0 <= n && n < 32)
#define PIC1_INT(n) (IRQ2INT(0) <= n && n <= IRQ2INT(7))
#define PIC2_INT(n) (IRQ2INT(8) <= n && n <= IRQ2INT(15))
#define PRIVATE static
PRIVATE void Abort(char *msg)
{
CLI ;
PutString(msg) ;
PutString("; system halted.") ;
for (;;) ;
}
PRIVATE void ISR00(void) { Abort("Divide error"); }
PRIVATE void ISR01(void) { Abort("Debug Interrupt"); }
PRIVATE void ISR02(void) { Abort("Non-Maskable Interrupt"); }
PRIVATE void ISR03(void) { Abort("Breakpoint Interrupt"); }
PRIVATE void ISR04(void) { Abort("Overflow"); }
PRIVATE void ISR05(void) { Abort("BOUND Range Exceeded"); }
PRIVATE void ISR06(void) { Abort("Invalid Opcode"); }
PRIVATE void ISR07(void) { Abort("No Math CoProcessor"); }
PRIVATE void ISR08(void) { Abort("Double Fault"); }
PRIVATE void ISR09(void) { Abort("Math CoProcessor Overrun"); }
PRIVATE void ISR10(void) { Abort("Invalid TSS"); }
PRIVATE void ISR11(void) { Abort("Segment Not Present"); }
PRIVATE void ISR12(void) { Abort("Stack Segment Fault"); }
PRIVATE void ISR13(void) { Abort("General Protection"); }
PRIVATE void ISR14(void) { Abort("Page Fault"); }
PRIVATE void ISR16(void) { Abort("Math CoProcessor Error"); }
PRIVATE void ISR17(void) { Abort("Alignment Check"); }
PRIVATE void ISR18(void) { Abort("Machine Check"); }
PRIVATE void ISR19(void) { Abort("SIMD floating-point exception"); }
PRIVATE void ISR_Rsvd(void) { Abort("Intel Reserved Interrupt"); }
PRIVATE void ISR_User(void) { Abort("Unassigned Interrupt"); }
PRIVATE ISR _intel_isr[] =
{
ISR00, /* Divide by zero */
ISR01, /* Debug exception */
ISR02, /* NMI */
ISR03, /* One byte interrupt */
ISR04, /* Interrupt on overflow */
ISR05, /* Array bounds error */
ISR06, /* Invalid opcode */
ISR07, /* Math not available */
ISR08, /* Double fault */
ISR09, /* Math segment overflow */
ISR10, /* Invalid TSS */
ISR11, /* Segment not present */
ISR12, /* Stack fault */
ISR13, /* General protection */
ISR14, /* Page fault */
ISR_Rsvd, /* Reserved */
ISR16, /* Math error */
ISR17, /* Alignment Check */
ISR18, /* Machine Check */
ISR19, /* SIMD floating-point except. */
ISR_Rsvd, /* Reserved */
ISR_Rsvd, /* Reserved */
ISR_Rsvd, /* Reserved */
ISR_Rsvd, /* Reserved */
ISR_Rsvd, /* Reserved */
ISR_Rsvd, /* Reserved */
ISR_Rsvd, /* Reserved */
ISR_Rsvd, /* Reserved */
ISR_Rsvd, /* Reserved */
ISR_Rsvd, /* Reserved */
ISR_Rsvd, /* Reserved */
ISR_Rsvd /* Reserved */
} ;
PRIVATE IDT_DESCRIPTOR idt[256] ;
PRIVATE IDT_INFO idt_info = { sizeof(idt) - 1, (DWORD32) idt } ;
int IRQ2INT(int irq)
{
return _HW_INT_BASE + irq ;
}
ISR GetISR(int int_numb)
{
IDT_DESCRIPTOR *p = &idt[int_numb] ;
DWORD32 offset ;
offset = (((DWORD32) p->offset_16) << 16) + p->offset_0 ;
return (ISR) offset ;
}
void SetISR(int int_numb, ISR isr)
{
IDT_DESCRIPTOR *p = &idt[int_numb] ;
p->offset_0 = ((WORD16 *) &isr)[0] ;
p->offset_16 = ((WORD16 *) &isr)[1] ;
}
/* Hide this function's name from C programs! */
void Init_IDT(void) __asm__ ("Init_IDT") ;
void Init_IDT(void)
{
extern void ISR_PIC1(void) __asm("ISR_PIC1") ;
extern void ISR_PIC2(void) __asm("ISR_PIC2") ;
IDT_DESCRIPTOR *p ;
int i ;
p = idt ;
for (i = 0; i < ENTRIES(idt); i++, p++)
{
ISR isr ;
p->selector = code_selector ;
p->not_used = 0x00 ;
p->flags = 0x8E ;
if (INTEL_INT(i)) isr = _intel_isr[i] ;
else if (PIC1_INT(i)) isr = ISR_PIC1 ;
else if (PIC2_INT(i)) isr = ISR_PIC2 ;
else isr = ISR_User ;
p->offset_0 = ((WORD16 *) &isr)[0] ;
p->offset_16 = ((WORD16 *) &isr)[1] ;
}
__asm__ __volatile__ ("lidt %0" : : "m" (idt_info)) ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -