mirror of
https://github.com/AmbiML/sparrow-kata-full.git
synced 2025-07-14 06:24:14 +00:00
Add capscan suport.
Add support to output the contents of the top-level CNode of a CAmkES service or KataOS application to the serial console. This is dependent on kernel support that is enabled with CONFIG_PRINTING. Applications must be running; otherwise there is no CSpace to dump. Specific changes: - add a "capscan" shell command - add capscan method to each CAmkES interface - add capscan_bundle method to the ProcessControlInterface - add Camkes::capscan() to dump the top-level CNode - add ProcessManager support to dump the CNode for a bundle TODO: fix syscall wrapper error return Change-Id: If6ca222decdb4c40a1d3a63e69792eb3feb30f6a GitOrigin-RevId: 504c0182ccccf287b5d58cd8e33981c11d7539d7
This commit is contained in:
parent
c2accc33b0
commit
05233af12c
@ -19,6 +19,7 @@ default = [
|
||||
"TEST_TIMER_SERVICE",
|
||||
]
|
||||
CONFIG_DEBUG_BUILD = []
|
||||
CONFIG_PRINTING = []
|
||||
CONFIG_KERNEL_MCS = []
|
||||
# Commands that are likely not useful
|
||||
FRINGE_CMDS = []
|
||||
|
@ -119,6 +119,7 @@ pub fn repl<T: io::BufRead>(
|
||||
cmds.extend([
|
||||
("builtins", builtins_command as CmdFn),
|
||||
("bundles", bundles_command as CmdFn),
|
||||
("capscan", capscan_command as CmdFn),
|
||||
("kvdelete", kvdelete_command as CmdFn),
|
||||
("kvread", kvread_command as CmdFn),
|
||||
("kvwrite", kvwrite_command as CmdFn),
|
||||
@ -231,12 +232,12 @@ fn ps_command(
|
||||
) -> Result<(), CommandError> {
|
||||
#[cfg(feature = "CONFIG_DEBUG_BUILD")]
|
||||
unsafe {
|
||||
kata_os_common::sel4_sys::seL4_DebugDumpScheduler();
|
||||
sel4_sys::seL4_DebugDumpScheduler();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "CONFIG_DEBUG_BUILD"))]
|
||||
Ok(writeln!(output, "Kernel support not configured!")?)
|
||||
Ok(writeln!(output, "Kernel support not configured with CONFIG_DEBUG_BUILD!")?)
|
||||
}
|
||||
|
||||
fn bundles_command(
|
||||
@ -258,6 +259,47 @@ fn bundles_command(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Implements a "capscan" command that dumps seL4 capabilities to the console.
|
||||
#[allow(unused_variables)]
|
||||
fn capscan_command(
|
||||
args: &mut dyn Iterator<Item = &str>,
|
||||
_input: &mut dyn io::BufRead,
|
||||
output: &mut dyn io::Write,
|
||||
_builtin_cpio: &[u8],
|
||||
) -> Result<(), CommandError> {
|
||||
#[cfg(feature = "CONFIG_PRINTING")]
|
||||
match args.next() {
|
||||
Some("console") => unsafe { sel4_sys::seL4_DebugDumpCNode(SELF_CNODE); }
|
||||
Some("memory") => { let _ = kata_memory_interface::kata_memory_capscan(); }
|
||||
Some("process") => { let _ = kata_proc_interface::kata_proc_ctrl_capscan(); }
|
||||
Some("mlcoord") => { let _ = kata_mlcoord_capscan(); }
|
||||
Some("security") => { let _ = kata_security_interface::kata_security_capscan(); }
|
||||
Some("storage") => { let _ = kata_storage_interface::kata_storage_capscan(); }
|
||||
Some("timer") => { let _ = kata_timer_interface::timer_service_capscan(); }
|
||||
Some(bundle_id) => {
|
||||
if let Err(e) = kata_proc_interface::kata_proc_ctrl_capscan_bundle(bundle_id) {
|
||||
writeln!(output, "{}: {:?}", bundle_id, e)?;
|
||||
}
|
||||
}
|
||||
None => {
|
||||
writeln!(output, "capscan <target>, where <target> is one of:")?;
|
||||
writeln!(output, " console (DebugConsole)")?;
|
||||
writeln!(output, " memory (MemoryManager)")?;
|
||||
writeln!(output, " process (ProcessManager)")?;
|
||||
writeln!(output, " mlcoord (MlCoordinator)")?;
|
||||
writeln!(output, " securiy (SecurityCoordinator)")?;
|
||||
writeln!(output, " storage (StorageManager)")?;
|
||||
writeln!(output, " timer (TimerService)")?;
|
||||
writeln!(output, "anything else is treated as a bundle_id")?;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "CONFIG_PRINTING"))]
|
||||
writeln!(output, "Kernel not configured with CONFIG_PRINTING!")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn collect_from_cpio(
|
||||
filename: &str,
|
||||
cpio: &[u8],
|
||||
|
@ -163,3 +163,13 @@ pub unsafe extern "C" fn memory_debug() -> MemoryManagerError {
|
||||
|
||||
KATA_MEMORY.debug().into()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn memory_capscan() {
|
||||
let recv_path = CAMKES.get_current_recv_path();
|
||||
// NB: make sure noone clobbers the setup done in memory__init
|
||||
CAMKES.assert_recv_path();
|
||||
Camkes::debug_assert_slot_empty("memory_debug", &recv_path);
|
||||
|
||||
let _ = Camkes::capscan();
|
||||
}
|
||||
|
@ -703,3 +703,13 @@ pub fn kata_memory_debug() -> Result<(), MemoryManagerError> {
|
||||
unsafe { memory_debug() };
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn kata_memory_capscan() -> Result<(), MemoryManagerError> {
|
||||
extern "C" {
|
||||
// NB: this assumes the MemoryManager component is named "memory".
|
||||
fn memory_capscan();
|
||||
}
|
||||
unsafe { memory_capscan() };
|
||||
Ok(())
|
||||
}
|
||||
|
@ -132,3 +132,8 @@ pub unsafe extern "C" fn data_fault_handle() {
|
||||
pub unsafe extern "C" fn mlcoord_debug_state() {
|
||||
ML_COORD.lock().debug_state();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn mlcoord_capscan() {
|
||||
let _ = Camkes::capscan();
|
||||
}
|
||||
|
@ -79,3 +79,12 @@ pub fn kata_mlcoord_debug_state() {
|
||||
}
|
||||
unsafe { mlcoord_debug_state() };
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn kata_mlcoord_capscan() -> Result<(), MlCoordError> {
|
||||
extern "C" {
|
||||
fn mlcoord_capscan();
|
||||
}
|
||||
unsafe { mlcoord_capscan() };
|
||||
Ok(())
|
||||
}
|
||||
|
@ -138,3 +138,21 @@ pub unsafe extern "C" fn proc_ctrl_get_running_bundles(
|
||||
Err(e) => e,
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn proc_ctrl_capscan() {
|
||||
let _ = Camkes::capscan();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn proc_ctrl_capscan_bundle(
|
||||
c_bundle_id: *const cstr_core::c_char
|
||||
) -> ProcessManagerError {
|
||||
match CStr::from_ptr(c_bundle_id).to_str() {
|
||||
Ok(str) => match KATA_PROC.capscan(str) {
|
||||
Ok(_) => ProcessManagerError::Success,
|
||||
Err(e) => e,
|
||||
},
|
||||
Err(_) => ProcessManagerError::BundleIdInvalid,
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ pub trait BundleImplInterface {
|
||||
fn stop(&mut self) -> Result<(), ProcessManagerError>;
|
||||
fn suspend(&self) -> Result<(), ProcessManagerError>;
|
||||
fn resume(&self) -> Result<(), ProcessManagerError>;
|
||||
fn capscan(&self) -> Result<(), ProcessManagerError>;
|
||||
}
|
||||
|
||||
// NB: struct's marked repr(C) are processed by cbindgen to get a .h file
|
||||
@ -71,6 +72,7 @@ pub enum ProcessManagerError {
|
||||
BundleNotFound,
|
||||
BundleFound,
|
||||
BundleRunning,
|
||||
BundleNotRunning,
|
||||
UnknownError,
|
||||
DeserializeError,
|
||||
SerializeError,
|
||||
@ -83,6 +85,7 @@ pub enum ProcessManagerError {
|
||||
// TODO(sleffler): for use if/when ProcessManagerInterface grows
|
||||
SuspendFailed,
|
||||
ResumeFailed,
|
||||
CapScanFailed,
|
||||
}
|
||||
|
||||
// Interface to underlying facilities (StorageManager, seL4); also
|
||||
@ -95,6 +98,7 @@ pub trait ProcessManagerInterface {
|
||||
fn uninstall(&mut self, bundle_id: &str) -> Result<(), ProcessManagerError>;
|
||||
fn start(&mut self, bundle: &Bundle) -> Result<Box<dyn BundleImplInterface>, ProcessManagerError>;
|
||||
fn stop(&mut self, bundle_impl: &mut dyn BundleImplInterface) -> Result<(), ProcessManagerError>;
|
||||
fn capscan(&self, bundle_impl: &dyn BundleImplInterface) -> Result<(), ProcessManagerError>;
|
||||
}
|
||||
|
||||
// NB: bundle_id comes across the C interface as *const cstr_core::c_char
|
||||
@ -112,6 +116,7 @@ pub trait ProcessControlInterface {
|
||||
fn start(&mut self, bundle_id: &str) -> Result<(), ProcessManagerError>;
|
||||
fn stop(&mut self, bundle_id: &str) -> Result<(), ProcessManagerError>;
|
||||
fn get_running_bundles(&self) -> Result<BundleIdArray, ProcessManagerError>;
|
||||
fn capscan(&self, bundle_id: &str) -> Result<(), ProcessManagerError>;
|
||||
}
|
||||
|
||||
impl From<postcard::Error> for ProcessManagerError {
|
||||
@ -231,6 +236,26 @@ pub fn kata_proc_ctrl_stop(bundle_id: &str) -> Result<(), ProcessManagerError> {
|
||||
unsafe { proc_ctrl_stop(cstr.as_ptr()) }.into()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub fn kata_proc_ctrl_capscan() -> Result<(), ProcessManagerError> {
|
||||
extern "C" {
|
||||
fn proc_ctrl_capscan();
|
||||
}
|
||||
unsafe { proc_ctrl_capscan() }
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub fn kata_proc_ctrl_capscan_bundle(bundle_id: &str) -> Result<(), ProcessManagerError> {
|
||||
extern "C" {
|
||||
fn proc_ctrl_capscan_bundle(c_bundle_id: *const cstr_core::c_char) -> ProcessManagerError;
|
||||
}
|
||||
let cstr = CString::new(bundle_id)?;
|
||||
unsafe { proc_ctrl_capscan_bundle(cstr.as_ptr()) }.into()
|
||||
}
|
||||
|
||||
// TODO(sleffler): move out of interface?
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
@ -13,6 +13,7 @@ default = []
|
||||
CONFIG_CAPDL_LOADER_CC_REGISTERS = []
|
||||
CONFIG_CAPDL_LOADER_WRITEABLE_PAGES = []
|
||||
CONFIG_DEBUG_BUILD = []
|
||||
CONFIG_PRINTING = []
|
||||
CONFIG_KERNEL_MCS = []
|
||||
CONFIG_SMP_SUPPORT = []
|
||||
|
||||
|
@ -84,6 +84,9 @@ impl ProcessControlInterface for KataProcManager {
|
||||
fn get_running_bundles(&self) -> Result<BundleIdArray, ProcessManagerError> {
|
||||
self.manager.lock().as_ref().unwrap().get_running_bundles()
|
||||
}
|
||||
fn capscan(&self, bundle_id: &str) -> Result<(), ProcessManagerError> {
|
||||
self.manager.lock().as_ref().unwrap().capscan(bundle_id)
|
||||
}
|
||||
}
|
||||
|
||||
struct KataManagerInterface;
|
||||
@ -161,4 +164,9 @@ impl ProcessManagerInterface for KataManagerInterface {
|
||||
// TODO(sleffler): fill-in 1+2
|
||||
bundle_impl.stop()
|
||||
}
|
||||
fn capscan(&self, bundle_impl: &dyn BundleImplInterface) -> Result<(), ProcessManagerError> {
|
||||
trace!("ProcessManagerInterface::capscan");
|
||||
|
||||
bundle_impl.capscan()
|
||||
}
|
||||
}
|
||||
|
@ -167,6 +167,21 @@ impl ProcessControlInterface for ProcessManager {
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn capscan(&self, bundle_id: &str) -> Result<(), ProcessManagerError> {
|
||||
trace!("capscan bundle_id {}", bundle_id);
|
||||
let bid = BundleId::from_str(bundle_id);
|
||||
if let Some(bundle) = self.bundles.get(&bid) {
|
||||
trace!("capscan state {:?}", bundle.state);
|
||||
if bundle.state != BundleState::Running {
|
||||
return Err(ProcessManagerError::BundleNotRunning)
|
||||
}
|
||||
self.manager.capscan(bundle.bundle_impl.as_deref().unwrap())
|
||||
} else {
|
||||
trace!("capscan {} not found", bundle_id);
|
||||
Err(ProcessManagerError::BundleNotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -192,6 +207,7 @@ mod tests {
|
||||
fn stop(&mut self) -> Result<(), ProcessManagerError> { Ok(()) }
|
||||
fn resume(&self) -> Result<(), ProcessManagerError> { Ok(()) }
|
||||
fn suspend(&self) -> Result<(), ProcessManagerError> { Ok(()) }
|
||||
fn capscan(&self) -> Result<(), ProcessManagerError> { Ok(()) }
|
||||
}
|
||||
impl ProcessManagerInterface for FakeManager {
|
||||
fn install(&mut self, pkg_buffer: *const u8, pkg_buffer_size: u32) -> Result<String, pme> {
|
||||
@ -215,6 +231,9 @@ mod tests {
|
||||
fn stop(&mut self, bundle_impl: &mut dyn BundleImplInterface) -> Result<(), pme> {
|
||||
Ok(())
|
||||
}
|
||||
fn capscan(&mut self, bundle_impl: &mut dyn BundleImplInterface) -> Result<(), pme> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -608,4 +608,9 @@ impl BundleImplInterface for seL4BundleImpl {
|
||||
unsafe { seL4_TCB_Suspend(self.cap_tcb.slot) }
|
||||
.map_err(|_| ProcessManagerError::SuspendFailed)
|
||||
}
|
||||
fn capscan(&self) -> Result<(), ProcessManagerError> {
|
||||
#[cfg(feature = "CONFIG_PRINTING")]
|
||||
unsafe { sel4_sys::seL4_DebugDumpCNode(self.cspace_root.objs[0].cptr); }
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -239,6 +239,11 @@ fn test_mailbox_request(
|
||||
unsafe { KATA_SECURITY.test_mailbox() }
|
||||
}
|
||||
|
||||
fn capscan_request() -> Result<(), SecurityRequestError> {
|
||||
let _ = Camkes::capscan();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn security_request(
|
||||
c_request: SecurityRequest,
|
||||
@ -272,5 +277,7 @@ pub unsafe extern "C" fn security_request(
|
||||
delete_key_request(request_buffer, reply_buffer),
|
||||
SecurityRequest::SrTestMailbox =>
|
||||
test_mailbox_request(),
|
||||
SecurityRequest::SrCapScan =>
|
||||
capscan_request(),
|
||||
}.map_or_else(|e| e, |_v| SecurityRequestError::SreSuccess)
|
||||
}
|
||||
|
@ -168,10 +168,14 @@ impl<'a> SecurityCapability for DeleteKeyRequest<'a> {}
|
||||
|
||||
// SecurityRequestTestMailbox
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct TestMailboxRequest {
|
||||
}
|
||||
pub struct TestMailboxRequest {}
|
||||
impl SecurityCapability for TestMailboxRequest {}
|
||||
|
||||
// SecurityRequestCapScan
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct CapScanRequest {}
|
||||
impl SecurityCapability for CapScanRequest {}
|
||||
|
||||
// NB: this is the union of InstallInterface & StorageInterface because
|
||||
// the camkes-generated interface code uses basic C which does not
|
||||
// tolerate overlapping member names.
|
||||
@ -241,6 +245,7 @@ pub enum SecurityRequest {
|
||||
SrDeleteKey, // Delete key [bundle_id, key]
|
||||
|
||||
SrTestMailbox, // Run mailbox tests
|
||||
SrCapScan, // Dump contents CNode to console
|
||||
}
|
||||
|
||||
// Interface to underlying facilities; also used to inject fakes for unit tests.
|
||||
@ -489,3 +494,13 @@ pub fn kata_security_test_mailbox() -> Result<(), SecurityRequestError> {
|
||||
&mut [0u8; SECURITY_REPLY_DATA_SIZE],
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub fn kata_security_capscan() -> Result<(), SecurityRequestError> {
|
||||
kata_security_request(
|
||||
SecurityRequest::SrCapScan,
|
||||
&CapScanRequest {},
|
||||
&mut [0u8; SECURITY_REPLY_DATA_SIZE],
|
||||
)
|
||||
}
|
||||
|
@ -75,3 +75,8 @@ pub unsafe extern "C" fn storage_delete(
|
||||
Err(_) => StorageManagerError::SmeKeyInvalid,
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn storage_capscan() {
|
||||
let _ = Camkes::capscan();
|
||||
}
|
||||
|
@ -139,3 +139,13 @@ pub fn kata_storage_write(key: &str, value: &[u8]) -> Result<(), StorageManagerE
|
||||
let cstr = CString::new(key)?;
|
||||
unsafe { storage_write(cstr.as_ptr(), value.len(), value.as_ptr()) }.into()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub fn kata_storage_capscan() -> Result<(), StorageManagerError> {
|
||||
extern "C" {
|
||||
fn storage_capscan();
|
||||
}
|
||||
unsafe { storage_capscan() }
|
||||
Ok(())
|
||||
}
|
||||
|
@ -87,3 +87,8 @@ pub unsafe extern "C" fn timer_interrupt_handle() {
|
||||
TIMER_SRV.lock().service_interrupt();
|
||||
assert!(timer_interrupt_acknowledge() == 0);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn timer_capscan() {
|
||||
let _ = Camkes::capscan();
|
||||
}
|
||||
|
@ -81,3 +81,13 @@ pub fn timer_service_wait() -> seL4_Word {
|
||||
|
||||
notification_badge
|
||||
}
|
||||
|
||||
#[inline]
|
||||
#[allow(dead_code)]
|
||||
pub fn timer_service_capscan() -> Result<(), TimerServiceError> {
|
||||
extern "C" {
|
||||
fn timer_capscan();
|
||||
}
|
||||
unsafe { timer_capscan() }
|
||||
Ok(())
|
||||
}
|
||||
|
@ -2,6 +2,13 @@
|
||||
name = "camkes"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
build = "build.rs"
|
||||
|
||||
[build-dependencies]
|
||||
sel4-config = { path = "../sel4-config" }
|
||||
|
||||
[features]
|
||||
CONFIG_PRINTING = []
|
||||
|
||||
[dependencies]
|
||||
log = "0.4"
|
||||
|
21
apps/system/components/kata-os-common/src/camkes/build.rs
Normal file
21
apps/system/components/kata-os-common/src/camkes/build.rs
Normal file
@ -0,0 +1,21 @@
|
||||
extern crate sel4_config;
|
||||
use std::env;
|
||||
|
||||
fn main() {
|
||||
// If SEL4_OUT_DIR is not set we expect the kernel build at a fixed
|
||||
// location relative to the ROOTDIR env variable.
|
||||
println!("SEL4_OUT_DIR {:?}", env::var("SEL4_OUT_DIR"));
|
||||
let sel4_out_dir = env::var("SEL4_OUT_DIR").unwrap_or_else(
|
||||
|_| format!("{}/out/kata/kernel", env::var("ROOTDIR").unwrap())
|
||||
);
|
||||
println!("sel4_out_dir {}", sel4_out_dir);
|
||||
|
||||
// Dredge seL4 kernel config for settings we need as features to generate
|
||||
// correct code: e.g. CONFIG_KERNEL_MCS enables MCS support which changes
|
||||
// the system call numbering.
|
||||
let features = sel4_config::get_sel4_features(&sel4_out_dir);
|
||||
println!("features={:?}", features);
|
||||
for feature in features {
|
||||
println!("cargo:rustc-cfg=feature=\"{}\"", feature);
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ use sel4_sys;
|
||||
use sel4_sys::seL4_CNode_Delete;
|
||||
use sel4_sys::seL4_CPtr;
|
||||
use sel4_sys::seL4_GetCapReceivePath;
|
||||
use sel4_sys::seL4_Result;
|
||||
use sel4_sys::seL4_SetCap;
|
||||
use sel4_sys::seL4_SetCapReceivePath;
|
||||
use sel4_sys::seL4_Word;
|
||||
@ -173,4 +174,13 @@ impl Camkes {
|
||||
"{}: expected cnode in slot {:?} but found cap type {:?}",
|
||||
tag, path, sel4_sys::cap_identify(path.1));
|
||||
}
|
||||
|
||||
// Dumps the contents of the toplevel CNode to the serial console.
|
||||
pub fn capscan() -> seL4_Result {
|
||||
// TODO(sleffler): requires CONFIG_PRINTING in the kernel
|
||||
#[cfg(feature = "CONFIG_PRINTING")]
|
||||
unsafe { sel4_sys::seL4_DebugDumpCNode(SELF_CNODE); }
|
||||
// XXX until seL4_Error is correctly returned
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -990,6 +990,16 @@ pub unsafe fn seL4_DebugCapIdentify(mut cap: seL4_CPtr) -> u32 {
|
||||
cap as _
|
||||
}
|
||||
|
||||
#[cfg(feature = "CONFIG_PRINTING")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn seL4_DebugDumpCNode(mut cap: seL4_CPtr) {
|
||||
asm!("swi 0",
|
||||
in("r7") swinum!(SyscallId::DebugDumpCNode),
|
||||
inout("r0") cap,
|
||||
options(nomem, nostack),
|
||||
);
|
||||
}
|
||||
|
||||
// Note: name MUST be NUL-terminated.
|
||||
#[cfg(feature = "CONFIG_DEBUG_BUILD")]
|
||||
#[inline(always)]
|
||||
|
@ -986,6 +986,16 @@ pub unsafe fn seL4_DebugCapIdentify(mut cap: seL4_CPtr) -> u32 {
|
||||
cap as _
|
||||
}
|
||||
|
||||
#[cfg(feature = "CONFIG_PRINTING")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn seL4_DebugDumpCNode(mut cap: seL4_CPtr) {
|
||||
asm!("svc 0",
|
||||
in("x7") swinum!(SyscallId::DebugDumpCNode),
|
||||
inout("x0") cap,
|
||||
options(nomem, nostack),
|
||||
);
|
||||
}
|
||||
|
||||
// Note: name MUST be NUL-terminated.
|
||||
#[cfg(feature = "CONFIG_DEBUG_BUILD")]
|
||||
#[inline(always)]
|
||||
|
@ -945,6 +945,16 @@ pub unsafe fn seL4_DebugCapIdentify(mut cap: seL4_CPtr) -> u32 {
|
||||
cap as _
|
||||
}
|
||||
|
||||
#[cfg(feature = "CONFIG_PRINTING")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn seL4_DebugDumpCNode(mut cap: seL4_CPtr) {
|
||||
asm!("ecall",
|
||||
in("a7") swinum!(SyscallId::DebugDumpCNode),
|
||||
inout("a0") cap,
|
||||
options(nomem, nostack),
|
||||
);
|
||||
}
|
||||
|
||||
// Note: name MUST be NUL-terminated.
|
||||
#[cfg(feature = "CONFIG_DEBUG_BUILD")]
|
||||
#[inline(always)]
|
||||
|
@ -952,6 +952,16 @@ pub unsafe fn seL4_DebugCapIdentify(mut cap: seL4_CPtr) -> u32 {
|
||||
cap as _
|
||||
}
|
||||
|
||||
#[cfg(feature = "CONFIG_PRINTING")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn seL4_DebugDumpCNode(mut cap: seL4_CPtr) {
|
||||
asm!("ecall",
|
||||
in("a7") swinum!(SyscallId::DebugDumpCNode),
|
||||
inout("a0") cap,
|
||||
options(nomem, nostack),
|
||||
);
|
||||
}
|
||||
|
||||
// Note: name MUST be NUL-terminated.
|
||||
#[cfg(feature = "CONFIG_DEBUG_BUILD")]
|
||||
#[inline(always)]
|
||||
|
@ -579,11 +579,21 @@ pub unsafe fn seL4_DebugCapIdentify(mut cap: seL4_CPtr) -> u32 {
|
||||
let mut unused0 = 0;
|
||||
let mut unused1 = 0;
|
||||
let mut unused2 = 0;
|
||||
x86_sys_send_recv(SyscallId::DebugCapIdentify as seL4_Word,
|
||||
x86_sys_send_recv(SyscallId::DebugCapIdentify as seL4_Word,
|
||||
cap, &mut cap, 0, &mut unused0, &mut unused1, &mut unused2);
|
||||
cap as _
|
||||
}
|
||||
|
||||
#[cfg(feature = "CONFIG_PRINTING")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn seL4_DebugDumpCNode(mut cap: seL4_CPtr) {
|
||||
let mut unused0 = 0;
|
||||
let mut unused1 = 0;
|
||||
let mut unused2 = 0;
|
||||
x86_sys_send_recv(SyscallId::DebugDumpCNode as seL4_Word,
|
||||
cap, &mut cap, 0, &mut unused0, &mut unused1, &mut unused2);
|
||||
}
|
||||
|
||||
/// Note: name MUST be NUL-terminated.
|
||||
#[inline(always)]
|
||||
pub unsafe fn seL4_DebugNameThread(tcb: seL4_CPtr, name: &[u8]) {
|
||||
@ -631,7 +641,7 @@ pub unsafe fn seL4_BenchmarkSetLogBuffer(mut frame_cptr: seL4_Word) -> seL4_Word
|
||||
let mut unused0 = 0;
|
||||
let mut unused1 = 0;
|
||||
let mut unused2 = 0;
|
||||
x86_sys_send_recv(SyscallId::BenchmarkSetLogBuffer as seL4_Word,
|
||||
x86_sys_send_recv(SyscallId::BenchmarkSetLogBuffer as seL4_Word,
|
||||
frame_cptr, &mut cap, 0, &mut unused0 as *mut _ as usize as seL4_Word, &mut unused1 as *mut _ as usize as seL4_Word, &mut unused2 as *mut _ as usize as seL4_Word);
|
||||
frame_cptr
|
||||
}
|
||||
|
@ -1123,6 +1123,21 @@ pub unsafe fn seL4_DebugCapIdentify(mut cap: seL4_CPtr) -> u32 {
|
||||
cap as _
|
||||
}
|
||||
|
||||
#[cfg(feature = "CONFIG_PRINTING")]
|
||||
#[inline(always)]
|
||||
pub unsafe fn seL4_DebugDumpCNode(mut cap: seL4_CPtr) {
|
||||
asm!("mov r14, rsp
|
||||
syscall
|
||||
mov rsp, r14",
|
||||
in("rdx") swinum!(SyscallId::DebugDumpCNode),
|
||||
inout("rdi") cap,
|
||||
lateout("rcx") _,
|
||||
lateout("r11") _,
|
||||
lateout("r14") _,
|
||||
options(nomem, nostack),
|
||||
);
|
||||
}
|
||||
|
||||
// Note: name MUST be NUL-terminated.
|
||||
#[cfg(feature = "CONFIG_DEBUG_BUILD")]
|
||||
#[inline(always)]
|
||||
|
@ -5,5 +5,6 @@ procedure MemoryInterface {
|
||||
MemoryManagerError free(in char request[]);
|
||||
MemoryManagerError stats(out RawMemoryStatsData data);
|
||||
|
||||
void capscan();
|
||||
void debug();
|
||||
};
|
||||
|
@ -6,4 +6,5 @@ procedure MlCoordinatorInterface {
|
||||
MlCoordError cancel(in string bundle_id, in string model_id);
|
||||
|
||||
void debug_state();
|
||||
void capscan();
|
||||
};
|
||||
|
@ -4,4 +4,7 @@ procedure ProcessControlInterface {
|
||||
ProcessManagerError start(in string bundleId);
|
||||
ProcessManagerError stop(in string bundleId);
|
||||
ProcessManagerError get_running_bundles(out RawBundleIdData raw_data);
|
||||
|
||||
void capscan();
|
||||
ProcessManagerError capscan_bundle(in string bundleId);
|
||||
};
|
||||
|
@ -4,4 +4,6 @@ procedure StorageInterface {
|
||||
StorageManagerError read(in string key, out KeyValueData value);
|
||||
StorageManagerError write(in string key, in char value[]);
|
||||
StorageManagerError delete(in string key);
|
||||
|
||||
void capscan();
|
||||
};
|
||||
|
@ -8,4 +8,6 @@ procedure Timer {
|
||||
TimerServiceError oneshot(uint32_t timer_id, uint32_t duration_in_ms);
|
||||
TimerServiceError periodic(uint32_t timer_id, uint32_t duration_in_ms);
|
||||
TimerServiceError cancel(uint32_t timer_id);
|
||||
|
||||
void capscan();
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user