1
0
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:
Stephen Marz 2020-06-04 18:06:17 -04:00
parent 2acb967a46
commit 69ef3475dd
2 changed files with 116 additions and 46 deletions

View File

@ -11,7 +11,7 @@ use crate::{block::block_op,
gpu,
input::{Event, ABS_EVENTS, KEY_EVENTS},
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};
/// 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
/// the next process--consider this a yield. A non-0 is the program counter
/// 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
// their lead.
// A7 is X17, so it's register number 17.
let syscall_number = (*frame).regs[gp(Registers::A7)];
// skip the ecall
(*frame).pc = mepc + 4;
match syscall_number {
93 | 94 => {
// exit and exit_group
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 => {
// Easy putchar
print!("{}", (*frame).regs[Registers::A0 as usize] as u8 as char);
0
}
8 => {
dump_registers(frame);
mepc + 4
}
10 => {
// Sleep
set_sleeping((*frame).pid as u16, (*frame).regs[Registers::A0 as usize]);
0
}
11 => {
// execv
@ -93,7 +95,6 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
println!("Could not open path '{}'.", path);
(*frame).regs[Registers::A0 as usize] = -1isize as usize;
}
0
}
17 => { //getcwd
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 {
(*frame).regs[gp(Registers::A0)] = -1isize as usize;
return 0;
return;
}
}
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);
iter += 1;
}
0
}
48 => {
// #define SYS_faccessat 48
(*frame).regs[gp(Registers::A0)] = -1isize as usize;
0
}
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 => {
// 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
// convenient function, but for now, it will show how
// translation will be done.
if (*frame).satp != 0 {
if (*frame).satp >> 60 != 0 {
let p = get_by_pid((*frame).pid as u16);
let table = ((*p).mmu_table).as_ref().unwrap();
let paddr = virt_to_phys(table, (*frame).regs[12]);
if paddr.is_none() {
(*frame).regs[Registers::A0 as usize] = -1isize as usize;
return 0;
return;
}
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
// another process.
0
}
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 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 {
// let table = ((*process).mmu_table).as_mut().unwrap();
// 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;
if (*frame).satp >> 60 != 0 {
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);
if let Some(bufaddr) = paddr {
let output = *(bufaddr as *const u8) as char;
print!("{}", output);
print!("{}", *(bufaddr as *const u8) as char);
}
else {
break;
@ -210,25 +218,40 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
(*frame).regs[gp(Registers::A0)] = iter as usize;
}
else {
// we don't have real stuff yet.
let descriptor = process.data.fdesc.get(&fd);
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 => {
(*frame).regs[gp(Registers::A0)] = -1isize as usize;
0
}
// #define SYS_fstat 80
80 => {
// int fstat(int filedes, struct stat *buf)
(*frame).regs[gp(Registers::A0)] = 0;
0
}
172 => {
// A0 = pid
(*frame).regs[Registers::A0 as usize] = (*frame).pid;
0
}
180 => {
set_waiting((*frame).pid as u16);
@ -240,11 +263,10 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
false,
(*frame).pid as u16
);
0
}
214 => { // brk
// #define SYS_brk 214
// int brk(void *addr);
// void *brk(void *addr);
let addr = (*frame).regs[gp(Registers::A0)];
let process = get_by_pid((*frame).pid as u16).as_mut().unwrap();
// 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;
}
(*frame).regs[gp(Registers::A0)] = process.brk;
0
}
// 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
@ -288,7 +309,6 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
(*frame).regs[Registers::A0 as usize] = 0x3000_0000;
}
}
0
}
1001 => {
// 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 height = (*frame).regs[Registers::A4 as usize] as u32;
gpu::transfer(dev, x, y, width, height);
0
}
1002 => {
// 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 table = (*process).mmu_table.as_mut().unwrap();
(*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
}
else {
ev.len()
} {
};
for i in 0..num_events {
let paddr = virt_to_phys(table, vaddr.add(i) as usize);
if paddr.is_none() {
break;
@ -325,7 +345,6 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
}
}
KEY_EVENTS.replace(ev);
0
}
1004 => {
// wait for abs events
@ -352,16 +371,69 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
}
}
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 => {
// gettime
(*frame).regs[Registers::A0 as usize] = crate::cpu::get_mtime();
0
}
_ => {
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) }
}
pub fn syscall_yield() {
let _ = do_make_syscall(1, 0, 0, 0, 0, 0, 0);
}
pub fn syscall_exit() {
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_mremap 216
// #define SYS_mmap 222
// #define SYS_open 1024
// #define SYS_link 1025
// #define SYS_unlink 1026
// #define SYS_mkdir 1030

View File

@ -101,16 +101,11 @@ extern "C" fn m_trap(epc: usize,
8 | 9 | 11 => unsafe {
// Environment (system) call from User, Supervisor, and Machine modes
// println!("E-call from User mode! CPU#{} -> 0x{:08x}", hart, epc);
return_pc = do_syscall(return_pc, frame);
if return_pc == 0 {
// We are about to schedule something else here, so we need to store PAST
// the system call so that when we resume this process, we're after the ecall.
(*frame).pc += 4;
do_syscall(return_pc, frame);
let frame = schedule();
schedule_next_context_switch(1);
rust_switch_to_user(frame);
}
}
// Page faults
12 => unsafe {
// Instruction page fault