mirror of
https://github.com/sgmarz/osblog.git
synced 2024-11-23 18:06:20 +04:00
Remove syscall returning a PC value.
This commit is contained in:
parent
2acb967a46
commit
69ef3475dd
@ -11,7 +11,7 @@ use crate::{block::block_op,
|
|||||||
gpu,
|
gpu,
|
||||||
input::{Event, ABS_EVENTS, KEY_EVENTS},
|
input::{Event, ABS_EVENTS, KEY_EVENTS},
|
||||||
page::{map, virt_to_phys, EntryBits, Table, PAGE_SIZE, zalloc},
|
page::{map, virt_to_phys, EntryBits, Table, PAGE_SIZE, zalloc},
|
||||||
process::{add_kernel_process_args, delete_process, get_by_pid, set_sleeping, set_waiting, PROCESS_LIST, PROCESS_LIST_MUTEX}};
|
process::{add_kernel_process_args, delete_process, get_by_pid, set_sleeping, set_waiting, PROCESS_LIST, PROCESS_LIST_MUTEX, FileDescriptor}};
|
||||||
use alloc::{boxed::Box, string::String};
|
use alloc::{boxed::Box, string::String};
|
||||||
|
|
||||||
/// do_syscall is called from trap.rs to invoke a system call. No discernment is
|
/// do_syscall is called from trap.rs to invoke a system call. No discernment is
|
||||||
@ -21,30 +21,32 @@ use alloc::{boxed::Box, string::String};
|
|||||||
/// If we return 0 from this function, the m_trap function will schedule
|
/// If we return 0 from this function, the m_trap function will schedule
|
||||||
/// the next process--consider this a yield. A non-0 is the program counter
|
/// the next process--consider this a yield. A non-0 is the program counter
|
||||||
/// we want to go back to.
|
/// we want to go back to.
|
||||||
pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) {
|
||||||
// Libgloss expects the system call number in A7, so let's follow
|
// Libgloss expects the system call number in A7, so let's follow
|
||||||
// their lead.
|
// their lead.
|
||||||
// A7 is X17, so it's register number 17.
|
// A7 is X17, so it's register number 17.
|
||||||
let syscall_number = (*frame).regs[gp(Registers::A7)];
|
let syscall_number = (*frame).regs[gp(Registers::A7)];
|
||||||
|
// skip the ecall
|
||||||
|
(*frame).pc = mepc + 4;
|
||||||
match syscall_number {
|
match syscall_number {
|
||||||
93 | 94 => {
|
93 | 94 => {
|
||||||
// exit and exit_group
|
// exit and exit_group
|
||||||
delete_process((*frame).pid as u16);
|
delete_process((*frame).pid as u16);
|
||||||
0
|
}
|
||||||
|
1 => {
|
||||||
|
//yield
|
||||||
|
// We don't do anything, but we don't want to print "unknown system call"
|
||||||
}
|
}
|
||||||
2 => {
|
2 => {
|
||||||
// Easy putchar
|
// Easy putchar
|
||||||
print!("{}", (*frame).regs[Registers::A0 as usize] as u8 as char);
|
print!("{}", (*frame).regs[Registers::A0 as usize] as u8 as char);
|
||||||
0
|
|
||||||
}
|
}
|
||||||
8 => {
|
8 => {
|
||||||
dump_registers(frame);
|
dump_registers(frame);
|
||||||
mepc + 4
|
|
||||||
}
|
}
|
||||||
10 => {
|
10 => {
|
||||||
// Sleep
|
// Sleep
|
||||||
set_sleeping((*frame).pid as u16, (*frame).regs[Registers::A0 as usize]);
|
set_sleeping((*frame).pid as u16, (*frame).regs[Registers::A0 as usize]);
|
||||||
0
|
|
||||||
}
|
}
|
||||||
11 => {
|
11 => {
|
||||||
// execv
|
// execv
|
||||||
@ -93,7 +95,6 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
|||||||
println!("Could not open path '{}'.", path);
|
println!("Could not open path '{}'.", path);
|
||||||
(*frame).regs[Registers::A0 as usize] = -1isize as usize;
|
(*frame).regs[Registers::A0 as usize] = -1isize as usize;
|
||||||
}
|
}
|
||||||
0
|
|
||||||
}
|
}
|
||||||
17 => { //getcwd
|
17 => { //getcwd
|
||||||
let mut buf = (*frame).regs[gp(Registers::A0)] as *mut u8;
|
let mut buf = (*frame).regs[gp(Registers::A0)] as *mut u8;
|
||||||
@ -108,7 +109,7 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
(*frame).regs[gp(Registers::A0)] = -1isize as usize;
|
(*frame).regs[gp(Registers::A0)] = -1isize as usize;
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i in process.data.cwd.as_bytes() {
|
for i in process.data.cwd.as_bytes() {
|
||||||
@ -118,16 +119,23 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
|||||||
buf.add(iter).write(*i);
|
buf.add(iter).write(*i);
|
||||||
iter += 1;
|
iter += 1;
|
||||||
}
|
}
|
||||||
0
|
|
||||||
}
|
}
|
||||||
48 => {
|
48 => {
|
||||||
// #define SYS_faccessat 48
|
// #define SYS_faccessat 48
|
||||||
(*frame).regs[gp(Registers::A0)] = -1isize as usize;
|
(*frame).regs[gp(Registers::A0)] = -1isize as usize;
|
||||||
0
|
|
||||||
}
|
}
|
||||||
57 => {
|
57 => {
|
||||||
// #define SYS_close 57
|
// #define SYS_close 57
|
||||||
0
|
let fd = (*frame).regs[gp(Registers::A0)] as u16;
|
||||||
|
let process = get_by_pid((*frame).pid as u16).as_mut().unwrap();
|
||||||
|
if process.data.fdesc.contains_key(&fd) {
|
||||||
|
process.data.fdesc.remove(&fd);
|
||||||
|
(*frame).regs[gp(Registers::A0)] = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(*frame).regs[gp(Registers::A0)] = -1isize as usize;
|
||||||
|
}
|
||||||
|
// Flush?
|
||||||
}
|
}
|
||||||
63 => {
|
63 => {
|
||||||
// Read system call
|
// Read system call
|
||||||
@ -146,13 +154,13 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
|||||||
// address. Eventually, I will put this code into a
|
// address. Eventually, I will put this code into a
|
||||||
// convenient function, but for now, it will show how
|
// convenient function, but for now, it will show how
|
||||||
// translation will be done.
|
// translation will be done.
|
||||||
if (*frame).satp != 0 {
|
if (*frame).satp >> 60 != 0 {
|
||||||
let p = get_by_pid((*frame).pid as u16);
|
let p = get_by_pid((*frame).pid as u16);
|
||||||
let table = ((*p).mmu_table).as_ref().unwrap();
|
let table = ((*p).mmu_table).as_ref().unwrap();
|
||||||
let paddr = virt_to_phys(table, (*frame).regs[12]);
|
let paddr = virt_to_phys(table, (*frame).regs[12]);
|
||||||
if paddr.is_none() {
|
if paddr.is_none() {
|
||||||
(*frame).regs[Registers::A0 as usize] = -1isize as usize;
|
(*frame).regs[Registers::A0 as usize] = -1isize as usize;
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
physical_buffer = paddr.unwrap();
|
physical_buffer = paddr.unwrap();
|
||||||
}
|
}
|
||||||
@ -171,13 +179,12 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
|||||||
);
|
);
|
||||||
// If we return 0, the trap handler will schedule
|
// If we return 0, the trap handler will schedule
|
||||||
// another process.
|
// another process.
|
||||||
0
|
|
||||||
}
|
}
|
||||||
64 => { // sys_write
|
64 => { // sys_write
|
||||||
let fd = (*frame).regs[gp(Registers::A0)];
|
let fd = (*frame).regs[gp(Registers::A0)] as u16;
|
||||||
let buf = (*frame).regs[gp(Registers::A1)] as *const u8;
|
let buf = (*frame).regs[gp(Registers::A1)] as *const u8;
|
||||||
let size = (*frame).regs[gp(Registers::A2)];
|
let size = (*frame).regs[gp(Registers::A2)];
|
||||||
let process = get_by_pid((*frame).pid as u16);
|
let process = get_by_pid((*frame).pid as u16).as_ref().unwrap();
|
||||||
// if (*frame).satp >> 60 != 0 {
|
// if (*frame).satp >> 60 != 0 {
|
||||||
// let table = ((*process).mmu_table).as_mut().unwrap();
|
// let table = ((*process).mmu_table).as_mut().unwrap();
|
||||||
// let paddr = virt_to_phys(table, buf as usize);
|
// let paddr = virt_to_phys(table, buf as usize);
|
||||||
@ -197,10 +204,11 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
|||||||
iter += 1;
|
iter += 1;
|
||||||
if (*frame).satp >> 60 != 0 {
|
if (*frame).satp >> 60 != 0 {
|
||||||
let table = ((*process).mmu_table).as_mut().unwrap();
|
let table = ((*process).mmu_table).as_mut().unwrap();
|
||||||
|
// We don't need to do the following until we reach a page boundary,
|
||||||
|
// however that code isn't written, yet.
|
||||||
let paddr = virt_to_phys(table, buf.add(i) as usize);
|
let paddr = virt_to_phys(table, buf.add(i) as usize);
|
||||||
if let Some(bufaddr) = paddr {
|
if let Some(bufaddr) = paddr {
|
||||||
let output = *(bufaddr as *const u8) as char;
|
print!("{}", *(bufaddr as *const u8) as char);
|
||||||
print!("{}", output);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
break;
|
break;
|
||||||
@ -210,25 +218,40 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
|||||||
(*frame).regs[gp(Registers::A0)] = iter as usize;
|
(*frame).regs[gp(Registers::A0)] = iter as usize;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// we don't have real stuff yet.
|
let descriptor = process.data.fdesc.get(&fd);
|
||||||
(*frame).regs[gp(Registers::A0)] = 0;
|
if descriptor.is_none() {
|
||||||
|
(*frame).regs[gp(Registers::A0)] = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let descriptor = descriptor.unwrap();
|
||||||
|
match descriptor {
|
||||||
|
FileDescriptor::Framebuffer(x) => {
|
||||||
|
|
||||||
|
}
|
||||||
|
FileDescriptor::File(inode) => {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// unsupported
|
||||||
|
(*frame).regs[gp(Registers::A0)] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
0
|
|
||||||
}
|
}
|
||||||
66 => {
|
66 => {
|
||||||
(*frame).regs[gp(Registers::A0)] = -1isize as usize;
|
(*frame).regs[gp(Registers::A0)] = -1isize as usize;
|
||||||
0
|
|
||||||
}
|
}
|
||||||
// #define SYS_fstat 80
|
// #define SYS_fstat 80
|
||||||
80 => {
|
80 => {
|
||||||
// int fstat(int filedes, struct stat *buf)
|
// int fstat(int filedes, struct stat *buf)
|
||||||
(*frame).regs[gp(Registers::A0)] = 0;
|
(*frame).regs[gp(Registers::A0)] = 0;
|
||||||
0
|
|
||||||
}
|
}
|
||||||
172 => {
|
172 => {
|
||||||
// A0 = pid
|
// A0 = pid
|
||||||
(*frame).regs[Registers::A0 as usize] = (*frame).pid;
|
(*frame).regs[Registers::A0 as usize] = (*frame).pid;
|
||||||
0
|
|
||||||
}
|
}
|
||||||
180 => {
|
180 => {
|
||||||
set_waiting((*frame).pid as u16);
|
set_waiting((*frame).pid as u16);
|
||||||
@ -240,11 +263,10 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
|||||||
false,
|
false,
|
||||||
(*frame).pid as u16
|
(*frame).pid as u16
|
||||||
);
|
);
|
||||||
0
|
|
||||||
}
|
}
|
||||||
214 => { // brk
|
214 => { // brk
|
||||||
// #define SYS_brk 214
|
// #define SYS_brk 214
|
||||||
// int brk(void *addr);
|
// void *brk(void *addr);
|
||||||
let addr = (*frame).regs[gp(Registers::A0)];
|
let addr = (*frame).regs[gp(Registers::A0)];
|
||||||
let process = get_by_pid((*frame).pid as u16).as_mut().unwrap();
|
let process = get_by_pid((*frame).pid as u16).as_mut().unwrap();
|
||||||
// println!("Break move from 0x{:08x} to 0x{:08x}", process.brk, addr);
|
// println!("Break move from 0x{:08x} to 0x{:08x}", process.brk, addr);
|
||||||
@ -261,7 +283,6 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
|||||||
process.brk = addr;
|
process.brk = addr;
|
||||||
}
|
}
|
||||||
(*frame).regs[gp(Registers::A0)] = process.brk;
|
(*frame).regs[gp(Registers::A0)] = process.brk;
|
||||||
0
|
|
||||||
}
|
}
|
||||||
// System calls 1000 and above are "special" system calls for our OS. I'll
|
// System calls 1000 and above are "special" system calls for our OS. I'll
|
||||||
// try to mimic the normal system calls below 1000 so that this OS is compatible
|
// try to mimic the normal system calls below 1000 so that this OS is compatible
|
||||||
@ -288,7 +309,6 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
|||||||
(*frame).regs[Registers::A0 as usize] = 0x3000_0000;
|
(*frame).regs[Registers::A0 as usize] = 0x3000_0000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0
|
|
||||||
}
|
}
|
||||||
1001 => {
|
1001 => {
|
||||||
// transfer rectangle and invalidate
|
// transfer rectangle and invalidate
|
||||||
@ -298,7 +318,6 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
|||||||
let width = (*frame).regs[Registers::A3 as usize] as u32;
|
let width = (*frame).regs[Registers::A3 as usize] as u32;
|
||||||
let height = (*frame).regs[Registers::A4 as usize] as u32;
|
let height = (*frame).regs[Registers::A4 as usize] as u32;
|
||||||
gpu::transfer(dev, x, y, width, height);
|
gpu::transfer(dev, x, y, width, height);
|
||||||
0
|
|
||||||
}
|
}
|
||||||
1002 => {
|
1002 => {
|
||||||
// wait for keyboard events
|
// wait for keyboard events
|
||||||
@ -309,12 +328,13 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
|||||||
let process = get_by_pid((*frame).pid as u16);
|
let process = get_by_pid((*frame).pid as u16);
|
||||||
let table = (*process).mmu_table.as_mut().unwrap();
|
let table = (*process).mmu_table.as_mut().unwrap();
|
||||||
(*frame).regs[Registers::A0 as usize] = 0;
|
(*frame).regs[Registers::A0 as usize] = 0;
|
||||||
for i in 0..if max_events <= ev.len() {
|
let num_events = if max_events <= ev.len() {
|
||||||
max_events
|
max_events
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ev.len()
|
ev.len()
|
||||||
} {
|
};
|
||||||
|
for i in 0..num_events {
|
||||||
let paddr = virt_to_phys(table, vaddr.add(i) as usize);
|
let paddr = virt_to_phys(table, vaddr.add(i) as usize);
|
||||||
if paddr.is_none() {
|
if paddr.is_none() {
|
||||||
break;
|
break;
|
||||||
@ -325,7 +345,6 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
KEY_EVENTS.replace(ev);
|
KEY_EVENTS.replace(ev);
|
||||||
0
|
|
||||||
}
|
}
|
||||||
1004 => {
|
1004 => {
|
||||||
// wait for abs events
|
// wait for abs events
|
||||||
@ -352,16 +371,69 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ABS_EVENTS.replace(ev);
|
ABS_EVENTS.replace(ev);
|
||||||
0
|
}
|
||||||
|
1024 => {
|
||||||
|
// #define SYS_open 1024
|
||||||
|
let mut path = (*frame).regs[gp(Registers::A0)];
|
||||||
|
let _perm = (*frame).regs[gp(Registers::A1)];
|
||||||
|
let process = get_by_pid((*frame).pid as u16).as_mut().unwrap();
|
||||||
|
if (*frame).satp >> 60 != 0 {
|
||||||
|
let table = process.mmu_table.as_mut().unwrap();
|
||||||
|
let paddr = virt_to_phys(table, path);
|
||||||
|
if paddr.is_none() {
|
||||||
|
(*frame).regs[gp(Registers::A0)] = -1isize as usize;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
path = paddr.unwrap();
|
||||||
|
}
|
||||||
|
let path_ptr = path as *const u8;
|
||||||
|
let mut str_path = String::new();
|
||||||
|
for i in 0..256 {
|
||||||
|
let c = path_ptr.add(i).read();
|
||||||
|
if c == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
str_path.push(c as char);
|
||||||
|
}
|
||||||
|
// Allocate a blank file descriptor
|
||||||
|
let mut max_fd = 2;
|
||||||
|
for k in process.data.fdesc.keys() {
|
||||||
|
if *k > max_fd {
|
||||||
|
max_fd = *k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
max_fd += 1;
|
||||||
|
match str_path.as_str() {
|
||||||
|
"/dev/fb" => {
|
||||||
|
// framebuffer
|
||||||
|
process.data.fdesc.insert(max_fd, FileDescriptor::Framebuffer(6));
|
||||||
|
}
|
||||||
|
"/dev/butev" => {
|
||||||
|
process.data.fdesc.insert(max_fd, FileDescriptor::ButtonEvents);
|
||||||
|
}
|
||||||
|
"/dev/absev" => {
|
||||||
|
process.data.fdesc.insert(max_fd, FileDescriptor::AbsoluteEvents);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
let res = fs::MinixFileSystem::open(8, &str_path);
|
||||||
|
if res.is_err() {
|
||||||
|
(*frame).regs[gp(Registers::A0)] = -1isize as usize;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let inode = res.ok().unwrap();
|
||||||
|
process.data.fdesc.insert(max_fd, FileDescriptor::File(inode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(*frame).regs[gp(Registers::A0)] = max_fd as usize;
|
||||||
}
|
}
|
||||||
1062 => {
|
1062 => {
|
||||||
// gettime
|
// gettime
|
||||||
(*frame).regs[Registers::A0 as usize] = crate::cpu::get_mtime();
|
(*frame).regs[Registers::A0 as usize] = crate::cpu::get_mtime();
|
||||||
0
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
println!("Unknown syscall number {}", syscall_number);
|
println!("Unknown syscall number {}", syscall_number);
|
||||||
0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -374,6 +446,10 @@ fn do_make_syscall(sysno: usize, arg0: usize, arg1: usize, arg2: usize, arg3: us
|
|||||||
unsafe { make_syscall(sysno, arg0, arg1, arg2, arg3, arg4, arg5) }
|
unsafe { make_syscall(sysno, arg0, arg1, arg2, arg3, arg4, arg5) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn syscall_yield() {
|
||||||
|
let _ = do_make_syscall(1, 0, 0, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn syscall_exit() {
|
pub fn syscall_exit() {
|
||||||
let _ = do_make_syscall(93, 0, 0, 0, 0, 0, 0);
|
let _ = do_make_syscall(93, 0, 0, 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
@ -456,7 +532,6 @@ fn exec_func(args: usize) {
|
|||||||
// #define SYS_munmap 215
|
// #define SYS_munmap 215
|
||||||
// #define SYS_mremap 216
|
// #define SYS_mremap 216
|
||||||
// #define SYS_mmap 222
|
// #define SYS_mmap 222
|
||||||
// #define SYS_open 1024
|
|
||||||
// #define SYS_link 1025
|
// #define SYS_link 1025
|
||||||
// #define SYS_unlink 1026
|
// #define SYS_unlink 1026
|
||||||
// #define SYS_mkdir 1030
|
// #define SYS_mkdir 1030
|
||||||
|
@ -101,15 +101,10 @@ extern "C" fn m_trap(epc: usize,
|
|||||||
8 | 9 | 11 => unsafe {
|
8 | 9 | 11 => unsafe {
|
||||||
// Environment (system) call from User, Supervisor, and Machine modes
|
// Environment (system) call from User, Supervisor, and Machine modes
|
||||||
// println!("E-call from User mode! CPU#{} -> 0x{:08x}", hart, epc);
|
// println!("E-call from User mode! CPU#{} -> 0x{:08x}", hart, epc);
|
||||||
return_pc = do_syscall(return_pc, frame);
|
do_syscall(return_pc, frame);
|
||||||
if return_pc == 0 {
|
let frame = schedule();
|
||||||
// We are about to schedule something else here, so we need to store PAST
|
schedule_next_context_switch(1);
|
||||||
// the system call so that when we resume this process, we're after the ecall.
|
rust_switch_to_user(frame);
|
||||||
(*frame).pc += 4;
|
|
||||||
let frame = schedule();
|
|
||||||
schedule_next_context_switch(1);
|
|
||||||
rust_switch_to_user(frame);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Page faults
|
// Page faults
|
||||||
12 => unsafe {
|
12 => unsafe {
|
||||||
|
Loading…
Reference in New Issue
Block a user