started properly implementing syscall structure

master
Anton Lydike 3 years ago
parent 962b209f30
commit ce9c6e6cfb

@ -2,20 +2,23 @@
#include "ecall.h" #include "ecall.h"
#include "sched.h" #include "sched.h"
void thread_1(); void create_processes_from_bin_table();
extern ProcessControlBlock processes[PROCESS_COUNT]; extern ProcessControlBlock processes[PROCESS_COUNT];
loaded_binary binary_table[NUM_BINARIES]; loaded_binary binary_table[NUM_BINARIES];
static int idx = 0;
extern void init() extern void init()
{ {
for (int i = 0; i < 100; i++) { init_ecall_table();
idx += binary_table[i].entrypoint + 4;
} create_processes_from_bin_table();
scheduler_run_next(); scheduler_run_next();
} }
void create_processes_from_bin_table()
{
}

@ -88,6 +88,10 @@ trap_vector:
mv a0, t6 // save struct address to already saved register mv a0, t6 // save struct address to already saved register
csrrw t6, mscratch, t6 // load original t6 register from mscratch csrrw t6, mscratch, t6 // load original t6 register from mscratch
sw t6, 120(a0) // save original t6 register sw t6, 120(a0) // save original t6 register
// save mepc to pc field in pcb
csrr t6, mepc
sw t6, -4(a0)
// load mcause and mtval values in the correct registers for call to trap_handle function
csrr a1, mcause csrr a1, mcause
srli a0, a1, 31 srli a0, a1, 31
slli a1, a1, 1 slli a1, a1, 1

@ -2,36 +2,71 @@
#include "sched.h" #include "sched.h"
#include "csr.h" #include "csr.h"
void ecall_handle_spawn(void* entry, void* args) typedef int (*ecall_handler)(int*,ProcessControlBlock*);
ecall_handler ecall_table[ECALL_TABLE_LEN] = { 0 };
int ecall_handle_spawn_thread(int* args_ptr, ProcessControlBlock* pcb)
{ {
void* entry = (void*) args_ptr[0];
void* args = (void*) args_ptr[1];
return EINVAL;
// void* entry, void* args
} }
void ecall_handle_sleep(int until) int ecall_handle_sleep(int* args, ProcessControlBlock* pcb)
{ {
int len = *args;
if (len < 0) {
return EINVAL;
}
pcb->asleep_until = read_time() + len;
pcb->status = PROC_WAIT_SLEEP;
return 0;
} }
void ecall_handle_join(int pid, int timeout) int ecall_handle_join(int* args, ProcessControlBlock* pcb)
{ {
return EINVAL;
} }
void ecall_handle_kill(int pid) int ecall_handle_kill(int* args, ProcessControlBlock* pcb)
{ {
return EINVAL;
} }
void ecall_handle_exit(int status) int ecall_handle_exit(int* args, ProcessControlBlock* pcb)
{ {
pcb->status = PROC_DEAD;
pcb->exit_code = *args;
return 0;
} }
void trap_handle_ecall() { void trap_handle_ecall() {
int *regs = get_current_process_registers(); ProcessControlBlock* pcb = get_current_process();
int *regs = pcb->regs;
int code = regs[16]; int code = regs[16];
__asm__("ebreak");
HALT(18); // check if the code is too large/small or if the handler is zero
if (code < 0 || code > ECALL_TABLE_LEN || ecall_table[code] == 0) {
regs[9] = ENOCODE;
__asm__("ebreak");
} else {
// get the corresponding ecall handler
ecall_handler handler = ecall_table[code];
regs[9] = handler(&regs[9], pcb);
}
// increment pc of this process
pcb->pc += 4;
// try to reschedule
scheduler_try_return_to(pcb);
} }
void trap_handle(int interrupt_bit, int code, int mtval) void trap_handle(int interrupt_bit, int code, int mtval)
@ -58,3 +93,12 @@ void trap_handle(int interrupt_bit, int code, int mtval)
HALT(1); HALT(1);
__builtin_unreachable(); __builtin_unreachable();
} }
void init_ecall_table()
{
ecall_table[ECALL_SPAWN] = ecall_handle_spawn_thread;
ecall_table[ECALL_SLEEP] = ecall_handle_sleep;
ecall_table[ECALL_JOIN] = ecall_handle_join;
ecall_table[ECALL_KILL] = ecall_handle_kill;
ecall_table[ECALL_EXIT] = ecall_handle_exit;
}

