diff options
author | Matthew Sotoudeh <matthewsot@outlook.com> | 2022-05-13 13:46:36 -0700 |
---|---|---|
committer | Matthew Sotoudeh <matthewsot@outlook.com> | 2022-05-13 13:46:36 -0700 |
commit | 0709935678687b5fa71da708c193cc378822cb73 (patch) | |
tree | 3946a3900c2ae2d981e56e08565b659c27c1238a | |
parent | 3b83b1f5f45ea2014ad846fc8c04f2e0537ae3c9 (diff) |
timeslicing works, also tabs->spaces in interrupts-asm.s
-rw-r--r-- | kern/Makefile | 5 | ||||
-rw-r--r-- | kern/interrupts-asm.s | 79 | ||||
-rw-r--r-- | kern/interrupts.c | 13 | ||||
-rw-r--r-- | kern/kern.c | 18 | ||||
-rw-r--r-- | kern/proc.c | 21 | ||||
-rw-r--r-- | kern/proc.h | 1 | ||||
-rw-r--r-- | kern/syscall.c | 4 | ||||
-rw-r--r-- | kern/syscall_list.h | 1 | ||||
-rw-r--r-- | kern/timer.h | 42 |
9 files changed, 139 insertions, 45 deletions
diff --git a/kern/Makefile b/kern/Makefile index 846ba69..f987b2a 100644 --- a/kern/Makefile +++ b/kern/Makefile @@ -54,4 +54,7 @@ p-basic.o: p-hello.o: make -C $(PIOS)/hello_os exostall -.PHONY: format all install +p-pidos.o: + make -C $(PIOS)/pid_os exostall + +.PHONY: format all install p-basic.o p-hello.o p-pidos.o diff --git a/kern/interrupts-asm.s b/kern/interrupts-asm.s index ee440aa..c90a24c 100644 --- a/kern/interrupts-asm.s +++ b/kern/interrupts-asm.s @@ -4,14 +4,14 @@ .globl _interrupt_table_end .align 5 _interrupt_table: - ldr pc, _reset_h - ldr pc, _undef_insn_h - ldr pc, _software_irq_h - ldr pc, _prefetch_abort_h - ldr pc, _data_abort_h - ldr pc, _reset_h - ldr pc, _irq_h - ldr pc, _fiq_h + ldr pc, _reset_h + ldr pc, _undef_insn_h + ldr pc, _software_irq_h + ldr pc, _prefetch_abort_h + ldr pc, _data_abort_h + ldr pc, _reset_h + ldr pc, _irq_h + ldr pc, _fiq_h _reset_h: .word asm_reset _undef_insn_h: .word asm_undef_insn @@ -23,32 +23,39 @@ _fiq_h: .word asm_fiq _interrupt_table_end: asm_reset: - ldr sp, =kstack - bl reboot + ldr sp, =kstack + bl reboot asm_undef_insn: - ldr sp, =kstack - ldr pc, _vec_undef_insn + ldr sp, =kstack + ldr pc, _vec_undef_insn asm_software_irq: - ldr sp, =kstack - sub lr, lr, #4 - push {lr} - stmfd sp, {r0-r14}^ - sub sp, sp, #60 - mov r0, sp - bl syscall - ldm sp, {r0-r15}^ + ldr sp, =kstack + // sub lr, lr, #4 + push {lr} + stmfd sp, {r0-r14}^ + sub sp, sp, #60 + mov r0, sp + bl syscall + ldm sp, {r0-r15}^ asm_prefetch_abort: - ldr sp, =kstack - ldr pc, _vec_prefetch_abort + ldr sp, =kstack + ldr pc, _vec_prefetch_abort asm_data_abort: - ldr sp, =kstack - ldr pc, _vec_data_abort + ldr sp, =kstack + ldr pc, _vec_data_abort asm_irq: - ldr sp, =kstack - ldr pc, _vec_irq + ldr sp, =kstack + sub lr, lr, #4 + push {lr} + stmfd sp, {r0-r14}^ + sub sp, sp, #60 + mov r0, sp + ldr r1, _vec_irq + blx r1 + ldm sp, {r0-r15}^ asm_fiq: - ldr sp, =kstack - ldr pc, _vec_fiq + ldr sp, =kstack + ldr pc, _vec_fiq .globl _vector_table _vector_table: @@ -61,14 +68,14 @@ _vec_fiq: .word vec_fiq .globl enable_interrupts enable_interrupts: - mrs r0, cpsr - bic r0, r0, #(1 << 7) - msr cpsr_c, r0 - bx lr + mrs r0, cpsr + bic r0, r0, #(1 << 7) + msr cpsr_c, r0 + bx lr .globl disable_interrupts disable_interrupts: - mrs r0, cpsr - orr r0, r0, #(1 << 7) - msr cpsr_c, r0 - bx lr + mrs r0, cpsr + orr r0, r0, #(1 << 7) + msr cpsr_c, r0 + bx lr diff --git a/kern/interrupts.c b/kern/interrupts.c index f211398..f140212 100644 --- a/kern/interrupts.c +++ b/kern/interrupts.c @@ -102,8 +102,17 @@ void __attribute__((interrupt("ABORT"))) vec_data_abort() { printf("!!!!!!! LR was: %x\n", lr); panic_unhandled("data_abort"); } -void __attribute__((interrupt("IRQ"))) vec_irq() { - panic_unhandled("irq"); +#include "proc.h" +#include "timer.h" +void vec_irq(regs_t *regs) { + dev_barrier(); + if (!timer_has_irq()) return; + + proc_scheduler_irq(regs); + + dev_barrier(); + timer_clear_irq(); + dev_barrier(); } void __attribute__((interrupt("FIQ"))) vec_fiq() { panic_unhandled("fiq"); diff --git a/kern/kern.c b/kern/kern.c index 533fe6a..da3e77b 100644 --- a/kern/kern.c +++ b/kern/kern.c @@ -10,6 +10,7 @@ #include "sys.h" #include "uart.h" #include "vm.h" +#include "timer.h" void reboot() { printf("DONE!!!\n"); @@ -36,15 +37,22 @@ void kernel_start() { uart_init(115200); init_printf(NULL, uart_putc); - irq_init(); + kmalloc_init(); + irq_init(); + irq_enable(BASIC_TIMER_IRQ); + timer_irq_load(0x1000); + printf("kernel booted\n"); - extern unsigned char _binary_hello_bin_start; - extern unsigned char _binary_hello_bin_end; - proc_t *p_hello = proc_new(&_binary_hello_bin_start, (size_t) (&_binary_hello_bin_end - &_binary_hello_bin_start)); - proc_run(p_hello); + extern unsigned char _binary_pidos_bin_start; + extern unsigned char _binary_pidos_bin_end; + + proc_t *p_pidos_1 = proc_new(&_binary_pidos_bin_start, (size_t) (&_binary_pidos_bin_end - &_binary_pidos_bin_start)); + proc_t *p_pidos_2 = proc_new(&_binary_pidos_bin_start, (size_t) (&_binary_pidos_bin_end - &_binary_pidos_bin_start)); + + proc_run(p_pidos_1); reboot(); return; diff --git a/kern/proc.c b/kern/proc.c index 4df3f3a..d08fad2 100644 --- a/kern/proc.c +++ b/kern/proc.c @@ -42,6 +42,7 @@ void __attribute__((noreturn)) proc_run(proc_t *proc) { vm_set_pt(proc->pt); curproc = proc; + enable_interrupts(); // TODO: Set this in the SPSR // NOTE: To use SPSR, need to be sure we are *NOT* in user/system mode. // TODO(masot): add an assert like that set_spsr((get_cpsr() & ~0b11111) | 0b10000); @@ -49,3 +50,23 @@ void __attribute__((noreturn)) proc_run(proc_t *proc) { while (1) { } } + +thread_id = 0; + +void swippityswap(regs_t *live_state, proc_t *new_thread, proc_t *old_thread) { + memcpy(&(old_thread->regs), live_state, sizeof(regs_t)); + memcpy(live_state, &(new_thread->regs), sizeof(regs_t)); +} + + +void proc_scheduler_irq(regs_t *regs) { + pid_t curr_pid = curproc->id, + next_pid = (curr_pid + 1) % id; + + swippityswap(regs, &(procs[next_pid]), &(procs[curr_pid])); + + curproc->state = PROC_RUNNABLE; + curproc = &(procs[next_pid]); + curproc->state = PROC_RUNNING; + vm_set_pt(curproc->pt); +} diff --git a/kern/proc.h b/kern/proc.h index d908d56..592538e 100644 --- a/kern/proc.h +++ b/kern/proc.h @@ -48,3 +48,4 @@ extern proc_t *curproc; proc_t *proc_new(uint8_t *code, size_t codesz); void proc_run(proc_t *proc); +void proc_scheduler_irq(regs_t *regs); diff --git a/kern/syscall.c b/kern/syscall.c index c108752..b3dab38 100644 --- a/kern/syscall.c +++ b/kern/syscall.c @@ -51,9 +51,11 @@ void syscall(regs_t *regs) { case SYSCALL_VM_MAP: regs->r0 = syscall_vm_map(regs->r1, regs->r2, regs->r3, regs->r4); break; + case SYSCALL_GET_PID: + regs->r0 = curproc->id; + break; default: panic("unhandled syscall %d\n", sysno); break; } - regs->pc += 4; } diff --git a/kern/syscall_list.h b/kern/syscall_list.h index e22d70d..9e4366a 100644 --- a/kern/syscall_list.h +++ b/kern/syscall_list.h @@ -4,6 +4,7 @@ #define SYSCALL_ALLOC_PAGE 1 #define SYSCALL_DEALLOC_PAGE 2 #define SYSCALL_VM_MAP 3 +#define SYSCALL_GET_PID 4 // NOTE: DO NOT CHANGE THESE without changing vm.h #define SYSCALL_ARG_ANY_PAGE 0 diff --git a/kern/timer.h b/kern/timer.h index 95c22b7..d4e1379 100644 --- a/kern/timer.h +++ b/kern/timer.h @@ -1,6 +1,8 @@ #pragma once #include "sys.h" +#include <stdbool.h> +#include <stdint.h> static inline void timer_init() { asm volatile("mcr p15, 0, %0, c15, c12, 0" ::"r"(1)); @@ -34,3 +36,43 @@ static inline void delay_us(unsigned us) { static inline void delay_ms(unsigned ms) { delay_us(ms * 1000); } + +typedef struct { + uint32_t load; + uint32_t value; + uint32_t ctrl; + uint32_t irq_clear; + uint32_t raw_irq; + uint32_t masked_irq; + uint32_t reload; + uint32_t pre_divider; + uint32_t free_running_counter; +} my_timer_t; + +#define TIMER_CTRL_32BIT (1 << 1) + +#define TIMER_CTRL_PRESCALE_1 (0 << 2) +#define TIMER_CTRL_PRESCALE_16 (1 << 2) +#define TIMER_CTRL_PRESCALE_256 (2 << 2) + +#define TIMER_CTRL_INT_ENABLE (1 << 5) +#define TIMER_CTRL_INT_DISABLE (0 << 5) + +#define TIMER_CTRL_ENABLE (1 << 7) +#define TIMER_CTRL_DISABLE (0 << 7) + +static volatile my_timer_t* const timer = (my_timer_t*) pa2ka(0x2000b400); + +static void timer_irq_load(uint32_t load) { + timer->load = load; + timer->ctrl = TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_INT_ENABLE | + TIMER_CTRL_PRESCALE_256; +} + +static bool timer_has_irq() { + return timer->masked_irq; +} + +static void timer_clear_irq() { + timer->irq_clear = 1; +} |