summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Sotoudeh <matthewsot@outlook.com>2022-05-13 13:46:36 -0700
committerMatthew Sotoudeh <matthewsot@outlook.com>2022-05-13 13:46:36 -0700
commit0709935678687b5fa71da708c193cc378822cb73 (patch)
tree3946a3900c2ae2d981e56e08565b659c27c1238a
parent3b83b1f5f45ea2014ad846fc8c04f2e0537ae3c9 (diff)
timeslicing works, also tabs->spaces in interrupts-asm.s
-rw-r--r--kern/Makefile5
-rw-r--r--kern/interrupts-asm.s79
-rw-r--r--kern/interrupts.c13
-rw-r--r--kern/kern.c18
-rw-r--r--kern/proc.c21
-rw-r--r--kern/proc.h1
-rw-r--r--kern/syscall.c4
-rw-r--r--kern/syscall_list.h1
-rw-r--r--kern/timer.h42
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;
+}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback