Finish part C.

This commit is contained in:
Danila Fedorin 2019-05-05 22:08:12 -07:00
parent 721a113c93
commit 9acc7c80f7
6 changed files with 88 additions and 9 deletions

View File

@ -255,6 +255,7 @@ env_alloc(struct Env **newenv_store, envid_t parent_id)
// Enable interrupts while in user mode. // Enable interrupts while in user mode.
// LAB 4: Your code here. // LAB 4: Your code here.
e->env_tf.tf_eflags |= FL_IF;
// Clear the page fault handler until user installs one. // Clear the page fault handler until user installs one.
e->env_pgfault_upcall = 0; e->env_pgfault_upcall = 0;

View File

@ -93,7 +93,7 @@ sched_halt(void)
"pushl $0\n" "pushl $0\n"
// LAB 4: // LAB 4:
// Uncomment the following line after completing exercise 13 // Uncomment the following line after completing exercise 13
//"sti\n" "sti\n"
"1:\n" "1:\n"
"hlt\n" "hlt\n"
"jmp 1b\n" "jmp 1b\n"

View File

@ -294,8 +294,38 @@ sys_page_unmap(envid_t envid, void *va)
static int static int
sys_ipc_try_send(envid_t envid, uint32_t value, void *srcva, unsigned perm) sys_ipc_try_send(envid_t envid, uint32_t value, void *srcva, unsigned perm)
{ {
// LAB 4: Your code here. struct Env* dest_env;
panic("sys_ipc_try_send not implemented"); struct Env* src_env;
int return_code;
if((return_code = envid2env(0, &src_env, 0)) < 0)
return return_code;
if((return_code = envid2env(envid, &dest_env, 0)) < 0)
return return_code;
if(!dest_env->env_ipc_recving)
return -E_IPC_NOT_RECV;
if((uintptr_t) srcva < UTOP && dest_env->env_ipc_dstva) {
if(!SYS_CHECKADDR(srcva)) return -E_INVAL;
if(!SYS_CHECKPERMS(perm)) return -E_INVAL;
pte_t* srcpte;
struct PageInfo* page = page_lookup(src_env->env_pgdir, srcva, &srcpte);
if(page == NULL) return -E_INVAL;
if(perm & PTE_W && !(*srcpte & PTE_W)) return -E_INVAL;
page_insert(dest_env->env_pgdir, page, dest_env->env_ipc_dstva, perm);
dest_env->env_ipc_perm = perm;
}
dest_env->env_ipc_from = src_env->env_id;
dest_env->env_ipc_value = value;
dest_env->env_ipc_recving = false;
if(dest_env->env_status == ENV_NOT_RUNNABLE)
dest_env->env_status = ENV_RUNNABLE;
return 0;
} }
// Block until a value is ready. Record that you want to receive // Block until a value is ready. Record that you want to receive
@ -312,8 +342,20 @@ sys_ipc_try_send(envid_t envid, uint32_t value, void *srcva, unsigned perm)
static int static int
sys_ipc_recv(void *dstva) sys_ipc_recv(void *dstva)
{ {
struct Env* env;
int return_code;
if((return_code = envid2env(0, &env, 1)) < 0)
return return_code;
// LAB 4: Your code here. // LAB 4: Your code here.
panic("sys_ipc_recv not implemented"); if((uintptr_t) dstva < UTOP) {
if(!SYS_CHECKADDR(dstva)) return -E_INVAL;
env->env_ipc_dstva = dstva;
}
env->env_ipc_recving = true;
env->env_status = ENV_NOT_RUNNABLE;
return 0; return 0;
} }
@ -350,6 +392,10 @@ syscall(uint32_t syscallno, uint32_t a1, uint32_t a2, uint32_t a3, uint32_t a4,
return sys_page_map(a1, (void*) a2, a3, (void*) a4, a5); return sys_page_map(a1, (void*) a2, a3, (void*) a4, a5);
case SYS_page_unmap: case SYS_page_unmap:
return sys_page_unmap(a1, (void*) a2); return sys_page_unmap(a1, (void*) a2);
case SYS_ipc_try_send:
return sys_ipc_try_send(a1, a2, (void*) a3, a4);
case SYS_ipc_recv:
return sys_ipc_recv((void*) a1);
default: default:
return -E_INVAL; return -E_INVAL;
} }

View File

