1
0
mirror of https://github.com/sgmarz/osblog.git synced 2024-11-23 18:06:20 +04:00

Added Registers to CPU so we don't have to hardcode the register number. This makes it easier to read and figure out what's happening

This commit is contained in:
Stephen Marz 2020-05-15 12:48:05 -04:00
parent adcc06d07a
commit c649947707
4 changed files with 65 additions and 35 deletions

View File

@ -27,6 +27,42 @@ pub enum CpuMode {
Machine = 3,
}
#[repr(usize)]
pub enum Registers {
Zero = 0,
Ra,
Sp,
Gp,
Tp,
T0,
T1,
T2,
S0,
S1,
A0, /* 10 */
A1,
A2,
A3,
A4,
A5,
A6,
A7,
S2,
S3,
S4, /* 20 */
S5,
S6,
S7,
S8,
S9,
S10,
S11,
T3,
T4,
T5, /* 30 */
T6
}
/// The trap frame is set into a structure
/// and packed into each hart's mscratch register.
/// This allows for quick reference and full

View File

@ -10,7 +10,8 @@ use crate::{buffer::Buffer,
satp_fence_asid,
CpuMode,
SatpMode,
TrapFrame},
TrapFrame,
Registers},
page::{map, zalloc, EntryBits, Table, PAGE_SIZE},
process::{Process,
ProcessData,
@ -243,7 +244,7 @@ impl File {
(*my_proc.frame).pc = elf_fl.header.entry_addr;
// Stack pointer. The stack starts at the bottom and works its
// way up, so we have to set the stack pointer to the bottom.
(*my_proc.frame).regs[2] =
(*my_proc.frame).regs[Registers::Sp as usize] =
STACK_ADDR as usize + STACK_PAGES * PAGE_SIZE;
// USER MODE! This is how we set what'll go into mstatus when we
// run the process.

View File

@ -8,7 +8,8 @@ use crate::{cpu::{build_satp,
satp_fence_asid,
CpuMode,
SatpMode,
TrapFrame},
TrapFrame,
Registers},
page::{alloc,
dealloc,
map,
@ -268,8 +269,8 @@ pub fn add_kernel_process(func: fn()) -> u16 {
// 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.frame).regs[Registers::Ra as usize] = ra_delete_proc as usize;
(*ret_proc.frame).regs[Registers::Sp as usize] =
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;
@ -350,12 +351,12 @@ pub fn add_kernel_process_args(func: fn(args_ptr: usize), args: usize) -> u16 {
// bottom of the memory and far away from heap allocations.
unsafe {
(*ret_proc.frame).pc = func_vaddr;
(*ret_proc.frame).regs[10] = args;
(*ret_proc.frame).regs[Registers::A0 as usize] = 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.frame).regs[Registers::Ra as usize] = ra_delete_proc as usize;
(*ret_proc.frame).regs[Registers::Sp as usize] =
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;
@ -519,7 +520,7 @@ impl Process {
let saddr = ret_proc.stack as usize;
unsafe {
(*ret_proc.frame).pc = func_vaddr;
(*ret_proc.frame).regs[2] =
(*ret_proc.frame).regs[Registers::Sp as usize] =
STACK_ADDR + PAGE_SIZE * STACK_PAGES;
(*ret_proc.frame).mode = CpuMode::User as usize;
(*ret_proc.frame).pid = ret_proc.pid as usize;

View File

@ -4,7 +4,7 @@
// 3 Jan 2020
use crate::{block::block_op,
cpu::{dump_registers, TrapFrame},
cpu::{dump_registers, TrapFrame, Registers},
fs,
page::{virt_to_phys, Table},
process::{Process, PROCESS_LIST, PROCESS_LIST_MUTEX, delete_process, get_by_pid, set_sleeping, set_waiting}};
@ -20,7 +20,7 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
// 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[17];
let syscall_number = (*frame).regs[Registers::A7 as usize];
match syscall_number {
0 | 93 => {
// Exit
@ -29,7 +29,7 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
},
2 => {
// Easy putchar
print!("{}", (*frame).regs[10] as u8 as char);
print!("{}", (*frame).regs[Registers::A0 as usize] as u8 as char);
mepc + 4
},
8 => {
@ -38,13 +38,13 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
},
10 => {
// Sleep
set_sleeping((*frame).pid as u16, (*frame).regs[10]);
set_sleeping((*frame).pid as u16, (*frame).regs[Registers::A0 as usize]);
0
},
11 => {
// Add process to the scheduler. This is obviously insecure and
// we wouldn't do this realistically.
let my_proc = (*frame).regs[10] as *const Process;
let my_proc = (*frame).regs[Registers::A0 as usize] as *const Process;
if PROCESS_LIST_MUTEX.try_lock() {
if let Some(mut pl) = PROCESS_LIST.take() {
// As soon as we push this process on the list, it'll be
@ -53,10 +53,10 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
PROCESS_LIST.replace(pl);
}
PROCESS_LIST_MUTEX.unlock();
(*frame).regs[10] = 1;
(*frame).regs[Registers::A0 as usize] = 1;
}
else {
(*frame).regs[10] = 0;
(*frame).regs[Registers::A0 as usize] = 0;
}
mepc + 4
},
@ -72,7 +72,7 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
// from a user process using virt_to_phys. If this turns
// out to be a page fault, we need to NOT proceed with
// the read!
let mut physical_buffer = (*frame).regs[12];
let mut physical_buffer = (*frame).regs[Registers::A2 as usize];
// If the MMU is turned on, we have to translate the
// address. Eventually, I will put this code into a
// convenient function, but for now, it will show how
@ -86,7 +86,7 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
let paddr =
virt_to_phys(table, (*frame).regs[12]);
if paddr.is_none() {
(*frame).regs[10] = -1isize as usize;
(*frame).regs[Registers::A0 as usize] = -1isize as usize;
return mepc + 4;
}
physical_buffer = paddr.unwrap();
@ -98,13 +98,13 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
// could be a missing page somewhere in between.
let _ = fs::process_read(
(*frame).pid as u16,
(*frame).regs[10]
(*frame).regs[Registers::A0 as usize]
as usize,
(*frame).regs[11] as u32,
(*frame).regs[Registers::A1 as usize] as u32,
physical_buffer
as *mut u8,
(*frame).regs[13] as u32,
(*frame).regs[14] as u32,
(*frame).regs[Registers::A3 as usize] as u32,
(*frame).regs[Registers::A4 as usize] as u32,
);
// If we return 0, the trap handler will schedule
// another process.
@ -112,24 +112,16 @@ pub unsafe fn do_syscall(mepc: usize, frame: *mut TrapFrame) -> usize {
},
172 => {
// A0 = pid
(*frame).regs[10] = (*frame).pid;
(*frame).regs[Registers::A0 as usize] = (*frame).pid;
mepc + 4
},
180 => {
// println!(
// "Pid: {}, Dev: {}, Buffer: 0x{:x}, Size: {},
// Offset: {}", (*frame).pid,
// (*frame).regs[10],
// (*frame).regs[11],
// (*frame).regs[12],
// (*frame).regs[13]
// );
set_waiting((*frame).pid as u16);
let _ = block_op(
(*frame).regs[10],
(*frame).regs[11] as *mut u8,
(*frame).regs[12] as u32,
(*frame).regs[13] as u64,
(*frame).regs[Registers::A0 as usize],
(*frame).regs[Registers::A1 as usize] as *mut u8,
(*frame).regs[Registers::A2 as usize] as u32,
(*frame).regs[Registers::A3 as usize] as u64,
false,
(*frame).pid as u16,
);