Nothing to see here, move along
at main 185 lines 6.0 kB view raw
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}