Finish part C.
This commit is contained in:
parent
721a113c93
commit
9acc7c80f7
|
@ -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;
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
17
kern/trap.c
17
kern/trap.c
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
19
lib/ipc.c
19
lib/ipc.c
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user