@ -89,6 +89,13 @@ void t_simderr();
void t_syscall(); void t_syscall();
void t_default(); void t_default();
void irq_timer();
void irq_kbd();
void irq_serial();
void irq_spurious();
void irq_ide();
void irq_error();
void void
trap_init(void) trap_init(void)
{ {
@ -125,6 +132,13 @@ trap_init(void)
SETGATE(idt[T_SYSCALL], 0, GD_KT, t_syscall, 3); SETGATE(idt[T_SYSCALL], 0, GD_KT, t_syscall, 3);
SETGATE(idt[T_DEFAULT], 0, GD_KT, t_default, 0); SETGATE(idt[T_DEFAULT], 0, GD_KT, t_default, 0);
SETGATE(idt[IRQ_OFFSET + IRQ_TIMER], 0, GD_KT, irq_timer, 0);
SETGATE(idt[IRQ_OFFSET + IRQ_KBD], 0, GD_KT, irq_kbd, 0);
SETGATE(idt[IRQ_OFFSET + IRQ_SERIAL], 0, GD_KT, irq_serial, 0);
SETGATE(idt[IRQ_OFFSET + IRQ_SPURIOUS], 0, GD_KT, irq_spurious, 0);
SETGATE(idt[IRQ_OFFSET + IRQ_IDE], 0, GD_KT, irq_ide, 0);
SETGATE(idt[IRQ_OFFSET + IRQ_ERROR], 0, GD_KT, irq_error, 0);
// Per-CPU setup // Per-CPU setup
trap_init_percpu(); trap_init_percpu();
} }
@ -243,6 +257,9 @@ trap_dispatch(struct Trapframe *tf)
tf->tf_regs.reg_esi); tf->tf_regs.reg_esi);
tf->tf_regs.reg_eax = returned; tf->tf_regs.reg_eax = returned;
return; return;
} else if (tf->tf_trapno == IRQ_OFFSET + IRQ_TIMER) {
lapic_eoi();
sched_yield();
} }
// Handle spurious interrupts // Handle spurious interrupts

View File

@ -82,6 +82,12 @@ TRAPHANDLER_NOEC(t_mchk, T_MCHK);
TRAPHANDLER_NOEC(t_simderr, T_SIMDERR); TRAPHANDLER_NOEC(t_simderr, T_SIMDERR);
TRAPHANDLER_NOEC(t_syscall, T_SYSCALL); TRAPHANDLER_NOEC(t_syscall, T_SYSCALL);
TRAPHANDLER(t_default, T_DEFAULT); TRAPHANDLER(t_default, T_DEFAULT);
TRAPHANDLER_NOEC(irq_timer, IRQ_OFFSET + IRQ_TIMER);
TRAPHANDLER_NOEC(irq_kbd, IRQ_OFFSET + IRQ_KBD);
TRAPHANDLER_NOEC(irq_serial, IRQ_OFFSET + IRQ_SERIAL);
TRAPHANDLER_NOEC(irq_spurious, IRQ_OFFSET + IRQ_SPURIOUS);
TRAPHANDLER_NOEC(irq_ide, IRQ_OFFSET + IRQ_IDE);
TRAPHANDLER_NOEC(irq_error, IRQ_OFFSET + IRQ_ERROR);
// HINT 1 : TRAPHANDLER_NOEC(t_divide, T_DIVIDE); // HINT 1 : TRAPHANDLER_NOEC(t_divide, T_DIVIDE);
// Do something like this if there is no error code for the trap // Do something like this if there is no error code for the trap

View File

@ -22,9 +22,14 @@
int32_t int32_t
ipc_recv(envid_t *from_env_store, void *pg, int *perm_store) ipc_recv(envid_t *from_env_store, void *pg, int *perm_store)
{ {
// LAB 4: Your code here. int return_code;
panic("ipc_recv not implemented"); if((return_code = sys_ipc_recv(pg ? pg : (void*) ~0)) < 0)
return 0; return return_code;
if(from_env_store) *from_env_store = thisenv->env_ipc_from;
if(perm_store) *perm_store = thisenv->env_ipc_perm;
return thisenv->env_ipc_value;
} }
// Send 'val' (and 'pg' with 'perm', if 'pg' is nonnull) to 'toenv'. // Send 'val' (and 'pg' with 'perm', if 'pg' is nonnull) to 'toenv'.
@ -38,8 +43,12 @@ ipc_recv(envid_t *from_env_store, void *pg, int *perm_store)
void void
ipc_send(envid_t to_env, uint32_t val, void *pg, int perm) ipc_send(envid_t to_env, uint32_t val, void *pg, int perm)
{ {
// LAB 4: Your code here. int return_code = -E_IPC_NOT_RECV;
panic("ipc_send not implemented"); while(return_code == -E_IPC_NOT_RECV) {
return_code = sys_ipc_try_send(to_env, val, pg ? pg : (void*) ~0, perm);
sys_yield();
}
if(return_code != 0) panic("failed to send\n");
} }
// Find the first environment of the given type. We'll use this to // Find the first environment of the given type. We'll use this to