1use crate::syscalls::syscall_table::_utee_log;
2use core::ffi::*;
3use core::fmt::{Arguments, Result, Write};
4
5pub const TRACE_MIN: i32 = 0;
6pub const TRACE_ERROR: i32 = 1;
7pub const TRACE_INFO: i32 = 2;
8pub const TRACE_DEBUG: i32 = 3;
9pub const TRACE_FLOW: i32 = 4;
10pub const TRACE_MAX: i32 = TRACE_FLOW;
11pub const TRACE_PRINTF_LEVEL: i32 = TRACE_ERROR;
12
13pub const DEFAULT_TRACE_LEVEL: i32 = {
14 if cfg!(feature = "trace-error") {
15 TRACE_ERROR
16 } else if cfg!(feature = "trace-flow") {
17 TRACE_FLOW
18 } else if cfg!(feature = "trace-info") {
19 TRACE_INFO
20 } else if cfg!(feature = "trace-debug") {
21 TRACE_DEBUG
22 } else {
23 TRACE_MAX
24 }
25};
26
27use core::sync::atomic::{AtomicI32, Ordering};
28
29static TRACE_LEVEL: AtomicI32 = AtomicI32::new(DEFAULT_TRACE_LEVEL);
30
31pub struct Trace;
32
33impl Trace {
34 fn new() -> Self {
35 Trace {}
36 }
37
38 pub fn _print(fmt: Arguments) {
39 let mut writer = Trace::new();
40 let result = writer.write_fmt(fmt);
41
42 if let Err(e) = result {
43 panic!("failed printing to trace: {}", e);
44 }
45 }
46
47 pub fn set_level(level: i32) {
48 let val = if level >= TRACE_MIN && level <= TRACE_MAX {
49 level
50 } else {
51 TRACE_MAX
52 };
53 TRACE_LEVEL.store(val, Ordering::Relaxed);
54 }
55
56 pub fn get_level() -> i32 {
57 TRACE_LEVEL.load(Ordering::Relaxed)
58 }
59}
60
61impl Write for Trace {
62 fn write_str(&mut self, buf: &str) -> Result {
63 _utee_log(buf.as_ptr() as *const c_void, buf.len());
64 Ok(())
65 }
66}