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