mirror of
https://github.com/rcore-os/rCore.git
synced 2024-11-22 16:16:16 +04:00
Merge for #3.
This commit is contained in:
parent
1bfb979d96
commit
5337852270
@ -7,22 +7,23 @@
|
||||
.globl switch_context
|
||||
.extern _root_page_table_ptr
|
||||
.extern _cur_kstack_ptr
|
||||
.extern _cur_tls
|
||||
|
||||
switch_context:
|
||||
// save from's registers
|
||||
addi sp, sp, (-4*14)
|
||||
sw sp, 0(a0)
|
||||
sw ra, 0(sp)
|
||||
sw s0, 2*4(sp)
|
||||
sw s1, 3*4(sp)
|
||||
sw s2, 4*4(sp)
|
||||
sw s3, 5*4(sp)
|
||||
sw s4, 6*4(sp)
|
||||
sw s5, 7*4(sp)
|
||||
sw s6, 8*4(sp)
|
||||
sw s7, 9*4(sp)
|
||||
sw s8, 10*4(sp)
|
||||
sw gp, 11*4(sp)
|
||||
sw s0, 4*4(sp)
|
||||
sw s1, 5*4(sp)
|
||||
sw s2, 6*4(sp)
|
||||
sw s3, 7*4(sp)
|
||||
sw s4, 8*4(sp)
|
||||
sw s5, 9*4(sp)
|
||||
sw s6, 10*4(sp)
|
||||
sw s7, 11*4(sp)
|
||||
sw s8, 12*4(sp)
|
||||
sw gp, 13*4(sp)
|
||||
// sw ra, 12*4(sp)
|
||||
// sw sp, 13*4(sp)
|
||||
|
||||
@ -31,27 +32,34 @@ switch_context:
|
||||
lw s1, 0(s0)
|
||||
sw s1, 4(sp)
|
||||
|
||||
// save TLS
|
||||
la s2, _cur_tls
|
||||
lw s1, 0(s2)
|
||||
sw s1, 2*4(sp)
|
||||
|
||||
// restore to's registers
|
||||
lw sp, 0(a1)
|
||||
|
||||
// restore page table address
|
||||
lw s1, 4(sp)
|
||||
sw s1, 0(s0)
|
||||
|
||||
// restore kstack ptr
|
||||
// la s0, _cur_kstack_ptr
|
||||
// addi s1, sp, 4 * 14
|
||||
// sw s1, 0(s0)
|
||||
// restore TLS
|
||||
lw s1, 2*4(sp)
|
||||
sw s1, 0(s2)
|
||||
mtc0 s1, $4, 2 // cp0.user_local
|
||||
|
||||
lw ra, 0(sp)
|
||||
lw s0, 2*4(sp)
|
||||
lw s1, 3*4(sp)
|
||||
lw s2, 4*4(sp)
|
||||
lw s3, 5*4(sp)
|
||||
lw s4, 6*4(sp)
|
||||
lw s5, 7*4(sp)
|
||||
lw s6, 8*4(sp)
|
||||
lw s7, 9*4(sp)
|
||||
lw s8, 10*4(sp)
|
||||
lw gp, 11*4(sp)
|
||||
lw s0, 4*4(sp)
|
||||
lw s1, 5*4(sp)
|
||||
lw s2, 6*4(sp)
|
||||
lw s3, 7*4(sp)
|
||||
lw s4, 8*4(sp)
|
||||
lw s5, 9*4(sp)
|
||||
lw s6, 10*4(sp)
|
||||
lw s7, 11*4(sp)
|
||||
lw s8, 12*4(sp)
|
||||
lw gp, 13*4(sp)
|
||||
addi sp, sp, (4*14)
|
||||
|
||||
sw zero, 0(a1)
|
||||
|
@ -177,3 +177,6 @@ _root_page_table_ptr:
|
||||
.global _cur_kstack_ptr
|
||||
_cur_kstack_ptr:
|
||||
.space 4 # 4bytes
|
||||
.global _cur_tls
|
||||
_cur_tls:
|
||||
.space 4 # 4bytes
|
||||
|
@ -1,8 +0,0 @@
|
||||
//! Workaround for missing compiler-builtin symbols
|
||||
//!
|
||||
//! [atomic](http://llvm.org/docs/Atomics.html#libcalls-atomic)
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn abort() {
|
||||
panic!("abort");
|
||||
}
|
@ -6,7 +6,8 @@ pub const KERNEL_OFFSET: usize = 0x80100000;
|
||||
|
||||
pub const MEMORY_OFFSET: usize = 0x8000_0000;
|
||||
|
||||
pub const USER_STACK_OFFSET: usize = 0x80000000 - USER_STACK_SIZE;
|
||||
pub const USER_STACK_OFFSET: usize = 0x70000000 - USER_STACK_SIZE;
|
||||
pub const USER_STACK_SIZE: usize = 0x10000;
|
||||
pub const USER32_STACK_OFFSET: usize = 0x70000000 - USER_STACK_SIZE;
|
||||
|
||||
pub const MAX_DTB_SIZE: usize = 0x2000;
|
||||
|
@ -50,8 +50,8 @@ pub struct TrapFrame {
|
||||
pub sp: usize,
|
||||
pub fp: usize,
|
||||
pub ra: usize,
|
||||
/// Reserve space for hartid
|
||||
pub _hartid: usize,
|
||||
/// Reserved
|
||||
pub reserved: usize,
|
||||
}
|
||||
|
||||
impl TrapFrame {
|
||||
@ -120,6 +120,7 @@ impl InitStack {
|
||||
|
||||
extern "C" {
|
||||
fn trap_return();
|
||||
fn _cur_tls();
|
||||
}
|
||||
|
||||
/// Saved registers for kernel context switches.
|
||||
@ -130,17 +131,21 @@ struct ContextData {
|
||||
ra: usize,
|
||||
/// Page table token
|
||||
satp: usize,
|
||||
/// Callee-saved registers
|
||||
/// s[0] = TLS
|
||||
/// s[1] = reserved
|
||||
/// s[2..11] = Callee-saved registers
|
||||
s: [usize; 12],
|
||||
}
|
||||
|
||||
impl ContextData {
|
||||
fn new(satp: usize) -> Self {
|
||||
ContextData {
|
||||
fn new(satp: usize, tls: usize) -> Self {
|
||||
let mut context = ContextData {
|
||||
ra: trap_return as usize,
|
||||
satp,
|
||||
satp: satp,
|
||||
..ContextData::default()
|
||||
}
|
||||
};
|
||||
context.s[0] = tls;
|
||||
context
|
||||
}
|
||||
}
|
||||
|
||||
@ -191,7 +196,7 @@ impl Context {
|
||||
);
|
||||
|
||||
InitStack {
|
||||
context: ContextData::new(satp),
|
||||
context: ContextData::new(satp, 0),
|
||||
tf: TrapFrame::new_kernel_thread(entry, arg, kstack_top),
|
||||
}
|
||||
.push_at(kstack_top)
|
||||
@ -214,7 +219,7 @@ impl Context {
|
||||
);
|
||||
|
||||
InitStack {
|
||||
context: ContextData::new(satp),
|
||||
context: ContextData::new(satp, 0),
|
||||
tf: TrapFrame::new_user_thread(entry_addr, ustack_top),
|
||||
}
|
||||
.push_at(kstack_top)
|
||||
@ -226,8 +231,9 @@ impl Context {
|
||||
/// The SATP register will be set to `satp`.
|
||||
/// All the other registers are same as the original.
|
||||
pub unsafe fn new_fork(tf: &TrapFrame, kstack_top: usize, satp: usize) -> Self {
|
||||
let tls = unsafe { *(_cur_tls as *const usize) };
|
||||
InitStack {
|
||||
context: ContextData::new(satp),
|
||||
context: ContextData::new(satp, tls),
|
||||
tf: {
|
||||
let mut tf = tf.clone();
|
||||
// fork function's ret value, the new process is 0
|
||||
@ -253,11 +259,10 @@ impl Context {
|
||||
tls: usize,
|
||||
) -> Self {
|
||||
InitStack {
|
||||
context: ContextData::new(satp),
|
||||
context: ContextData::new(satp, tls),
|
||||
tf: {
|
||||
let mut tf = tf.clone();
|
||||
tf.sp = ustack_top; // sp
|
||||
tf.v1 = tls;
|
||||
tf.v0 = 0; // return value
|
||||
tf
|
||||
},
|
||||
|
@ -1,5 +1,6 @@
|
||||
use crate::consts::MAX_CPU_NUM;
|
||||
use core::ptr::{read_volatile, write_volatile};
|
||||
use mips::instructions;
|
||||
use mips::registers::cp0;
|
||||
|
||||
static mut STARTED: [bool; MAX_CPU_NUM] = [false; MAX_CPU_NUM];
|
||||
@ -21,7 +22,9 @@ pub unsafe fn start_others(hart_mask: usize) {
|
||||
}
|
||||
|
||||
pub fn halt() {
|
||||
/* nothing to do */
|
||||
unsafe {
|
||||
instructions::wait();
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn exit_in_qemu(error_code: u8) -> ! {
|
||||
|
@ -70,6 +70,17 @@ pub extern "C" fn rust_trap(tf: &mut TrapFrame) {
|
||||
E::TLBModification => page_fault(tf),
|
||||
E::TLBLoadMiss => page_fault(tf),
|
||||
E::TLBStoreMiss => page_fault(tf),
|
||||
E::ReservedInstruction => {
|
||||
if !reserved_inst(tf) {
|
||||
error!("Unhandled Exception @ CPU{}: {:?} ", 0, tf.cause.cause());
|
||||
crate::trap::error(tf)
|
||||
} else {
|
||||
tf.epc = tf.epc + 4;
|
||||
}
|
||||
}
|
||||
E::CoprocessorUnusable => {
|
||||
tf.epc = tf.epc + 4;
|
||||
}
|
||||
_ => {
|
||||
error!("Unhandled Exception @ CPU{}: {:?} ", 0, tf.cause.cause());
|
||||
crate::trap::error(tf)
|
||||
@ -149,6 +160,75 @@ fn syscall(tf: &mut TrapFrame) {
|
||||
}
|
||||
}
|
||||
|
||||
fn set_trapframe_register(rt: usize, val: usize, tf: &mut TrapFrame) {
|
||||
match rt {
|
||||
1 => tf.at = val,
|
||||
2 => tf.v0 = val,
|
||||
3 => tf.v1 = val,
|
||||
4 => tf.a0 = val,
|
||||
5 => tf.a1 = val,
|
||||
6 => tf.a2 = val,
|
||||
7 => tf.a3 = val,
|
||||
8 => tf.t0 = val,
|
||||
9 => tf.t1 = val,
|
||||
10 => tf.t2 = val,
|
||||
11 => tf.t3 = val,
|
||||
12 => tf.t4 = val,
|
||||
13 => tf.t5 = val,
|
||||
14 => tf.t6 = val,
|
||||
15 => tf.t7 = val,
|
||||
16 => tf.s0 = val,
|
||||
17 => tf.s1 = val,
|
||||
18 => tf.s2 = val,
|
||||
19 => tf.s3 = val,
|
||||
20 => tf.s4 = val,
|
||||
21 => tf.s5 = val,
|
||||
22 => tf.s6 = val,
|
||||
23 => tf.s7 = val,
|
||||
24 => tf.t8 = val,
|
||||
25 => tf.t9 = val,
|
||||
26 => tf.k0 = val,
|
||||
27 => tf.k1 = val,
|
||||
28 => tf.gp = val,
|
||||
29 => tf.sp = val,
|
||||
30 => tf.fp = val,
|
||||
31 => tf.ra = val,
|
||||
_ => {
|
||||
error!("Unknown register {:?} ", rt);
|
||||
crate::trap::error(tf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn reserved_inst(tf: &mut TrapFrame) -> bool {
|
||||
let inst = unsafe { *(tf.epc as *const usize) };
|
||||
|
||||
let opcode = inst >> 26;
|
||||
let rt = (inst >> 16) & 0b11111;
|
||||
let rd = (inst >> 11) & 0b11111;
|
||||
let sel = (inst >> 6) & 0b111;
|
||||
let format = inst & 0b111111;
|
||||
|
||||
if opcode == 0b011111 && format == 0b111011 {
|
||||
// RDHWR
|
||||
if rd == 29 && sel == 0 {
|
||||
extern "C" {
|
||||
fn _cur_tls();
|
||||
}
|
||||
|
||||
let tls = unsafe { *(_cur_tls as *const usize) };
|
||||
|
||||
set_trapframe_register(rt, tls, tf);
|
||||
info!("Read TLS by rdhdr {:x} to register {:?}", tls, rt);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
fn page_fault(tf: &mut TrapFrame) {
|
||||
// TODO: set access/dirty bit
|
||||
let addr = tf.vaddr;
|
||||
@ -164,6 +244,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(()) => {
|
||||
|
@ -1,4 +1,3 @@
|
||||
pub mod compiler_rt;
|
||||
pub mod consts;
|
||||
pub mod cpu;
|
||||
pub mod driver;
|
||||
|
@ -33,8 +33,7 @@ impl Font for Font8x16 {
|
||||
// + Character row offset (row 0 = 0, row 1 = (192 * 8) = 1536)
|
||||
// + X offset for the pixel block that comprises this char
|
||||
// + Y offset for pixel block
|
||||
let bitmap_bit_index = char_x + x
|
||||
+ (FONT_IMAGE_WIDTH * (char_y + y));
|
||||
let bitmap_bit_index = char_x + x + (FONT_IMAGE_WIDTH * (char_y + y));
|
||||
|
||||
let bitmap_byte = bitmap_bit_index / 8;
|
||||
let bitmap_bit = 7 - (bitmap_bit_index % 8);
|
||||
|
@ -41,10 +41,31 @@ lazy_static! {
|
||||
pub static ref STDOUT: Arc<Stdout> = Arc::new(Stdout::default());
|
||||
}
|
||||
|
||||
// 32bits total, command in lower 16bits, size of the parameter structure in the lower 14 bits of the upper 16 bits
|
||||
// higher 2 bits: 01 = write, 10 = read
|
||||
|
||||
#[cfg(not(target_arch = "mips"))]
|
||||
const TCGETS: u32 = 0x5401;
|
||||
#[cfg(target_arch = "mips")]
|
||||
const TCGETS: u32 = 0x540D;
|
||||
|
||||
#[cfg(not(target_arch = "mips"))]
|
||||
const TIOCGPGRP: u32 = 0x540F;
|
||||
// _IOR('t', 119, int)
|
||||
#[cfg(target_arch = "mips")]
|
||||
const TIOCGPGRP: u32 = 0x4_004_74_77;
|
||||
|
||||
#[cfg(not(target_arch = "mips"))]
|
||||
const TIOCSPGRP: u32 = 0x5410;
|
||||
// _IOW('t', 118, int)
|
||||
#[cfg(target_arch = "mips")]
|
||||
const TIOCSPGRP: u32 = 0x8_004_74_76;
|
||||
|
||||
#[cfg(not(target_arch = "mips"))]
|
||||
const TIOCGWINSZ: u32 = 0x5413;
|
||||
// _IOR('t', 104, struct winsize)
|
||||
#[cfg(target_arch = "mips")]
|
||||
const TIOCGWINSZ: u32 = 0x4_008_74_68;
|
||||
|
||||
// TODO: better way to provide default impl?
|
||||
macro_rules! impl_inode {
|
||||
|
@ -106,7 +106,7 @@ impl Drop for KernelStack {
|
||||
/// Handle page fault at `addr`.
|
||||
/// Return true to continue, false to halt.
|
||||
pub fn handle_page_fault(addr: usize) -> bool {
|
||||
debug!("page fault @ {:#x}", addr);
|
||||
// debug!("page fault @ {:#x}", addr);
|
||||
|
||||
// This is safe as long as page fault never happens in page fault handler
|
||||
unsafe { process_unsafe().vm.handle_page_fault(addr) }
|
||||
|
@ -3,6 +3,7 @@
|
||||
use core::cell::UnsafeCell;
|
||||
use core::cmp::min;
|
||||
use core::mem::size_of;
|
||||
#[cfg(not(target_arch = "mips"))]
|
||||
use rcore_fs::vfs::Timespec;
|
||||
|
||||
use crate::drivers::SOCKET_ACTIVITY;
|
||||
@ -464,7 +465,7 @@ pub fn sys_dup2(fd1: usize, fd2: usize) -> SysResult {
|
||||
|
||||
pub fn sys_ioctl(fd: usize, request: usize, arg1: usize, arg2: usize, arg3: usize) -> SysResult {
|
||||
info!(
|
||||
"ioctl: fd: {}, request: {}, args: {} {} {}",
|
||||
"ioctl: fd: {}, request: {:x}, args: {} {} {}",
|
||||
fd, request, arg1, arg2, arg3
|
||||
);
|
||||
let mut proc = process();
|
||||
@ -983,7 +984,55 @@ pub struct Stat {
|
||||
ctime: Timespec,
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "x86_64"))]
|
||||
#[cfg(target_arch = "mips")]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
|
||||
pub struct Timespec {
|
||||
pub sec: i32,
|
||||
pub nsec: i32,
|
||||
}
|
||||
|
||||
#[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 {
|
||||
@ -1112,7 +1161,38 @@ impl From<Metadata> 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: Timespec {
|
||||
sec: info.atime.sec as i32,
|
||||
nsec: info.atime.nsec,
|
||||
},
|
||||
mtime: Timespec {
|
||||
sec: info.mtime.sec as i32,
|
||||
nsec: info.mtime.nsec,
|
||||
},
|
||||
ctime: Timespec {
|
||||
sec: info.ctime.sec as i32,
|
||||
nsec: info.ctime.nsec,
|
||||
},
|
||||
__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,
|
||||
|
@ -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.
|
||||
|
@ -59,8 +59,8 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
|
||||
SYS_MPROTECT => sys_mprotect(args[0], args[1], args[2]),
|
||||
SYS_MUNMAP => sys_munmap(args[0], args[1]),
|
||||
SYS_BRK => {
|
||||
warn!("sys_brk is unimplemented");
|
||||
Ok(0)
|
||||
warn!("sys_brk is unimplemented, return -1");
|
||||
Err(SysError::ENOMEM)
|
||||
}
|
||||
SYS_RT_SIGACTION => {
|
||||
warn!("sys_sigaction is unimplemented");
|
||||
@ -174,6 +174,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
|
||||
// SYS_GETRLIMIT => sys_getrlimit(),
|
||||
SYS_GETRUSAGE => sys_getrusage(args[0], args[1] as *mut RUsage),
|
||||
SYS_SYSINFO => sys_sysinfo(args[0] as *mut SysInfo),
|
||||
SYS_TIMES => sys_times(args[0] as *mut Tms),
|
||||
SYS_GETUID => {
|
||||
warn!("sys_getuid is unimplemented");
|
||||
Ok(0)
|
||||
@ -319,8 +320,15 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
|
||||
let x86_64_ret = x86_64_syscall(id, args, tf);
|
||||
#[cfg(not(target_arch = "x86_64"))]
|
||||
let x86_64_ret = None;
|
||||
|
||||
#[cfg(target_arch = "mips")]
|
||||
let mips_ret = mips_syscall(id, args, tf);
|
||||
#[cfg(not(target_arch = "mips"))]
|
||||
let mips_ret = None;
|
||||
if let Some(ret) = x86_64_ret {
|
||||
ret
|
||||
} else if let Some(ret) = mips_ret {
|
||||
ret
|
||||
} else {
|
||||
error!("unknown syscall id: {}, args: {:x?}", id, args);
|
||||
crate::trap::error(tf);
|
||||
@ -340,6 +348,61 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "mips")]
|
||||
fn mips_syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> Option<SysResult> {
|
||||
let ret = match id {
|
||||
SYS_OPEN => sys_open(args[0] as *const u8, args[1], args[2]),
|
||||
SYS_POLL => sys_poll(args[0] as *mut PollFd, args[1], args[2]),
|
||||
SYS_DUP2 => sys_dup2(args[0], args[1]),
|
||||
SYS_FORK => sys_fork(tf),
|
||||
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_LSTAT64 => sys_lstat(args[0] as *const u8, args[1] as *mut Stat),
|
||||
SYS_STAT64 => sys_stat(args[0] as *const u8, args[1] as *mut Stat),
|
||||
SYS_PIPE => {
|
||||
let fd_ptr = args[0] as *mut u32;
|
||||
match sys_pipe(fd_ptr) {
|
||||
Ok(code) => {
|
||||
unsafe {
|
||||
tf.v0 = *fd_ptr as usize;
|
||||
tf.v1 = *(fd_ptr.add(1)) as usize;
|
||||
}
|
||||
Ok(tf.v0)
|
||||
}
|
||||
Err(err) => Err(err),
|
||||
}
|
||||
}
|
||||
SYS_GETPGID => {
|
||||
warn!("sys_getpgid is unimplemented");
|
||||
Ok(0)
|
||||
}
|
||||
SYS_SETPGID => {
|
||||
warn!("sys_setpgid is unimplemented");
|
||||
Ok(0)
|
||||
}
|
||||
SYS_FCNTL64 => {
|
||||
warn!("sys_fcntl64 is unimplemented");
|
||||
Ok(0)
|
||||
}
|
||||
SYS_SET_THREAD_AREA => {
|
||||
info!("set_thread_area: tls: 0x{:x}", args[0]);
|
||||
extern "C" {
|
||||
fn _cur_tls();
|
||||
}
|
||||
|
||||
unsafe {
|
||||
asm!("mtc0 $0, $$4, 2": :"r"(args[0]));
|
||||
*(_cur_tls as *mut usize) = args[0];
|
||||
}
|
||||
Ok(0)
|
||||
}
|
||||
_ => {
|
||||
return None;
|
||||
}
|
||||
};
|
||||
Some(ret)
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn x86_64_syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> Option<SysResult> {
|
||||
let ret = match id {
|
||||
|
@ -33,9 +33,13 @@ pub fn sys_clone(
|
||||
warn!("sys_clone is calling sys_fork instead, ignoring other args");
|
||||
return sys_fork(tf);
|
||||
}
|
||||
if (flags != 0x7d0f00) && (flags!= 0x5d0f00) { //0x5d0f00 is the args from gcc of alpine linux
|
||||
if (flags != 0x7d0f00) && (flags != 0x5d0f00) {
|
||||
//0x5d0f00 is the args from gcc of alpine linux
|
||||
//warn!("sys_clone only support musl pthread_create");
|
||||
panic!("sys_clone only support sys_fork OR musl pthread_create without flags{:x}", flags);
|
||||
panic!(
|
||||
"sys_clone only support sys_fork OR musl pthread_create without flags{:x}",
|
||||
flags
|
||||
);
|
||||
//return Err(SysError::ENOSYS);
|
||||
}
|
||||
{
|
||||
|
@ -33,20 +33,20 @@ fn get_epoch_usec() -> u64 {
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct TimeVal {
|
||||
sec: u64,
|
||||
usec: u64,
|
||||
sec: usize,
|
||||
usec: usize,
|
||||
}
|
||||
|
||||
impl TimeVal {
|
||||
pub fn to_msec(&self) -> u64 {
|
||||
self.sec * MSEC_PER_SEC + self.usec / USEC_PER_MSEC
|
||||
(self.sec as u64) * MSEC_PER_SEC + (self.usec as u64) / USEC_PER_MSEC
|
||||
}
|
||||
|
||||
pub fn get_epoch() -> Self {
|
||||
let usec = get_epoch_usec();
|
||||
TimeVal {
|
||||
sec: usec / USEC_PER_SEC,
|
||||
usec: usec % USEC_PER_SEC,
|
||||
sec: (usec / USEC_PER_SEC) as usize,
|
||||
usec: (usec % USEC_PER_SEC) as usize,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -54,24 +54,24 @@ impl TimeVal {
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct TimeSpec {
|
||||
sec: u64,
|
||||
nsec: u64,
|
||||
sec: usize,
|
||||
nsec: usize,
|
||||
}
|
||||
|
||||
impl TimeSpec {
|
||||
pub fn to_msec(&self) -> u64 {
|
||||
self.sec * MSEC_PER_SEC + self.nsec / NSEC_PER_MSEC
|
||||
(self.sec as u64) * MSEC_PER_SEC + (self.nsec as u64) / NSEC_PER_MSEC
|
||||
}
|
||||
|
||||
pub fn to_duration(&self) -> Duration {
|
||||
Duration::new(self.sec, self.nsec as u32)
|
||||
Duration::new(self.sec as u64, self.nsec as u32)
|
||||
}
|
||||
|
||||
pub fn get_epoch() -> Self {
|
||||
let usec = get_epoch_usec();
|
||||
TimeSpec {
|
||||
sec: usec / USEC_PER_SEC,
|
||||
nsec: usec % USEC_PER_SEC * NSEC_PER_USEC,
|
||||
sec: (usec / USEC_PER_SEC) as usize,
|
||||
nsec: (usec % USEC_PER_SEC * NSEC_PER_USEC) as usize,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -135,14 +135,44 @@ pub fn sys_getrusage(who: usize, rusage: *mut RUsage) -> SysResult {
|
||||
let usec = (tick - tick_base) * USEC_PER_TICK as u64;
|
||||
let new_rusage = RUsage {
|
||||
utime: TimeVal {
|
||||
sec: usec / USEC_PER_SEC,
|
||||
usec: usec % USEC_PER_SEC,
|
||||
sec: (usec / USEC_PER_SEC) as usize,
|
||||
usec: (usec % USEC_PER_SEC) as usize,
|
||||
},
|
||||
stime: TimeVal {
|
||||
sec: usec / USEC_PER_SEC,
|
||||
usec: usec % USEC_PER_SEC,
|
||||
sec: (usec / USEC_PER_SEC) as usize,
|
||||
usec: (usec % USEC_PER_SEC) as usize,
|
||||
},
|
||||
};
|
||||
unsafe { *rusage = new_rusage };
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Tms {
|
||||
tms_utime: u64, /* user time */
|
||||
tms_stime: u64, /* system time */
|
||||
tms_cutime: u64, /* user time of children */
|
||||
tms_cstime: u64, /* system time of children */
|
||||
}
|
||||
|
||||
|
||||
pub fn sys_times(buf:*mut Tms)-> SysResult {
|
||||
info!("times: buf: {:?}", buf);
|
||||
let proc = process();
|
||||
proc.vm.check_write_ptr(buf)?;
|
||||
|
||||
let tick_base = *TICK_BASE;
|
||||
let tick = unsafe { crate::trap::TICK as u64 };
|
||||
|
||||
let new_buf = Tms {
|
||||
tms_utime: 0,
|
||||
tms_stime: 0,
|
||||
tms_cutime: 0,
|
||||
tms_cstime: 0,
|
||||
};
|
||||
|
||||
unsafe { *buf = new_buf };
|
||||
Ok(tick as usize)
|
||||
}
|
Loading…
Reference in New Issue
Block a user