diff --git a/build.sh b/build.sh index fa85160..2876036 100755 --- a/build.sh +++ b/build.sh @@ -4,11 +4,19 @@ if [ -z "${MACH}" ]; then MACH=rpi3b fi +if [ -z "${PROFILE}" ]; then + PROFILE=debug +fi + LLVM_DIR=$(llvm-config --bindir) ARCH=aarch64-unknown-none-${MACH} CARGO_ARGS="--target ../etc/aarch64-unknown-none-$MACH.json \ --features mach_$MACH,fdt-rs" +if [ "$PROFILE" = "release" ]; then + CARGO_ARGS="$CARGO_ARGS --release" +fi + set -e cd kernel @@ -21,4 +29,5 @@ case $1 in ;; esac cd .. -${LLVM_DIR}/llvm-objcopy -O binary target/${ARCH}/debug/kernel target/${ARCH}/debug/kernel.bin +${LLVM_DIR}/llvm-objcopy -O binary target/${ARCH}/${PROFILE}/kernel \ + target/${ARCH}/${PROFILE}/kernel.bin diff --git a/kernel/src/arch/cpu.rs b/kernel/src/arch/cpu.rs index fc66721..f853654 100644 --- a/kernel/src/arch/cpu.rs +++ b/kernel/src/arch/cpu.rs @@ -8,9 +8,9 @@ pub struct Cpu { index: u32, // 0x00 } -#[repr(transparent)] pub struct CpuRef { inner: &'static mut Cpu, + irq_state: usize } impl Cpu { @@ -30,16 +30,19 @@ impl Cpu { #[inline] pub fn get() -> CpuRef { - // TODO lock + let irq_state = unsafe { intrin::save_irq() }; CpuRef { inner: unsafe { Self::get_raw() }, + irq_state } } } impl Drop for CpuRef { fn drop(&mut self) { - // TODO release + unsafe { + intrin::restore_irq(self.irq_state); + } } } diff --git a/kernel/src/arch/intrin.rs b/kernel/src/arch/intrin.rs index aa24a02..b50e53e 100644 --- a/kernel/src/arch/intrin.rs +++ b/kernel/src/arch/intrin.rs @@ -8,6 +8,21 @@ pub unsafe fn enable_irq() { llvm_asm!("msr daifclr, #0xF"); } +#[inline(always)] +pub unsafe fn save_irq() -> usize { + let mut out: usize; + llvm_asm!(r#" + mrs $0, daif + msr daifset, #0xF + "#:"=r"(out)); + out +} + +#[inline(always)] +pub unsafe fn restore_irq(state: usize) { + llvm_asm!("msr daif, $0"::"r"(state)); +} + #[inline(always)] pub fn nop() { unsafe { diff --git a/kernel/src/arch/mach_bcm283x/aux.rs b/kernel/src/arch/mach_bcm283x/aux.rs index 0071d43..422f125 100644 --- a/kernel/src/arch/mach_bcm283x/aux.rs +++ b/kernel/src/arch/mach_bcm283x/aux.rs @@ -12,7 +12,7 @@ impl Aux { const AUX_ENABLES_MUART: u32 = 1 << 0; pub unsafe fn enable_uart(&self) { - let tmp = mmio_read(Self::REG_AUX_ENABLES); + let tmp: u32 = mmio_read(Self::REG_AUX_ENABLES); mmio_write(Self::REG_AUX_ENABLES, tmp | Self::AUX_ENABLES_MUART); } } @@ -61,7 +61,7 @@ impl SerialDevice for AuxUart { impl InterruptHandler for AuxUart { fn do_irq(&self, _irq: u32) { - let _byte = unsafe { mmio_read(Self::REG_AUX_MU_IO) } as u8; + let _byte = unsafe { mmio_read::(Self::REG_AUX_MU_IO) } as u8; } } diff --git a/kernel/src/arch/mach_bcm283x/intc.rs b/kernel/src/arch/mach_bcm283x/intc.rs index ac7d332..6a344e7 100644 --- a/kernel/src/arch/mach_bcm283x/intc.rs +++ b/kernel/src/arch/mach_bcm283x/intc.rs @@ -59,7 +59,7 @@ impl InterruptController for Qa7Intc { match irq { super::IRQ_LOCAL_TIMER => { let phys_core_id = cpu::get_phys_id(); - let tmp = mmio_read(Self::REG_TIMER_INTC + 4 * phys_core_id); + let tmp: u32 = mmio_read(Self::REG_TIMER_INTC + 4 * phys_core_id); mmio_write( Self::REG_TIMER_INTC + 4 * phys_core_id, tmp | Self::INTC_CNTPNSIRQ_IRQ, @@ -74,7 +74,7 @@ impl InterruptController for Qa7Intc { } fn is_irq_pending(&self, irq: u32) -> bool { - unsafe { mmio_read(Self::REG_INT_SRC) & (1 << irq) != 0 } + unsafe { mmio_read::(Self::REG_INT_SRC) & (1 << irq) != 0 } } unsafe fn clear_irq(&self, _irq: u32) {} @@ -95,9 +95,9 @@ impl InterruptController for Bcm2837Intc { fn is_irq_pending(&self, irq: u32) -> bool { if irq < 32 { - unsafe { mmio_read(Self::REG_PENDING_IRQ1) & (1 << irq) != 0 } + unsafe { mmio_read::(Self::REG_PENDING_IRQ1) & (1 << irq) != 0 } } else if irq < 64 { - unsafe { mmio_read(Self::REG_PENDING_IRQ2) & (1 << (irq - 32)) != 0 } + unsafe { mmio_read::(Self::REG_PENDING_IRQ2) & (1 << (irq - 32)) != 0 } } else { false } diff --git a/kernel/src/arch/mach_bcm283x/mbox.rs b/kernel/src/arch/mach_bcm283x/mbox.rs index 1f7a8f5..b57af17 100644 --- a/kernel/src/arch/mach_bcm283x/mbox.rs +++ b/kernel/src/arch/mach_bcm283x/mbox.rs @@ -1,5 +1,8 @@ use crate::{ - arch::{cpu, intrin, mmio_read, mmio_write, smp::{self, IpiDelivery, IpiMessage}}, + arch::{ + cpu, intrin, mmio_read, mmio_write, + smp::{self, IpiDelivery, IpiMessage}, + }, KernelSpace, }; use address::{PhysicalAddress, VirtualAddress}; @@ -44,7 +47,10 @@ impl IpiDelivery for CoreMailbox { fn send_ipi(target_id: u32, message: IpiMessage) { unsafe { - mmio_write(Self::REG_SET + target_id as usize * 16, 1 << (message as u32)); + mmio_write( + Self::REG_SET + target_id as usize * 16, + 1 << (message as u32), + ); } } } @@ -56,21 +62,21 @@ impl CoreMailbox { pub fn do_irq(&self) { let phys_core_id = cpu::get_phys_id(); - let value = unsafe { mmio_read(Self::REG_RDCLR + phys_core_id * 16 + self.index * 4) }; + let value: u32 = unsafe { mmio_read(Self::REG_RDCLR + phys_core_id * 16 + self.index * 4) }; if value != 0 { macro_rules! test_ipi { ($value:expr, $msg:expr) => { if $value & (1 << ($msg as u32)) != 0 { smp::handle_ipi($msg); } - } + }; } test_ipi!(value, IpiMessage::Halt); test_ipi!(value, IpiMessage::Tick); unsafe { - mmio_write( + mmio_write::( Self::REG_RDCLR + phys_core_id * 16 + self.index * 4, 0xFFFFFFFF, ); @@ -85,7 +91,7 @@ unsafe fn call(ch: u32) -> Result<(), ()> { )) as u32) | (ch & 0xF); - while mmio_read(MBOX_STATUS) & MBOX_STATUS_FULL != 0 { + while mmio_read::(MBOX_STATUS) & MBOX_STATUS_FULL != 0 { llvm_asm!("nop"); } @@ -93,11 +99,11 @@ unsafe fn call(ch: u32) -> Result<(), ()> { mmio_write(MBOX_WRITE, value); loop { - while mmio_read(MBOX_STATUS) & MBOX_STATUS_EMPTY != 0 { + while mmio_read::(MBOX_STATUS) & MBOX_STATUS_EMPTY != 0 { llvm_asm!("nop"); } - if mmio_read(MBOX_READ) == value { + if mmio_read::(MBOX_READ) == value { if MESSAGE.data[1] == MBOX_RESPONSE { return Ok(()); } else { diff --git a/kernel/src/arch/macros.S b/kernel/src/arch/macros.S index 32571d1..b31c0ec 100644 --- a/kernel/src/arch/macros.S +++ b/kernel/src/arch/macros.S @@ -28,62 +28,4 @@ .set PAGE_ATTR_SHIFT, 2 .set KERNEL_OFFSET, 0xFFFFFF8000000000 - -.macro __exc_save_ctx - sub sp, sp, #192 - - stp x0, x1, [sp, #0] - stp x2, x3, [sp, #16] - stp x4, x5, [sp, #32] - stp x6, x7, [sp, #48] - stp x8, x9, [sp, #64] - stp x10, x11, [sp, #80] - stp x12, x13, [sp, #96] - stp x14, x15, [sp, #112] - stp x16, x17, [sp, #128] - stp x18, x29, [sp, #144] - - mrs x0, elr_el1 - stp x30, x0, [sp, #160] -.endm - -.macro __exc_restore_ctx - ldp x30, x0, [sp, #160] - msr elr_el1, x0 - - ldp x0, x1, [sp, #0] - ldp x2, x3, [sp, #16] - ldp x4, x5, [sp, #32] - ldp x6, x7, [sp, #48] - ldp x8, x9, [sp, #64] - ldp x10, x11, [sp, #80] - ldp x12, x13, [sp, #96] - ldp x14, x15, [sp, #112] - ldp x16, x17, [sp, #128] - ldp x18, x29, [sp, #144] - - add sp, sp, #192 -.endm - -.macro __callee_save_ctx - sub sp, sp, #96 - - stp x19, x20, [sp, #0] - stp x21, x22, [sp, #16] - stp x23, x24, [sp, #32] - stp x25, x26, [sp, #48] - stp x27, x29, [sp, #64] - stp xzr, lr, [sp, #80] -.endm - -.macro __callee_restore_ctx - ldp x19, x20, [sp, #0] - ldp x21, x22, [sp, #16] - ldp x23, x24, [sp, #32] - ldp x25, x26, [sp, #48] - ldp x27, x29, [sp, #64] - ldp xzr, lr, [sp, #80] - - add sp, sp, #96 -.endm .endif diff --git a/kernel/src/arch/vectors.S b/kernel/src/arch/vectors.S index 320347f..4cf0d92 100644 --- a/kernel/src/arch/vectors.S +++ b/kernel/src/arch/vectors.S @@ -1,5 +1,63 @@ .include "kernel/src/arch/macros.S" +.macro __exc_save_ctx + sub sp, sp, #192 + + stp x0, x1, [sp, #0] + stp x2, x3, [sp, #16] + stp x4, x5, [sp, #32] + stp x6, x7, [sp, #48] + stp x8, x9, [sp, #64] + stp x10, x11, [sp, #80] + stp x12, x13, [sp, #96] + stp x14, x15, [sp, #112] + stp x16, x17, [sp, #128] + stp x18, x29, [sp, #144] + + mrs x0, elr_el1 + stp x30, x0, [sp, #160] +.endm + +.macro __exc_restore_ctx + ldp x30, x0, [sp, #160] + msr elr_el1, x0 + + ldp x0, x1, [sp, #0] + ldp x2, x3, [sp, #16] + ldp x4, x5, [sp, #32] + ldp x6, x7, [sp, #48] + ldp x8, x9, [sp, #64] + ldp x10, x11, [sp, #80] + ldp x12, x13, [sp, #96] + ldp x14, x15, [sp, #112] + ldp x16, x17, [sp, #128] + ldp x18, x29, [sp, #144] + + add sp, sp, #192 +.endm + +.macro __callee_save_ctx + sub sp, sp, #96 + + stp x19, x20, [sp, #0] + stp x21, x22, [sp, #16] + stp x23, x24, [sp, #32] + stp x25, x26, [sp, #48] + stp x27, x29, [sp, #64] + stp xzr, lr, [sp, #80] +.endm + +.macro __callee_restore_ctx + ldp x19, x20, [sp, #0] + ldp x21, x22, [sp, #16] + ldp x23, x24, [sp, #32] + ldp x25, x26, [sp, #48] + ldp x27, x29, [sp, #64] + ldp xzr, lr, [sp, #80] + + add sp, sp, #96 +.endm + .section .rodata .global el1_vectors .p2align 7 diff --git a/kernel/src/proc/mod.rs b/kernel/src/proc/mod.rs new file mode 100644 index 0000000..a0f3dd1 --- /dev/null +++ b/kernel/src/proc/mod.rs @@ -0,0 +1,3 @@ +pub mod sched; + +pub struct Process {} diff --git a/kernel/src/proc/sched.rs b/kernel/src/proc/sched.rs new file mode 100644 index 0000000..5fb6a01 --- /dev/null +++ b/kernel/src/proc/sched.rs @@ -0,0 +1,5 @@ +pub struct Queue {} + +pub struct Scheduler { + queue: Queue, +} diff --git a/qemu.sh b/qemu.sh index 9cf5893..e85ff29 100755 --- a/qemu.sh +++ b/qemu.sh @@ -6,12 +6,16 @@ if [ -z "${MACH}" ]; then MACH=rpi3b fi +if [ -z "${PROFILE}" ]; then + PROFILE=debug +fi + if [ -z "$QEMU_BIN" ]; then QEMU_BIN=qemu-system-aarch64 fi ARCH=aarch64-unknown-none-${MACH} -KERNEL=target/${ARCH}/debug/kernel +KERNEL=target/${ARCH}/${PROFILE}/kernel QEMU_OPTS="-chardev stdio,wait=off,id=char0,mux=on \ -mon chardev=char0"