Revert Intel-style assembly back to AT&T-style.
[pintos-anon] / src / threads / interrupt.c
index c886cc9d709ab71a3c4bc870eb758ea92321b1a5..2b43fd9a109d6bc1cae7280f46164533e86f0b0b 100644 (file)
@@ -50,7 +50,10 @@ enum intr_level
 intr_get_level (void) 
 {
   uint32_t flags;
 intr_get_level (void) 
 {
   uint32_t flags;
-  
+
+  /* Push the flags register on the processor stack, then pop the
+     value off the stack into `flags'.  See [IA32-v2b] "PUSHF"
+     and "POP" and [IA32-v3] 5.8.1. */
   asm volatile ("pushfl; popl %0" : "=g" (flags));
 
   return flags & FLAG_IF ? INTR_ON : INTR_OFF;
   asm volatile ("pushfl; popl %0" : "=g" (flags));
 
   return flags & FLAG_IF ? INTR_ON : INTR_OFF;
@@ -70,7 +73,11 @@ intr_enable (void)
 {
   enum intr_level old_level = intr_get_level ();
   ASSERT (!intr_context ());
 {
   enum intr_level old_level = intr_get_level ();
   ASSERT (!intr_context ());
+
+  /* Enable interrupts by setting the interrupt flag.
+     See [IA32-v2b] "STI" and [IA32-v3] 5.8.1. */
   asm volatile ("sti");
   asm volatile ("sti");
+
   return old_level;
 }
 
   return old_level;
 }
 
@@ -79,7 +86,11 @@ enum intr_level
 intr_disable (void) 
 {
   enum intr_level old_level = intr_get_level ();
 intr_disable (void) 
 {
   enum intr_level old_level = intr_get_level ();
+
+  /* Disable interrupts by clearing the interrupt flag.
+     See [IA32-v2b] "CLI" and [IA32-v3] 5.8.1. */
   asm volatile ("cli");
   asm volatile ("cli");
+
   return old_level;
 }
 \f
   return old_level;
 }
 \f
@@ -97,7 +108,8 @@ intr_init (void)
   for (i = 0; i < INTR_CNT; i++)
     idt[i] = make_intr_gate (intr_stubs[i], 0);
 
   for (i = 0; i < INTR_CNT; i++)
     idt[i] = make_intr_gate (intr_stubs[i], 0);
 
-  /* Load IDT register. */
+  /* Load IDT register.
+     See [IA32-v2a] "LIDT" and [IA32-v3] 5.10. */
   idtr_operand = make_idtr_operand (sizeof idt - 1, idt);
   asm volatile ("lidt %0" :: "m" (idtr_operand));
 
   idtr_operand = make_idtr_operand (sizeof idt - 1, idt);
   asm volatile ("lidt %0" :: "m" (idtr_operand));
 
@@ -125,9 +137,37 @@ intr_init (void)
   intr_names[19] = "#XF SIMD Floating-Point Exception";
 }
 
   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
 
    The handler will have descriptor privilege level DPL, meaning
    that it can be invoked intentionally when the processor is in
@@ -137,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
    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
 }
 
 /* Returns true during processing of an external interrupt
@@ -298,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
 
 /* 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) 
 {
 void
 intr_handler (struct intr_frame *frame) 
 {
@@ -349,9 +373,14 @@ intr_handler (struct intr_frame *frame)
 void
 intr_dump_frame (const struct intr_frame *f) 
 {
 void
 intr_dump_frame (const struct intr_frame *f) 
 {
-  uint32_t cr2, ss;
+  uint32_t cr2;
+
+  /* Store current value of CR2 into `cr2'.
+     CR2 is the linear address of the last page fault.
+     See [IA32-v2a] "MOV--Move to/from Control Registers" and
+     [IA32-v3] 5.14 "Interrupt 14--Page Fault Exception
+     (#PF)". */
   asm ("movl %%cr2, %0" : "=r" (cr2));
   asm ("movl %%cr2, %0" : "=r" (cr2));
-  asm ("movl %%ss, %0" : "=r" (ss));
 
   printf ("Interrupt %#04x (%s) at eip=%p\n",
           f->vec_no, intr_names[f->vec_no], f->eip);
 
   printf ("Interrupt %#04x (%s) at eip=%p\n",
           f->vec_no, intr_names[f->vec_no], f->eip);
@@ -361,7 +390,7 @@ intr_dump_frame (const struct intr_frame *f)
   printf (" esi=%08"PRIx32" edi=%08"PRIx32" esp=%08"PRIx32" ebp=%08"PRIx32"\n",
           f->esi, f->edi, (uint32_t) f->esp, f->ebp);
   printf (" cs=%04"PRIx16" ds=%04"PRIx16" es=%04"PRIx16" ss=%04"PRIx16"\n",
   printf (" esi=%08"PRIx32" edi=%08"PRIx32" esp=%08"PRIx32" ebp=%08"PRIx32"\n",
           f->esi, f->edi, (uint32_t) f->esp, f->ebp);
   printf (" cs=%04"PRIx16" ds=%04"PRIx16" es=%04"PRIx16" ss=%04"PRIx16"\n",
-          f->cs, f->ds, f->es, f->cs != SEL_KCSEG ? f->ss : ss);
+          f->cs, f->ds, f->es, f->ss);
 }
 
 /* Returns the name of interrupt VEC. */
 }
 
 /* Returns the name of interrupt VEC. */