Skip to content
Permalink
Browse files

Added machine/hypervisor kernel heap memory management and build opti…

…on to enable debugging
  • Loading branch information...
diodesign committed Dec 14, 2018
1 parent 7357090 commit d9956b8bc8e8bf01409f3e0fd49e1ad41c0461ca
@@ -7,7 +7,7 @@
# see this thread for more information:
# https://users.rust-lang.org/t/does-target-cfg-in-cargo-config-not-support-user-supplied-features/20275

# syntax: ./build.sh --triple [build triple] --platform [target platform]
# syntax: ./build.sh [--debug] --triple [build triple] --platform [target platform]
#
# eg: ./build.sh --triple riscv32imac-unknown-none-elf --platform sifive_u34
#
@@ -17,6 +17,10 @@
# supported target platforms:
# sifive_u34 (SiFive-U34 RV32 series)
# qemu_virt (Qemu Virt hardware environment)
#
# Debug mode: --debug switches to a debug build, otherwise a release build is created
# as well as adding extra debug info to the kernel executable, --debug also enables kdebug!() output
#

# process command line arguments
while [[ $# -gt 0 ]]
@@ -34,12 +38,16 @@ case $SETTING in
shift # past argument
shift # past value
;;
-d|--debug)
DEBUG_MODE="(DEBUG ENABLED)"
shift # past argument
;;
esac
done

# sanity chacks...
if [[ $TRIPLE == "" || $PLATFORM == "" ]]; then
echo "Usage: build.sh --triple [build triple] --platform [target platform]"
echo "Usage: build.sh [--debug] --triple [build triple] --platform [target platform]"
exit 1
fi

@@ -55,10 +63,10 @@ esac

case $PLATFORM in
sifive_u34)
echo "[+] Building for ${CPU_ARCH} SiFive Freedom U34 series"
echo "[+] Building for ${CPU_ARCH} SiFive Freedom U34 series ${DEBUG_MODE}"
;;
qemu32_virt)
echo "[+] Building for ${CPU_ARCH} Qemu Virt environment"
echo "[+] Building for ${CPU_ARCH} Qemu Virt environment ${DEBUG_MODE}"
;;
*)
echo "[-] Unsupported platform '${PLATFORM}'"
@@ -71,5 +79,10 @@ cat cargoes/Cargo.toml.common cargoes/Cargo.toml.${PLATFORM} > Cargo.toml
# we can't do this from cargo, have to set it outside the toolchain
export RUSTFLAGS="-C link-arg=-Tsrc/platform/${CPU_ARCH}/${PLATFORM}/link.ld"

# invoke the compiler toolchain
cargo build --release --target $TRIPLE --features $PLATFORM
# invoke the compiler toolchain, enabling debug mode if required
if [[ -z $DEBUG_MODE ]]
then
cargo build --release --target $TRIPLE --features $PLATFORM
else
cargo build --target $TRIPLE --features $PLATFORM
fi
@@ -15,6 +15,17 @@ regex = "1"

[profile.dev]
panic = "abort"
debug-assertions = true
debug = true
overflow-checks = true
opt-level = 0
incremental = true

[profile.release]
panic = "abort"
debug-assertions = false
debug = false
overflow-checks = false
opt-level = 3
incremental = false

@@ -9,17 +9,25 @@ use core::panic::PanicInfo;

/* we need to provide these */
#[panic_handler]
pub fn panic(_info: &PanicInfo) -> !
pub fn panic(info: &PanicInfo) -> !
{
kalert!("Panic handler reached!");
kalert!("Rust runtime panicked unexpectedly");
match info.location()
{
Some(location) =>
{
kalert!("... crashed in {}: {}", location.file(), location.line())
},
None => kalert!("... crash location unknown")
};
loop
{}
}

#[no_mangle]
pub extern "C" fn abort() -> !
{
kalert!("Abort handler reached!");
kalert!("Rust runtime hit the abort button");
loop
{}
}
@@ -5,28 +5,48 @@
* See LICENSE for usage and copying.
*/

/* platform-specific code must implement all this */
use platform;
use heap;

/* require some help from the underlying platform */
extern "C"
{
fn platform_cpu_private_variables() -> *mut Core;
}

/* set to true to unblock SMP cores and allow them to initialize */
static mut SMP_GREEN_LIGHT: bool = false;

