Nothing to see here, move along
1use core::sync::atomic::{AtomicU8, Ordering};
2
3use crate::error::KernelError;
4use crate::proc::context::CpuContext;
5use crate::syscall::{SyscallResult, copy_from_user};
6
7static LOG_THRESHOLD: AtomicU8 = AtomicU8::new(2);
8
9#[allow(dead_code)]
10pub fn threshold() -> u8 {
11 LOG_THRESHOLD.load(Ordering::Relaxed)
12}
13
14#[allow(dead_code)]
15pub fn set_threshold(level: u8) {
16 LOG_THRESHOLD.store(level.min(3), Ordering::Relaxed);
17}
18
19const GLASS_BIT: u8 = 0x80;
20
21pub fn sys_log(ctx: &mut CpuContext) {
22 let raw_level = ctx.rdi as u8;
23 let glass = raw_level & GLASS_BIT != 0;
24 let level = raw_level & !GLASS_BIT;
25 let ptr = ctx.rsi;
26 let len = ctx.rdx;
27
28 if level > 3 {
29 ctx.rax = SyscallResult::error(KernelError::InvalidParameter).raw();
30 return;
31 }
32
33 if !glass && level > LOG_THRESHOLD.load(Ordering::Relaxed) {
34 ctx.rax = SyscallResult::ok().raw();
35 return;
36 }
37
38 let irq = match crate::sync::InterruptsDisabledToken::new_checked() {
39 Some(tok) => tok,
40 None => {
41 x86_64::instructions::interrupts::disable();
42 match crate::sync::InterruptsDisabledToken::new_checked() {
43 Some(tok) => tok,
44 None => {
45 ctx.rax = SyscallResult::error(KernelError::BadState).raw();
46 return;
47 }
48 }
49 }
50 };
51
52 if len > 256 {
53 ctx.rax = SyscallResult::error(KernelError::InvalidParameter).raw();
54 return;
55 }
56
57 let mut buf = [0u8; 256];
58 match copy_from_user(ptr, &mut buf, len as usize, &irq) {
59 Err(e) => {
60 ctx.rax = SyscallResult::error(e).raw();
61 }
62 Ok(()) => match core::str::from_utf8(&buf[..len as usize]) {
63 Err(_) => {
64 ctx.rax = SyscallResult::error(KernelError::InvalidParameter).raw();
65 }
66 Ok(msg) => {
67 let pid = crate::arch::syscall::current_pid();
68 let mut name_buf = [0u8; 32];
69 let name_len = {
70 let ptable = crate::proc::PROCESSES.lock();
71 let name = ptable.exec(pid).map(|e| e.name_str()).unwrap_or("?");
72 let n = name.len().min(32);
73 name_buf[..n].copy_from_slice(&name.as_bytes()[..n]);
74 n
75 };
76 let name_str = unsafe { core::str::from_utf8_unchecked(&name_buf[..name_len]) };
77 let severity =
78 lancer_log::Severity::from_u8(level).unwrap_or(lancer_log::Severity::Info);
79 let tsc = crate::wcet::tsc::read_tsc();
80 crate::flight::recorder().append(tsc, severity, name_str, format_args!("{}", msg));
81 if glass {
82 use core::fmt::Write;
83 let mut w = crate::arch::serial::SerialWriter;
84 let _ = lancer_log::format::write_gutter(
85 &mut w,
86 name_str,
87 severity,
88 format_args!("{}", msg),
89 crate::log::KLOG_GUTTER,
90 );
91 let _ = w.write_str("\n");
92 }
93 ctx.rax = SyscallResult::ok().raw();
94 }
95 },
96 }
97}
98
99pub fn sys_get_proc_name(ctx: &mut CpuContext) {
100 let dst_ptr = ctx.rdi;
101 let dst_cap = ctx.rsi;
102
103 let irq = match crate::sync::InterruptsDisabledToken::new_checked() {
104 Some(tok) => tok,
105 None => {
106 x86_64::instructions::interrupts::disable();
107 match crate::sync::InterruptsDisabledToken::new_checked() {
108 Some(tok) => tok,
109 None => {
110 ctx.rax = SyscallResult::error(KernelError::BadState).raw();
111 return;
112 }
113 }
114 }
115 };
116
117 let pid = crate::arch::syscall::current_pid();
118 let mut name_buf = [0u8; 32];
119 let name_len = {
120 let ptable = crate::proc::PROCESSES.lock();
121 let name = ptable.exec(pid).map(|e| e.name_str()).unwrap_or("?");
122 let n = name.len().min(32);
123 name_buf[..n].copy_from_slice(&name.as_bytes()[..n]);
124 n
125 };
126
127 let copy_len = name_len.min(dst_cap as usize);
128 if copy_len > 0 {
129 match crate::syscall::copy_to_user(dst_ptr, &name_buf[..copy_len], copy_len, &irq) {
130 Ok(()) => {
131 ctx.rax = SyscallResult::success(copy_len as u64).raw();
132 }
133 Err(e) => {
134 ctx.rax = SyscallResult::error(e).raw();
135 }
136 }
137 } else {
138 ctx.rax = SyscallResult::success(0).raw();
139 }
140}
141
142pub fn sys_blackbox_read(ctx: &mut CpuContext) {
143 let cursor = ctx.rdi as usize;
144 let dst_ptr = ctx.rsi;
145 let dst_len = ctx.rdx as usize;
146 ctx.rsi = 0;
147
148 let irq = match crate::sync::InterruptsDisabledToken::new_checked() {
149 Some(tok) => tok,
150 None => {
151 x86_64::instructions::interrupts::disable();
152 match crate::sync::InterruptsDisabledToken::new_checked() {
153 Some(tok) => tok,
154 None => {
155 ctx.rax = SyscallResult::error(KernelError::BadState).raw();
156 return;
157 }
158 }
159 }
160 };
161
162 if dst_len == 0 || dst_len > 65536 {
163 ctx.rax = SyscallResult::error(KernelError::InvalidParameter).raw();
164 return;
165 }
166
167 let mut tmp = [0u8; 4096];
168 let read_cap = dst_len.min(4096);
169 let (new_cursor, bytes_read) = crate::flight::recorder().read(cursor, &mut tmp[..read_cap]);
170
171 if bytes_read > 0 {
172 match crate::syscall::copy_to_user(dst_ptr, &tmp[..bytes_read], bytes_read, &irq) {
173 Ok(()) => {
174 ctx.rax = new_cursor as u64;
175 ctx.rsi = bytes_read as u64;
176 }
177 Err(e) => {
178 ctx.rax = SyscallResult::error(e).raw();
179 }
180 }
181 } else {
182 ctx.rax = new_cursor as u64;
183 ctx.rsi = 0;
184 }
185}