X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fthreads%2Finterrupt.c;h=82b7db7d724bed32a60fe5d9c1c004192d2049fd;hb=615bf3b3d2a8573ed6fb9ddc0055745e163ac999;hp=380544a1779e6a75a2e08baa8b81ceb5ad68c67e;hpb=7d4e3dda080a47db88616f1c0d975f2091be47f1;p=pintos-anon diff --git a/src/threads/interrupt.c b/src/threads/interrupt.c index 380544a..82b7db7 100644 --- a/src/threads/interrupt.c +++ b/src/threads/interrupt.c @@ -137,9 +137,37 @@ intr_init (void) intr_names[19] = "#XF SIMD Floating-Point Exception"; } -/* Registers interrupt VEC_NO to invoke HANDLER, which is named - NAME for debugging purposes. The interrupt handler will be - invoked with interrupt status set to LEVEL. +/* Registers interrupt VEC_NO to invoke HANDLER with descriptor + privilege level DPL. Names the interrupt NAME for debugging + purposes. The interrupt handler will be invoked with + interrupt status set to LEVEL. */ +static void +register_handler (uint8_t vec_no, int dpl, enum intr_level level, + intr_handler_func *handler, const char *name) +{ + ASSERT (intr_handlers[vec_no] == NULL); + if (level == INTR_ON) + idt[vec_no] = make_trap_gate (intr_stubs[vec_no], dpl); + else + idt[vec_no] = make_intr_gate (intr_stubs[vec_no], dpl); + intr_handlers[vec_no] = handler; + intr_names[vec_no] = name; +} + +/* Registers external interrupt VEC_NO to invoke HANDLER, which + is named NAME for debugging purposes. The handler will + execute with interrupts disabled. */ +void +intr_register_ext (uint8_t vec_no, intr_handler_func *handler, + const char *name) +{ + ASSERT (vec_no >= 0x20 && vec_no <= 0x2f); + register_handler (vec_no, 0, INTR_OFF, handler, name); +} + +/* Registers internal interrupt VEC_NO to invoke HANDLER, which + is named NAME for debugging purposes. The interrupt handler + will be invoked with interrupt status LEVEL. The handler will have descriptor privilege level DPL, meaning that it can be invoked intentionally when the processor is in @@ -149,27 +177,11 @@ intr_init (void) still cause interrupts with DPL==0 to be invoked. See [IA32-v3] sections 4.5 and 4.8.1.1 for further discussion. */ void -intr_register (uint8_t vec_no, int dpl, enum intr_level level, - intr_handler_func *handler, - const char *name) +intr_register_int (uint8_t vec_no, int dpl, enum intr_level level, + intr_handler_func *handler, const char *name) { - /* Make sure this handler isn't already registered to someone - else. */ - ASSERT (intr_handlers[vec_no] == NULL); - - /* Interrupts generated by external hardware (0x20 <= VEC_NO <= - 0x2f) should specify INTR_OFF for LEVEL. Otherwise a timer - interrupt could cause a task switch during interrupt - handling. Most other interrupts can and should be handled - with interrupts enabled. */ - ASSERT (vec_no < 0x20 || vec_no > 0x2f || level == INTR_OFF); - - if (level == INTR_ON) - idt[vec_no] = make_trap_gate (intr_stubs[vec_no], dpl); - else - idt[vec_no] = make_intr_gate (intr_stubs[vec_no], dpl); - intr_handlers[vec_no] = handler; - intr_names[vec_no] = name; + ASSERT (vec_no < 0x20 || vec_no > 0x2f); + register_handler (vec_no, dpl, level, handler, name); } /* Returns true during processing of an external interrupt @@ -310,8 +322,8 @@ make_idtr_operand (uint16_t limit, void *base) /* Handler for all interrupts, faults, and exceptions. This function is called by the assembly language interrupt stubs in - intr-stubs.S (see intr-stubs.pl). FRAME describes the - interrupt and the interrupted thread's registers. */ + intr-stubs.S. FRAME describes the interrupt and the + interrupted thread's registers. */ void intr_handler (struct intr_frame *frame) {