/* intiialize CPU core. Prepare it for running supervisor code.
blocks until cleared to continue by the boot CPU
<= returns true if success, or false for failure */
pub fn init() -> bool
/* describe a CPU core - this structure is stored in the per-CPU private variable space */
#[repr(C)]
pub struct Core
{
/* block until the boot CPU has given us the green light to continue.
this is unsafe because we're reading without any locking. however,
there is only one writer (the boot CPU) and multiple readers,
so there is no data race issue. assumes aligned writes are atomic */
while !unsafe { SMP_GREEN_LIGHT } { keep_me!(); /* don't optimize away this loop */ }

return platform::common::cpu::init();
pub heap: heap::Heap,
}

/* only the boot CPU should call this: give waiting SMP cores the green light */
pub fn unblock_smp()
impl Core
{
unsafe { SMP_GREEN_LIGHT = true; }
/* intiialize a CPU core. Prepare it for running supervisor code.
blocks until cleared to continue by the boot CPU */
pub fn init()
{
/* block until the boot CPU has given us the green light to continue.
this is unsafe because we're reading without any locking. however,
there is only one writer (the boot CPU) and multiple readers,
so there is no data race issue. assumes aligned writes are atomic */
while !unsafe { SMP_GREEN_LIGHT } { keep_me!(); /* don't optimize away this loop */ }

/* assume the startup code has allocated space for per-CPU core variables.
this function returns a pointer to that structure */
let cpu = Core::this();

/* initialize private heap */
unsafe { (*cpu).heap.init(); }
}

/* return pointer to the calling CPU core's fixed private data structure */
pub fn this() -> *mut Core { return unsafe { platform_cpu_private_variables() } }
}

/* only the boot CPU should call this: give waiting SMP cores the green light */
pub fn unblock_smp() { unsafe { SMP_GREEN_LIGHT = true; } }

@@ -18,20 +18,38 @@ extern "C" {
pub fn platform_get_cpu_id() -> usize;
}

/* top level debug macros - harmless logging */
/* top level debug macros */
/* useful messages */
#[macro_export]
macro_rules! klog
{
($fmt:expr) => (kprintln!("[CPU {}] {}", $crate::debug::platform_get_cpu_id(), $fmt));
($fmt:expr, $($arg:tt)*) => (kprintln!(concat!("[CPU {}] ", $fmt), $crate::debug::platform_get_cpu_id(), $($arg)*));
($fmt:expr) => (kprintln!("[-] CPU {}: {}", ::debug::platform_get_cpu_id(), $fmt));
($fmt:expr, $($arg:tt)*) => (kprintln!(concat!("[-] CPU {}: ", $fmt), ::debug::platform_get_cpu_id(), $($arg)*));
}

/* bad news: bug detection, failures, etc */
#[macro_export]
macro_rules! kalert
{
($fmt:expr) => (kprintln!("[CPU {}] ALERT: {}", $crate::debug::platform_get_cpu_id(), $fmt));
($fmt:expr, $($arg:tt)*) => (kprintln!(concat!("[CPU {}] ALERT: ", $fmt), $crate::debug::platform_get_cpu_id(), $($arg)*));
($fmt:expr) => (kprintln!("[!] CPU {}: ALERT: {}", ::debug::platform_get_cpu_id(), $fmt));
($fmt:expr, $($arg:tt)*) => (kprintln!(concat!("[!] CPU {}: ", $fmt), ::debug::platform_get_cpu_id(), $($arg)*));
}

/* only output if debug build is enabled */
#[macro_export]
#[cfg(debug_assertions)]
macro_rules! kdebug
{
($fmt:expr) => (kprintln!("[?] CPU {}: {}", ::debug::platform_get_cpu_id(), $fmt));
($fmt:expr, $($arg:tt)*) => (kprintln!(concat!("[?] CPU {}: ", $fmt), ::debug::platform_get_cpu_id(), $($arg)*));
}

#[macro_export]
#[cfg(not(debug_assertions))]
macro_rules! kdebug
{
($fmt:expr) => ();
($fmt:expr, $($arg:tt)*) => ();
}

/* use this to stop rust optimizing away loops and other code */
Oops, something went wrong.

0 comments on commit d9956b8

Please sign in to comment.
You can’t perform that action at this time.