@ -1,6 +1,8 @@
#ifndef H_ECALL #ifndef H_ECALL
#define H_ECALL #define H_ECALL
#include "sched.h"
/* ecall codes are defined here /* ecall codes are defined here
* *
* *
@ -13,12 +15,23 @@ enum ecall_codes {
ECALL_EXIT = 5, ECALL_EXIT = 5,
}; };
#define ECALL_TABLE_LEN 16
enum ecall_errors {
ENOCODE = -1, // invalid syscall code
EINVAL = -2, // invalid argument value
ENOMEM = -3, // not enough memory
};
// initializer for ecall lookup table
void init_ecall_table();
// syscall handlers, are setup in the mtvec csr // syscall handlers, are setup in the mtvec csr
void ecall_handle_spawn(void* entry, void* args); int ecall_handle_spawn(int*, ProcessControlBlock*);
void ecall_handle_sleep(int until); int ecall_handle_sleep(int*, ProcessControlBlock*);
void ecall_handle_join(int pid, int timeout); int ecall_handle_join(int*, ProcessControlBlock*);
void ecall_handle_kill(int pid); int ecall_handle_kill(int*, ProcessControlBlock*);
void ecall_handle_exit(int status); int ecall_handle_exit(int*, ProcessControlBlock*);
void __attribute__((__noreturn__)) trap_handle(int interrupt_bit, int code, int mtval); void __attribute__((__noreturn__)) trap_handle(int interrupt_bit, int code, int mtval);

@ -16,9 +16,22 @@ void scheduler_run_next ()
scheduler_switch_to(current_process_index); scheduler_switch_to(current_process_index);
} }
void scheduler_try_return_to(ProcessControlBlock* pcb)
{
if (pcb->status != PROC_RDY) {
scheduler_run_next();
} else {
current_process_index = scheduler_index_from_pid(pcb->pid);
//FIXME: this refreshes the processes time slice which we actually don't want!
unsigned long long int mtimecmp = read_time() + TIME_SLICE_LEN;
write_mtimecmp(mtimecmp);
scheduler_switch_to(current_process_index);
}
}
int scheduler_select_free() int scheduler_select_free()
{ {
long long int mtime; unsigned long long int mtime;
int i; int i;
int timeout_available = false; // note if a timeout is available int timeout_available = false; // note if a timeout is available

@ -16,6 +16,7 @@ struct ProcessControlBlock {
int pid; int pid;
int pc; int pc;
int regs[31]; int regs[31];
int exit_code;
// scheduling information // scheduling information
enum process_status status; enum process_status status;
ProcessControlBlock *waiting_for_process; ProcessControlBlock *waiting_for_process;
@ -29,6 +30,7 @@ extern ProcessControlBlock processes[PROCESS_COUNT];
int scheduler_select_free(); int scheduler_select_free();
int scheduler_create_process(int binid); int scheduler_create_process(int binid);
void __attribute__((noreturn)) scheduler_run_next(); void __attribute__((noreturn)) scheduler_run_next();
void __attribute__((noreturn)) scheduler_try_return_to(ProcessControlBlock*);
void __attribute__((noreturn)) scheduler_switch_to(int proc_index); void __attribute__((noreturn)) scheduler_switch_to(int proc_index);
int scheduler_index_from_pid(int pid); int scheduler_index_from_pid(int pid);
int* get_current_process_registers(); int* get_current_process_registers();

Loading…
Cancel
Save