IDT set up
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 20 Feb 2009 09:01:55 +0000 (01:01 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 20 Feb 2009 09:01:55 +0000 (01:01 -0800)
Handles the setup of the IDT and handler functions.  Doesn't do much
other than detect and print out messages.  Backtrace doesn't work right
once kicked to the monitor.  O/W, things seem fine.

inc/mmu.h
kern/env.c
kern/init.c
kern/trap.c
kern/trapentry.S

index 0bcbbec..633a1b5 100644 (file)
--- a/inc/mmu.h
+++ b/inc/mmu.h
@@ -266,7 +266,7 @@ struct Gatedesc {
        unsigned gd_rsv1 : 3;        // reserved(should be zero I guess)
        unsigned gd_type : 4;        // type(STS_{TG,IG32,TG32})
        unsigned gd_s : 1;           // must be 0 (system)
-       unsigned gd_dpl : 2;         // descriptor(meaning new) privilege level
+       unsigned gd_dpl : 2;         // DPL - highest ring allowed to use this
        unsigned gd_p : 1;           // Present
        unsigned gd_off_31_16 : 16;  // high bits of offset in segment
 };
index af583ee..b086a2d 100644 (file)
@@ -404,6 +404,14 @@ env_destroy(struct Env *e)
 {
        env_free(e);
 
+       int i;
+       // ugly, but for now just linearly search through all possible
+       // environments for a runnable one.
+       for (i = 0; i < NENV; i++) {
+               e = &envs[ENVX(i)];
+               if (e && e->env_status == ENV_RUNNABLE)
+                       env_run(e);
+       }
        cprintf("Destroyed the only environment - nothing more to do!\n");
        while (1)
                monitor(NULL);
@@ -450,10 +458,11 @@ env_run(struct Env *e)
        //      e->env_tf to sensible values.
        
                // would set the curenv->env_status if we had more states
-       curenv = e;
-       e->env_runs++;
-       lcr3(e->env_cr3);
-       panic("remove me to step through env_pop_tf or once int 0x30 is supported.");
+       if (e != curenv) {
+               curenv = e;
+               e->env_runs++;
+               lcr3(e->env_cr3);
+       }
     env_pop_tf(&e->env_tf);
 }
 
index 3e7362a..4299b36 100644 (file)
@@ -46,10 +46,12 @@ void kernel_init(multiboot_info_t *mboot_info)
        ENV_CREATE2(TEST, TESTSIZE);
 #else
        // Touch all you want.
+       ENV_CREATE(user_softint);
+       ENV_CREATE(user_badsegment);
+       ENV_CREATE(user_divzero);
        ENV_CREATE(user_hello);
 #endif // TEST*
 
-
        // We only have one user environment for now, so just run it.
        env_run(&envs[0]);
 }
