73 asm volatile (
"pushfl; popl %0" :
"=g" (flags));
111 asm volatile (
"cli" : : :
"memory");
134 asm volatile (
"lidt %0" : :
"m" (idtr_operand));
144 intr_names[5] =
"#BR BOUND Range Exceeded Exception";
145 intr_names[6] =
"#UD Invalid Opcode Exception";
146 intr_names[7] =
"#NM Device Not Available Exception";
148 intr_names[9] =
"Coprocessor Segment Overrun";
152 intr_names[13] =
"#GP General Protection Exception";
154 intr_names[16] =
"#MF x87 FPU Floating-Point Error";
155 intr_names[17] =
"#AC Alignment Check Exception";
156 intr_names[18] =
"#MC Machine-Check Exception";
157 intr_names[19] =
"#XF SIMD Floating-Point Exception";
184 ASSERT (vec_no >= 0x20 && vec_no <= 0x2f);
205 ASSERT (vec_no < 0x20 || vec_no > 0x2f);
267 ASSERT (irq >= 0x20 && irq < 0x30);
299 ASSERT (dpl >= 0 && dpl <= 3);
300 ASSERT (type >= 0 && type <= 15);
302 e0 = (((
uint32_t)
function & 0xffff)
305 e1 = (((
uint32_t)
function & 0xffff0000)
354 external = frame->
vec_no >= 0x20 && frame->
vec_no < 0x30;
368 else if (frame->
vec_no == 0x27 || frame->
vec_no == 0x2f)
404 if ((n & (n - 1)) == 0)
405 printf (
"Unexpected interrupt %#04x (%s)\n",
420 asm (
"movl %%cr2, %0" :
"=r" (cr2));
422 printf (
"Interrupt %#04x (%s) at eip=%p\n",
#define ASSERT(CONDITION)
This is outside the header guard so that debug.h may be included multiple times with different settin...
#define FLAG_IF
Interrupt Flag.
static uint64_t make_gate(void(*function)(void), int dpl, int type)
Creates an gate that invokes FUNCTION.
static uint64_t idt[INTR_CNT]
The Interrupt Descriptor Table (IDT).
static void unexpected_interrupt(const struct intr_frame *)
Handles an unexpected interrupt with interrupt frame F.
void intr_register_int(uint8_t vec_no, int dpl, enum intr_level level, intr_handler_func *handler, const char *name)
Registers internal interrupt VEC_NO to invoke HANDLER, which is named NAME for debugging purposes.
void intr_register_ext(uint8_t vec_no, intr_handler_func *handler, const char *name)
Registers external interrupt VEC_NO to invoke HANDLER, which is named NAME for debugging purposes.
static unsigned int unexpected_cnt[INTR_CNT]
Number of unexpected interrupts for each vector.
#define PIC0_CTRL
Programmable Interrupt Controller (PIC) registers.
void intr_yield_on_return(void)
During processing of an external interrupt, directs the interrupt handler to yield to a new process j...
enum intr_level intr_enable(void)
Enables interrupts and returns the previous interrupt status.
#define PIC1_CTRL
Slave PIC control register address.
#define PIC0_DATA
Master PIC data register address.
static void pic_end_of_interrupt(int irq)
Sends an end-of-interrupt signal to the PIC for the given IRQ.
const char * intr_name(uint8_t vec)
Returns the name of interrupt VEC.
static void pic_init(void)
Programmable Interrupt Controller helpers.
static uint64_t make_intr_gate(void(*)(void), int dpl)
Interrupt Descriptor Table helpers.
static uint64_t make_trap_gate(void(*)(void), int dpl)
Creates a trap gate that invokes FUNCTION with the given DPL.
static void register_handler(uint8_t vec_no, int dpl, enum intr_level level, intr_handler_func *handler, const char *name)
Registers interrupt VEC_NO to invoke HANDLER with descriptor privilege level DPL.
static intr_handler_func * intr_handlers[INTR_CNT]
Interrupt handler functions for each interrupt.
static const char * intr_names[INTR_CNT]
Names for each interrupt, for debugging purposes.
void intr_dump_frame(const struct intr_frame *f)
Dumps interrupt frame F to the console, for debugging.
bool intr_context(void)
Returns true during processing of an external interrupt and false at all other times.
void intr_init(void)
Initializes the interrupt system.
enum intr_level intr_disable(void)
Disables interrupts and returns the previous interrupt status.
enum intr_level intr_get_level(void)
Returns the current interrupt status.
static bool in_external_intr
External interrupts are those generated by devices outside the CPU, such as the timer.
void intr_handler(struct intr_frame *args)
Interrupt handlers.
enum intr_level intr_set_level(enum intr_level level)
Enables or disables interrupts as specified by LEVEL and returns the previous interrupt status.
static bool yield_on_return
Should we yield on interrupt return?
#define PIC1_DATA
Slave PIC data register address.
#define INTR_CNT
Number of x86 interrupts.
static uint64_t make_idtr_operand(uint16_t limit, void *base)
Returns a descriptor that yields the given LIMIT and BASE when used as an operand for the LIDT instru...
void intr_handler_func(struct intr_frame *)
intr_level
Interrupts on or off?
@ INTR_ON
Interrupts enabled.
@ INTR_OFF
Interrupts disabled.
intr_stub_func * intr_stubs[256]
static void outb(uint16_t port, uint8_t data)
Writes byte DATA to PORT.
int printf(const char *format,...)
Writes formatted output to the console.
#define SEL_KCSEG
Kernel code selector.
unsigned long long int uint64_t
unsigned short int uint16_t
void(* eip)(void)
Next instruction to execute.
uint16_t uint16_t uint16_t uint16_t uint32_t vec_no
Saved DS segment register.
uint32_t error_code
Error code.
uint16_t uint16_t uint16_t es
Saved FS segment register.
uint16_t uint16_t uint16_t uint16_t ds
Saved ES segment register.
void * esp
Saved stack pointer.
void thread_yield(void)
Yields the CPU.