From a113db700ab0379e389059d721adb959fa384f9b Mon Sep 17 00:00:00 2001 From: Stephen Marz Date: Fri, 24 Apr 2020 19:16:45 -0400 Subject: [PATCH] Added RA to call syscall_exit for kernel processes. --- risc_v/src/block.rs | 5 +++-- risc_v/src/fs.rs | 4 ++-- risc_v/src/minixfs.rs | 26 ++++++++++---------------- risc_v/src/process.rs | 13 ++++++++++++- risc_v/src/syscall.rs | 16 ++++++++-------- 5 files changed, 35 insertions(+), 29 deletions(-) diff --git a/risc_v/src/block.rs b/risc_v/src/block.rs index 3fd7e7f..af77dd3 100755 --- a/risc_v/src/block.rs +++ b/risc_v/src/block.rs @@ -402,7 +402,8 @@ fn read_proc(args_addr: usize) { let args = unsafe { args_ptr.as_ref().unwrap() }; let _ = block_op(args.dev, args.buffer, args.size, args.offset, false, args.pid); tfree(args_ptr); - syscall_exit(); + // This should be handled by the RA now. + // syscall_exit(); } pub fn process_read(pid: u16, dev: usize, buffer: *mut u8, size: u32, offset: u64) { @@ -423,7 +424,7 @@ fn write_proc(args_addr: usize) { let _ = block_op(args.dev, args.buffer, args.size, args.offset, true, args.pid); tfree(args_ptr); - syscall_exit(); + // syscall_exit(); } pub fn process_write(pid: u16, dev: usize, buffer: *mut u8, size: u32, offset: u64) { diff --git a/risc_v/src/fs.rs b/risc_v/src/fs.rs index 36f8157..bb706bc 100755 --- a/risc_v/src/fs.rs +++ b/risc_v/src/fs.rs @@ -8,8 +8,8 @@ use alloc::string::String; pub trait FileSystem { fn init(bdev: usize) -> bool; fn open(path: &String) -> Result; - fn read(desc: &Descriptor, buffer: *mut u8, offset: u32, size: u32) -> u32; - fn write(desc: &Descriptor, buffer: *const u8, offset: u32, size: u32) -> u32; + fn read(desc: &Descriptor, buffer: *mut u8, size: u32, offset: u32) -> u32; + fn write(desc: &Descriptor, buffer: *const u8, size: u32, offset: u32) -> u32; fn close(desc: &mut Descriptor); fn stat(desc: &Descriptor) -> Stat; } diff --git a/risc_v/src/minixfs.rs b/risc_v/src/minixfs.rs index 27fa31e..f59c50f 100755 --- a/risc_v/src/minixfs.rs +++ b/risc_v/src/minixfs.rs @@ -6,7 +6,7 @@ use crate::{fs::{Descriptor, FileSystem, FsError, Stat}, kmem::{kfree, kmalloc, talloc, tfree}, process::{add_kernel_process_args, set_waiting}, - syscall::{syscall_exit, syscall_block_read}}; + syscall::{syscall_block_read, syscall_exit}}; use alloc::string::String; use core::{mem::size_of, ptr::null_mut}; @@ -122,11 +122,6 @@ impl MinixFileSystem { let inode = unsafe { &*(buffer.get_mut() as *mut Inode) }; // Read from the block device. The size is 1 sector (512 bytes) and our offset is past // the boot block (first 1024 bytes). This is where the superblock sits. - println!( - "DO READ, magic should be next, buffer is at {:p}, desc is at {:p}", - buffer.get(), - desc as *const Descriptor - ); syc_read(desc, buffer.get_mut(), 512, 1024); println!("Magic is {:x}", super_block.magic); if super_block.magic == MAGIC { @@ -140,7 +135,7 @@ impl MinixFileSystem { // Now, we read the inode itself. syc_read(desc, buffer.get_mut(), 512, inode_offset as u32); - println!("Inode sizex = {} {:o}", inode.size, inode.mode); + println!("Inode sizex = {} {:o}, DZ {} {} {} {} {} {} {}", inode.size, inode.mode, inode.zones[0], inode.zones[1], inode.zones[2], inode.zones[3], inode.zones[4], inode.zones[5], inode.zones[6]); return Some(*inode); } // If we get here, some result wasn't OK. Either the super block @@ -158,13 +153,13 @@ impl FileSystem for MinixFileSystem { Err(FsError::FileNotFound) } - fn read(desc: &Descriptor, buffer: *mut u8, offset: u32, size: u32) -> u32 { + fn read(desc: &Descriptor, buffer: *mut u8, size: u32, offset: u32) -> u32 { println!("MinixFileSystem::read: {}, {:p}, off: {}, sz: {}", desc.blockdev, buffer, offset, size); let mut blocks_seen = 0u32; let offset_block = offset / BLOCK_SIZE; let offset_byte = offset % BLOCK_SIZE; - // let stats = Self::stat(desc); + let stats = Self::stat(desc); let inode_result = Self::get_inode(desc, desc.node); let mut block_buffer = BlockBuffer::new(BLOCK_SIZE); if inode_result.is_none() { @@ -175,12 +170,12 @@ impl FileSystem for MinixFileSystem { // First, the _size parameter (now in bytes_left) is the size of the buffer, not // necessarily the size of the file. If our buffer is bigger than the file, we're OK. // If our buffer is smaller than the file, then we can only read up to the buffer size. - // let mut bytes_left = if size > stats.size { - // stats.size - // } - // else { - // size - // }; + let mut bytes_left = if size > stats.size { + stats.size + } + else { + size + }; let mut bytes_left = 0; let mut bytes_read = 0u32; // In Rust, our for loop automatically "declares" i from 0 to < 7. The syntax @@ -252,7 +247,6 @@ fn read_proc(args_addr: usize) { MinixFileSystem::read(&desc, args.buffer, args.offset, args.size); tfree(args_ptr); - syscall_exit(); } pub fn process_read(pid: u16, dev: usize, buffer: *mut u8, size: u32, offset: u32) { diff --git a/risc_v/src/process.rs b/risc_v/src/process.rs index e4d6337..4f767fc 100644 --- a/risc_v/src/process.rs +++ b/risc_v/src/process.rs @@ -4,7 +4,8 @@ // 27 Nov 2019 use crate::{cpu::{build_satp, get_mtime, satp_fence_asid, CpuMode, SatpMode, TrapFrame}, - page::{alloc, dealloc, map, unmap, zalloc, EntryBits, Table, PAGE_SIZE}}; + page::{alloc, dealloc, map, unmap, zalloc, EntryBits, Table, PAGE_SIZE}}; +use crate::syscall::syscall_exit; use alloc::collections::vec_deque::VecDeque; use core::ptr::null_mut; @@ -234,6 +235,9 @@ pub fn add_kernel_process(func: fn()) -> u16 { // bottom of the memory and far away from heap allocations. unsafe { (*ret_proc.frame).pc = func_vaddr; + // 1 is the return address register. This makes it so we don't have to do + // syscall_exit() when a kernel process finishes. + (*ret_proc.frame).regs[1] = ra_delete_proc as usize; (*ret_proc.frame).regs[2] = ret_proc.stack as usize + STACK_PAGES * 4096; (*ret_proc.frame).mode = CpuMode::Machine as usize; (*ret_proc.frame).pid = ret_proc.pid as usize; @@ -254,6 +258,10 @@ pub fn add_kernel_process(func: fn()) -> u16 { } } +fn ra_delete_proc() { + syscall_exit(); +} + /// This is the same as the add_kernel_process function, except you can pass /// arguments. Typically, this will be a memory address on the heap where /// arguments can be found. @@ -297,6 +305,9 @@ pub fn add_kernel_process_args(func: fn(args_ptr: usize), args: usize) -> u16 { unsafe { (*ret_proc.frame).pc = func_vaddr; (*ret_proc.frame).regs[10] = args; + // 1 is the return address register. This makes it so we don't have to do + // syscall_exit() when a kernel process finishes. + (*ret_proc.frame).regs[1] = ra_delete_proc as usize; (*ret_proc.frame).regs[2] = ret_proc.stack as usize + STACK_PAGES * 4096; (*ret_proc.frame).mode = CpuMode::Machine as usize; (*ret_proc.frame).pid = ret_proc.pid as usize; diff --git a/risc_v/src/syscall.rs b/risc_v/src/syscall.rs index 4ecd4d2..90f5c8e 100755 --- a/risc_v/src/syscall.rs +++ b/risc_v/src/syscall.rs @@ -58,14 +58,14 @@ pub fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize { 0 }, 180 => unsafe { - println!( - "Pid: {}, Dev: {}, Buffer: 0x{:x}, Size: {}, Offset: {}", - (*frame).pid, - (*frame).regs[10], - (*frame).regs[11], - (*frame).regs[12], - (*frame).regs[13] - ); + // println!( + // "Pid: {}, Dev: {}, Buffer: 0x{:x}, Size: {}, Offset: {}", + // (*frame).pid, + // (*frame).regs[10], + // (*frame).regs[11], + // (*frame).regs[12], + // (*frame).regs[13] + // ); let _ = block_op((*frame).regs[10], (*frame).regs[11] as *mut u8, (*frame).regs[12] as u32,