diff --git a/kinclude/csr.c b/kinclude/csr.c index bf54fdb..4e5d28f 100644 --- a/kinclude/csr.c +++ b/kinclude/csr.c @@ -31,15 +31,3 @@ void write_mtimecmp(unsigned long long int mtimecmp) { } #endif - - -unsigned long long int read_time() { - unsigned int lower, higher; - __asm__( - "csrr %0, %2\n" - "csrr %1, %3\n" - : "=r"(lower), "=r"(higher) - : "i"(CSR_TIME), "i"(CSR_TIMEH) - ); - return (unsigned long long) higher << 32 | lower; -} diff --git a/kinclude/csr.h b/kinclude/csr.h index 567eef9..f85a79b 100644 --- a/kinclude/csr.h +++ b/kinclude/csr.h @@ -36,7 +36,17 @@ } void write_mtimecmp(unsigned long long int mtimecmp); -unsigned long long int read_time(); + +inline __attribute__((always_inline)) unsigned long long int read_time() { + unsigned int lower, higher; + __asm__( + "csrr %0, %2\n" + "csrr %1, %3\n" + : "=r"(lower), "=r"(higher) + : "i"(CSR_TIME), "i"(CSR_TIMEH) + ); + return (unsigned long long) higher << 32 | lower; +} #endif diff --git a/kinclude/ecall.c b/kinclude/ecall.c index 0cd18d9..90d01ff 100644 --- a/kinclude/ecall.c +++ b/kinclude/ecall.c @@ -48,6 +48,10 @@ int ecall_handle_exit(int* args, ProcessControlBlock* pcb) } void trap_handle_ecall() { + { + + mark_ecall_entry(); + }; ProcessControlBlock* pcb = get_current_process(); int *regs = pcb->regs; int code = regs[16]; @@ -73,19 +77,39 @@ void trap_handle(int interrupt_bit, int code, int mtval) { if (interrupt_bit) { switch (code) { + // timer interrupts + case 4: + case 5: + case 6: case 7: scheduler_run_next(); break; default: // impossible - HALT(12) + HALT(12); break; } } else { switch (code) { - case 8: // user ecall + // any known exception code: + case 0: + case 1: + case 2: + case 4: + case 5: + case 6: + case 7: + case 12: + case 13: + case 15: + handle_exception(code, mtval); + break; + // user or supervisor ecall + case 8: + case 9: trap_handle_ecall(); break; + // unknown code default: HALT(13); } @@ -101,4 +125,9 @@ void init_ecall_table() ecall_table[ECALL_JOIN] = ecall_handle_join; ecall_table[ECALL_KILL] = ecall_handle_kill; ecall_table[ECALL_EXIT] = ecall_handle_exit; -} \ No newline at end of file +} + +void handle_exception(int ecode, int mtval) +{ + +} diff --git a/kinclude/ecall.h b/kinclude/ecall.h index fce68c2..e786c72 100644 --- a/kinclude/ecall.h +++ b/kinclude/ecall.h @@ -33,6 +33,7 @@ int ecall_handle_join(int*, ProcessControlBlock*); int ecall_handle_kill(int*, ProcessControlBlock*); int ecall_handle_exit(int*, ProcessControlBlock*); +void handle_exception(int ecode, int mtval); void __attribute__((__noreturn__)) trap_handle(int interrupt_bit, int code, int mtval); diff --git a/kinclude/sched.c b/kinclude/sched.c index d864235..bb24b93 100644 --- a/kinclude/sched.c +++ b/kinclude/sched.c @@ -6,13 +6,14 @@ // scheduling data: ProcessControlBlock processes[PROCESS_COUNT]; int current_process_index = 1; +unsigned long long int scheduling_interrupted_start; +unsigned long long int next_interrupt_scheduled_for; void scheduler_run_next () { current_process_index = scheduler_select_free(); // set up timer interrupt - unsigned long long int mtimecmp = read_time() + TIME_SLICE_LEN; - write_mtimecmp(mtimecmp); + set_next_interrupt(); scheduler_switch_to(current_process_index); } @@ -22,9 +23,9 @@ void scheduler_try_return_to(ProcessControlBlock* pcb) 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); + // add time spent in ecall handler to the processes time slice + next_interrupt_scheduled_for = next_interrupt_scheduled_for + (read_time() - scheduling_interrupted_start); + write_mtimecmp(next_interrupt_scheduled_for); scheduler_switch_to(current_process_index); } } @@ -135,3 +136,14 @@ ProcessControlBlock* get_current_process() { return &processes[current_process_index]; } + +void set_next_interrupt() +{ + next_interrupt_scheduled_for = read_time() + TIME_SLICE_LEN; + write_mtimecmp(next_interrupt_scheduled_for); +} + +void mark_ecall_entry() +{ + scheduling_interrupted_start = read_time(); +} \ No newline at end of file diff --git a/kinclude/sched.h b/kinclude/sched.h index a564fd4..de2875d 100644 --- a/kinclude/sched.h +++ b/kinclude/sched.h @@ -29,11 +29,12 @@ extern ProcessControlBlock processes[PROCESS_COUNT]; // scheduler methods int scheduler_select_free(); int scheduler_create_process(int binid); +void set_next_interrupt(); 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(); ProcessControlBlock* get_current_process(); - +void mark_ecall_entry(); #endif \ No newline at end of file