started properly implementing syscall structure

master
Anton Lydike 3 years ago
parent 962b209f30
commit ce9c6e6cfb

@ -2,20 +2,23 @@
#include "ecall.h"
#include "sched.h"
void thread_1();
void create_processes_from_bin_table();
extern ProcessControlBlock processes[PROCESS_COUNT];
loaded_binary binary_table[NUM_BINARIES];
static int idx = 0;
extern void init()
{
for (int i = 0; i < 100; i++) {
idx += binary_table[i].entrypoint + 4;
}
init_ecall_table();
create_processes_from_bin_table();
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
csrrw t6, mscratch, t6 // load original t6 register from mscratch
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
srli a0, a1, 31
slli a1, a1, 1

@ -2,36 +2,71 @@
#include "sched.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() {
int *regs = get_current_process_registers();
ProcessControlBlock* pcb = get_current_process();
int *regs = pcb->regs;
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)
@ -58,3 +93,12 @@ void trap_handle(int interrupt_bit, int code, int mtval)
HALT(1);
__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
#define H_ECALL
#include "sched.h"
/* ecall codes are defined here
*
*
@ -13,12 +15,23 @@ enum ecall_codes {
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
void ecall_handle_spawn(void* entry, void* args);
void ecall_handle_sleep(int until);
void ecall_handle_join(int pid, int timeout);
void ecall_handle_kill(int pid);
void ecall_handle_exit(int status);
int ecall_handle_spawn(int*, ProcessControlBlock*);
int ecall_handle_sleep(int*, ProcessControlBlock*);
int ecall_handle_join(int*, ProcessControlBlock*);
int ecall_handle_kill(int*, ProcessControlBlock*);
int ecall_handle_exit(int*, ProcessControlBlock*);
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);
}
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()
{
long long int mtime;
unsigned long long int mtime;
int i;
int timeout_available = false; // note if a timeout is available

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

Loading…
Cancel
Save