1
0
mirror of https://github.com/sgmarz/osblog.git synced 2024-11-24 02:16:19 +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, 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 /// The trap frame is set into a structure
/// and packed into each hart's mscratch register. /// and packed into each hart's mscratch register.
/// This allows for quick reference and full /// This allows for quick reference and full

View File

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

View File

@ -8,7 +8,8 @@ use crate::{cpu::{build_satp,
satp_fence_asid, satp_fence_asid,
CpuMode, CpuMode,
SatpMode, SatpMode,
TrapFrame}, TrapFrame,
Registers},
page::{alloc, page::{alloc,
dealloc, dealloc,
map, map,
@ -268,8 +269,8 @@ pub fn add_kernel_process(func: fn()) -> u16 {
// 1 is the return address register. This makes it so we // 1 is the return address register. This makes it so we
// don't have to do syscall_exit() when a kernel process // don't have to do syscall_exit() when a kernel process
// finishes. // finishes.
(*ret_proc.frame).regs[1] = ra_delete_proc as usize; (*ret_proc.frame).regs[Registers::Ra as usize] = ra_delete_proc as usize;
(*ret_proc.frame).regs[2] = (*ret_proc.frame).regs[Registers::Sp as usize] =
ret_proc.stack as usize + STACK_PAGES * 4096; ret_proc.stack as usize + STACK_PAGES * 4096;
(*ret_proc.frame).mode = CpuMode::Machine as usize; (*ret_proc.frame).mode = CpuMode::Machine as usize;
(*ret_proc.frame).pid = ret_proc.pid 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. // bottom of the memory and far away from heap allocations.
unsafe { unsafe {
(*ret_proc.frame).pc = func_vaddr; (*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 // 1 is the return address register. This makes it so we
// don't have to do syscall_exit() when a kernel process // don't have to do syscall_exit() when a kernel process
// finishes. // finishes.
(*ret_proc.frame).regs[1] = ra_delete_proc as usize; (*ret_proc.frame).regs[Registers::Ra as usize] = ra_delete_proc as usize;
(*ret_proc.frame).regs[2] = (*ret_proc.frame).regs[Registers::Sp as usize] =
ret_proc.stack as usize + STACK_PAGES * 4096; ret_proc.stack as usize + STACK_PAGES * 4096;
(*ret_proc.frame).mode = CpuMode::Machine as usize; (*ret_proc.frame).mode = CpuMode::Machine as usize;
(*ret_proc.frame).pid = ret_proc.pid as usize; (*ret_proc.frame).pid = ret_proc.pid as usize;
@ -519,7 +520,7 @@ impl Process {
let saddr = ret_proc.stack as usize; let saddr = ret_proc.stack as usize;
unsafe { unsafe {
(*ret_proc.frame).pc = func_vaddr; (*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; STACK_ADDR + PAGE_SIZE * STACK_PAGES;
(*ret_proc.frame).mode = CpuMode::User as usize; (*ret_proc.frame).mode = CpuMode::User as usize;
(*ret_proc.frame).pid = ret_proc.pid as usize; (*ret_proc.frame).pid = ret_proc.pid as usize;

View File

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