From 4cdeeb8556a5364f5dee9e2dfb5ca1fdb4c2aa32 Mon Sep 17 00:00:00 2001 From: Berkus Decker Date: Sat, 22 Jan 2022 23:15:50 +0200 Subject: [PATCH] =?UTF-8?q?refactor:=20=F0=9F=93=A6=20Split=20kernel=20int?= =?UTF-8?q?o=20machine=20and=20nucleus?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move openocd task to upper level and remove kernel build dependency - the qemu runner doesn't really depend on it. --- .cargo/config.toml | 12 +-- Cargo.lock | 56 +++++++----- Justfile | 2 +- Makefile.toml | 83 ++++++++++++++++- machine/Cargo.toml | 36 ++++++++ {nucleus => machine}/src/arch/README.md | 0 {nucleus => machine}/src/arch/aarch64/boot.rs | 0 {nucleus => machine}/src/arch/aarch64/jtag.rs | 0 .../src/arch/aarch64/memory/README.md | 0 .../src/arch/aarch64/memory/addr/asid.rs | 0 .../src/arch/aarch64/memory/addr/mod.rs | 4 +- .../src/arch/aarch64/memory/addr/phys_addr.rs | 0 .../src/arch/aarch64/memory/addr/virt_addr.rs | 0 .../src/arch/aarch64/memory/mmu.rs | 12 +-- .../src/arch/aarch64/memory/mod.rs | 3 +- {nucleus => machine}/src/arch/aarch64/mod.rs | 0 .../src/arch/aarch64/traps.rs | 0 .../src/arch/aarch64/vectors.S | 0 {nucleus => machine}/src/arch/mod.rs | 0 {nucleus => machine}/src/devices/console.rs | 3 +- {nucleus => machine}/src/devices/mod.rs | 0 machine/src/lib.rs | 55 ++++++++++++ {nucleus => machine}/src/macros.rs | 0 {nucleus => machine}/src/mm/bump_allocator.rs | 0 {nucleus => machine}/src/mm/mod.rs | 0 {nucleus => machine}/src/panic.rs | 8 +- {nucleus => machine}/src/platform/README.md | 0 {nucleus => machine}/src/platform/mod.rs | 0 .../src/platform/rpi3/display.rs | 0 {nucleus => machine}/src/platform/rpi3/fb.rs | 0 .../src/platform/rpi3/gpio.rs | 0 .../src/platform/rpi3/mailbox.rs | 1 + .../src/platform/rpi3/mini_uart.rs | 0 {nucleus => machine}/src/platform/rpi3/mod.rs | 0 .../src/platform/rpi3/pl011_uart.rs | 0 .../src/platform/rpi3/power.rs | 1 + {nucleus => machine}/src/platform/rpi3/vc.rs | 0 {nucleus => machine}/src/qemu.rs | 2 - {nucleus => machine}/src/sync.rs | 0 {nucleus => machine}/src/tests.rs | 3 +- {nucleus => machine}/src/write_to.rs | 0 nucleus/Cargo.toml | 20 ++--- nucleus/Makefile.toml | 83 ++--------------- nucleus/src/main.rs | 90 +++++++------------ 44 files changed, 270 insertions(+), 204 deletions(-) create mode 100644 machine/Cargo.toml rename {nucleus => machine}/src/arch/README.md (100%) rename {nucleus => machine}/src/arch/aarch64/boot.rs (100%) rename {nucleus => machine}/src/arch/aarch64/jtag.rs (100%) rename {nucleus => machine}/src/arch/aarch64/memory/README.md (100%) rename {nucleus => machine}/src/arch/aarch64/memory/addr/asid.rs (100%) rename {nucleus => machine}/src/arch/aarch64/memory/addr/mod.rs (71%) rename {nucleus => machine}/src/arch/aarch64/memory/addr/phys_addr.rs (100%) rename {nucleus => machine}/src/arch/aarch64/memory/addr/virt_addr.rs (100%) rename {nucleus => machine}/src/arch/aarch64/memory/mmu.rs (98%) rename {nucleus => machine}/src/arch/aarch64/memory/mod.rs (99%) rename {nucleus => machine}/src/arch/aarch64/mod.rs (100%) rename {nucleus => machine}/src/arch/aarch64/traps.rs (100%) rename {nucleus => machine}/src/arch/aarch64/vectors.S (100%) rename {nucleus => machine}/src/arch/mod.rs (100%) rename {nucleus => machine}/src/devices/console.rs (98%) rename {nucleus => machine}/src/devices/mod.rs (100%) create mode 100644 machine/src/lib.rs rename {nucleus => machine}/src/macros.rs (100%) rename {nucleus => machine}/src/mm/bump_allocator.rs (100%) rename {nucleus => machine}/src/mm/mod.rs (100%) rename {nucleus => machine}/src/panic.rs (69%) rename {nucleus => machine}/src/platform/README.md (100%) rename {nucleus => machine}/src/platform/mod.rs (100%) rename {nucleus => machine}/src/platform/rpi3/display.rs (100%) rename {nucleus => machine}/src/platform/rpi3/fb.rs (100%) rename {nucleus => machine}/src/platform/rpi3/gpio.rs (100%) rename {nucleus => machine}/src/platform/rpi3/mailbox.rs (99%) rename {nucleus => machine}/src/platform/rpi3/mini_uart.rs (100%) rename {nucleus => machine}/src/platform/rpi3/mod.rs (100%) rename {nucleus => machine}/src/platform/rpi3/pl011_uart.rs (100%) rename {nucleus => machine}/src/platform/rpi3/power.rs (98%) rename {nucleus => machine}/src/platform/rpi3/vc.rs (100%) rename {nucleus => machine}/src/qemu.rs (96%) rename {nucleus => machine}/src/sync.rs (100%) rename {nucleus => machine}/src/tests.rs (95%) rename {nucleus => machine}/src/write_to.rs (100%) diff --git a/.cargo/config.toml b/.cargo/config.toml index 7b9f8a7..b452adf 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -1,16 +1,12 @@ -[unstable] -build-std = ["core", "compiler_builtins", "alloc"] -build-std-features = ["compiler-builtins-mem"] - [build] # https://internals.rust-lang.org/t/evaluating-pipelined-rustc-compilation/10199/12 pipelining = true [target.aarch64-vesper-metta] rustflags = [ - "-C", "target-feature=-fp-armv8", - "-C", "target-cpu=cortex-a53", - "-C", "embed-bitcode=yes", - "-Z", "macro-backtrace", + "-C", "target-feature=-fp-armv8", + "-C", "target-cpu=cortex-a53", + "-C", "embed-bitcode=yes", + "-Z", "macro-backtrace", ] runner = "cargo make test-runner" diff --git a/Cargo.lock b/Cargo.lock index f27e78d..7182cb2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,6 +44,38 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "machine" +version = "0.0.1" +dependencies = [ + "bit_field", + "bitflags", + "cfg-if", + "cortex-a", + "qemu-exit", + "r0", + "snafu", + "tock-registers", + "usize_conversions", + "ux", +] + +[[package]] +name = "nucleus" +version = "0.0.1" +dependencies = [ + "bit_field", + "bitflags", + "cfg-if", + "cortex-a", + "machine", + "r0", + "snafu", + "tock-registers", + "usize_conversions", + "ux", +] + [[package]] name = "proc-macro2" version = "1.0.27" @@ -76,9 +108,9 @@ checksum = "bd7a31eed1591dcbc95d92ad7161908e72f4677f8fabf2a32ca49b4237cbf211" [[package]] name = "snafu" -version = "0.7.0-beta.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c25527526a3f0e26586508fc008e03929bc74c64fb00f34c6b22922bf39eaca" +checksum = "2eba135d2c579aa65364522eb78590cdf703176ef71ad4c32b00f58f7afb2df5" dependencies = [ "doc-comment", "snafu-derive", @@ -86,9 +118,9 @@ dependencies = [ [[package]] name = "snafu-derive" -version = "0.7.0-beta.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6cdd4a5d0765ccc385665731d230efeb3b7e43df0770b625161da46bd5c9247" +checksum = "7a7fe9b0669ef117c5cabc5549638528f36771f058ff977d7689deb517833a75" dependencies = [ "heck", "proc-macro2", @@ -136,19 +168,3 @@ name = "ux" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88dfeb711b61ce620c0cb6fd9f8e3e678622f0c971da2a63c4b3e25e88ed012f" - -[[package]] -name = "vesper" -version = "0.0.1" -dependencies = [ - "bit_field", - "bitflags", - "cfg-if", - "cortex-a", - "qemu-exit", - "r0", - "snafu", - "tock-registers", - "usize_conversions", - "ux", -] diff --git a/Justfile b/Justfile index a96ea0e..ab9944e 100644 --- a/Justfile +++ b/Justfile @@ -3,7 +3,7 @@ _default: # Build and run kernel in QEMU with serial port emulation zellij: - cargo make zellij-config + cargo make zellij-nucleus zellij --layout-path emulation/layout.zellij # Build and run kernel in QEMU diff --git a/Makefile.toml b/Makefile.toml index 520b8b0..092f29a 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -38,7 +38,9 @@ VOLUME = { value = "/Volumes/BOOT", condition = { env_not_set = ["VOLUME"] } } # CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true +RUST_LIBS = "-Z build-std=compiler_builtins,core,alloc -Z build-std-features=compiler-builtins-mem" TARGET_JSON = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/targets/${TARGET}.json" +PLATFORM_TARGET="--target=${TARGET_JSON} --features=${TARGET_FEATURES} ${RUST_LIBS}" DEVICE_FEATURES = "noserial" QEMU_FEATURES = "qemu" @@ -65,8 +67,8 @@ QEMU_GDB_OPTS = "-gdb tcp::5555 -S" GDB_CONNECT_FILE = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${TARGET}/gdb-connect" -KERNEL_ELF = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/kernel8" -KERNEL_BIN = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/kernel8.img" +KERNEL_ELF = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${TARGET}/release/nucleus" +KERNEL_BIN = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/nucleus.bin" [tasks.default] alias = "all" @@ -78,6 +80,83 @@ dependencies = ["kernel-binary"] command = "cargo" args = ["modules", "tree"] +[tasks.build] +env = { "TARGET_FEATURES" = "" } +command = "cargo" +args = ["build", "@@split(PLATFORM_TARGET, )", "--release"] + +[tasks.build-qemu] +env = { "TARGET_FEATURES" = "${QEMU_FEATURES}" } +command = "cargo" +args = ["build", "@@split(PLATFORM_TARGET, )", "--release"] + +[tasks.expand] +env = { "TARGET_FEATURES" = "" } +command = "cargo" +args = ["expand", "@@split(PLATFORM_TARGET, )", "--release"] + +[tasks.test] +env = { "TARGET_FEATURES" = "${QEMU_FEATURES}" } +command = "cargo" +args = ["test", "@@split(PLATFORM_TARGET, )"] + +[tasks.docs] +env = { "TARGET_FEATURES" = "" } +command = "cargo" +args = ["doc", "--open", "--no-deps", "@@split(PLATFORM_TARGET, )"] + +[tasks.clippy] +env = { "TARGET_FEATURES" = "", "CLIPPY_FEATURES" = { value = "--features=${CLIPPY_FEATURES}", condition = { env_set = ["CLIPPY_FEATURES"] } } } +command = "cargo" +args = ["clippy", "@@split(PLATFORM_TARGET, )", "@@remove-empty(CLIPPY_FEATURES)", "--", "-D", "warnings"] + +# These tasks are written in cargo-make's own script to make it portable across platforms (no `basename` on Windows) +[tasks.custom-binary] +env = { "BINARY_FILE" = "${BINARY_FILE}" } +script_runner = "@duckscript" +script = [ +''' + binaryFile = basename ${BINARY_FILE} + cp ${BINARY_FILE} ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${binaryFile}.elf + exec --fail-on-error ${OBJCOPY} %{OBJCOPY_PARAMS} ${BINARY_FILE} ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${binaryFile}.bin +''' +] +install_crate = { crate_name = "cargo-binutils", binary = "rust-objcopy", test_arg = ["--help"] } + +[tasks.test-binary] +env = { "BINARY_FILE" = "${CARGO_MAKE_TASK_ARGS}" } +run_task = "custom-binary" + +[tasks.test-runner] +dependencies = ["test-binary"] +script_runner = "@duckscript" +script = [ +''' + binaryFile = basename ${CARGO_MAKE_TASK_ARGS} + exec --fail-on-error ${QEMU} %{QEMU_OPTS} %{QEMU_TESTS_OPTS} -dtb ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/targets/bcm2710-rpi-3-b-plus.dtb -kernel ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${binaryFile}.bin +''' +] + +[tasks.zellij-config] +dependencies = ["build-qemu", "kernel-binary"] +script_runner = "@duckscript" +env = { "ZELLIJ_CONFIG_FILE" = "${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/emulation/zellij-config.sh" } +script = [ +''' + writefile ${ZELLIJ_CONFIG_FILE} "QEMU=${QEMU}\n" + appendfile ${ZELLIJ_CONFIG_FILE} "QEMU_OPTS=\"${QEMU_OPTS}\"\n" + appendfile ${ZELLIJ_CONFIG_FILE} "QEMU_RUNNER_OPTS=${QEMU_RUNNER_OPTS}\n" + appendfile ${ZELLIJ_CONFIG_FILE} "CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}\n" + appendfile ${ZELLIJ_CONFIG_FILE} "KERNEL_BIN=${KERNEL_BIN}\n" +''' +] +install_crate = { crate_name = "zellij", binary = "zellij", test_arg = ["--help"] } + +[tasks.openocd] +script = [ + "${OPENOCD} -f interface/jlink.cfg -f ../ocd/${TARGET_BOARD}_target.cfg" +] + [tasks.sdeject] dependencies = ["sdcard"] script = [ diff --git a/machine/Cargo.toml b/machine/Cargo.toml new file mode 100644 index 0000000..3e78c8e --- /dev/null +++ b/machine/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "machine" +version = "0.0.1" +authors = ["Berkus Decker "] +description = "Vesper nanokernel shared code library." +documentation = "https://docs.metta.systems/vesper" +homepage = "https://github.com/metta-systems/vesper" +repository = "https://github.com/metta-systems/vesper" +readme = "README.md" +license = "BlueOak-1.0.0" +categories = ["no-std", "embedded", "os"] +publish = false +edition = "2021" + +[badges] +maintenance = { status = "experimental" } + +[features] +noserial = [] +# Enable JTAG debugging of kernel - enable jtag helpers and +# block waiting for JTAG probe attach at the start of kernel main. +jtag = [] +# Build for running under QEMU with semihosting, so various halt/reboot options would for example quit QEMU instead. +qemu = [] + +[dependencies] +r0 = "1.0" +qemu-exit = "3.0" +cortex-a = "7.0" +tock-registers = "0.7" +ux = { version = "0.1", default-features = false } +usize_conversions = "0.2" +bit_field = "0.10" +bitflags = "1.3" +cfg-if = "1.0" +snafu = { version = "0.7", default-features = false } diff --git a/nucleus/src/arch/README.md b/machine/src/arch/README.md similarity index 100% rename from nucleus/src/arch/README.md rename to machine/src/arch/README.md diff --git a/nucleus/src/arch/aarch64/boot.rs b/machine/src/arch/aarch64/boot.rs similarity index 100% rename from nucleus/src/arch/aarch64/boot.rs rename to machine/src/arch/aarch64/boot.rs diff --git a/nucleus/src/arch/aarch64/jtag.rs b/machine/src/arch/aarch64/jtag.rs similarity index 100% rename from nucleus/src/arch/aarch64/jtag.rs rename to machine/src/arch/aarch64/jtag.rs diff --git a/nucleus/src/arch/aarch64/memory/README.md b/machine/src/arch/aarch64/memory/README.md similarity index 100% rename from nucleus/src/arch/aarch64/memory/README.md rename to machine/src/arch/aarch64/memory/README.md diff --git a/nucleus/src/arch/aarch64/memory/addr/asid.rs b/machine/src/arch/aarch64/memory/addr/asid.rs similarity index 100% rename from nucleus/src/arch/aarch64/memory/addr/asid.rs rename to machine/src/arch/aarch64/memory/addr/asid.rs diff --git a/nucleus/src/arch/aarch64/memory/addr/mod.rs b/machine/src/arch/aarch64/memory/addr/mod.rs similarity index 71% rename from nucleus/src/arch/aarch64/memory/addr/mod.rs rename to machine/src/arch/aarch64/memory/addr/mod.rs index 54076b1..665f2ff 100644 --- a/nucleus/src/arch/aarch64/memory/addr/mod.rs +++ b/machine/src/arch/aarch64/memory/addr/mod.rs @@ -7,6 +7,4 @@ mod asid; mod phys_addr; mod virt_addr; -pub use asid::*; -pub use phys_addr::*; -pub use virt_addr::*; +pub use {asid::*, phys_addr::*, virt_addr::*}; diff --git a/nucleus/src/arch/aarch64/memory/addr/phys_addr.rs b/machine/src/arch/aarch64/memory/addr/phys_addr.rs similarity index 100% rename from nucleus/src/arch/aarch64/memory/addr/phys_addr.rs rename to machine/src/arch/aarch64/memory/addr/phys_addr.rs diff --git a/nucleus/src/arch/aarch64/memory/addr/virt_addr.rs b/machine/src/arch/aarch64/memory/addr/virt_addr.rs similarity index 100% rename from nucleus/src/arch/aarch64/memory/addr/virt_addr.rs rename to machine/src/arch/aarch64/memory/addr/virt_addr.rs diff --git a/nucleus/src/arch/aarch64/memory/mmu.rs b/machine/src/arch/aarch64/memory/mmu.rs similarity index 98% rename from nucleus/src/arch/aarch64/memory/mmu.rs rename to machine/src/arch/aarch64/memory/mmu.rs index c3d6e8b..19a0b80 100644 --- a/nucleus/src/arch/aarch64/memory/mmu.rs +++ b/machine/src/arch/aarch64/memory/mmu.rs @@ -13,18 +13,12 @@ use { crate::{ - arch::aarch64::memory::{ - get_virt_addr_properties, AttributeFields, /*FrameAllocator, PhysAddr, VirtAddr,*/ - }, + arch::aarch64::memory::{get_virt_addr_properties, AttributeFields}, println, }, - // bitflags::bitflags, core::{ - // convert::TryInto, - // fmt, marker::PhantomData, ops::{Index, IndexMut}, - // ptr::Unique, }, cortex_a::{ asm::barrier, @@ -35,12 +29,10 @@ use { interfaces::{ReadWriteable, Readable, Writeable}, register_bitfields, }, - // ux::*, }; mod mair { - use cortex_a::registers::MAIR_EL1; - use tock_registers::interfaces::Writeable; + use {cortex_a::registers::MAIR_EL1, tock_registers::interfaces::Writeable}; /// Setup function for the MAIR_EL1 register. pub fn set_up() { diff --git a/nucleus/src/arch/aarch64/memory/mod.rs b/machine/src/arch/aarch64/memory/mod.rs similarity index 99% rename from nucleus/src/arch/aarch64/memory/mod.rs rename to machine/src/arch/aarch64/memory/mod.rs index 2df8fe7..b5a1aa2 100644 --- a/nucleus/src/arch/aarch64/memory/mod.rs +++ b/machine/src/arch/aarch64/memory/mod.rs @@ -13,8 +13,7 @@ use { mod addr; pub mod mmu; -pub use addr::PhysAddr; -pub use addr::VirtAddr; +pub use addr::{PhysAddr, VirtAddr}; // aarch64 granules and page sizes howto: // https://stackoverflow.com/questions/34269185/simultaneous-existence-of-different-sized-pages-on-aarch64 diff --git a/nucleus/src/arch/aarch64/mod.rs b/machine/src/arch/aarch64/mod.rs similarity index 100% rename from nucleus/src/arch/aarch64/mod.rs rename to machine/src/arch/aarch64/mod.rs diff --git a/nucleus/src/arch/aarch64/traps.rs b/machine/src/arch/aarch64/traps.rs similarity index 100% rename from nucleus/src/arch/aarch64/traps.rs rename to machine/src/arch/aarch64/traps.rs diff --git a/nucleus/src/arch/aarch64/vectors.S b/machine/src/arch/aarch64/vectors.S similarity index 100% rename from nucleus/src/arch/aarch64/vectors.S rename to machine/src/arch/aarch64/vectors.S diff --git a/nucleus/src/arch/mod.rs b/machine/src/arch/mod.rs similarity index 100% rename from nucleus/src/arch/mod.rs rename to machine/src/arch/mod.rs diff --git a/nucleus/src/devices/console.rs b/machine/src/devices/console.rs similarity index 98% rename from nucleus/src/devices/console.rs rename to machine/src/devices/console.rs index 87095d7..6df1176 100644 --- a/nucleus/src/devices/console.rs +++ b/machine/src/devices/console.rs @@ -4,8 +4,7 @@ #![allow(dead_code)] -use crate::platform; -use core::fmt; +use {crate::platform, core::fmt}; /// A trait that must be implemented by devices that are candidates for the /// global console. diff --git a/nucleus/src/devices/mod.rs b/machine/src/devices/mod.rs similarity index 100% rename from nucleus/src/devices/mod.rs rename to machine/src/devices/mod.rs diff --git a/machine/src/lib.rs b/machine/src/lib.rs new file mode 100644 index 0000000..4d30c40 --- /dev/null +++ b/machine/src/lib.rs @@ -0,0 +1,55 @@ +#![no_std] +#![no_main] +#![feature(decl_macro)] +#![feature(allocator_api)] +#![feature(format_args_nl)] +#![feature(nonnull_slice_from_raw_parts)] +#![feature(custom_test_frameworks)] +#![test_runner(crate::tests::test_runner)] +#![reexport_test_harness_main = "test_main"] +#![allow(clippy::upper_case_acronyms)] +#![allow(clippy::enum_variant_names)] +#![allow(clippy::nonstandard_macro_braces)] // https://github.com/shepmaster/snafu/issues/296 +#![allow(missing_docs)] // Temp: switch to deny +#![deny(warnings)] + +#[cfg(not(target_arch = "aarch64"))] +use architecture_not_supported_sorry; + +/// Architecture-specific code. +#[macro_use] +pub mod arch; + +pub use arch::*; + +pub mod devices; +pub mod macros; +mod mm; +pub mod panic; +pub mod platform; +pub mod qemu; +mod sync; +pub mod tests; +pub mod write_to; + +/// The global console. Output of the kernel print! and println! macros goes here. +pub static CONSOLE: sync::NullLock = sync::NullLock::new(devices::Console::new()); + +/// The global allocator for DMA-able memory. That is, memory which is tagged +/// non-cacheable in the page tables. +static DMA_ALLOCATOR: sync::NullLock = + sync::NullLock::new(mm::BumpAllocator::new( + // @todo Init this after we loaded boot memory map + memory::map::virt::DMA_HEAP_START as usize, + memory::map::virt::DMA_HEAP_END as usize, + "Global DMA Allocator", + // Try the following arguments instead to see all mailbox operations + // fail. It will cause the allocator to use memory that are marked + // cacheable and therefore not DMA-safe. The answer from the VideoCore + // won't be received by the CPU because it reads an old cached value + // that resembles an error case instead. + + // 0x00600000 as usize, + // 0x007FFFFF as usize, + // "Global Non-DMA Allocator", + )); diff --git a/nucleus/src/macros.rs b/machine/src/macros.rs similarity index 100% rename from nucleus/src/macros.rs rename to machine/src/macros.rs diff --git a/nucleus/src/mm/bump_allocator.rs b/machine/src/mm/bump_allocator.rs similarity index 100% rename from nucleus/src/mm/bump_allocator.rs rename to machine/src/mm/bump_allocator.rs diff --git a/nucleus/src/mm/mod.rs b/machine/src/mm/mod.rs similarity index 100% rename from nucleus/src/mm/mod.rs rename to machine/src/mm/mod.rs diff --git a/nucleus/src/panic.rs b/machine/src/panic.rs similarity index 69% rename from nucleus/src/panic.rs rename to machine/src/panic.rs index 0dce614..3ca9075 100644 --- a/nucleus/src/panic.rs +++ b/machine/src/panic.rs @@ -1,14 +1,10 @@ -#[cfg(not(test))] -#[panic_handler] -fn panicked(info: &core::panic::PanicInfo) -> ! { +pub fn handler(info: &core::panic::PanicInfo) -> ! { // @todo This may fail to print if the panic message is too long for local print buffer. crate::println!("{}", info); crate::endless_sleep() } -#[cfg(test)] -#[panic_handler] -fn panicked(info: &core::panic::PanicInfo) -> ! { +pub fn handler_for_tests(info: &core::panic::PanicInfo) -> ! { crate::println!("\n[failed]\n"); // @todo This may fail to print if the panic message is too long for local print buffer. crate::println!("\nError: {}\n", info); diff --git a/nucleus/src/platform/README.md b/machine/src/platform/README.md similarity index 100% rename from nucleus/src/platform/README.md rename to machine/src/platform/README.md diff --git a/nucleus/src/platform/mod.rs b/machine/src/platform/mod.rs similarity index 100% rename from nucleus/src/platform/mod.rs rename to machine/src/platform/mod.rs diff --git a/nucleus/src/platform/rpi3/display.rs b/machine/src/platform/rpi3/display.rs similarity index 100% rename from nucleus/src/platform/rpi3/display.rs rename to machine/src/platform/rpi3/display.rs diff --git a/nucleus/src/platform/rpi3/fb.rs b/machine/src/platform/rpi3/fb.rs similarity index 100% rename from nucleus/src/platform/rpi3/fb.rs rename to machine/src/platform/rpi3/fb.rs diff --git a/nucleus/src/platform/rpi3/gpio.rs b/machine/src/platform/rpi3/gpio.rs similarity index 100% rename from nucleus/src/platform/rpi3/gpio.rs rename to machine/src/platform/rpi3/gpio.rs diff --git a/nucleus/src/platform/rpi3/mailbox.rs b/machine/src/platform/rpi3/mailbox.rs similarity index 99% rename from nucleus/src/platform/rpi3/mailbox.rs rename to machine/src/platform/rpi3/mailbox.rs index 76eff72..fe4c112 100644 --- a/nucleus/src/platform/rpi3/mailbox.rs +++ b/machine/src/platform/rpi3/mailbox.rs @@ -361,6 +361,7 @@ impl PreparedMailbox { impl Mailbox { /// Create a new mailbox in the DMA-able memory area. + #[allow(clippy::result_unit_err)] pub fn new(base_addr: usize) -> ::core::result::Result { use core::alloc::Allocator; crate::DMA_ALLOCATOR diff --git a/nucleus/src/platform/rpi3/mini_uart.rs b/machine/src/platform/rpi3/mini_uart.rs similarity index 100% rename from nucleus/src/platform/rpi3/mini_uart.rs rename to machine/src/platform/rpi3/mini_uart.rs diff --git a/nucleus/src/platform/rpi3/mod.rs b/machine/src/platform/rpi3/mod.rs similarity index 100% rename from nucleus/src/platform/rpi3/mod.rs rename to machine/src/platform/rpi3/mod.rs diff --git a/nucleus/src/platform/rpi3/pl011_uart.rs b/machine/src/platform/rpi3/pl011_uart.rs similarity index 100% rename from nucleus/src/platform/rpi3/pl011_uart.rs rename to machine/src/platform/rpi3/pl011_uart.rs diff --git a/nucleus/src/platform/rpi3/power.rs b/machine/src/platform/rpi3/power.rs similarity index 98% rename from nucleus/src/platform/rpi3/power.rs rename to machine/src/platform/rpi3/power.rs index 882d9c8..279b901 100644 --- a/nucleus/src/platform/rpi3/power.rs +++ b/machine/src/platform/rpi3/power.rs @@ -64,6 +64,7 @@ impl ops::Deref for Power { } impl Power { + #[allow(clippy::new_without_default)] pub fn new() -> Power { Power } diff --git a/nucleus/src/platform/rpi3/vc.rs b/machine/src/platform/rpi3/vc.rs similarity index 100% rename from nucleus/src/platform/rpi3/vc.rs rename to machine/src/platform/rpi3/vc.rs diff --git a/nucleus/src/qemu.rs b/machine/src/qemu.rs similarity index 96% rename from nucleus/src/qemu.rs rename to machine/src/qemu.rs index 4160433..2aff30b 100644 --- a/nucleus/src/qemu.rs +++ b/machine/src/qemu.rs @@ -12,7 +12,6 @@ pub mod semihosting { qemu_exit_handle.exit_success() } - #[cfg(test)] pub fn exit_failure() -> ! { use qemu_exit::QEMUExit; @@ -22,7 +21,6 @@ pub mod semihosting { qemu_exit_handle.exit_failure() } - #[cfg(test)] pub fn sys_write0_call(text: &str) { // SAFETY: text must be \0-terminated! let cmd = 0x04; diff --git a/nucleus/src/sync.rs b/machine/src/sync.rs similarity index 100% rename from nucleus/src/sync.rs rename to machine/src/sync.rs diff --git a/nucleus/src/tests.rs b/machine/src/tests.rs similarity index 95% rename from nucleus/src/tests.rs rename to machine/src/tests.rs index 7fe9835..52df0bf 100644 --- a/nucleus/src/tests.rs +++ b/machine/src/tests.rs @@ -8,7 +8,7 @@ use crate::{print, println, qemu}; pub trait TestFn { - fn run(&self) -> (); + fn run(&self); } impl TestFn for T @@ -22,7 +22,6 @@ where } } -#[cfg(test)] pub fn test_runner(tests: &[&dyn TestFn]) { println!("Running {} tests", tests.len()); for test in tests { diff --git a/nucleus/src/write_to.rs b/machine/src/write_to.rs similarity index 100% rename from nucleus/src/write_to.rs rename to machine/src/write_to.rs diff --git a/nucleus/Cargo.toml b/nucleus/Cargo.toml index 9b9b24c..2dd4ebb 100644 --- a/nucleus/Cargo.toml +++ b/nucleus/Cargo.toml @@ -1,8 +1,8 @@ [package] -name = "vesper" +name = "nucleus" version = "0.0.1" authors = ["Berkus Decker "] -description = "Vesper exokernel" +description = "Vesper nanokernel binary" documentation = "https://docs.metta.systems/vesper" homepage = "https://github.com/metta-systems/vesper" repository = "https://github.com/metta-systems/vesper" @@ -16,21 +16,21 @@ edition = "2021" maintenance = { status = "experimental" } [features] -noserial = [] +noserial = ["machine/noserial"] # Enable JTAG debugging of kernel - enable jtag helpers and # block waiting for JTAG probe attach at the start of kernel main. -jtag = [] +jtag = ["machine/jtag"] # Build for running under QEMU with semihosting, so various halt/reboot options would for example quit QEMU instead. -qemu = ["qemu-exit"] +qemu = ["machine/qemu"] [dependencies] +machine = { path = "../machine" } r0 = "1.0" -qemu-exit = { version = "3.0", optional = true } cortex-a = "7.0" tock-registers = "0.7" -ux = { version = "0.1.3", default-features = false } -usize_conversions = "0.2.0" -bit_field = "0.10.1" +ux = { version = "0.1", default-features = false } +usize_conversions = "0.2" +bit_field = "0.10" bitflags = "1.3" cfg-if = "1.0" -snafu = { version = "0.7.0-beta.2", default-features = false } +snafu = { version = "0.7", default-features = false } diff --git a/nucleus/Makefile.toml b/nucleus/Makefile.toml index 9b7a90b..3d6249d 100644 --- a/nucleus/Makefile.toml +++ b/nucleus/Makefile.toml @@ -3,92 +3,28 @@ # # Copyright (c) Berkus Decker # -[tasks.build] -env = { "TARGET_FEATURES" = "" } -args = ["build", "--target=${TARGET_JSON}", "--release", "--features=${TARGET_FEATURES}"] - -[tasks.expand] -env = { "TARGET_FEATURES" = "" } -args = ["expand", "--target=${TARGET_JSON}", "--release", "--features=${TARGET_FEATURES}"] - -[tasks.test] -env = { "TARGET_FEATURES" = "${QEMU_FEATURES}" } -args = ["test", "--target=${TARGET_JSON}", "--features=${TARGET_FEATURES}"] - -[tasks.docs] -env = { "TARGET_FEATURES" = "" } -args = ["doc", "--open", "--no-deps", "--target=${TARGET_JSON}", "--features=${TARGET_FEATURES}"] - -# These tasks are written in cargo-make's own script to make it portable across platforms (no `basename` on Windows) [tasks.kernel-binary] -script_runner = "@duckscript" -script = [ -''' - cp ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${TARGET}/release/vesper ${KERNEL_ELF} - exec --fail-on-error ${OBJCOPY} %{OBJCOPY_PARAMS} ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${TARGET}/release/vesper ${KERNEL_BIN} -''' -] - -[tasks.custom-binary] -script_runner = "@duckscript" -script = [ -''' - binaryFile = basename ${CARGO_MAKE_TASK_ARGS} - cp ${CARGO_MAKE_TASK_ARGS} ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${binaryFile}.elf - exec --fail-on-error ${OBJCOPY} %{OBJCOPY_PARAMS} ${CARGO_MAKE_TASK_ARGS} ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${binaryFile}.bin -''' -] - -[tasks.test-runner] -dependencies = ["custom-binary"] -script_runner = "@duckscript" -script = [ -''' - binaryFile = basename ${CARGO_MAKE_TASK_ARGS} - exec --fail-on-error ${QEMU} %{QEMU_OPTS} %{QEMU_TESTS_OPTS} -dtb ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/targets/bcm2710-rpi-3-b-plus.dtb -kernel ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/target/${binaryFile}.bin -''' -] - -[tasks.build-qemu] -env = { "TARGET_FEATURES" = "${QEMU_FEATURES}" } -command = "cargo" -args = ["build", "--target=${TARGET_JSON}", "--release", "--features=${TARGET_FEATURES}"] +env = { "BINARY_FILE" = "${KERNEL_ELF}" } +run_task = "custom-binary" [tasks.qemu-runner] +dependencies = ["build-qemu", "kernel-binary"] env = { "TARGET_FEATURES" = "${QEMU_FEATURES}" } script = [ "${QEMU} ${QEMU_OPTS} ${QEMU_RUNNER_OPTS} -dtb ${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}/targets/bcm2710-rpi-3-b-plus.dtb -kernel ${KERNEL_BIN}" ] -dependencies = ["build-qemu", "kernel-binary"] [tasks.qemu] extend = "qemu-runner" env = { "QEMU_RUNNER_OPTS" = "${QEMU_SERIAL_OPTS}" } -[tasks.zellij-config] -extend = "qemu-runner" -script_runner = "@duckscript" -env = { "ZELLIJ_CONFIG_FILE" = "../emulation/zellij-config.sh" } -script = [ -''' - writefile ${ZELLIJ_CONFIG_FILE} "QEMU=${QEMU}\n" - appendfile ${ZELLIJ_CONFIG_FILE} "QEMU_OPTS=\"${QEMU_OPTS}\"\n" - appendfile ${ZELLIJ_CONFIG_FILE} "QEMU_RUNNER_OPTS=${QEMU_RUNNER_OPTS}\n" - appendfile ${ZELLIJ_CONFIG_FILE} "CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY=${CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY}\n" - appendfile ${ZELLIJ_CONFIG_FILE} "KERNEL_BIN=${KERNEL_BIN}\n" -''' -] -install_crate = { crate_name = "zellij", binary = "zellij", test_arg = ["--help"] } - [tasks.qemu-gdb] extend = "qemu-runner" env = { "QEMU_RUNNER_OPTS" = "${QEMU_SERIAL_OPTS} ${QEMU_GDB_OPTS}" } -[tasks.openocd] -dependencies = ["build", "kernel-binary"] -script = [ - "${OPENOCD} -f interface/jlink.cfg -f ../ocd/${TARGET_BOARD}_target.cfg" -] +[tasks.zellij-nucleus] +env = { "KERNEL_BIN" = "${KERNEL_BIN}" } +run_task = "zellij-config" [tasks.gdb-config] script_runner = "@duckscript" @@ -110,7 +46,7 @@ dependencies = ["build", "kernel-binary"] script = [ "${NM} -- ${KERNEL_ELF} | sort" ] -#install_crate = "cargo-binutils" +install_crate = { crate_name = "cargo-binutils", binary = "rust-nm", test_arg = ["--help"] } [tasks.sdcard] dependencies = ["build", "kernel-binary"] @@ -122,11 +58,6 @@ script = [ ''' ] -[tasks.clippy] -env = { "TARGET_FEATURES" = { value = "--features=${CLIPPY_FEATURES}", condition = { env_set = ["CLIPPY_FEATURES"] } } } -command = "cargo" -args = ["clippy", "--target=${TARGET_JSON}", "@@remove-empty(TARGET_FEATURES)", "--", "-D", "warnings"] - [tasks.hopper] dependencies = ["build", "kernel-binary"] # The cmd line below causes a bug in hopper, see https://www.dropbox.com/s/zyw5mfx0bepcjb1/hopperv4-RAW-bug.mov?dl=0 diff --git a/nucleus/src/main.rs b/nucleus/src/main.rs index 381ac02..8a60006 100644 --- a/nucleus/src/main.rs +++ b/nucleus/src/main.rs @@ -9,71 +9,36 @@ #![no_std] #![no_main] -#![feature(decl_macro)] -#![feature(allocator_api)] #![feature(ptr_internals)] #![feature(format_args_nl)] -#![feature(nonnull_slice_from_raw_parts)] #![feature(custom_test_frameworks)] -#![test_runner(crate::tests::test_runner)] +#![test_runner(machine::tests::test_runner)] #![reexport_test_harness_main = "test_main"] #![deny(missing_docs)] #![deny(warnings)] -#![allow(clippy::nonstandard_macro_braces)] // https://github.com/shepmaster/snafu/issues/296 -#![allow(clippy::upper_case_acronyms)] -#![allow(clippy::enum_variant_names)] - -#[cfg(not(target_arch = "aarch64"))] -use architecture_not_supported_sorry; - -/// Architecture-specific code. -#[macro_use] -pub mod arch; -pub use arch::*; -mod devices; -mod macros; -mod mm; -mod panic; -mod platform; -#[cfg(feature = "qemu")] -mod qemu; -mod sync; -#[cfg(test)] -mod tests; -mod write_to; +#[cfg(not(test))] +use core::panic::PanicInfo; use { - crate::platform::rpi3::{ - display::{Color, DrawError}, - mailbox::{channel, Mailbox, MailboxOps}, - vc::VC, - }, cfg_if::cfg_if, + machine::{ + arch, entry, memory, + platform::rpi3::{ + display::{Color, DrawError}, + mailbox::{channel, Mailbox, MailboxOps}, + vc::VC, + }, + println, CONSOLE, + }, }; entry!(kmain); -/// The global console. Output of the kernel print! and println! macros goes here. -static CONSOLE: sync::NullLock = sync::NullLock::new(devices::Console::new()); - -/// The global allocator for DMA-able memory. That is, memory which is tagged -/// non-cacheable in the page tables. -static DMA_ALLOCATOR: sync::NullLock = - sync::NullLock::new(mm::BumpAllocator::new( - // @todo Init this after we loaded boot memory map - memory::map::virt::DMA_HEAP_START as usize, - memory::map::virt::DMA_HEAP_END as usize, - "Global DMA Allocator", - // Try the following arguments instead to see all mailbox operations - // fail. It will cause the allocator to use memory that are marked - // cacheable and therefore not DMA-safe. The answer from the VideoCore - // won't be received by the CPU because it reads an old cached value - // that resembles an error case instead. - - // 0x00600000 as usize, - // 0x007FFFFF as usize, - // "Global Non-DMA Allocator", - )); +#[cfg(not(test))] +#[panic_handler] +fn panicked(info: &PanicInfo) -> ! { + machine::panic::handler(info) +} fn print_mmu_state_and_features() { memory::mmu::print_features(); @@ -103,7 +68,7 @@ fn init_exception_traps() { #[cfg(not(feature = "noserial"))] fn init_uart_serial() { - use crate::platform::rpi3::{gpio::GPIO, mini_uart::MiniUart, pl011_uart::PL011Uart}; + use machine::platform::rpi3::{gpio::GPIO, mini_uart::MiniUart, pl011_uart::PL011Uart}; let gpio = GPIO::default(); let uart = MiniUart::default(); @@ -131,7 +96,7 @@ fn init_uart_serial() { // physical wires (e.g. the Framebuffer), you don't need to do this, // because flush() is anyways called implicitly by replace_with(). This // is just a special case. - use crate::devices::console::ConsoleOps; + use machine::devices::console::ConsoleOps; CONSOLE.lock(|c| c.flush()); match uart.prepare(mbox, &gpio) { @@ -151,7 +116,7 @@ fn init_uart_serial() { #[inline] pub fn kmain() -> ! { #[cfg(feature = "jtag")] - jtag::wait_debugger(); + machine::arch::jtag::wait_debugger(); init_mmu(); init_exception_traps(); @@ -181,7 +146,7 @@ fn command_prompt() { b"uart" => init_uart_serial(), b"disp" => check_display_init(), b"trap" => check_data_abort_trap(), - b"map" => arch::memory::print_layout(), + b"map" => machine::arch::memory::print_layout(), b"led on" => set_led(true), b"led off" => set_led(false), b"help" => print_help(), @@ -222,9 +187,9 @@ fn reboot() -> ! { cfg_if! { if #[cfg(feature = "qemu")] { println!("Bye, shutting down QEMU"); - qemu::semihosting::exit_success() + machine::qemu::semihosting::exit_success() } else { - use crate::platform::rpi3::power::Power; + use machine::platform::rpi3::power::Power; println!("Bye, going to reset now"); Power::new().reset() @@ -251,7 +216,7 @@ fn display_graphics() -> Result<(), DrawError> { display.draw_text(50, 50, "Hello there!", Color::rgb(128, 192, 255))?; let mut buf = [0u8; 64]; - let s = write_to::show(&mut buf, format_args!("Display width {}", display.width)); + let s = machine::write_to::show(&mut buf, format_args!("Display width {}", display.width)); if s.is_err() { display.draw_text(50, 150, "Error displaying", Color::red())? @@ -280,7 +245,12 @@ fn check_data_abort_trap() { #[cfg(test)] mod main_tests { - use super::*; + use {super::*, core::panic::PanicInfo}; + + #[panic_handler] + fn panicked(info: &PanicInfo) -> ! { + machine::panic::handler_for_tests(info) + } #[test_case] fn test_data_abort_trap() {