diff --git a/kernel/src/arch/mipsel/interrupt.rs b/kernel/src/arch/mipsel/interrupt.rs index 5ae84dd..1c45132 100644 --- a/kernel/src/arch/mipsel/interrupt.rs +++ b/kernel/src/arch/mipsel/interrupt.rs @@ -78,6 +78,9 @@ pub extern "C" fn rust_trap(tf: &mut TrapFrame) { tf.epc = tf.epc + 4; } } + E::CoprocessorUnusable => { + tf.epc = tf.epc + 4; + } _ => { error!("Unhandled Exception @ CPU{}: {:?} ", 0, tf.cause.cause()); crate::trap::error(tf) @@ -244,6 +247,19 @@ fn page_fault(tf: &mut TrapFrame) { tlb_entry.entry_lo0.get_pfn() << 12, tlb_entry.entry_lo1.get_pfn() << 12 ); + + let tlb_valid = if virt_addr.page_number() & 1 == 0 { + tlb_entry.entry_lo0.valid() + } else { + tlb_entry.entry_lo1.valid() + }; + + if !tlb_valid { + if !crate::memory::handle_page_fault(addr) { + crate::trap::error(tf); + } + } + tlb::write_tlb_random(tlb_entry) } Err(()) => { diff --git a/kernel/src/syscall/fs.rs b/kernel/src/syscall/fs.rs index d94e8b5..7035b31 100644 --- a/kernel/src/syscall/fs.rs +++ b/kernel/src/syscall/fs.rs @@ -913,7 +913,48 @@ pub struct Stat { ctime: Timespec, } -#[cfg(not(target_arch = "x86_64"))] +#[cfg(target_arch = "mips")] +#[repr(C)] +#[derive(Debug)] +pub struct Stat { + /// ID of device containing file + dev: u64, + /// padding + __pad1: u64, + /// inode number + ino: u64, + /// file type and mode + mode: StatMode, + /// number of hard links + nlink: u32, + + /// user ID of owner + uid: u32, + /// group ID of owner + gid: u32, + /// device ID (if special file) + rdev: u64, + /// padding + __pad2: u64, + /// total size, in bytes + size: u64, + + /// last access time + atime: Timespec, + /// last modification time + mtime: Timespec, + /// last status change time + ctime: Timespec, + + /// blocksize for filesystem I/O + blksize: u32, + /// padding + __pad3: u32, + /// number of 512B blocks allocated + blocks: u64, +} + +#[cfg(not(any(target_arch = "x86_64", target_arch = "mips"))] #[repr(C)] #[derive(Debug)] pub struct Stat { @@ -1042,7 +1083,29 @@ impl From for Stat { } } - #[cfg(not(target_arch = "x86_64"))] + #[cfg(target_arch = "mips")] + fn from(info: Metadata) -> Self { + Stat { + dev: info.dev as u64, + ino: info.inode as u64, + mode: StatMode::from_type_mode(info.type_, info.mode as u16), + nlink: info.nlinks as u32, + uid: info.uid as u32, + gid: info.gid as u32, + rdev: 0, + size: info.size as u64, + blksize: info.blk_size as u32, + blocks: info.blocks as u64, + atime: info.atime, + mtime: info.mtime, + ctime: info.ctime, + __pad1: 0, + __pad2: 0, + __pad3: 0, + } + } + + #[cfg(not(any(target_arch = "x86_64", target_arch="mips")))] fn from(info: Metadata) -> Self { Stat { dev: info.dev as u64, diff --git a/kernel/src/syscall/mem.rs b/kernel/src/syscall/mem.rs index 1c5bee9..0b471c2 100644 --- a/kernel/src/syscall/mem.rs +++ b/kernel/src/syscall/mem.rs @@ -123,6 +123,21 @@ bitflags! { } } +#[cfg(target_arch = "mips")] +bitflags! { + pub struct MmapFlags: usize { + /// Changes are shared. + const SHARED = 1 << 0; + /// Changes are private. + const PRIVATE = 1 << 1; + /// Place the mapping at the exact address + const FIXED = 1 << 4; + /// The mapping is not backed by any file. (non-POSIX) + const ANONYMOUS = 0x800; + } +} + +#[cfg(not(target_arch = "mips"))] bitflags! { pub struct MmapFlags: usize { /// Changes are shared. diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 961f794..efc5c0f 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -322,6 +322,12 @@ fn mips_syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> Option sys_open(args[0] as *const u8, args[1], args[2]), SYS_DUP2 => sys_dup2(args[0], args[1]), SYS_MMAP2 => sys_mmap(args[0], args[1], args[2], args[3], args[4], args[5] * 4096), + SYS_FSTAT64 => sys_fstat(args[0], args[1] as *mut Stat), + SYS_STAT64 => sys_stat(args[0] as *const u8, args[1] as *mut Stat), + SYS_FCNTL64 => { + warn!("sys_fcntl64 is unimplemented"); + Ok(0) + } SYS_SET_THREAD_AREA => { extern "C" { fn _cur_tls();