Implement power-efficient sleep after boot-up

* arch-based crates, inspired by Redox
* Do not burn cpu uselessly.
* Start using cortex-a registers.
* Important: initialise stack pointer!
This commit is contained in:
Berkus Decker 2020-08-09 21:56:09 +03:00
parent 8bacc7cfb7
commit 57e4b81e1c
7 changed files with 85 additions and 5 deletions

25
Cargo.lock generated
View File

@ -26,6 +26,14 @@ dependencies = [
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cortex-a"
version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"register 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nodrop"
version = "0.1.14"
@ -44,6 +52,14 @@ name = "r0"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "register"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"tock-registers 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rlibc"
version = "1.0.0"
@ -70,6 +86,11 @@ name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "tock-registers"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ux"
version = "0.1.3"
@ -79,6 +100,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "vesper"
version = "0.0.1"
dependencies = [
"cortex-a 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"qemu-exit 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rlibc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -101,12 +123,15 @@ dependencies = [
"checksum bit_field 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed8765909f9009617974ab6b7d332625b320b33c326b1e9321382ef1999b5d56"
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
"checksum cast 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b9434b9a5aa1450faa3f9cb14ea0e8c53bb5d2b3c1bfd1ab4fc03e9f33fbfb0"
"checksum cortex-a 3.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6922a40af4d1a2deac8c963b9f3e57311b8912490740234f1ad182425c547f80"
"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
"checksum qemu-exit 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "95533662c327a4b3be4203123662b7eca1c39d73d66020c52280e4ff0e9c9a41"
"checksum r0 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e2a38df5b15c8d5c7e8654189744d8e396bddc18ad48041a500ce52d6948941f"
"checksum register 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "deaba5b0e477d21f61a57504bb5cef4a1e86de30300b457d38971c1cfc98b815"
"checksum rlibc 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc874b127765f014d792f16763a81245ab80500e2ad921ed4ee9e82481ee08fe"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum tock-registers 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "70323afdb8082186c0986da0e10f6e4ed103d681c921c00597e98d9806dac20f"
"checksum ux 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "88dfeb711b61ce620c0cb6fd9f8e3e678622f0c971da2a63c4b3e25e88ed012f"
"checksum x86_64 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1f27d9168654aee1b0c1b73746caeb4aa33248f8b8c8f6e100e697fcc2a794b2"

View File

@ -4,7 +4,7 @@
* Original code distributed under MIT, additional changes are under BlueOak-1.0.0
*/
ENTRY(_boot_cores);
ENTRY(karch_start);
/* Symbols between __boot_start and __boot_end should be dropped after init is complete.
Symbols between __ro_start and __ro_end are the kernel code.

View File

@ -23,3 +23,4 @@ qemu = ["qemu-exit"]
r0 = "0.2"
rlibc = "1.0"
qemu-exit = { version = "0.1", optional = true }
cortex-a = "3.0"

View File

@ -0,0 +1,5 @@
# Architecture-specific code
This directory contains code specific to a certain architecture.
Implementations of arch-specific kernel calls are also placed here.

View File

@ -0,0 +1,36 @@
use {
crate::kmain,
cortex_a::{
asm,
regs::{RegisterReadOnly, RegisterReadWrite, MPIDR_EL1, SP},
},
};
/// The entry to Rust, all things must be initialized
/// This is invoked from the linker script, does arch-specific init
/// and passes control to the kernel boot function kmain().
#[no_mangle]
pub unsafe extern "C" fn karch_start() -> ! {
// Set sp to 0x80000 (just before kernel start)
const STACK_START: u64 = 0x8_0000;
SP.set(STACK_START);
match read_cpu_id() {
0 => kmain(),
_ => endless_sleep(), // if not core0, indefinitely wait for events
}
}
#[inline]
pub fn read_cpu_id() -> u64 {
const CORE_MASK: u64 = 0x3;
MPIDR_EL1.get() & CORE_MASK
}
#[inline]
pub fn endless_sleep() -> ! {
loop {
asm::wfe();
}
}

5
nucleus/src/arch/mod.rs Normal file
View File

@ -0,0 +1,5 @@
#[cfg(target_arch = "aarch64")]
#[macro_use]
pub mod aarch64;
#[cfg(target_arch = "aarch64")]
pub use self::aarch64::*;

View File

@ -1,12 +1,20 @@
#![no_std]
#![no_main]
#[no_mangle]
pub extern "C" fn _boot_cores() -> ! {
loop {}
#[cfg(not(target_arch = "aarch64"))]
use architecture_not_supported_sorry;
#[macro_use]
pub mod arch;
pub use arch::*;
// Kernel entry point
// arch crate is responsible for calling this
pub fn kmain() -> ! {
endless_sleep()
}
#[panic_handler]
fn panicked(_info: &core::panic::PanicInfo) -> ! {
loop {}
endless_sleep()
}