void kbd_init(void) { // Drain the kbd buffer so that Bochs generates interrupts. kbd_intr(); irq_setmask_8259A(irq_mask_8259A & ~(1<<1)); }
void ukbd_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status) { keyboard_t *kbd = (keyboard_t *)addr; kbd_intr(kbd, (void *)status); }
void i386_init(void) { extern char edata[], end[]; // Before doing anything else, complete the ELF loading process. // Clear the uninitialized global data (BSS) section of our program. // This ensures that all static/global variables start out zero. memset(edata, 0, end - edata); // Initialize the console. // Can't call cprintf until after we do this! cons_init(); cprintf("6828 decimal is %o octal!\n", 6828); // Lab 2 memory management initialization functions i386_detect_memory(); i386_vm_init(); page_init(); page_check(); // Lab 3 user environment initialization functions env_init(); idt_init(); // Lab 4 multitasking initialization functions pic_init(); kclock_init(); // Should always have an idle process as first one. ENV_CREATE(user_idle); // Start fs. ENV_CREATE(fs_fs); ENV_CREATE(user_icode); #if defined(TEST) // Don't touch -- used by grading script! ENV_CREATE2(TEST, TESTSIZE) #else // Touch all you want. // ENV_CREATE(user_icode); // ENV_CREATE(user_pipereadeof); // ENV_CREATE(user_pipewriteeof); // ENV_CREATE(user_testpipe); // ENV_CREATE(user_primespipe); // ENV_CREATE(user_testpiperace); // ENV_CREATE(user_testpiperace2); // ENV_CREATE(user_testfdsharing); #endif // TEST* // Should not be necessary - drain keyboard because interrupt has given up. kbd_intr(); // Schedule and run the first user environment! sched_yield(); }
void i386_init(void) { extern char edata[], end[]; // Before doing anything else, complete the ELF loading process. // Clear the uninitialized global data (BSS) section of our program. // This ensures that all static/global variables start out zero. memset(edata, 0, end - edata); // Initialize the console. // Can't call cprintf until after we do this! cons_init(); cprintf("6828 decimal is %o octal!\n", 6828); // Lab 2 memory management initialization functions mem_init(); // Lab 3 user environment initialization functions env_init(); trap_init(); // Lab 4 multiprocessor initialization functions mp_init(); lapic_init(); // Lab 4 multitasking initialization functions pic_init(); // Acquire the big kernel lock before waking up APs // Your code here: lock_kernel(); // Starting non-boot CPUs boot_aps(); // Start fs. ENV_CREATE(fs_fs, ENV_TYPE_FS); #if defined(TEST) // Don't touch -- used by grading script! ENV_CREATE(TEST, ENV_TYPE_USER); #else // Touch all you want. //<<<<<<< HEAD ENV_CREATE(user_icode, ENV_TYPE_USER); //======= // ENV_CREATE(user_dumbfork, ENV_TYPE_USER); //>>>>>>> lab4 #endif // TEST* // Should not be necessary - drains keyboard because interrupt has given up. kbd_intr(); // Schedule and run the first user environment! sched_yield(); }
static void ukbd_timeout(void *arg) { keyboard_t *kbd; ukbd_state_t *state; kbd = (keyboard_t *)arg; state = (ukbd_state_t *)kbd->kb_data; crit_enter(); kbd_intr(kbd, (void *)USBD_NORMAL_COMPLETION); callout_reset(&state->ks_timeout, hz / 40, ukbd_timeout, arg); crit_exit(); }
static void trap_dispatch(struct Trapframe *tf) { // Handle processor exceptions. // LAB 3: Your code here. switch (tf->tf_trapno) { case T_PGFLT: page_fault_handler(tf); return; case T_BRKPT: monitor(tf); return; case T_SYSCALL: tf->tf_regs.reg_eax = syscall(tf->tf_regs.reg_eax, tf->tf_regs.reg_edx, tf->tf_regs.reg_ecx, tf->tf_regs.reg_ebx, tf->tf_regs.reg_edi, tf->tf_regs.reg_esi); return; } // Handle clock and serial interrupts. // LAB 4: Your code here. if (tf->tf_trapno == IRQ_OFFSET+IRQ_TIMER) { if(tf->tf_cs == GD_KT) { return; } else { sched_yield(); return; } } // Handle keyboard interrupts. // LAB 5: Your code here. if (tf->tf_trapno == IRQ_OFFSET+IRQ_KBD) { kbd_intr(); return; } // Unexpected trap: The user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } }
void trap(struct Trapframe *tf) { int ret; // Handle processor exceptions // Your code here. switch(tf->tf_trapno) { case T_BRKPT: while(1) monitor(NULL); break; case T_PGFLT: page_fault_handler(tf); tf->tf_eflags |= FL_IF; //env_pop_tf(tf); memcpy(&curenv->env_tf, tf, sizeof(*tf)); env_run(curenv); return; case T_SYSCALL: ret = syscall(tf->tf_eax, tf->tf_edx, tf->tf_ecx, tf->tf_ebx, tf->tf_edi, tf->tf_esi); tf->tf_eax = ret; tf->tf_eflags |= FL_IF; // env_pop_tf(tf); memcpy(&curenv->env_tf, tf, sizeof(*tf)); env_run(curenv); case IRQ_OFFSET: sched_yield(); break; case IRQ_KBD: kbd_intr(); memcpy(&curenv->env_tf, tf, sizeof(*tf)); env_run(curenv); break; default: break; } // the user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } }
static void atkbd_timeout(void *arg) { keyboard_t *kbd; /* * The original text of the following comments are extracted * from syscons.c (1.287) * * With release 2.1 of the Xaccel server, the keyboard is left * hanging pretty often. Apparently an interrupt from the * keyboard is lost, and I don't know why (yet). * This ugly hack calls the low-level interrupt routine if input * is ready for the keyboard and conveniently hides the problem. XXX * * Try removing anything stuck in the keyboard controller; whether * it's a keyboard scan code or mouse data. The low-level * interrupt routine doesn't read the mouse data directly, * but the keyboard controller driver will, as a side effect. */ /* * And here is bde's original comment about this: * * This is necessary to handle edge triggered interrupts - if we * returned when our IRQ is high due to unserviced input, then there * would be no more keyboard IRQs until the keyboard is reset by * external powers. * * The keyboard apparently unwedges the irq in most cases. */ crit_enter(); kbd = (keyboard_t *)arg; if (kbd_lock(kbd, TRUE)) { /* * We have seen the lock flag is not set. Let's reset * the flag early, otherwise the LED update routine fails * which may want the lock during the interrupt routine. */ kbd_lock(kbd, FALSE); if (kbd_check_char(kbd)) kbd_intr(kbd, NULL); } callout_reset(&kbd->kb_atkbd_timeout_ch, hz / 10, atkbd_timeout, arg); crit_exit(); }
// return the next input character from the console, or 0 if none waiting int cons_getc(void) { int c; // poll for any pending input characters, // so that this function works even when interrupts are disabled // (e.g., when called from the kernel monitor). kbd_intr(); //cprintf("TEST:rpos %d wpos %d\n", cons.rpos, cons.wpos); // grab the next character from the input buffer. if (cons.rpos != cons.wpos) { c = cons.buf[cons.rpos++]; if (cons.rpos == CONSBUFSIZE) cons.rpos = 0; return c; }//if return 0; }//cons_getc()
// return the next input character from the console, or 0 if none waiting static int cons_getc(void) { int c; // poll for any pending input characters, // so that this function works even when interrupts are disabled // (e.g., when called from the kernel monitor). //serial_intr(); kbd_intr(); // grab the next character from the input buffer. if(cons.rpos != cons.wpos) { c = cons.buf[cons.rpos++]; if(CONSBUFSIZE == cons.rpos) cons.rpos = 0; return c; } return 0; }
/* * * cons_getc - return the next input character from console, * or 0 if none waiting. * */ int cons_getc(void) { int c = 0; unsigned long intr_flag; local_irq_save(intr_flag); { // poll for any pending input characters, // so that this function works even when interrupts are disabled // (e.g., when called from the kernel monitor). serial_intr(); kbd_intr(); // grab the next character from the input buffer. if (cons.rpos != cons.wpos) { c = cons.buf[cons.rpos ++]; if (cons.rpos == CONSBUFSIZE) { cons.rpos = 0; } } } local_irq_restore(intr_flag); return c; }
static void trap_dispatch(struct Trapframe *tf) { // Handle processor exceptions. // LAB 3: Your code here. int32_t ret; switch (tf->tf_trapno){ case T_PGFLT:{ //14 page_fault_handler(tf); return; } case T_BRKPT:{ //3 breakpoint_handler(tf); return; } case T_DEBUG:{ breakpoint_handler(tf); return; } case T_SYSCALL:{ ret = system_call_handler(tf); tf->tf_regs.reg_eax = ret; return; } case IRQ_OFFSET+IRQ_TIMER:{ lapic_eoi(); time_tick(); sched_yield(); return; } case IRQ_OFFSET+IRQ_KBD:{ kbd_intr(); return; } case IRQ_OFFSET+IRQ_SERIAL:{ serial_intr(); return; } case IRQ_OFFSET+IRQ_E1000:{ e1000_trap_handler(); return; } } // Handle spurious interrupts // The hardware sometimes raises these because of noise on the // IRQ line or other reasons. We don't care. if (tf->tf_trapno == IRQ_OFFSET + IRQ_SPURIOUS) { cprintf("Spurious interrupt on irq 7\n"); print_trapframe(tf); return; } // Handle clock interrupts. Don't forget to acknowledge the // interrupt using lapic_eoi() before calling the scheduler! // LAB 4: Your code here. // Add time tick increment to clock interrupts. // Be careful! In multiprocessors, clock interrupts are // triggered on every CPU. // LAB 6: Your code here. // Handle keyboard and serial interrupts. // LAB 5: Your code here. // Unexpected trap: The user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } }
static void trap_dispatch(struct Trapframe *tf) { static int page_to_age = 0; int page_to_age_first = page_to_age; int num_page_updates = NPAGEUPDATES_FACTOR*NPAGESFREE_LOW_THRESHOLD; struct PteChain *pp_refs_chain; char page_accessed; // Handle processor exceptions. // LAB 3: Your code here. if (tf->tf_trapno == T_PGFLT) { page_fault_handler(tf); return; } else if (tf->tf_trapno == T_BRKPT) { monitor(tf); // breakpoint exceptions invoke the kernel monitor return; } else if (tf->tf_trapno == T_SYSCALL) { tf->tf_regs.reg_eax = syscall(tf->tf_regs.reg_eax, tf->tf_regs.reg_edx, tf->tf_regs.reg_ecx, tf->tf_regs.reg_ebx, tf->tf_regs.reg_edi, tf->tf_regs.reg_esi); return; } // Handle spurious interrupts // The hardware sometimes raises these because of noise on the // IRQ line or other reasons. We don't care. if (tf->tf_trapno == IRQ_OFFSET + IRQ_SPURIOUS) { cprintf("Spurious interrupt on irq 7\n"); print_trapframe(tf); return; } // Handle clock interrupts. Don't forget to acknowledge the // interrupt using lapic_eoi() before calling the scheduler! // LAB 4: Your code here. if (tf->tf_trapno == IRQ_OFFSET + IRQ_TIMER) { lapic_eoi(); // Update the age of some physical pages // If we fall below the thresholds, update more pages than usual // This is somewhat arbitrary, we can tweak these numbers // We also might want to increase the order of magnitude of the number of pages we update per clock tick // This will require some testing and profiling // There is also no reason why num_page_updates is based on the threshold values, it can be incremented by its own macros if (num_free_pages <= NPAGESFREE_LOW_THRESHOLD) { num_page_updates += NPAGEUPDATES_FACTOR*NPAGESFREE_HIGH_THRESHOLD; } if (num_free_pages <= NPAGESFREE_HIGH_THRESHOLD) { num_page_updates += NPAGEUPDATES_FACTOR*NPAGESFREE_LOW_THRESHOLD; } for ( ; num_page_updates >= 0; --num_page_updates) { // Find the next page that is currently mapped in user space, by finding one with a nonzero pp_ref while (!pages[page_to_age].pp_ref) { // If we wrap around to where we started, stop updating page ages if ((page_to_age=(page_to_age+1)%npages) == page_to_age_first) { goto end_of_page_age_updates; } } // Iterate through all of the user space PTEs that map to this page // If any of them have been accessed, increment the age, and then clear the PTE_A bit in all of the PTEs page_accessed = 0; for (pp_refs_chain = pages[page_to_age].pp_refs_chain; pp_refs_chain; pp_refs_chain = pp_refs_chain->pc_link) { if (*pp_refs_chain->pc_pte & PTE_A) { page_accessed = 1; pages[page_to_age].age += PAGE_AGE_INCREMENT_ON_ACCESS; for ( ; pp_refs_chain; pp_refs_chain = pp_refs_chain->pc_link) { *(pp_refs_chain->pc_pte) &= ~PTE_A; } break; } } pages[page_to_age].age = (pages[page_to_age].age > MAX_PAGE_AGE ? MAX_PAGE_AGE : pages[page_to_age].age); if (!page_accessed) { if (pages[page_to_age].age >= (uint8_t)PAGE_AGE_DECREMENT_ON_CLOCK) { pages[page_to_age].age -= (uint8_t)PAGE_AGE_DECREMENT_ON_CLOCK; } else { pages[page_to_age].age = 0; } } // If we wrap around to where we started, stop updating page ages if ((page_to_age=(page_to_age+1)%npages) == page_to_age_first) { goto end_of_page_age_updates; } } end_of_page_age_updates: sched_yield(); } // Handle keyboard and serial interrupts. // LAB 5: Your code here. if (tf->tf_trapno == IRQ_OFFSET + IRQ_KBD) { lapic_eoi(); kbd_intr(); return; } if (tf->tf_trapno == IRQ_OFFSET + IRQ_SERIAL) { lapic_eoi(); serial_intr(); return; } // Unexpected trap: The user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } }
static void trap_dispatch(struct Trapframe *tf) { int32_t res; // Handle processor exceptions. // LAB 3: Your code here. // Handle spurious interrupts // The hardware sometimes raises these because of noise on the // IRQ line or other reasons. We don't care. if (tf->tf_trapno == IRQ_OFFSET + IRQ_SPURIOUS) { cprintf("Spurious interrupt on irq 7\n"); print_trapframe(tf); return; } // Handle clock interrupts. Don't forget to acknowledge the // interrupt using lapic_eoi() before calling the scheduler! // LAB 4: Your code here. // Add time tick increment to clock interrupts. // Be careful! In multiprocessors, clock interrupts are // triggered on every CPU. // LAB 6: Your code here. // Handle keyboard and serial interrupts. // LAB 5: Your code here. //if(tf->tf_trapno == 48 && tf->tf_regs.reg_eax==7) //{ //cprintf("trap no = %d at cpu %d env %x\n",tf->tf_trapno,cpunum(),curenv->env_id); //print_trapframe(tf); //} switch(tf->tf_trapno) { case IRQ_OFFSET + IRQ_TIMER: //cprintf("clock interrupt on irq 7 on cpu %d\n",cpunum()); //print_trapframe(tf); //cprintf(" eip 0x%08x\n", tf->tf_eip); //cprintf(" esp 0x%08x\n", tf->tf_esp); lapic_eoi(); time_tick(); sched_yield(); break; case IRQ_OFFSET + IRQ_SERIAL: serial_intr(); break; case IRQ_OFFSET + IRQ_KBD: kbd_intr(); break; case T_DIVIDE: tf->tf_regs.reg_ecx = 1; break; case T_PGFLT: page_fault_handler(tf); goto err; case T_SYSCALL: res = syscall(tf->tf_regs.reg_eax,tf->tf_regs.reg_edx,tf->tf_regs.reg_ecx,tf->tf_regs.reg_ebx,tf->tf_regs.reg_edi,tf->tf_regs.reg_esi); tf->tf_regs.reg_eax = res; break; case T_BRKPT:print_trapframe(tf);monitor(NULL);break; default: goto err; } return; err: // Unexpected trap: The user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } }
static void trap_dispatch(struct Trapframe *tf) { // Handle processor exceptions. // LAB 3: Your code here. // TODO: chky int r; switch (tf->tf_trapno) { case T_PGFLT: page_fault_handler(tf); break; case T_BRKPT: // TODO: lab3 ex6 challenge monitor(tf); break; case T_SYSCALL: r = syscall(tf->tf_regs.reg_eax, // syscallno tf->tf_regs.reg_edx, // a1 tf->tf_regs.reg_ecx, // a2 tf->tf_regs.reg_ebx, // a3 tf->tf_regs.reg_edi, // a4 tf->tf_regs.reg_esi // a5 ); tf->tf_regs.reg_eax = r; return; default: break; } // Handle spurious interrupts // The hardware sometimes raises these because of noise on the // IRQ line or other reasons. We don't care. if (tf->tf_trapno == IRQ_OFFSET + IRQ_SPURIOUS) { cprintf("Spurious interrupt on irq 7\n"); print_trapframe(tf); return; } // Handle clock interrupts. Don't forget to acknowledge the // interrupt using lapic_eoi() before calling the scheduler! // LAB 4: Your code here. // TODO: chky if (tf->tf_trapno == IRQ_OFFSET + IRQ_TIMER) { lapic_eoi(); sched_yield(); return; } // chky end // Handle keyboard and serial interrupts. // LAB 5: Your code here. // TODO: chky if (tf->tf_trapno == IRQ_OFFSET + IRQ_KBD) { kbd_intr(); return; } if (tf->tf_trapno == IRQ_OFFSET + IRQ_SERIAL) { serial_intr(); return; } // chky end // Unexpected trap: The user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } }
void i386_init(uint32_t memsize) { extern char etext[],edata[], end[]; // Before doing anything else, complete the ELF loading process. // Clear the uninitialized global data (BSS) section of our program. // This ensures that all static/global variables start out zero. /* * From http://en.wikipedia.org/wiki/.bss * In computer programming * .bss or bss (Block Started by Symbol) is used by many compilers and linkers * as the name of the data segment containing static variables * that are filled solely with zero-valued data initially * (i. e., when execution begins). * It is often referred to as the "bss section" or "bss segment". * The program loader initializes the memory allocated for the bss section * when it loads the program. */ memset(edata, 0, end - edata); // Initialize the console. // Can't call cprintf until after we do this! cons_init(); cprintf("6828 decimal is %o octal!\n", 6828); cprintf("etext:%08x,edata:%08x,end:%08x\n",etext,edata,end); // Lab 2 memory management initialization functions i386_detect_memory(memsize); i386_vm_init(); // Lab 3 user environment initialization functions env_init(); idt_init(); // Lab 4 multitasking initialization functions pic_init(); kclock_init(); // Should always have an idle process as first one. ENV_CREATE(user_idle); // Start fs. ENV_CREATE(fs_fs); // Start init #if defined(TEST) // Don't touch -- used by grading script! ENV_CREATE2(TEST, TESTSIZE); #else // Touch all you want. ENV_CREATE(user_fairness); //ENV_CREATE(user_pipereadeof); // ENV_CREATE(user_pipewriteeof); #endif // Should not be necessary - drain keyboard because interrupt has given up. kbd_intr(); //while(login() != 0) // continue; // Schedule and run the first user environment! sched_yield(); }
void i386_init(void) { extern char edata[], end[]; // Before doing anything else, complete the ELF loading process. // Clear the uninitialized global data (BSS) section of our program. // This ensures that all static/global variables start out zero. memset(edata, 0, end - edata); // Initialize the console. // Can't call cprintf until after we do this! cons_init(); // Lab 2 memory management initialization functions mem_init(); // Lab 3 user environment initialization functions env_init(); trap_init(); // Lab 4 multiprocessor initialization functions mp_init(); lapic_init(); // Lab 4 multitasking initialization functions pic_init(); // Lab 6 hardware initialization functions time_init(); pci_init(); // Acquire the big kernel lock before waking up APs // Your code here: lock_kernel(); // Starting non-boot CPUs boot_aps(); // Should always have idle processes at first. int i; for (i = 0; i < NCPU; i++) ENV_CREATE(user_idle, ENV_TYPE_IDLE); // Start fs. ENV_CREATE(fs_fs, ENV_TYPE_FS); #if !defined(TEST_NO_NS) // Start ns. ENV_CREATE(net_ns, ENV_TYPE_NS); #endif #if defined(TEST) // Don't touch -- used by grading script! ENV_CREATE(TEST, ENV_TYPE_USER); #else // Touch all you want. ENV_CREATE(user_icode, ENV_TYPE_USER); #endif // TEST* // Should not be necessary - drains keyboard because interrupt has given up. kbd_intr(); // Schedule and run the first user environment! sched_yield(); }
static void trap_dispatch(struct Trapframe *tf) { //cprintf("[%08x] user fault va %08x ip %08x\n", // curenv->env_id, fault_va, tf->tf_eip); //cprintf("now:%x\n",tf->tf_cs); // Handle processor exceptions. // LAB 3: Your code here. // Handle spurious interrupts // The hardware sometimes raises these because of noise on the // IRQ line or other reasons. We don't care. if (tf->tf_trapno == IRQ_OFFSET + IRQ_SPURIOUS) { cprintf("Spurious interrupt on irq 7\n"); print_trapframe(tf); return; } // Handle clock interrupts. Don't forget to acknowledge the // interrupt using lapic_eoi() before calling the scheduler! // LAB 4: Your code here. if (tf->tf_trapno == IRQ_OFFSET+IRQ_TIMER) { lapic_eoi(); sched_yield(); return; } // Handle keyboard and serial interrupts. // LAB 5: Your code here. if (tf->tf_trapno == IRQ_OFFSET + IRQ_SERIAL) { serial_intr(); return; } if (tf->tf_trapno == IRQ_OFFSET + IRQ_KBD) { kbd_intr(); return; } // Unexpected trap: The user process or the kernel has a bug. //Check for fault in kernel mode if (tf->tf_trapno == T_SYSCALL) { tf->tf_regs.reg_eax = syscall(tf->tf_regs.reg_eax, tf->tf_regs.reg_edx, tf->tf_regs.reg_ecx, tf->tf_regs.reg_ebx, tf->tf_regs.reg_edi, tf->tf_regs.reg_esi); return; } if (tf->tf_trapno == T_PGFLT) page_fault_handler(tf); if (tf->tf_trapno == T_BRKPT) monitor(tf); print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } }
static void kbd_init(void) { // drain the kbd buffer kbd_intr(); intr_umask(IRQ_KBD); }
static void kbd_init(void) { // drain the kbd buffer kbd_intr(); pic_enable(IRQ_KBD); }
static void trap_dispatch(struct Trapframe *tf) { uint32_t temp; // Switch on the trap number switch(tf->tf_trapno) { case T_DEBUG: // Unset the step flag in EFLAGS before entering the monitor tf->tf_eflags &= ~FL_TF; case T_BRKPT: // Use breakpoints and debug interrupts as a shortcut to // start the kernel monitor monitor(tf); return; case T_PGFLT: // Handle page faults with their own handler. page_fault_handler(tf); return; case T_SYSCALL: // For system calls, pass arguments to the syscall handler // and return the result in register EAX. // // The number must be stored away, and tf->tf_regs.reg_eax // set to 0 before the call. This is because some system // calls such as sys_ipc_recv don't return (due to a call to // sched_yield()), but expect to return 0 for the return value. // If reg_eax is not cleared, then whatever is in it might be // mistaken for the return value. -_- temp = tf->tf_regs.reg_eax; tf->tf_regs.reg_eax = 0; tf->tf_regs.reg_eax = syscall(temp, tf->tf_regs.reg_edx, tf->tf_regs.reg_ecx, tf->tf_regs.reg_ebx, tf->tf_regs.reg_edi, tf->tf_regs.reg_esi); return; } // Handle spurious interrupts // The hardware sometimes raises these because of noise on the // IRQ line or other reasons. We don't care. if (tf->tf_trapno == IRQ_OFFSET + IRQ_SPURIOUS) { cprintf("Spurious interrupt on irq 7\n"); print_trapframe(tf); return; } // Handle clock interrupts. Don't forget to acknowledge the // interrupt using lapic_eoi() before calling the scheduler! if(tf->tf_trapno == IRQ_OFFSET+IRQ_TIMER) { // Timer interrupts should cause the scheduler to be run lapic_eoi(); sched_yield(); } // Handle keyboard and serial interrupts. if(tf->tf_trapno == IRQ_OFFSET+IRQ_KBD) { // kern/console.c function that handles the keyboard kbd_intr(); return; } if(tf->tf_trapno == IRQ_OFFSET+IRQ_SERIAL) { // kern/console.c function that handles serial input serial_intr(); return; } // Unexpected trap: The user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } }
static void trap_dispatch(struct Trapframe *tf) { // Handle processor exceptions. // LAB 3: Your code here. //<<<<<<< HEAD // Handle spurious interrupts // The hardware sometimes raises these because of noise on the // IRQ line or other reasons. We don't care. if (tf->tf_trapno == IRQ_OFFSET + IRQ_SPURIOUS) { cprintf("Spurious interrupt on irq 7\n"); print_trapframe(tf); return; } //cprintf("entering trap dispathc\n"); // Handle clock interrupts. Don't forget to acknowledge the // interrupt using lapic_eoi() before calling the scheduler! // LAB 4: Your code here. //<<<<<<< HEAD // Add time tick increment to clock interrupts. // Be careful! In multiprocessors, clock interrupts are // triggered on every CPU. // LAB 6: Your code here. //======= //<<<<<<< HEAD //>>>>>>> lab5 // Handle keyboard and serial interrupts. // LAB 5: Your code here. if(tf->tf_trapno==IRQ_OFFSET+IRQ_KBD) { //cprintf("IRQ_OFFSET+IRQ_KBD trap\n"); kbd_intr(); return; } if(tf->tf_trapno==IRQ_OFFSET+IRQ_SERIAL) { //cprintf("IRQ_OFFSET+IRQ_serial trap\n"); serial_intr(); return; } //======= //======= if(tf->tf_trapno==T_PGFLT) { // cprintf("pagefault handler\n"); page_fault_handler(tf); return; } else if((tf->tf_trapno==T_GPFLT)) { print_trapframe(tf); return; } else if(tf->tf_trapno==T_BRKPT) { // cprintf("T_BRKPT"); monitor(tf); return; } else if(tf->tf_trapno==T_SYSCALL) {// cprintf("calling syscal'\n"); tf->tf_regs.reg_rax =syscall(tf->tf_regs.reg_rax,tf->tf_regs.reg_rdx,tf->tf_regs.reg_rcx,tf->tf_regs.reg_rbx,tf->tf_regs.reg_rdi,tf->tf_regs.reg_rsi); // cprintf("syscall exit\n"); return; } //>>>>>>> lab3 //>>>>>>> lab4 // Unexpected trap: The user process or the kernel has a bug. else if(tf->tf_trapno == IRQ_OFFSET + IRQ_TIMER) { lapic_eoi(); time_tick(); sched_yield(); } print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { cprintf("destroy env\n"); env_destroy(curenv); return; } // cprintf("exiting trap_dispatch\n"); }
void i386_init(void) { /* __asm __volatile("int $12"); */ extern char edata[], end[]; int num = 0, res; // Before doing anything else, complete the ELF loading process. // Clear the uninitialized global data (BSS) section of our program. // This ensures that all static/global variables start out zero. memset(edata, 0, end - edata); // Initialize the console. // Can't call cprintf until after we do this! cons_init(); cprintf("6828 decimal is %o octal!\n", 6828); #ifdef VMM_GUEST /* Guest VMX extension exposure check */ { uint32_t ecx = 0; cpuid(0x1, NULL, NULL, &ecx, NULL); if (ecx & 0x20) panic("[ERR] VMX extension exposed to guest.\n"); else cprintf("VMX extension hidden from guest.\n"); } #endif #ifndef VMM_GUEST extern char end[]; end_debug = read_section_headers((0x10000+KERNBASE), (uintptr_t)end); #endif // Lab 2 memory management initialization functions x64_vm_init(); // Lab 3 user environment initialization functions env_init(); trap_init(); //test_traps(); #ifndef VMM_GUEST // Lab 4 multiprocessor initialization functions mp_init(); lapic_init(); #endif // Lab 4 multitasking initialization functions pic_init(); // Lab 6 hardware initialization functions time_init(); pci_init(); // Acquire the big kernel lock before waking up APs // Your code here: #ifndef VMM_GUEST // Starting non-boot CPUs //boot_aps(); #endif // Should always have idle processes at first. int i; for (i = 0; i < NCPU; i++) ENV_CREATE(user_idle, ENV_TYPE_IDLE); // Start fs. ENV_CREATE(fs_fs, ENV_TYPE_FS); ENV_CREATE(net_ns, ENV_TYPE_NS); //ENV_CREATE(user_testfile, ENV_TYPE_USER); #if defined(TEST) // Don't touch -- used by grading script! ENV_CREATE(TEST, ENV_TYPE_USER); #else // Touch all you want. #if defined(TEST_EPT_MAP) test_ept_map(); #endif //ENV_CREATE(user_httpd, ENV_TYPE_USER); ENV_CREATE(user_icode, ENV_TYPE_USER); //ENV_CREATE(user_forktree, ENV_TYPE_USER); //ENV_CREATE(user_buggyhello, ENV_TYPE_USER); #endif // TEST* // Should not be necessary - drains keyboard because interrupt has given up. kbd_intr(); cprintf("Running first environment"); // Schedule and run the first user environment! sched_yield(); }
static void trap_dispatch(struct Trapframe *tf) { // Handle processor exceptions. // LAB 3: Your code here. if (tf->tf_trapno == T_BRKPT) { print_trapframe(tf); // cprintf("Breakpoint!\n"); while (1) monitor(NULL); } else if (tf->tf_trapno == T_PGFLT) { page_fault_handler(tf); return; } else if (tf->tf_trapno == T_SYSCALL) { uint32_t syscallno; uint32_t a1, a2, a3, a4, a5; syscallno = tf->tf_regs.reg_eax; a1 = tf->tf_regs.reg_edx; a2 = tf->tf_regs.reg_ecx; a3 = tf->tf_regs.reg_ebx; a4 = tf->tf_regs.reg_edi; a5 = tf->tf_regs.reg_esi; int32_t ret = syscall(syscallno, a1, a2, a3, a4, a5); tf->tf_regs.reg_eax = ret; return; } // Handle spurious interrupts // The hardware sometimes raises these because of noise on the // IRQ line or other reasons. We don't care. if (tf->tf_trapno == IRQ_OFFSET + IRQ_SPURIOUS) { cprintf("Spurious interrupt on irq 7\n"); print_trapframe(tf); return; } // Handle clock interrupts. Don't forget to acknowledge the // interrupt using lapic_eoi() before calling the scheduler! // LAB 4: Your code here. if (tf->tf_trapno == IRQ_OFFSET + IRQ_TIMER) { time_tick(); lapic_eoi(); /* what's that? */ sched_yield(); } // Handle keyboard and serial interrupts. // LAB 5: Your code here. if (tf->tf_trapno == IRQ_OFFSET + IRQ_KBD) { kbd_intr(); return; } if (tf->tf_trapno == IRQ_OFFSET + IRQ_SERIAL) { serial_intr(); return; } // Unexpected trap: The user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } }
static void trap_dispatch(struct Trapframe *tf) { // Handle processor exceptions. // LAB 3: Your code here. int32_t ret; // if (tf->tf_trapno != 48) cprintf("****** No. %d\n", tf->tf_trapno); // Handle clock interrupts. // LAB 4: Your code here. if (tf->tf_trapno == IRQ_OFFSET + 0){ // cprintf("Timer interrupt\n"); time_tick(); sched_yield(); return ; } // Add time tick increment to clock interrupts. // LAB 6: Your code here. // Add time_tick above sched_yield // Handle spurious interrupts // The hardware sometimes raises these because of noise on the // IRQ line or other reasons. We don't care. if (tf->tf_trapno == IRQ_OFFSET + IRQ_SPURIOUS) { cprintf("Spurious interrupt on irq 7\n"); print_trapframe(tf); return; } // LAB 7: Keyboard interface if (tf->tf_trapno == IRQ_OFFSET + 1){ kbd_intr(); return ; } if (tf->tf_trapno == IRQ_OFFSET + 4){ serial_intr(); return ; } if (tf->tf_trapno == T_DIVIDE || tf->tf_trapno == T_ILLOP || tf->tf_trapno == T_GPFLT){ // cprintf("*************"); // return ; } if (tf->tf_trapno == T_DEBUG){ // Debug info // cprintf("*** trap %08x %s ***\n", tf->tf_trapno, trapname(tf->tf_trapno)); // Invoke monitor monitor(tf); return ; } if (tf->tf_trapno == T_BRKPT){ // Debug info // cprintf("*** trap %08x %s ***\n", tf->tf_trapno, trapname(tf->tf_trapno)); // Invoke monitor monitor(tf); return ; } if (tf->tf_trapno == T_PGFLT){ page_fault_handler(tf); } if (tf->tf_trapno == T_SYSCALL){ ret = syscall(tf->tf_regs.reg_eax, tf->tf_regs.reg_edx, tf->tf_regs.reg_ecx, tf->tf_regs.reg_ebx, tf->tf_regs.reg_edi, tf->tf_regs.reg_esi); tf->tf_regs.reg_eax = ret; return ; } // Handle keyboard and serial interrupts. // LAB 7: Your code here. // Unexpected trap: The user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT){ if (tf->tf_trapno == T_DEBUG){ return ; } panic("unhandled trap in kernel"); } else { env_destroy(curenv); return; } }
void trap(struct trapframe *tf) { int v = tf->trapno; struct proc *cp = curproc[cpu()]; if(v == T_SYSCALL){ if(cp->killed) proc_exit(); cp->tf = tf; syscall(); if(cp->killed) proc_exit(); return; } // Increment nlock to make sure interrupts stay off // during interrupt handler. Decrement before returning. cpus[cpu()].nlock++; switch(v){ case IRQ_OFFSET + IRQ_TIMER: lapic_timerintr(); cpus[cpu()].nlock--; if(cp){ // Force process exit if it has been killed and is in user space. // (If it is still executing in the kernel, let it keep running // until it gets to the regular system call return.) if((tf->cs&3) == 3 && cp->killed) proc_exit(); // Force process to give up CPU and let others run. if(cp->state == RUNNING) yield(); } return; case IRQ_OFFSET + IRQ_IDE: ide_intr(); lapic_eoi(); break; case IRQ_OFFSET + IRQ_KBD: kbd_intr(); lapic_eoi(); break; case IRQ_OFFSET + IRQ_SPURIOUS: cprintf("spurious interrupt from cpu %d eip %x\n", cpu(), tf->eip); break; default: if(curproc[cpu()]) { // Assume process divided by zero or dereferenced null, etc. cprintf("pid %d: unhandled trap %d on cpu %d eip %x -- kill proc\n", curproc[cpu()]->pid, v, cpu(), tf->eip); proc_exit(); } // Otherwise it's our mistake. cprintf("unexpected trap %d from cpu %d eip %x\n", v, cpu(), tf->eip); panic("trap"); } cpus[cpu()].nlock--; }
void trap(struct trapframe *tf) { if(tf->trapno == T_SYSCALL){ if(cp->killed) exit(); cp->tf = tf; syscall(); if(cp->killed) exit(); return; } switch(tf->trapno){ case IRQ_OFFSET + IRQ_TIMER: if(cpu() == 0){ acquire(&tickslock); ticks++; wakeup(&ticks); release(&tickslock); } lapic_eoi(); break; case IRQ_OFFSET + IRQ_IDE: ide_intr(); lapic_eoi(); break; case IRQ_OFFSET + IRQ_KBD: kbd_intr(); lapic_eoi(); break; case IRQ_OFFSET + IRQ_SPURIOUS: cprintf("cpu%d: spurious interrupt at %x:%x\n", cpu(), tf->cs, tf->eip); lapic_eoi(); break; default: if(cp == 0 || (tf->cs&3) == 0){ // In kernel, it must be our mistake. cprintf("unexpected trap %d from cpu %d eip %x\n", tf->trapno, cpu(), tf->eip); panic("trap"); } // In user space, assume process misbehaved. cprintf("pid %d %s: trap %d err %d on cpu %d eip %x -- kill proc\n", cp->pid, cp->name, tf->trapno, tf->err, cpu(), tf->eip); cp->killed = 1; } // Force process exit if it has been killed and is in user space. // (If it is still executing in the kernel, let it keep running // until it gets to the regular system call return.) if(cp && cp->killed && (tf->cs&3) == DPL_USER) exit(); // Force process to give up CPU on clock tick. // If interrupts were on while locks held, would need to check nlock. if(cp && cp->state == RUNNING && tf->trapno == IRQ_OFFSET+IRQ_TIMER) yield(); }
static void trap_dispatch(struct Trapframe *tf) { // Handle processor exceptions. // LAB 3: Your code here. switch(tf->tf_trapno) { case T_PGFLT: page_fault_handler(tf); return; case T_BRKPT: case T_DEBUG: monitor(tf); return; case T_SYSCALL: tf->tf_regs.reg_eax = syscall(tf->tf_regs.reg_eax, // syscall # tf->tf_regs.reg_edx, // arg1 tf->tf_regs.reg_ecx, // arg2 tf->tf_regs.reg_ebx, // arg3 tf->tf_regs.reg_edi, // arg4 tf->tf_regs.reg_esi);// arg5 return; } // Handle spurious interrupts // The hardware sometimes raises these because of noise on the // IRQ line or other reasons. We don't care. if (tf->tf_trapno == IRQ_OFFSET + IRQ_SPURIOUS) { cprintf("Spurious interrupt on irq 7\n"); print_trapframe(tf); return; } // Handle clock interrupts. Don't forget to acknowledge the // interrupt using lapic_eoi() before calling the scheduler! // Add time tick increment to clock interrupts. // Be careful! In multiprocessors, clock interrupts are // triggered on every CPU. // LAB 4: Your code here. // LAB 6: Your code here. if (tf->tf_trapno == IRQ_OFFSET + IRQ_TIMER) { time_tick(); lapic_eoi(); sched_yield(); return; } // Handle keyboard and serial interrupts. // LAB 7: Your code here. if (tf->tf_trapno == IRQ_OFFSET + IRQ_SERIAL) { serial_intr(); return; } if (tf->tf_trapno == IRQ_OFFSET + IRQ_KBD) { kbd_intr(); return; } // Unexpected trap: The user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } }
void trap(struct trapframe *tf) { uint cr2; //print_trapframe(tf); procdump(); //chy for debug if (cp!=NULL) dbmsg("trap frame from %x %x, cp name %s\n",tf->eip, tf->trapno,cp->name); if(tf->trapno == T_SYSCALL){ if(cp->killed) exit(); cp->tf = tf; syscall(); if(cp->killed) exit(); return; } switch(tf->trapno){ cprintf("interrupt %x, trap frame : %x\n",tf->trapno, (uint)tf); case IRQ_OFFSET + IRQ_TIMER: // if(cpu() == 0){ acquire(&tickslock); ticks++; wakeup(&ticks); release(&tickslock); // } lapic_eoi(); break; case IRQ_OFFSET + IRQ_IDE: ide_intr(); lapic_eoi(); break; case IRQ_OFFSET + IRQ_KBD: kbd_intr(); lapic_eoi(); break; case IRQ_OFFSET + IRQ_SPURIOUS: cprintf("cpu%d: spurious interrupt at %x:%x\n", cpu(), tf->cs, tf->eip); lapic_eoi(); break; case T_PGFLT: cprintf("page fault!\n"); //cprintf("current process uses %d pages.\n", cp->sz/PAGE); cr2=rcr2(); if(handle_pgfault(cr2)<0){ cprintf("cannot handle page fault! Virtual addr: %x, eip: %x\n", cr2, tf->eip); }else{ cprintf("page fault handled successfully! Virtual addr: %x, eip: %x\n", cr2, tf->eip); } //cprintf("current process uses %d pages.\n", cp->sz/PAGE); break; default: if(cp == 0 || (tf->cs&3) == 0){ // In kernel, it must be our mistake. cprintf("unexpected trap %d from cpu %d eip %x esp %x cr2 %x, pid %d %s \n", tf->trapno, cpu(), tf->eip, tf->esp, rcr2(),cp->pid, cp->name); panic("trap"); } // In user space, assume process misbehaved. cprintf("pid %d %s: trap %d err %d on cpu %d eip %x cr2 %x -- kill proc\n", cp->pid, cp->name, tf->trapno, tf->err, cpu(), tf->eip, rcr2()); cp->killed = 1; } // Force process exit if it has been killed and is in user space. // (If it is still executing in the kernel, let it keep running // until it gets to the regular system call return.) if(cp && cp->killed && (tf->cs&3) == DPL_USER) exit(); // Force process to give up CPU on clock tick. // If interrupts were on while locks held, would need to check nlock. if(cp && cp->state == RUNNING && tf->trapno == IRQ_OFFSET+IRQ_TIMER){ #ifdef LOAD_BALANCE_ON if(cp == idleproc[cpu()]){ struct rq* rq = theCpu.rq; rq->sched_class->load_balance(rq); } #endif proc_tick(theCpu.rq, cp); } }
static void trap_dispatch(struct Trapframe *tf) { // Handle processor exceptions. // LAB 3: Your code here. //---------------------------------------- Lab3 ------------------------------------------------------------ if (tf->tf_trapno == T_PGFLT) { //cprintf("pagefault!\n"); page_fault_handler(tf); return; } if (tf->tf_trapno == T_BRKPT) { //cprintf("brkpt!\n"); monitor(tf); return; } if (tf->tf_trapno == T_DEBUG) { my_monitor(tf); return; } if (tf->tf_trapno == T_SYSCALL) { //cprintf("Syscall!\n"); tf->tf_regs.reg_eax = syscall(tf->tf_regs.reg_eax, tf->tf_regs.reg_edx, tf->tf_regs.reg_ecx, tf->tf_regs.reg_ebx, tf->tf_regs.reg_edi, tf->tf_regs.reg_esi); if (tf->tf_regs.reg_eax < 0) panic("syscall failed: %e\n", tf->tf_regs.reg_eax); return; } //---------------------------------------- Lab3 ------------------------------------------------------------ // Handle spurious interrupts // The hardware sometimes raises these because of noise on the // IRQ line or other reasons. We don't care. if (tf->tf_trapno == IRQ_OFFSET + IRQ_SPURIOUS) { cprintf("Spurious interrupt on irq 7\n"); print_trapframe(tf); return; } // Handle clock interrupts. Don't forget to acknowledge the // interrupt using lapic_eoi() before calling the scheduler! // LAB 4: Your code here. //------------ Lab4 ---------------------------------------------------------------------------------------- if (tf->tf_trapno == IRQ_OFFSET + IRQ_TIMER) { // cprintf("clock interrupt!\n"); lapic_eoi(); sched_yield(); return; } //------------ Lab4 ---------------------------------------------------------------------------------------- // Handle keyboard and serial interrupts. // LAB 5: Your code here. //----------------------------------------------------------------------- Lab5 ----------------------------- if (tf->tf_trapno == IRQ_OFFSET + IRQ_KBD) { kbd_intr(); return; } if (tf->tf_trapno == IRQ_OFFSET + IRQ_SERIAL) { serial_intr(); return ; } //----------------------------------------------------------------------- Lab5 ----------------------------- // Unexpected trap: The user process or the kernel has a bug. print_trapframe(tf); if (tf->tf_cs == GD_KT) panic("unhandled trap in kernel"); else { env_destroy(curenv); return; } }