started properly implementing syscall structure
This commit is contained in:
parent
962b209f30
commit
ce9c6e6cfb
15
kernel.c
15
kernel.c
@ -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
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
int ecall_handle_join(int* args, ProcessControlBlock* pcb)
|
||||
{
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
int ecall_handle_kill(int* args, ProcessControlBlock* pcb)
|
||||
{
|
||||
return EINVAL;
|
||||
|
||||
}
|
||||
|
||||
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_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(®s[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…
Reference in New Issue
Block a user