diff --git a/earth/cpu_intr.c b/earth/cpu_intr.c index 19feafe0..0663d7d8 100644 --- a/earth/cpu_intr.c +++ b/earth/cpu_intr.c @@ -37,22 +37,20 @@ static void trap_entry() { intr_handler(id); else FATAL("Got interrupt %d but handler not registered", id); + __asm__ volatile("csrw mepc, %0" ::"r"(mepc)); } else { if (excp_handler != NULL) excp_handler(id); else { if (id == 2 && mepc == 0) { - /* This may be a bug of CPU implementation */ + /* This seems to be a bug of CPU implementation */ INFO("Got spurious exception %d (mepc=%x)", id, mepc); __asm__ volatile("csrw mepc, %0" ::"r"(VADDR_START)); - return; } else { FATAL("Got exception %d (mepc=%x) but handler not registered", id, mepc); } } } - - __asm__ volatile("csrw mepc, %0" ::"r"(mepc)); } int intr_register(handler_t _handler) { diff --git a/grass/grass.c b/grass/grass.c index b9ad742a..6c01cea3 100644 --- a/grass/grass.c +++ b/grass/grass.c @@ -29,12 +29,11 @@ int main() { /* Enter kernel process sys_proc */ void (*sys_proc_entry)(void*) = (void*)VADDR_START; earth->mmu_switch(GPID_PROCESS); // setup virtual address space - proc_set_running(GPID_PROCESS); // set status timer_reset(); // start timer earth->intr_enable(); // enable interrupt - sys_proc_entry(&pcb); - FATAL("Should never return to the grass kernel main()"); + sys_proc_entry(&pcb); // enter the application layer + FATAL("Should never return to the grass kernel main()"); return 0; } diff --git a/grass/grass.h b/grass/grass.h index 3751de51..3ed7ce8f 100644 --- a/grass/grass.h +++ b/grass/grass.h @@ -6,7 +6,6 @@ #include "mmu.h" #include "print.h" #include "syscall.h" -#include "process.h" struct earth *earth; @@ -14,12 +13,37 @@ struct earth *earth; #define RISCV_CLINT0_MTIME_BASE 0x200bff8 #define RISCV_CLINT0_MTIMECMP_BASE 0x2004000 +void timer_init(); +long long timer_reset(); + +enum { + PROC_UNUSED, + PROC_READY, // loaded into memory but haven't started running + PROC_RUNNING, + PROC_RUNNABLE, + PROC_ZOMBIE +}; + +struct process{ + int pid; + int status; + void* sp; +}; + +/* interface for kernel process sys_proc */ +struct pcb_intf { + int (*proc_alloc)(); + void (*proc_free)(int); + void (*proc_set_ready)(int); +}; + +#define MAX_NPROCESS 64 +#define KERNEL_STACK_TOP 0x08007f80 //0x08008000 - 128 +#define PID(x) proc_set[x].pid + void proc_init(); int proc_alloc(); void proc_free(int); void proc_set_ready (int); void proc_set_running (int); void proc_set_runnable (int); - -void timer_init(); -long long timer_reset(); diff --git a/grass/process.c b/grass/proc_sched.c similarity index 65% rename from grass/process.c rename to grass/proc_sched.c index acee0e73..4f173522 100644 --- a/grass/process.c +++ b/grass/proc_sched.c @@ -8,32 +8,24 @@ * system calls are basically inter-process communication */ + #include "egos.h" #include "grass.h" -#include - -int proc_nprocs, proc_curr_idx; -struct process proc_set[MAX_NPROCESS]; -static void (*kernel_entry)(); static void proc_yield(); -static void intr_entry(int id); - - -void proc_init() { - earth->intr_register(intr_entry); +static void (*kernel_entry)(); - proc_nprocs = 0; - memset(proc_set, 0, sizeof(struct process) * MAX_NPROCESS); +int proc_curr_idx; +struct process proc_set[MAX_NPROCESS]; - /* the first process is now running */ - proc_alloc(); - proc_curr_idx = 0; - proc_set_running(PID(proc_curr_idx)); +void ctx_entry() { + kernel_entry(); + /* switch back to user application */ + void* tmp; + ctx_switch(&tmp, proc_set[proc_curr_idx].sp); } - -static void intr_entry(int id) { +void intr_entry(int id) { if (id == INTR_ID_TMR) { /* switch to kernel stack and call kernel_entry */ kernel_entry = proc_yield; @@ -50,15 +42,6 @@ static void intr_entry(int id) { } } - -void ctx_entry() { - kernel_entry(); - /* switch back to user application */ - void* tmp; - ctx_switch(&tmp, proc_set[proc_curr_idx].sp); -} - - static void proc_yield() { int mepc; __asm__ volatile("csrr %0, mepc" : "=r"(mepc)); @@ -106,43 +89,3 @@ static void proc_yield() { FATAL("Reach the end of proc_yield without switching to any process"); } - -int proc_alloc() { - proc_nprocs++; - for (int i = 0; i < MAX_NPROCESS; i++) { - if (proc_set[i].pid == 0) { - proc_set[i].pid = proc_nprocs; - proc_set[i].status = PROC_UNUSED; - return proc_nprocs; - } - } - FATAL("Reach the limit of %d processes", MAX_NPROCESS); - return -1; -} - - -void proc_free(int pid) { - FATAL("proc_free not implemented"); -} - - -static void proc_set_status(int pid, int status) { - for (int i = 0; i < MAX_NPROCESS; i++) { - if (proc_set[i].pid == pid) { - proc_set[i].status = status; - return; - } - } -} - -void proc_set_ready(int pid) { - proc_set_status(pid, PROC_READY); -} - -void proc_set_running(int pid) { - proc_set_status(pid, PROC_RUNNING); -} - -void proc_set_runnable(int pid) { - proc_set_status(pid, PROC_RUNNABLE); -} diff --git a/grass/proc_utils.c b/grass/proc_utils.c new file mode 100644 index 00000000..59f94675 --- /dev/null +++ b/grass/proc_utils.c @@ -0,0 +1,68 @@ +/* + * (C) 2022, Cornell University + * All rights reserved. + */ + +/* Author: Yunhao Zhang + * Description: process util functions + */ + +#include "egos.h" +#include "grass.h" +#include + +static int proc_nprocs; +extern int proc_curr_idx; +extern struct process proc_set[MAX_NPROCESS]; + +void intr_entry(int id); + +void proc_init() { + earth->intr_register(intr_entry); + + proc_nprocs = 0; + memset(proc_set, 0, sizeof(struct process) * MAX_NPROCESS); + + /* the first process is now running */ + proc_alloc(); + proc_curr_idx = 0; + proc_set_running(PID(proc_curr_idx)); +} + +int proc_alloc() { + proc_nprocs++; + for (int i = 0; i < MAX_NPROCESS; i++) { + if (proc_set[i].pid == 0) { + proc_set[i].pid = proc_nprocs; + proc_set[i].status = PROC_UNUSED; + return proc_nprocs; + } + } + FATAL("Reach the limit of %d processes", MAX_NPROCESS); + return -1; +} + +void proc_free(int pid) { + FATAL("proc_free not implemented"); +} + +static void proc_set_status(int pid, int status) { + for (int i = 0; i < MAX_NPROCESS; i++) { + if (proc_set[i].pid == pid) { + proc_set[i].status = status; + return; + } + } +} + +void proc_set_ready(int pid) { + proc_set_status(pid, PROC_READY); +} + +void proc_set_running(int pid) { + proc_set_status(pid, PROC_RUNNING); +} + +void proc_set_runnable(int pid) { + proc_set_status(pid, PROC_RUNNABLE); +} diff --git a/grass/process.h b/grass/process.h deleted file mode 100644 index b62de19f..00000000 --- a/grass/process.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -enum { - PROC_UNUSED, - PROC_READY, // loaded into memory but haven't started running - PROC_RUNNING, - PROC_RUNNABLE, - PROC_ZOMBIE -}; - -struct process{ - int pid; - int status; - void* sp; -}; - -/* interface for kernel process sys_proc */ -struct pcb_intf { - int (*proc_alloc)(); - void (*proc_free)(int); - void (*proc_set_ready)(int); -}; - -#define MAX_NPROCESS 64 -#define KERNEL_STACK_TOP 0x08007f80 //0x08008000 - 128 -#define PID(x) proc_set[x].pid