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:
parent
adcc06d07a
commit
c649947707
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user