feature: x86_64 serial console

This commit is contained in:
2022-03-22 15:37:33 +02:00
parent 6a1a6a8910
commit cf104ecf28
11 changed files with 397 additions and 349 deletions
+4 -1
View File
@@ -5,7 +5,7 @@ use crate::arch::x86_64::{
};
use crate::config::{ConfigKey, CONFIG};
use crate::debug;
use crate::dev::{display::FramebufferInfo, pseudo, Device};
use crate::dev::{display::FramebufferInfo, irq::IntSource, pseudo, Device};
use crate::font;
use crate::fs::{devfs::{self, CharDeviceType}, sysfs};
use crate::mem::{
@@ -93,6 +93,9 @@ extern "C" fn __x86_64_bsp_main(mb_checksum: u32, mb_info_ptr: u32) -> ! {
phys_base: fb_info.address as usize,
virt_base: virt,
});
unsafe {
x86_64::COM1.init_irqs();
}
font::init();
debug::set_display(&x86_64::DISPLAY);
syscall::init();
+1
View File
@@ -100,6 +100,7 @@ impl IntController for I8259 {
let irq_number = ic.token();
assert!(irq_number > 0);
// Clear irq
if irq_number > 8 {
self.cmd_b.write(0x20);
}
+19 -5
View File
@@ -24,7 +24,25 @@ __x86_64_irq_\no:
mov %rsp, %rdi
call __x86_64_irq_handler
jmp .
pop %r15
pop %r14
pop %r13
pop %r12
pop %r11
pop %r10
pop %r9
pop %r8
pop %rdi
pop %rsi
pop %rbp
pop %rbx
pop %rdx
pop %rcx
pop %rax
add $16, %rsp
iretq
.endm
.section .text
@@ -49,10 +67,6 @@ __x86_64_irq_0:
push %r14
push %r15
mov $0x3F8, %dx
mov $'T', %al
outb %al, %dx
mov $0x20, %al
mov $0x20, %dx
outb %al, %dx
+3 -2
View File
@@ -5,6 +5,7 @@ mod uart;
use uart::Uart;
mod intc;
use intc::I8259;
pub use intc::IrqNumber;
mod io;
pub(self) use io::PortIo;
@@ -54,6 +55,6 @@ pub fn console() -> &'static impl SerialDevice {
&COM1
}
static COM1: Uart = unsafe { Uart::new(0x3F8) };
static INTC: I8259 = I8259::new();
static COM1: Uart = unsafe { Uart::new(0x3F8, IrqNumber::new(4)) };
pub(self) static INTC: I8259 = I8259::new();
pub(self) static DISPLAY: StaticFramebuffer = StaticFramebuffer::uninit();
+30 -6
View File
@@ -1,16 +1,19 @@
use crate::arch::x86_64::PortIo;
use libsys::error::Errno;
use crate::arch::x86_64::{self, IrqNumber, PortIo};
use crate::dev::{
tty::{CharRing, TtyDevice},
irq::{IntController, IntSource},
serial::SerialDevice,
tty::{CharRing, TtyDevice},
Device,
};
use libsys::error::Errno;
#[derive(TtyCharDevice)]
pub(super) struct Uart {
dr: PortIo<u8>,
ring: CharRing<16>
ier: PortIo<u8>,
isr: PortIo<u8>,
ring: CharRing<16>,
irq: IrqNumber,
}
impl Device for Uart {
@@ -29,6 +32,24 @@ impl TtyDevice<16> for Uart {
}
}
impl IntSource for Uart {
fn handle_irq(&self) -> Result<(), Errno> {
if self.isr.read() != 0 {
self.recv_byte(self.dr.read());
}
Ok(())
}
fn init_irqs(&'static self) -> Result<(), Errno> {
// TODO shared IRQs between COM# ports
x86_64::INTC.register_handler(self.irq, self)?;
self.ier.write((1 << 0));
x86_64::INTC.enable_irq(self.irq)?;
Ok(())
}
}
impl SerialDevice for Uart {
fn send(&self, byte: u8) -> Result<(), Errno> {
self.dr.write(byte);
@@ -41,10 +62,13 @@ impl SerialDevice for Uart {
}
impl Uart {
pub const unsafe fn new(base: u16) -> Self {
pub const unsafe fn new(base: u16, irq: IrqNumber) -> Self {
Self {
dr: PortIo::new(base),
ring: CharRing::new()
ier: PortIo::new(base + 1),
isr: PortIo::new(base + 2),
ring: CharRing::new(),
irq,
}
}
}
-1
View File
@@ -229,7 +229,6 @@ impl Space for SpaceImpl {
);
Err(Errno::AlreadyExists)
} else {
debugln!("write_last_level {:#x}, {:#x?}", virt, entry);
l2_table[l3i] = entry;
unsafe {
core::arch::asm!("invlpg ({})", in(reg) virt, options(att_syntax));
+1
View File
@@ -137,6 +137,7 @@ pub trait Space {
/// Creates a new virtual -> physical memory mapping. Will fail if one is
/// already associated with given virtual address.
fn map(&mut self, virt: usize, phys: usize, attrs: MapAttributes) -> Result<(), Errno> {
#[cfg(feature = "verbose")]
debugln!("Map {:#x} -> {:#x}, {:?}", virt, phys, attrs);
unsafe {
self.write_last_level(
+26 -1
View File
@@ -69,7 +69,32 @@ impl Wait {
/// Interrupt wait pending on the channel
pub fn abort(&self, tid: Tid, enqueue: bool) {
todo!();
let mut queue = self.queue.lock();
let mut tick_lock = TICK_LIST.lock();
let mut cursor = tick_lock.cursor_front_mut();
while let Some(item) = cursor.current() {
if tid == item.tid {
cursor.remove_current();
break;
} else {
cursor.move_next();
}
}
let mut cursor = queue.cursor_front_mut();
while let Some(item) = cursor.current() {
if tid == *item {
cursor.remove_current();
let thread = Thread::get(tid).unwrap();
thread.set_wait_status(WaitStatus::Interrupted);
if enqueue {
SCHED.enqueue(tid);
}
break;
} else {
cursor.move_next();
}
}
}
fn wakeup_some(&self, mut limit: usize) -> usize {
+306 -307
View File
@@ -1,16 +1,17 @@
//! System call implementation
// use crate::arch::{machine, platform::exception::ExceptionFrame};
use crate::arch::platform::ForkFrame;
use crate::arch::{machine, platform::ForkFrame};
use crate::debug::Level;
// use crate::dev::timer::TimestampSource;
use crate::fs::create_filesystem;
use crate::mem::{
phys::PageUsage,
virt::table::{Space, MapAttributes},
virt::table::{MapAttributes, Space},
};
use crate::proc::{self, elf, wait, Process, ProcessIo, Thread};
use core::mem::size_of;
use core::ops::DerefMut;
use core::time::Duration;
use libsys::{
abi::SystemCall,
debug::TraceLevel,
@@ -77,132 +78,132 @@ fn _syscall(num: SystemCall, args: &[usize]) -> Result<usize, Errno> {
io.file(fd)?.borrow_mut().write(buf)
}
// SystemCall::Open => {
// let at_fd = FileDescriptor::from_i32(args[0] as i32)?;
// let path = arg::str_ref(args[1], args[2])?;
// let mode = FileMode::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?;
// let opts = OpenFlags::from_bits(args[4] as u32).ok_or(Errno::InvalidArgument)?;
//
// let proc = Process::current();
// let mut io = proc.io.lock();
//
// let at = if let Some(fd) = at_fd {
// io.file(fd)?.borrow().node()
// } else {
// None
// };
//
// let file = io.ioctx().open(at, path, mode, opts)?;
// Ok(u32::from(io.place_file(file)?) as usize)
// }
// SystemCall::Close => {
// let proc = Process::current();
// let mut io = proc.io.lock();
// let fd = FileDescriptor::from(args[0] as u32);
//
// io.close_file(fd)?;
// Ok(0)
// }
// SystemCall::FileStatus => {
// let at_fd = FileDescriptor::from_i32(args[0] as i32)?;
// let filename = arg::str_ref(args[1], args[2])?;
// let buf = arg::struct_mut::<Stat>(args[3])?;
// let flags = args[4] as u32;
//
// let proc = Process::current();
// let mut io = proc.io.lock();
// let stat =
// find_at_node(&mut io, at_fd, filename, flags & AT_EMPTY_PATH != 0)?.stat()?;
// *buf = stat;
// Ok(0)
// }
// SystemCall::Ioctl => {
// let fd = FileDescriptor::from(args[0] as u32);
// let cmd = IoctlCmd::try_from(args[1] as u32)?;
//
// let proc = Process::current();
// let mut io = proc.io.lock();
//
// let node = io.file(fd)?.borrow().node().ok_or(Errno::InvalidFile)?;
// node.ioctl(cmd, args[2], args[3])
// }
// SystemCall::Select => {
// let rfds = arg::option_struct_mut::<FdSet>(args[0])?;
// let wfds = arg::option_struct_mut::<FdSet>(args[1])?;
// let timeout = if args[2] == 0 {
// None
// } else {
// Some(Duration::from_nanos(args[2] as u64))
// };
//
// wait::select(Thread::current(), rfds, wfds, timeout)
// }
// SystemCall::Access => {
// let at_fd = FileDescriptor::from_i32(args[0] as i32)?;
// let path = arg::str_ref(args[1], args[2])?;
// let mode = AccessMode::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?;
// let flags = args[4] as u32;
//
// let proc = Process::current();
// let mut io = proc.io.lock();
//
// find_at_node(&mut io, at_fd, path, flags & AT_EMPTY_PATH != 0)?
// .check_access(io.ioctx(), mode)?;
// Ok(0)
// }
// SystemCall::ReadDirectory => {
// let proc = Process::current();
// let fd = FileDescriptor::from(args[0] as u32);
// let mut io = proc.io.lock();
// let buf = arg::struct_buf_mut::<DirectoryEntry>(args[1], args[2])?;
//
// io.file(fd)?.borrow_mut().readdir(buf)
// }
// SystemCall::GetUserId => {
// let proc = Process::current();
// let uid = proc.io.lock().uid();
// Ok(u32::from(uid) as usize)
// }
// SystemCall::GetGroupId => {
// let proc = Process::current();
// let gid = proc.io.lock().gid();
// Ok(u32::from(gid) as usize)
// }
// SystemCall::DuplicateFd => {
// let src = FileDescriptor::from(args[0] as u32);
// let dst = FileDescriptor::from_i32(args[1] as i32)?;
//
// let proc = Process::current();
// let mut io = proc.io.lock();
//
// let res = io.duplicate_file(src, dst)?;
//
// Ok(u32::from(res) as usize)
// }
// SystemCall::SetUserId => {
// let uid = UserId::from(args[0] as u32);
// let proc = Process::current();
// proc.io.lock().set_uid(uid)?;
// Ok(0)
// }
// SystemCall::SetGroupId => {
// let gid = GroupId::from(args[0] as u32);
// let proc = Process::current();
// proc.io.lock().set_gid(gid)?;
// Ok(0)
// }
// SystemCall::SetCurrentDirectory => {
// let path = arg::str_ref(args[0], args[1])?;
// let proc = Process::current();
// proc.io.lock().ioctx().chdir(path)?;
// Ok(0)
// }
// SystemCall::GetCurrentDirectory => {
// todo!()
// }
// SystemCall::Seek => {
// todo!()
// }
SystemCall::Open => {
let at_fd = FileDescriptor::from_i32(args[0] as i32)?;
let path = arg::str_ref(args[1], args[2])?;
let mode = FileMode::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?;
let opts = OpenFlags::from_bits(args[4] as u32).ok_or(Errno::InvalidArgument)?;
let proc = Process::current();
let mut io = proc.io.lock();
let at = if let Some(fd) = at_fd {
io.file(fd)?.borrow().node()
} else {
None
};
let file = io.ioctx().open(at, path, mode, opts)?;
Ok(u32::from(io.place_file(file)?) as usize)
}
SystemCall::Close => {
let proc = Process::current();
let mut io = proc.io.lock();
let fd = FileDescriptor::from(args[0] as u32);
io.close_file(fd)?;
Ok(0)
}
SystemCall::FileStatus => {
let at_fd = FileDescriptor::from_i32(args[0] as i32)?;
let filename = arg::str_ref(args[1], args[2])?;
let buf = arg::struct_mut::<Stat>(args[3])?;
let flags = args[4] as u32;
let proc = Process::current();
let mut io = proc.io.lock();
let stat =
find_at_node(&mut io, at_fd, filename, flags & AT_EMPTY_PATH != 0)?.stat()?;
*buf = stat;
Ok(0)
}
SystemCall::Ioctl => {
let fd = FileDescriptor::from(args[0] as u32);
let cmd = IoctlCmd::try_from(args[1] as u32)?;
let proc = Process::current();
let mut io = proc.io.lock();
let node = io.file(fd)?.borrow().node().ok_or(Errno::InvalidFile)?;
node.ioctl(cmd, args[2], args[3])
}
SystemCall::Select => {
let rfds = arg::option_struct_mut::<FdSet>(args[0])?;
let wfds = arg::option_struct_mut::<FdSet>(args[1])?;
let timeout = if args[2] == 0 {
None
} else {
Some(Duration::from_nanos(args[2] as u64))
};
wait::select(Thread::current(), rfds, wfds, timeout)
}
SystemCall::Access => {
let at_fd = FileDescriptor::from_i32(args[0] as i32)?;
let path = arg::str_ref(args[1], args[2])?;
let mode = AccessMode::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?;
let flags = args[4] as u32;
let proc = Process::current();
let mut io = proc.io.lock();
find_at_node(&mut io, at_fd, path, flags & AT_EMPTY_PATH != 0)?
.check_access(io.ioctx(), mode)?;
Ok(0)
}
SystemCall::ReadDirectory => {
let proc = Process::current();
let fd = FileDescriptor::from(args[0] as u32);
let mut io = proc.io.lock();
let buf = arg::struct_buf_mut::<DirectoryEntry>(args[1], args[2])?;
io.file(fd)?.borrow_mut().readdir(buf)
}
SystemCall::GetUserId => {
let proc = Process::current();
let uid = proc.io.lock().uid();
Ok(u32::from(uid) as usize)
}
SystemCall::GetGroupId => {
let proc = Process::current();
let gid = proc.io.lock().gid();
Ok(u32::from(gid) as usize)
}
SystemCall::DuplicateFd => {
let src = FileDescriptor::from(args[0] as u32);
let dst = FileDescriptor::from_i32(args[1] as i32)?;
let proc = Process::current();
let mut io = proc.io.lock();
let res = io.duplicate_file(src, dst)?;
Ok(u32::from(res) as usize)
}
SystemCall::SetUserId => {
let uid = UserId::from(args[0] as u32);
let proc = Process::current();
proc.io.lock().set_uid(uid)?;
Ok(0)
}
SystemCall::SetGroupId => {
let gid = GroupId::from(args[0] as u32);
let proc = Process::current();
proc.io.lock().set_gid(gid)?;
Ok(0)
}
SystemCall::SetCurrentDirectory => {
let path = arg::str_ref(args[0], args[1])?;
let proc = Process::current();
proc.io.lock().ioctx().chdir(path)?;
Ok(0)
}
SystemCall::GetCurrentDirectory => {
todo!()
}
SystemCall::Seek => {
todo!()
}
SystemCall::MapMemory => {
let len = args[1];
if len == 0 || (len & 0xFFF) != 0 {
@@ -211,8 +212,7 @@ fn _syscall(num: SystemCall, args: &[usize]) -> Result<usize, Errno> {
let acc = MemoryAccess::from_bits(args[2] as u32).ok_or(Errno::InvalidArgument)?;
let _flags = MemoryAccess::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?;
let mut attrs =
MapAttributes::SHARE_OUTER | MapAttributes::USER_READ;
let mut attrs = MapAttributes::SHARE_OUTER | MapAttributes::USER_READ;
if !acc.contains(MemoryAccess::READ) {
return Err(Errno::NotImplemented);
}
@@ -237,186 +237,185 @@ fn _syscall(num: SystemCall, args: &[usize]) -> Result<usize, Errno> {
space.allocate(0x100000000, 0xF00000000, len / 4096, attrs, usage)
})
}
// SystemCall::UnmapMemory => {
// let addr = args[0];
// let len = args[1];
//
// if addr == 0 || len == 0 || addr & 0xFFF != 0 || len & 0xFFF != 0 {
// return Err(Errno::InvalidArgument);
// }
//
// let proc = Process::current();
// proc.manipulate_space(move |space| space.free(addr, len / 4096))?;
// Ok(0)
// }
//
// // Process
// SystemCall::Clone => {
// let entry = args[0];
// let stack = args[1];
// let arg = args[2];
//
// Process::current()
// .new_user_thread(entry, stack, arg)
// .map(|e| u32::from(e) as usize)
// }
// SystemCall::Exec => {
// let filename = arg::str_ref(args[0], args[1])?;
// let argv = arg::struct_buf_ref::<&str>(args[2], args[3])?;
// // Validate each argument as well
// for item in argv.iter() {
// arg::validate_ptr(item.as_ptr() as usize, item.len(), false)?;
// }
// let node = {
// let proc = Process::current();
// let mut io = proc.io.lock();
// // TODO argv, envp array passing ABI?
// let node = io.ioctx().find(None, filename, true)?;
// drop(io);
// node
// };
// let file = node.open(OpenFlags::O_RDONLY)?;
// Process::execve(move |space| elf::load_elf(space, file), argv).unwrap();
// panic!();
// }
SystemCall::Exit => {
let status = ExitCode::from(args[0] as i32);
let flags = args[1];
SystemCall::UnmapMemory => {
let addr = args[0];
let len = args[1];
if flags & (1 << 0) != 0 {
Process::exit_thread(Thread::current(), status);
} else {
Process::current().exit(status);
}
if addr == 0 || len == 0 || addr & 0xFFF != 0 || len & 0xFFF != 0 {
return Err(Errno::InvalidArgument);
}
unreachable!();
let proc = Process::current();
proc.manipulate_space(move |space| space.free(addr, len / 4096))?;
Ok(0)
}
// // Process
// SystemCall::Clone => {
// let entry = args[0];
// let stack = args[1];
// let arg = args[2];
// Process::current()
// .new_user_thread(entry, stack, arg)
// .map(|e| u32::from(e) as usize)
// }
SystemCall::Exec => {
let filename = arg::str_ref(args[0], args[1])?;
let argv = arg::struct_buf_ref::<&str>(args[2], args[3])?;
// Validate each argument as well
for item in argv.iter() {
arg::validate_ptr(item.as_ptr() as usize, item.len(), false)?;
}
let node = {
let proc = Process::current();
let mut io = proc.io.lock();
// TODO argv, envp array passing ABI?
let node = io.ioctx().find(None, filename, true)?;
drop(io);
node
};
let file = node.open(OpenFlags::O_RDONLY)?;
Process::execve(move |space| elf::load_elf(space, file), argv).unwrap();
panic!();
}
SystemCall::Exit => {
let status = ExitCode::from(args[0] as i32);
let flags = args[1];
if flags & (1 << 0) != 0 {
Process::exit_thread(Thread::current(), status);
} else {
Process::current().exit(status);
}
unreachable!();
}
SystemCall::WaitPid => {
// TODO special "pid" values
let pid = Pid::try_from(args[0] as u32)?;
let status = arg::struct_mut::<i32>(args[1])?;
match Process::waitpid(pid) {
Ok(exit) => {
*status = i32::from(exit);
Ok(0)
}
SystemCall::WaitPid => {
// TODO special "pid" values
let pid = Pid::try_from(args[0] as u32)?;
let status = arg::struct_mut::<i32>(args[1])?;
e => e.map(|e| i32::from(e) as usize),
}
}
SystemCall::WaitTid => {
let tid = Tid::from(args[0] as u32);
match Process::waitpid(pid) {
Ok(exit) => {
*status = i32::from(exit);
Ok(0)
}
e => e.map(|e| i32::from(e) as usize),
}
match Thread::waittid(tid) {
Ok(_) => Ok(0),
_ => todo!(),
}
}
SystemCall::GetPid => Ok(u32::from(Process::current().id()) as usize),
SystemCall::GetTid => Ok(u32::from(Thread::current().id()) as usize),
SystemCall::Sleep => {
let rem_buf = arg::option_buf_ref(args[1], size_of::<u64>() * 2)?;
let mut rem = Duration::new(0, 0);
let res = wait::sleep(Duration::from_nanos(args[0] as u64), &mut rem);
if res == Err(Errno::Interrupt) {
warnln!("Sleep interrupted, {:?} remaining", rem);
if rem_buf.is_some() {
todo!()
}
// SystemCall::WaitTid => {
// let tid = Tid::from(args[0] as u32);
//
// match Thread::waittid(tid) {
// Ok(_) => Ok(0),
// _ => todo!(),
// }
// }
// SystemCall::GetPid => Ok(u32::from(Process::current().id()) as usize),
// SystemCall::GetTid => Ok(u32::from(Thread::current().id()) as usize),
// SystemCall::Sleep => {
// let rem_buf = arg::option_buf_ref(args[1], size_of::<u64>() * 2)?;
// let mut rem = Duration::new(0, 0);
// let res = wait::sleep(Duration::from_nanos(args[0] as u64), &mut rem);
// if res == Err(Errno::Interrupt) {
// warnln!("Sleep interrupted, {:?} remaining", rem);
// if rem_buf.is_some() {
// todo!()
// }
// }
// res.map(|_| 0)
// }
// SystemCall::SetSignalEntry => {
// Thread::current().set_signal_entry(args[0], args[1]);
// Ok(0)
// }
// SystemCall::SignalReturn => {
// Thread::current().return_from_signal();
// unreachable!();
// }
// SystemCall::SendSignal => {
// let target = SignalDestination::from(args[0] as isize);
// let signal = Signal::try_from(args[1] as u32)?;
//
// match target {
// SignalDestination::This => Process::current().set_signal(signal),
// SignalDestination::Process(pid) => Process::get(pid)
// .ok_or(Errno::DoesNotExist)?
// .set_signal(signal),
// _ => todo!(),
// };
// Ok(0)
// }
// SystemCall::Yield => {
// proc::switch();
// Ok(0)
// }
// SystemCall::GetSid => {
// // TODO handle kernel processes here?
// let pid = Pid::to_option(args[0] as u32);
// let current = Process::current();
// let proc = if let Some(pid) = pid {
// let proc = Process::get(pid).ok_or(Errno::DoesNotExist)?;
// if proc.sid() != current.sid() {
// return Err(Errno::PermissionDenied);
// }
// proc
// } else {
// current
// };
//
// Ok(u32::from(proc.sid()) as usize)
// }
// SystemCall::GetPgid => {
// // TODO handle kernel processes here?
// let pid = Pid::to_option(args[0] as u32);
// let current = Process::current();
// let proc = if let Some(pid) = pid {
// Process::get(pid).ok_or(Errno::DoesNotExist)?
// } else {
// current
// };
//
// Ok(u32::from(proc.pgid()) as usize)
// }
// SystemCall::GetPpid => Ok(u32::from(Process::current().ppid().unwrap()) as usize),
// SystemCall::SetSid => {
// let proc = Process::current();
// let mut io = proc.io.lock();
//
// if let Some(_ctty) = io.ctty() {
// todo!();
// }
//
// let id = proc.id();
// proc.set_sid(id);
// Ok(u32::from(id) as usize)
// }
// SystemCall::SetPgid => {
// let pid = Pid::to_option(args[0] as u32);
// let pgid = Pid::to_option(args[1] as u32);
//
// let current = Process::current();
// let proc = if let Some(_pid) = pid {
// todo!()
// } else {
// current
// };
//
// if let Some(_pgid) = pgid {
// todo!();
// } else {
// proc.set_pgid(proc.id());
// }
//
// Ok(u32::from(proc.pgid()) as usize)
// }
//
// // System
// SystemCall::GetCpuTime => {
// let time = machine::local_timer().timestamp()?;
// Ok(time.as_nanos() as usize)
// }
}
res.map(|_| 0)
}
// SystemCall::SetSignalEntry => {
// Thread::current().set_signal_entry(args[0], args[1]);
// Ok(0)
// }
// SystemCall::SignalReturn => {
// Thread::current().return_from_signal();
// unreachable!();
// }
// SystemCall::SendSignal => {
// let target = SignalDestination::from(args[0] as isize);
// let signal = Signal::try_from(args[1] as u32)?;
// match target {
// SignalDestination::This => Process::current().set_signal(signal),
// SignalDestination::Process(pid) => Process::get(pid)
// .ok_or(Errno::DoesNotExist)?
// .set_signal(signal),
// _ => todo!(),
// };
// Ok(0)
// }
SystemCall::Yield => {
proc::switch();
Ok(0)
}
SystemCall::GetSid => {
// TODO handle kernel processes here?
let pid = Pid::to_option(args[0] as u32);
let current = Process::current();
let proc = if let Some(pid) = pid {
let proc = Process::get(pid).ok_or(Errno::DoesNotExist)?;
if proc.sid() != current.sid() {
return Err(Errno::PermissionDenied);
}
proc
} else {
current
};
Ok(u32::from(proc.sid()) as usize)
}
SystemCall::GetPgid => {
// TODO handle kernel processes here?
let pid = Pid::to_option(args[0] as u32);
let current = Process::current();
let proc = if let Some(pid) = pid {
Process::get(pid).ok_or(Errno::DoesNotExist)?
} else {
current
};
Ok(u32::from(proc.pgid()) as usize)
}
SystemCall::GetPpid => Ok(u32::from(Process::current().ppid().unwrap()) as usize),
SystemCall::SetSid => {
let proc = Process::current();
let mut io = proc.io.lock();
if let Some(_ctty) = io.ctty() {
todo!();
}
let id = proc.id();
proc.set_sid(id);
Ok(u32::from(id) as usize)
}
SystemCall::SetPgid => {
let pid = Pid::to_option(args[0] as u32);
let pgid = Pid::to_option(args[1] as u32);
let current = Process::current();
let proc = if let Some(_pid) = pid {
todo!()
} else {
current
};
if let Some(_pgid) = pgid {
todo!();
} else {
proc.set_pgid(proc.id());
}
Ok(u32::from(proc.pgid()) as usize)
}
// // System
// SystemCall::GetCpuTime => {
// let time = machine::local_timer().timestamp()?;
// Ok(time.as_nanos() as usize)
// }
SystemCall::Mount => {
let target = arg::str_ref(args[0], args[1])?;
let options = arg::struct_ref::<MountOptions>(args[2])?;
@@ -432,7 +431,7 @@ fn _syscall(num: SystemCall, args: &[usize]) -> Result<usize, Errno> {
target_node.mount(root)?;
Ok(0)
},
}
// Debugging
SystemCall::DebugTrace => {