diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index c93dfe7..ed35d9b 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -10,7 +10,7 @@ jobs: build: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 diff --git a/.gitmodules b/.gitmodules index 3851b15..de3dd3f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,6 @@ [submodule "src/services/src/supervisor-riscv"] path = src/services/src/supervisor-riscv url = https://github.com/diodesign/supervisor-riscv.git -[submodule "src/mason"] - path = src/mason - url = https://github.com/diodesign/mason.git [submodule "src/mkdmfs"] path = src/mkdmfs url = https://github.com/diodesign/mkdmfs @@ -19,3 +16,6 @@ [submodule "src/services/src/gooey"] path = src/services/src/gooey url = https://github.com/diodesign/gooey.git +[submodule "src/itsylinker"] + path = src/itsylinker + url = https://github.com/diodesign/itsylinker.git diff --git a/Dockerfile b/Dockerfile index aedfb22..8bb3b3c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -22,7 +22,7 @@ COPY . /diosix WORKDIR /diosix # Install necessary bits and pieces of Rust and just, pull in the submodules, and then build diosix -RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly -y \ +RUN curl https://sh.rustup.rs -sSf | sh -s -- --profile minimal --default-toolchain nightly -y \ && . $HOME/.cargo/env \ && cargo install --force just \ && git submodule update --init --recursive \ diff --git a/docs/running.md b/docs/running.md index 1310ce9..ec1e30a 100644 --- a/docs/running.md +++ b/docs/running.md @@ -32,11 +32,7 @@ These steps will prepare your system for building and running Diosix using its l sudo apt -y install build-essential pkg-config git curl binutils-riscv64-linux-gnu qemu-system-misc libssl-dev ``` -2. If you have not yet installed the Rust toolchain, follow [these instructions](https://www.rust-lang.org/tools/install) to do so. Make the `nightly` version of Rust the default toolchain: - - ``` - rustup default nightly - ``` +2. If you have not yet installed the Rust toolchain, follow [these instructions](https://www.rust-lang.org/tools/install) to do so. 3. Install [`just`](https://github.com/casey/just), which Diosix uses to automate the steps needed to build and run the project: @@ -63,7 +59,7 @@ This will check to see if Diosix needs to be built. If so, the project will auto Diosix is then booted in a Qemu RISC-V environment, and the hypervisor will start the included services and guests. To exit the emulator, press `Control-a` then `x`. The guest OSes provided by default are BusyBox-based Linux operating systems. To log in, use the username `root`. No password is required. -## Using the system console +### Using the system console By default, Diosix will run a system service called `gooey` that provides a very simple user interface. This is accessed through the terminal when using Qemu, and on real hardware, through the system's first serial port. diff --git a/justfile b/justfile index 0bc5778..ad62615 100644 --- a/justfile +++ b/justfile @@ -155,6 +155,9 @@ guests_sw := if guests == "no" { "--skip-guests" } else { "" } downloads_sw := if guests-download == "no" { "--skip-downloads" } else { "" } builds_sw := if guests-build == "no" { "--skip-buildroot" } else { "" } +# use rustc's nightly build +cargo_cmd := "cargo +nightly" + # the default recipe # build diosix with its components, and run it within qemu @qemu: build @@ -176,7 +179,7 @@ builds_sw := if guests-build == "no" { "--skip-buildroot" } else { "" } # the core workflow for building diosix and its components # a link is created at final-exe-path to the final packaged executable -@build: _descr _rustup _hypervisor +@build: _descr _rustup _itsylinker _hypervisor ln -fs {{target}}/{{quality_sw}}/hypervisor {{final-exe-path}} echo "{{builtmsg}} {{final-exe-path}}" @@ -184,43 +187,49 @@ builds_sw := if guests-build == "no" { "--skip-buildroot" } else { "" } @_descr: echo "{{buildmsg}} {{quality_sw}}-grade Diosix for {{target}} systems" -# build the hypervisor and ensure it has a boot file system to include +# build the itsy-bitsy linker ready for use +@_itsylinker: + echo "{{buildmsg}} linker" + cd src/itsylinker && {{cargo_cmd}} build {{quiet_sw}} + +# build the hypervisor after ensuring it has a boot file system to include @_hypervisor: _mkdmfs echo "{{buildmsg}} hypervisor" - cd src/hypervisor && cargo build {{cargo_sw}} {{qemuprint_sw}} {{sifiveprint_sw}} {{htifprint_sw}} {{integritychecks_sw}} + cd src/hypervisor && {{cargo_cmd}} build {{cargo_sw}} {{qemuprint_sw}} {{sifiveprint_sw}} {{htifprint_sw}} {{integritychecks_sw}} # build and run the dmfs generator to include banners and system services. # mkdmfs is configured by manifest.toml in the project root directory. -# the output fs image is linked in the hypervisor and unpacked at run-time +# the output fs image is linked in the hypervisor and unpacked at run-time. # # the target directory stores the dmfs image file @_mkdmfs: _services echo "{{buildmsg}} dmfs image" - cd src/mkdmfs && cargo run {{quiet_sw}} -- -t {{target}} -q {{quality_sw}} {{verbose_sw}} {{services_sw}} {{guests_sw}} {{downloads_sw}} {{builds_sw}} + cd src/mkdmfs && {{cargo_cmd}} run {{quiet_sw}} --release -- -t {{target}} -q {{quality_sw}} {{verbose_sw}} {{services_sw}} {{guests_sw}} {{downloads_sw}} {{builds_sw}} # build the system services @_services: echo "{{buildmsg}} system services" - cd src/services && cargo build {{cargo_sw}} + cd src/services && {{cargo_cmd}} build {{cargo_sw}} # make sure we've got the cross-compiler installed and setup @_rustup: echo "{{rustupmsg}} {{target}}" - rustup {{quiet_sw}} target install {{target}} + rustup {{quiet_sw}} toolchain install nightly + rustup {{quiet_sw}} target install {{target}} --toolchain nightly # delete intermediate build files and update cargo dependencies to start afresh @clean: echo "{{cleanmsg}}" - -cd src/hypervisor && cargo {{quiet_sw}} clean && cargo {{quiet_sw}} update - -cd src/services && cargo {{quiet_sw}} clean && cargo {{quiet_sw}} update - -cd src/mkdmfs && cargo {{quiet_sw}} clean && cargo {{quiet_sw}} update + -cd src/hypervisor && {{cargo_cmd}} {{quiet_sw}} clean && {{cargo_cmd}} {{quiet_sw}} update + -cd src/services && {{cargo_cmd}} {{quiet_sw}} clean && {{cargo_cmd}} {{quiet_sw}} update + -cd src/mkdmfs && {{cargo_cmd}} {{quiet_sw}} clean && {{cargo_cmd}} {{quiet_sw}} update # FIXME: the framework for this is broken. # run unit tests for each major component # @_test: -# -cd src/hypervisor && cargo {{quiet_sw}} test -# -cd src/services && cargo {{quiet_sw}} test -# -cd src/mkdmfs && cargo {{quiet_sw}} test +# -cd src/hypervisor && {{cargo_cmd}} {{quiet_sw}} test +# -cd src/services && {{cargo_cmd}} {{quiet_sw}} test +# -cd src/mkdmfs && {{cargo_cmd}} {{quiet_sw}} test # are we allowed one easter egg? @_incredible: diff --git a/manifest.toml b/manifest.toml index 6d4e0e8..bdc37a9 100644 --- a/manifest.toml +++ b/manifest.toml @@ -63,6 +63,14 @@ description = "64-bit RISC-V Linux with Busybox" ram = 128 cpus = 2 +# repnop's vanadinite Rust operating system +# see https://github.com/repnop/vanadinite +[guest.vanadinite] +path = "boot/guests" +description = "RV64GC Vanadinite microkernel with userspace" +ram = 128 +cpus = 1 + # select the guests to include for a given target # To include and boot more than one guest, add more than one entry to the guests array diff --git a/src/hypervisor/.cargo/config b/src/hypervisor/.cargo/config index c073061..ad5290d 100644 --- a/src/hypervisor/.cargo/config +++ b/src/hypervisor/.cargo/config @@ -5,20 +5,16 @@ # See LICENSE for usage and copying. # -# # set the default build triple -# [build] target = "riscv64gc-unknown-none-elf" # Find the linker for 64-bit RISC-V (IMAC) targets [target.riscv64imac-unknown-none-elf] -rustflags = [ "-Z", "pre-link-arg=-nostartfiles", "-C", "link-arg=-Tsrc/platform-riscv/link.ld", "-C", "link-arg=--no-eh-frame-hdr" ] -linker = "riscv64-linux-gnu-ld" -ar = "riscv64-linux-gnu-ar" +linker = "../itsylinker/target/debug/itsylinker" +rustflags = [ "-C", "link-arg=-T", "-C", "link-arg=src/platform-riscv/link.toml" ] # Find the linker for 64-bit RISC-V (GC) targets [target.riscv64gc-unknown-none-elf] -rustflags = [ "-Z", "pre-link-arg=-nostartfiles", "-C", "link-arg=-Tsrc/platform-riscv/link.ld", "-C", "link-arg=--no-eh-frame-hdr" ] -linker = "riscv64-linux-gnu-ld" -ar = "riscv64-linux-gnu-ar" +linker = "../itsylinker/target/debug/itsylinker" +rustflags = [ "-C", "link-arg=-T", "-C", "link-arg=src/platform-riscv/link.toml" ] diff --git a/src/hypervisor/Cargo.toml b/src/hypervisor/Cargo.toml index 4cd80ea..51698c1 100644 --- a/src/hypervisor/Cargo.toml +++ b/src/hypervisor/Cargo.toml @@ -3,7 +3,6 @@ name = "hypervisor" version = "0.0.2" authors = ["Chris Williams "] license = "MIT" -build = "../mason/build.rs" publish = false edition = "2018" @@ -31,12 +30,12 @@ xmas-elf = { git = "https://github.com/nrc/xmas-elf.git" } # external dependencies [dependencies.hashbrown] -version = "0.9.1" +version = "0.11.1" features = [ "nightly" ] -[dependencies.lazy_static] -version = "1.4.0" -features = [ "spin_no_std" ] +[dependencies.spinning] +git = "https://github.com/diodesign/spinning-rs" +default-features = false # supported build targets - don't forget to update .cargo with details for the linker and runner when adding new ports [target.riscv64imac-unknown-none-elf.dependencies] diff --git a/src/hypervisor/mason.toml b/src/hypervisor/mason.toml deleted file mode 100644 index b975208..0000000 --- a/src/hypervisor/mason.toml +++ /dev/null @@ -1,17 +0,0 @@ -# Configure Mason to build non-Rust portions of the diosix hypervisor -# -# Directory paths are relative to this manifest.toml file - -[defaults] -# include_files is a colon-separated list of arbitrary files -# to include in the hypervisor's executable -include_files = [ "../mkdmfs/target/dmfs.img" ] - -# Set up assembly code directories for supported architectures -# asm_dirs is a colon-separated list of directories to scan -# for assembly code to build and link to the hypervisor's executable -[target.riscv64imac-unknown-none-elf] -asm_dirs = [ "src/platform-riscv/asm" ] - -[target.riscv64gc-unknown-none-elf] -asm_dirs = [ "src/platform-riscv/asm" ] \ No newline at end of file diff --git a/src/hypervisor/src/capsule.rs b/src/hypervisor/src/capsule.rs index bb83393..858ca24 100644 --- a/src/hypervisor/src/capsule.rs +++ b/src/hypervisor/src/capsule.rs @@ -10,6 +10,7 @@ use super::lock::Mutex; use hashbrown::hash_map::HashMap; use hashbrown::hash_map::Entry::{Occupied, Vacant}; use hashbrown::hash_set::HashSet; +use spinning::Lazy; use alloc::vec::Vec; use alloc::string::{String, ToString}; use platform::cpu::{Entry, CPUcount}; @@ -29,26 +30,20 @@ pub type CapsuleID = usize; const CAPSULES_MAX: usize = 1000000; /* needed to assign system-wide unique capsule ID numbers */ -lazy_static! -{ - static ref CAPSULE_ID_NEXT: AtomicUsize = AtomicUsize::new(0); -} +static CAPSULE_ID_NEXT: Lazy = Lazy::new(|| AtomicUsize::new(0)); /* maintain a shared table of capsules and linked data */ -lazy_static! -{ - /* acquire CAPSULES lock before accessing any capsules */ - static ref CAPSULES: Mutex> = Mutex::new("capsule ID table", HashMap::new()); +/* acquire CAPSULES lock before accessing any capsules */ +static CAPSULES: Lazy>> = Lazy::new(|| Mutex::new("capsule ID table", HashMap::new())); - /* set of capsules to restart */ - static ref TO_RESTART: Mutex> = Mutex::new("capsule restart list", HashSet::new()); +/* set of capsules to restart */ +static TO_RESTART: Lazy>> = Lazy::new(|| Mutex::new("capsule restart list", HashSet::new())); - /* maintain collective input and output system console buffers for capsules. - the console system service capsule (ServiceConsole) will read from - STDOUT to display capsules' text, and will write to STDIN to inject characters into capsules */ - static ref STDIN: Mutex>> = Mutex::new("capsule STDIN table", HashMap::new()); - static ref STDOUT: Mutex>> = Mutex::new("capsule STDOUT table", HashMap::new()); -} +/* maintain collective input and output system console buffers for capsules. + the console system service capsule (ServiceConsole) will read from + STDOUT to display capsules' text, and will write to STDIN to inject characters into capsules */ +static STDIN: Lazy>>> = Lazy::new(|| Mutex::new("capsule STDIN table", HashMap::new())); +static STDOUT: Lazy>>> = Lazy::new(|| Mutex::new("capsule STDOUT table", HashMap::new())); /* perform housekeeping duties on idle physical CPU cores */ macro_rules! capsulehousekeeper diff --git a/src/hypervisor/src/debug.rs b/src/hypervisor/src/debug.rs index edc3458..0733a20 100644 --- a/src/hypervisor/src/debug.rs +++ b/src/hypervisor/src/debug.rs @@ -13,6 +13,7 @@ use core::fmt; use super::lock::Mutex; use alloc::vec::Vec; use alloc::string::String; +use spinning::Lazy; use super::hardware; use super::service; use super::message; @@ -30,12 +31,9 @@ use super::message; const DEBUG_LOG_MAX_LEN: usize = 64 * 1024; /* 64KB max length for debug log buffer */ -lazy_static! -{ - pub static ref DEBUG_LOCK: Mutex = Mutex::new("primary debug lock", false); - static ref DEBUG_QUEUE: Mutex = Mutex::new("debug output queue", String::new()); - static ref DEBUG_LOG: Mutex> = Mutex::new("debug log buffer", Vec::new()); -} +pub static DEBUG_LOCK: Lazy> = Lazy::new(|| Mutex::new("primary debug lock", false)); +static DEBUG_QUEUE: Lazy> = Lazy::new(|| Mutex::new("debug output queue", String::new())); +static DEBUG_LOG: Lazy>> = Lazy::new(|| Mutex::new("debug log buffer", Vec::new())); /* top level debug macros */ /* bad news: bug detection, failures, etc. */ diff --git a/src/hypervisor/src/devicetree b/src/hypervisor/src/devicetree index 87c23af..8b4da16 160000 --- a/src/hypervisor/src/devicetree +++ b/src/hypervisor/src/devicetree @@ -1 +1 @@ -Subproject commit 87c23afedf37d12213a9cc8606d5df839fb0ac4d +Subproject commit 8b4da16e569b869b9e4860aeceefe3bd2c749469 diff --git a/src/hypervisor/src/hardware.rs b/src/hypervisor/src/hardware.rs index b39df79..eb36d06 100644 --- a/src/hypervisor/src/hardware.rs +++ b/src/hypervisor/src/hardware.rs @@ -7,16 +7,14 @@ use alloc::vec::Vec; use super::lock::Mutex; +use spinning::Lazy; use platform::devices::Devices; use platform::physmem::{PhysMemBase, PhysMemSize}; use platform::timer; use super::error::Cause; -lazy_static! -{ - /* acquire HARDWARE before accessing any system hardware */ - static ref HARDWARE: Mutex> = Mutex::new("hardware management", None); -} +/* acquire HARDWARE before accessing any system hardware */ +static HARDWARE: Lazy>> = Lazy::new(|| Mutex::new("hardware management", None)); /* parse_and_init Parse a device tree structure to create a base set of hardware devices. diff --git a/src/hypervisor/src/loader.rs b/src/hypervisor/src/loader.rs index 5542faf..e071dd0 100644 --- a/src/hypervisor/src/loader.rs +++ b/src/hypervisor/src/loader.rs @@ -216,9 +216,7 @@ pub fn load(target: Region, source: &[u8]) -> Result match (offset, info, addend) { (Some(&o), Some(&i), Some(&a)) => - { - // hvdebug!("reloc: offset {:x}, addend {:x}", o, a); - + { /* different CPU architectures have different relocation rules. relocation type is in the lower byte of the info word */ match (&cpu, (i & 0xff) as u8) diff --git a/src/hypervisor/src/main.rs b/src/hypervisor/src/main.rs index bfb224d..b0d404e 100644 --- a/src/hypervisor/src/main.rs +++ b/src/hypervisor/src/main.rs @@ -43,8 +43,8 @@ extern crate devicetree; extern crate dmfs; /* needed for lazyily-allocated static variables */ -#[macro_use] -extern crate lazy_static; +extern crate spinning; +use spinning::Lazy; /* this will bring in all the hardware-specific code */ extern crate platform; @@ -70,11 +70,9 @@ mod message; /* send messages between physical cores */ mod service; /* allow capsules to register services */ mod manifest; /* manage capsules loaded with the hypervisor */ -/* needed for exclusive locks */ mod lock; use lock::Mutex; -/* list of error codes */ mod error; use error::Cause; @@ -84,21 +82,18 @@ use pcore::{PhysicalCoreID, BOOT_PCORE_ID}; although we'll keep track of physical memory, we'll let Rust perform essential tasks, such as dropping objects when it's no longer needed, borrow checking, etc */ #[global_allocator] -static HV_HEAP: heap::HVallocator = heap::HVallocator; +static HV_HEAP: Lazy = Lazy::new(|| heap::HVallocator); -lazy_static! -{ - /* set to true to allow physical CPU cores to start running supervisor code */ - static ref INIT_DONE: Mutex = Mutex::new("system bring-up", false); +/* set to true to allow physical CPU cores to start running supervisor code */ +static INIT_DONE: Lazy> = Lazy::new(|| Mutex::new("system bring-up", false)); - /* a physical CPU core obtaining this lock when it is false must walk the DMFS, create - capsules required to run at boot time, and set the flag to true. any other core - obtaining it as true must release the lock and move on */ - static ref MANIFEST_UNPACKED: Mutex = Mutex::new("dmfs unpacked", false); +/* a physical CPU core obtaining this lock when it is false must walk the DMFS, create +capsules required to run at boot time, and set the flag to true. any other core +obtaining it as true must release the lock and move on */ +static MANIFEST_UNPACKED: Lazy> = Lazy::new(|| Mutex::new("dmfs unpacked", false)); - /* set to true if individual cores can sound off their presence and capabilities */ - static ref ROLL_CALL: Mutex = Mutex::new("CPU roll call", false); -} +/* set to true if individual cores can sound off their presence and capabilities */ +static ROLL_CALL: Lazy> = Lazy::new(|| Mutex::new("CPU roll call", false)); /* pointer sizes: stick to usize as much as possible: don't always assume it's a 64-bit machine */ diff --git a/src/hypervisor/src/manifest.rs b/src/hypervisor/src/manifest.rs index e3a057b..df0714d 100644 --- a/src/hypervisor/src/manifest.rs +++ b/src/hypervisor/src/manifest.rs @@ -16,37 +16,14 @@ use dmfs::{ManifestImageIter, ManifestObject, ManifestObjectType, ManifestObject use alloc::string::String; use alloc::vec::Vec; -/* bring in the built-in dmfs image */ -use core::slice; -use core::intrinsics::transmute; -extern "C" -{ - static _binary_dmfs_img_start: u8; - static _binary_dmfs_img_size: u8; -} - -/* convert the included dmfs image into a byte slice */ -macro_rules! get_dmfs_image -{ - () => - { - unsafe - { - slice::from_raw_parts - ( - transmute(&_binary_dmfs_img_start), - transmute(&_binary_dmfs_img_size) - ) - } - } -} +/* drop in the dmfs image built by mkdmfs */ +static DMFS_IMAGE: &[u8] = include_bytes!("../../mkdmfs/target/dmfs.img"); /* return a list of a DMFS image's asset names and descriptions <= array of (names, descriptions) of image's assets */ pub fn list_assets() -> Result, Cause> { - let image = get_dmfs_image!(); - let manifest = match ManifestImageIter::from_slice(image) + let manifest = match ManifestImageIter::from_slice(&DMFS_IMAGE) { Ok(m) => m, Err(_) => return Err(Cause::ManifestBadFS) @@ -64,8 +41,7 @@ pub fn list_assets() -> Result, Cause> /* look up an asset from the given DMFS image by its name */ pub fn get_named_asset(name: &str) -> Result { - let image = get_dmfs_image!(); - let manifest = match ManifestImageIter::from_slice(image) + let manifest = match ManifestImageIter::from_slice(&DMFS_IMAGE) { Ok(m) => m, Err(_) => return Err(Cause::ManifestBadFS) @@ -87,8 +63,7 @@ pub fn get_named_asset(name: &str) -> Result and output any included boot banner messages, during system start up */ pub fn unpack_at_boot() -> Result<(), Cause> { - let image = get_dmfs_image!(); - let manifest = match ManifestImageIter::from_slice(image) + let manifest = match ManifestImageIter::from_slice(&DMFS_IMAGE) { Ok(m) => m, Err(_) => return Err(Cause::ManifestBadFS) @@ -115,12 +90,11 @@ pub fn unpack_at_boot() -> Result<(), Cause> */ pub fn load_asset(asset: ManifestObject) -> Result<(), Cause> { - let image = get_dmfs_image!(); let properties = asset.get_properties(); let content = match asset.get_contents() { ManifestObjectData::Bytes(b) => b.as_slice(), - ManifestObjectData::Region(r) => &image[r.start..r.end] + ManifestObjectData::Region(r) => &DMFS_IMAGE[r.start..r.end] }; match asset.get_type() @@ -145,7 +119,7 @@ pub fn load_asset(asset: ManifestObject) -> Result<(), Cause> { Ok(cid) => hvdebug!("Created guest OS {} ({}) {} bytes (capsule {})", asset.get_name(), asset.get_description(), asset.get_contents_size(), cid), - Err(_e) => hvdebug!("Failed to create capsule for system service {}: {:?}", asset.get_name(), _e) + Err(_e) => hvdebug!("Failed to create capsule for guest OS {}: {:?}", asset.get_name(), _e) }, t => hvdebug!("Found manifest object type {:?}", t) diff --git a/src/hypervisor/src/message.rs b/src/hypervisor/src/message.rs index b79b38d..702d928 100644 --- a/src/hypervisor/src/message.rs +++ b/src/hypervisor/src/message.rs @@ -9,6 +9,7 @@ use super::lock::Mutex; use alloc::collections::vec_deque::VecDeque; use alloc::string::String; use hashbrown::hash_map::HashMap; +use spinning::Lazy; use super::error::Cause; use super::service::{self, ServiceType}; use super::capsule::CapsuleID; @@ -30,10 +31,7 @@ use super::pcore::{PhysicalCoreID, PhysicalCore}; */ /* maintain a mailbox of messages per physical CPU core */ -lazy_static! -{ - static ref MAILBOXES: Mutex>> = Mutex::new("mailbox", HashMap::new()); -} +static MAILBOXES: Lazy>>> = Lazy::new(|| Mutex::new("mailbox", HashMap::new())); /* create a mailbox for physical CPU core coreid */ pub fn create_mailbox(coreid: PhysicalCoreID) diff --git a/src/hypervisor/src/pcore.rs b/src/hypervisor/src/pcore.rs index 5c49f61..b501e1e 100644 --- a/src/hypervisor/src/pcore.rs +++ b/src/hypervisor/src/pcore.rs @@ -15,6 +15,7 @@ so it's OK to keep it really simple for now. */ use super::lock::Mutex; use hashbrown::hash_map::HashMap; +use spinning::Lazy; use platform::physmem::PhysMemSize; use platform::cpu::{SupervisorState, CPUFeatures}; use platform::timer; @@ -41,17 +42,14 @@ extern "C" fn platform_load_supervisor_state(state: &SupervisorState); } -lazy_static! -{ - /* map running virtual CPU cores to physical CPU cores, and vice-versa - we can't store these in Core structs because it upsets Rust's borrow checker. - note: PCORES keeps track of the last physical CPU core to run a given virtual - core. this is more of a hint than a concrete guarantee: the virtual core - may have been scheduled away, though it should be in the last physical - CPU core's scheduling queue. */ - static ref VCORES: Mutex> = Mutex::new("physical-virtual core table", HashMap::new()); - static ref PCORES: Mutex> = Mutex::new("physical-virtual core ID table", HashMap::new()); -} +/* map running virtual CPU cores to physical CPU cores, and vice-versa +we can't store these in Core structs because it upsets Rust's borrow checker. +note: PCORES keeps track of the last physical CPU core to run a given virtual +core. this is more of a hint than a concrete guarantee: the virtual core +may have been scheduled away, though it should be in the last physical +CPU core's scheduling queue. */ +static VCORES: Lazy>> = Lazy::new(|| Mutex::new("physical-virtual core table", HashMap::new())); +static PCORES: Lazy>> = Lazy::new(|| Mutex::new("physical-virtual core ID table", HashMap::new())); /* describe a physical CPU core - this structure is stored in the per-CPU private variable space. this is below the per-CPU machine-level stack */ diff --git a/src/hypervisor/src/platform-riscv b/src/hypervisor/src/platform-riscv index a66d625..61e094b 160000 --- a/src/hypervisor/src/platform-riscv +++ b/src/hypervisor/src/platform-riscv @@ -1 +1 @@ -Subproject commit a66d62552e80a2670eec96e78e8465ff52377147 +Subproject commit 61e094b95344582a69694aae4d53ae95b74baf87 diff --git a/src/hypervisor/src/scheduler.rs b/src/hypervisor/src/scheduler.rs index 59d60d6..3899d8f 100644 --- a/src/hypervisor/src/scheduler.rs +++ b/src/hypervisor/src/scheduler.rs @@ -11,6 +11,7 @@ use super::lock::Mutex; use alloc::collections::vec_deque::VecDeque; use hashbrown::hash_map::HashMap; +use spinning::Lazy; use platform::timer::TimerValue; use super::error::Cause; use super::vcore::{VirtualCore, Priority}; @@ -41,12 +42,9 @@ const MAINTENANCE_LENGTH: TimerValue = TimerValue::Seconds(5); of high-normal wait queues, virtual cores waiting to be assigned to a physical CPU sit in these global queues. when a physical CPU runs out of queued virtual cores, it pulls one from these global queues. a physical CPU core can ask fellow CPUs to push virtual cores onto the global queues via messages */ -lazy_static! -{ - static ref GLOBAL_QUEUES: Mutex = Mutex::new("global scheduler queue", ScheduleQueues::new()); - static ref WORKLOAD: Mutex> = Mutex::new("workload balancer", HashMap::new()); - static ref LAST_HOUSEKEEP_CHECK: Mutex = Mutex::new("housekeeper tracking", TimerValue::Exact(0)); -} +static GLOBAL_QUEUES: Lazy> = Lazy::new(|| Mutex::new("global scheduler queue", ScheduleQueues::new())); +static WORKLOAD: Lazy>> = Lazy::new(|| Mutex::new("workload balancer", HashMap::new())); +static LAST_HOUSEKEEP_CHECK: Lazy> = Lazy::new(|| Mutex::new("housekeeper tracking", TimerValue::Exact(0))); #[derive(PartialEq, Clone, Copy, Debug)] pub enum SearchMode diff --git a/src/hypervisor/src/service.rs b/src/hypervisor/src/service.rs index 1cd43ef..eeeaabf 100644 --- a/src/hypervisor/src/service.rs +++ b/src/hypervisor/src/service.rs @@ -7,6 +7,7 @@ use super::lock::Mutex; use hashbrown::hash_map::{HashMap, Entry}; +use spinning::Lazy; use alloc::collections::vec_deque::VecDeque; use alloc::vec::Vec; use super::message; @@ -43,10 +44,7 @@ then other capsules can message those services to access those underlying resources. */ /* maintain a table of registered services */ -lazy_static! -{ - static ref SERVICES: Mutex> = Mutex::new("system service table", HashMap::new()); -} +static SERVICES: Lazy>> = Lazy::new(|| Mutex::new("system service table", HashMap::new())); /* return true if the given service type is registered */ pub fn is_registered(stype: ServiceType) -> bool diff --git a/src/itsylinker b/src/itsylinker new file mode 160000 index 0000000..bf33135 --- /dev/null +++ b/src/itsylinker @@ -0,0 +1 @@ +Subproject commit bf33135091e90b1cc6d99140b7be2b520613bd57 diff --git a/src/mason b/src/mason deleted file mode 160000 index 8da6657..0000000 --- a/src/mason +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8da66577e3e8497a0f1359f29af79f23bdf971cc diff --git a/src/mkdmfs b/src/mkdmfs index bc45c9c..480d979 160000 --- a/src/mkdmfs +++ b/src/mkdmfs @@ -1 +1 @@ -Subproject commit bc45c9cd55b6e7a70a6aa46682c8389bc95c4772 +Subproject commit 480d979f90b156198728f036ae2d68ffd04d0751 diff --git a/src/services/.cargo/config b/src/services/.cargo/config index 51dab60..3286b7e 100644 --- a/src/services/.cargo/config +++ b/src/services/.cargo/config @@ -1,7 +1,7 @@ # # diosix supervisor platform-specific linker settings # -# (c) Chris Williams, 2020. +# (c) Chris Williams, 2020-2021. # See LICENSE for usage and copying. # @@ -11,24 +11,16 @@ [build] target = "riscv64gc-unknown-none-elf" -# Find the linker for 64-bit RISC-V (IMAC) targets -[target.riscv64imac-unknown-none-elf] -rustflags = [ - "-Z", "pre-link-arg=-nostartfiles", - "-C", "link-arg=-Tsrc/supervisor-riscv/link.ld", - "-C", "link-arg=-pie", - "-C", "link-arg=--no-dynamic-linker", - "-C", "relocation-model=pic" ] -linker = "riscv64-linux-gnu-ld" -ar = "riscv64-linux-gnu-ar" - # Find the linker for 64-bit RISC-V (GC) targets [target.riscv64gc-unknown-none-elf] +linker = "../itsylinker/target/debug/itsylinker" +rustflags = [ + "-C", "link-arg=-T", "-C", "link-arg=src/supervisor-riscv/link.toml", + "-C", "relocation-model=pic" ] + +# Find the linker for 64-bit RISC-V (IMAC) t0argets +[target.riscv64imac-unknown-none-elf] +linker = "../itsylinker/target/debug/itsylinker" rustflags = [ - "-Z", "pre-link-arg=-nostartfiles", - "-C", "link-arg=-Tsrc/supervisor-riscv/link.ld", - "-C", "link-arg=-pie", - "-C", "link-arg=--no-dynamic-linker", - "-C", "relocation-model=pic" ] -linker = "riscv64-linux-gnu-ld" -ar = "riscv64-linux-gnu-ar" + "-C", "link-arg=-T", "-C", "link-arg=src/supervisor-riscv/link.toml", + "-C", "relocation-model=pic" ] diff --git a/src/services/Cargo.toml b/src/services/Cargo.toml index d6081d0..38e6a4f 100644 --- a/src/services/Cargo.toml +++ b/src/services/Cargo.toml @@ -3,7 +3,6 @@ name = "diosix-services" version = "1.0.0" authors = ["Chris Williams "] license = "MIT" -build = "../mason/build.rs" publish = false edition = "2018" @@ -17,12 +16,9 @@ toml = "0.5.8" serde = "1.0.118" serde_derive = "1.0.118" -[dependencies.lazy_static] -version = "1.4.0" -features = [ "spin_no_std" ] - -[dependencies.spin] -version = "0.7.0" +[dependencies.spinning] +git = "https://github.com/diodesign/spinning-rs" +default-features = false [target.riscv64imac-unknown-none-elf.dependencies] supervisor = { path = "src/supervisor-riscv" } diff --git a/src/services/mason.toml b/src/services/mason.toml deleted file mode 100644 index 5e88706..0000000 --- a/src/services/mason.toml +++ /dev/null @@ -1,13 +0,0 @@ -# Configure Mason to build non-Rust portions of hypervisor services -# -# Directory paths are relative to this manifest.toml file - -# Set up assembly code directories for supported architectures -# asm_dirs is a colon-separated list of directories to scan -# for assembly code to build and link to the hypervisor's executable - -[target.riscv64imac-unknown-none-elf] -asm_dirs = [ "src/supervisor-riscv/asm" ] - -[target.riscv64gc-unknown-none-elf] -asm_dirs = [ "src/supervisor-riscv/asm" ] diff --git a/src/services/src/gooey b/src/services/src/gooey index fdc993a..fae2300 160000 --- a/src/services/src/gooey +++ b/src/services/src/gooey @@ -1 +1 @@ -Subproject commit fdc993a2415d27d4bc409158f8fff7b2ec83738d +Subproject commit fae2300b85f09ba556460885925d91f6fb458f41 diff --git a/src/services/src/supervisor-riscv b/src/services/src/supervisor-riscv index 8fc7bad..b6388e2 160000 --- a/src/services/src/supervisor-riscv +++ b/src/services/src/supervisor-riscv @@ -1 +1 @@ -Subproject commit 8fc7bad8e4ccf076bb77d513a0aad099cc82ca22 +Subproject commit b6388e2c2e0e41c4036476b16002705f7a7097c0