index efe3a5b..ec7cd1b 100644 (file)
@@ -58,7 +58,25 @@ idt_init(void)
 {
        extern struct Segdesc gdt[];
        
-       // LAB 3: Your code here.
+       // This table is made in trapentry.S by each macro in that file.
+       // It is layed out such that the ith entry is the ith's traphandler's
+       // (uint32_t) trap addr, then (uint32_t) trap number
+       struct trapinfo { uint32_t trapaddr; uint32_t trapnumber; };
+       extern struct trapinfo trap_tbl[];
+       extern struct trapinfo trap_tbl_end[];
+       int i, trap_tbl_size = trap_tbl_end - trap_tbl;
+       extern void ISR_default(void);
+
+       // set all to default, to catch everything
+       for(i = 0; i < 256; i++)
+               SETGATE(idt[i], 1, GD_KT, &ISR_default, 3);
+       
+       // set all entries that have real trap handlers
+       // we need to stop short of the last one, since the last is the default
+       // handler with a fake interrupt number (500) that is out of bounds of
+       // the idt[]
+       for(i = 0; i < trap_tbl_size - 1; i++)
+               SETGATE(idt[trap_tbl[i].trapnumber], 1, GD_KT, trap_tbl[i].trapaddr, 3);
 
        // Setup a TSS so that we get the right stack
        // when we trap to the kernel.
@@ -142,6 +160,7 @@ trap(struct Trapframe *tf)
        // Dispatch based on what type of trap occurred
        trap_dispatch(tf);
 
+       // should this be if == 3?  Sort out later when we handle traps.
         // Return to the current environment, which should be runnable.
         assert(curenv && curenv->env_status == ENV_RUNNABLE);
         env_run(curenv);
index bab74b7..85abc62 100644 (file)
 
 /* The TRAPHANDLER macro defines a globally-visible function for handling
  * a trap.  It pushes a trap number onto the stack, then jumps to _alltraps.
+ * It also builds this traps portion of the trap_tbl.
  * Use TRAPHANDLER for traps where the CPU automatically pushes an error code.
  */ 
-#define TRAPHANDLER(name, num)                                         \
+#define TRAPHANDLER(name, num)                                                                 \
+       .text;                                                                                                          \
        .globl name;            /* define global symbol for 'name' */   \
        .type name, @function;  /* symbol type is function */           \
-       .align 2;               /* align function definition */         \
-       name:                   /* function starts here */              \
-       pushl $(num);                                                   \
-       jmp _alltraps
+       .align 2;               /* align function definition */                         \
+       name:                   /* function starts here */                                      \
+       pushl $(num);                                                                                           \
+       jmp _alltraps;                                                                                          \
+       .data;                                                                                                          \
+       .long name;                                                                                                     \
+       .long num
 
 /* Use TRAPHANDLER_NOEC for traps where the CPU doesn't push an error code.
  * It pushes a 0 in place of the error code, so the trap frame has the same
  * format in either case.
  */
-#define TRAPHANDLER_NOEC(name, num)                                    \
-       .globl name;                                                    \
-       .type name, @function;                                          \
+#define TRAPHANDLER_NOEC(name, num)            \
+       .text;                                                          \
+       .globl name;                                            \
+       .type name, @function;                          \
        .align 2;                                                       \
        name:                                                           \
        pushl $0;                                                       \
-       pushl $(num);                                                   \
-       jmp _alltraps
+       pushl $(num);                                           \
+       jmp _alltraps;                                          \
+       .data;                                                          \
+       .long name;                                                     \
+       .long num
 
-.text
+.data
+.globl trap_tbl;
+trap_tbl:
 
 /*
  * Lab 3: Your code here for generating entry points for the different traps.
  */
+TRAPHANDLER(ISR_divide_error, T_DIVIDE);
+TRAPHANDLER(ISR_debug_exceptions, T_DEBUG);
+TRAPHANDLER(ISR_breakpoint, T_BRKPT);
+TRAPHANDLER(ISR_overflow, T_OFLOW);
+TRAPHANDLER(ISR_bounds_check, T_BOUND);
+TRAPHANDLER(ISR_invalid_opcode, T_ILLOP);
+TRAPHANDLER(ISR_device_not_available, T_DEVICE);
+TRAPHANDLER_NOEC(ISR_double_fault, T_DBLFLT);
+TRAPHANDLER_NOEC(ISR_invalid_TSS, T_TSS);
+TRAPHANDLER_NOEC(ISR_segment_not_present, T_SEGNP);
+TRAPHANDLER_NOEC(ISR_stack_exception, T_STACK);
+TRAPHANDLER_NOEC(ISR_general_protection_fault, T_GPFLT);
+TRAPHANDLER_NOEC(ISR_page_fault, T_PGFLT);
+TRAPHANDLER(ISR_floating_point_error, T_FPERR);
+TRAPHANDLER(ISR_alignment_check, T_ALIGN);
+TRAPHANDLER_NOEC(ISR_machine_check, T_MCHK);
+TRAPHANDLER_NOEC(ISR_simd_error, T_SIMDERR);
+
+TRAPHANDLER(ISR_syscall, T_SYSCALL);
+/* make sure default is last */
+TRAPHANDLER(ISR_default, T_DEFAULT);
 
-       
+.data
+.globl trap_tbl_end;
+trap_tbl_end:
 
+.text
 /*
  * Lab 3: Your code here for _alltraps
  */
-       
+_alltraps:
+       pushl %ds;
+       pushl %es;
+       pushal;
+       movw $GD_KD, %ax; /* data segments aren't accessible by default */
+       movw %ax, %ds;
+       movw %ax, %es;
+       pushl %esp;
+       call trap;
+       popl %esp;
+       popal;
+       popl %es;
+       popl %ds;
+       addl $0x8, %esp; /* skip trapno and err */
+       iret;