|
@@ -1,19 +1,14 @@
|
|
|
use serde_device_tree::Dtb;
|
|
|
|
|
|
-use crate::dt;
|
|
|
+use crate::devicetree;
|
|
|
|
|
|
-#[cfg(not(feature = "payload"))]
|
|
|
-use crate::firmware::dynamic;
|
|
|
-#[cfg(not(feature = "payload"))]
|
|
|
-use crate::sbi::reset;
|
|
|
-#[cfg(not(feature = "payload"))]
|
|
|
-use riscv::register::mstatus;
|
|
|
+#[cfg(all(feature = "payload", feature = "jump"))]
|
|
|
+compile_error!("feature \"payload\" and feature \"jump\" cannot be enabled at the same time");
|
|
|
|
|
|
-// TODO: Need a better way to handle device tree parsing errors
|
|
|
|
|
|
/// Handles device tree format parsing errors by logging and resetting.
|
|
|
#[cold]
|
|
|
-pub fn device_tree_format(_err: dt::ParseDeviceTreeError) -> Dtb {
|
|
|
+pub fn device_tree_format(_err: devicetree::ParseDeviceTreeError) -> Dtb {
|
|
|
loop {
|
|
|
core::hint::spin_loop()
|
|
|
}
|
|
@@ -28,72 +23,78 @@ pub fn device_tree_deserialize_root<'a>(
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/// Handles invalid dynamic information data by logging details and resetting.
|
|
|
-#[cold]
|
|
|
-#[cfg(not(feature = "payload"))]
|
|
|
-pub fn invalid_dynamic_data(err: dynamic::DynamicError) -> (mstatus::MPP, usize) {
|
|
|
- error!("Invalid data in dynamic information:");
|
|
|
- if err.invalid_mpp {
|
|
|
- error!("* dynamic information contains invalid privilege mode");
|
|
|
- }
|
|
|
- if err.invalid_next_addr {
|
|
|
- error!("* dynamic information contains invalid next jump address");
|
|
|
- }
|
|
|
- let explain_next_mode = match err.bad_info.next_mode {
|
|
|
- 3 => "Machine",
|
|
|
- 1 => "Supervisor",
|
|
|
- 0 => "User",
|
|
|
- _ => "Invalid",
|
|
|
- };
|
|
|
- error!(
|
|
|
- "@ help: dynamic information contains magic value 0x{:x}, version {}, next jump address 0x{:x}, next privilege mode {} ({}), options {:x}, boot hart ID {}",
|
|
|
- err.bad_info.magic, err.bad_info.version, err.bad_info.next_addr, err.bad_info.next_mode, explain_next_mode, err.bad_info.options, err.bad_info.boot_hart
|
|
|
- );
|
|
|
- reset::fail()
|
|
|
-}
|
|
|
-
|
|
|
-/// Handles case where dynamic information is not available by logging details and resetting.
|
|
|
-#[cold]
|
|
|
-#[cfg(not(feature = "payload"))]
|
|
|
-pub fn no_dynamic_info_available(err: dynamic::DynamicReadError) -> dynamic::DynamicInfo {
|
|
|
- if let Some(bad_paddr) = err.bad_paddr {
|
|
|
- error!(
|
|
|
- "No dynamic information available at address 0x{:x}",
|
|
|
- bad_paddr
|
|
|
- );
|
|
|
+cfg_if::cfg_if! {
|
|
|
+ if #[cfg(feature = "payload")] {
|
|
|
+ } else if #[cfg(feature = "jump")] {
|
|
|
} else {
|
|
|
- error!("No valid dynamic information available:");
|
|
|
- if let Some(bad_magic) = err.bad_magic {
|
|
|
+ use crate::firmware::dynamic;
|
|
|
+ use crate::sbi::reset;
|
|
|
+ use riscv::register::mstatus;
|
|
|
+ /// Handles invalid dynamic information data by logging details and resetting.
|
|
|
+ #[cold]
|
|
|
+ pub fn invalid_dynamic_data(err: dynamic::DynamicError) -> (mstatus::MPP, usize) {
|
|
|
+ error!("Invalid data in dynamic information:");
|
|
|
+ if err.invalid_mpp {
|
|
|
+ error!("* dynamic information contains invalid privilege mode");
|
|
|
+ }
|
|
|
+ if err.invalid_next_addr {
|
|
|
+ error!("* dynamic information contains invalid next jump address");
|
|
|
+ }
|
|
|
+ let explain_next_mode = match err.bad_info.next_mode {
|
|
|
+ 3 => "Machine",
|
|
|
+ 1 => "Supervisor",
|
|
|
+ 0 => "User",
|
|
|
+ _ => "Invalid",
|
|
|
+ };
|
|
|
error!(
|
|
|
- "* tried to identify dynamic information, but found invalid magic number 0x{:x}",
|
|
|
- bad_magic
|
|
|
+ "@ help: dynamic information contains magic value 0x{:x}, version {}, next jump address 0x{:x}, next privilege mode {} ({}), options {:x}, boot hart ID {}",
|
|
|
+ err.bad_info.magic, err.bad_info.version, err.bad_info.next_addr, err.bad_info.next_mode, explain_next_mode, err.bad_info.options, err.bad_info.boot_hart
|
|
|
);
|
|
|
+ reset::fail()
|
|
|
}
|
|
|
- if let Some(bad_version) = err.bad_version {
|
|
|
- error!("* tries to identify version of dynamic information, but the version number {} is not supported", bad_version);
|
|
|
- }
|
|
|
- if err.bad_magic.is_none() {
|
|
|
- error!("@ help: magic number is valid")
|
|
|
- }
|
|
|
- if err.bad_version.is_none() {
|
|
|
- error!("@ help: dynamic information version is valid")
|
|
|
+
|
|
|
+ /// Handles case where dynamic information is not available by logging details and resetting.
|
|
|
+ #[cold]
|
|
|
+ pub fn no_dynamic_info_available(err: dynamic::DynamicReadError) -> dynamic::DynamicInfo {
|
|
|
+ if let Some(bad_paddr) = err.bad_paddr {
|
|
|
+ error!(
|
|
|
+ "No dynamic information available at address 0x{:x}",
|
|
|
+ bad_paddr
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ error!("No valid dynamic information available:");
|
|
|
+ if let Some(bad_magic) = err.bad_magic {
|
|
|
+ error!(
|
|
|
+ "* tried to identify dynamic information, but found invalid magic number 0x{:x}",
|
|
|
+ bad_magic
|
|
|
+ );
|
|
|
+ }
|
|
|
+ if let Some(bad_version) = err.bad_version {
|
|
|
+ error!("* tries to identify version of dynamic information, but the version number {} is not supported", bad_version);
|
|
|
+ }
|
|
|
+ if err.bad_magic.is_none() {
|
|
|
+ error!("@ help: magic number is valid")
|
|
|
+ }
|
|
|
+ if err.bad_version.is_none() {
|
|
|
+ error!("@ help: dynamic information version is valid")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ reset::fail()
|
|
|
}
|
|
|
- }
|
|
|
- reset::fail()
|
|
|
-}
|
|
|
|
|
|
-/// Fallback function that returns default dynamic info with boot_hart set to MAX.
|
|
|
-///
|
|
|
-/// Used when dynamic info read fails but execution should continue.
|
|
|
-#[cold]
|
|
|
-#[cfg(not(feature = "payload"))]
|
|
|
-pub fn use_lottery(_err: dynamic::DynamicReadError) -> dynamic::DynamicInfo {
|
|
|
- dynamic::DynamicInfo {
|
|
|
- magic: 0,
|
|
|
- version: 0,
|
|
|
- next_addr: 0,
|
|
|
- next_mode: 0,
|
|
|
- options: 0,
|
|
|
- boot_hart: usize::MAX,
|
|
|
+ /// Fallback function that returns default dynamic info with boot_hart set to MAX.
|
|
|
+ ///
|
|
|
+ /// Used when dynamic info read fails but execution should continue.
|
|
|
+ #[cold]
|
|
|
+ pub fn use_lottery(_err: dynamic::DynamicReadError) -> dynamic::DynamicInfo {
|
|
|
+ dynamic::DynamicInfo {
|
|
|
+ magic: 0,
|
|
|
+ version: 0,
|
|
|
+ next_addr: 0,
|
|
|
+ next_mode: 0,
|
|
|
+ options: 0,
|
|
|
+ boot_hart: usize::MAX,
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|