wip
This commit is contained in:
parent
aadedf4863
commit
bf76e671e9
1 changed files with 99 additions and 99 deletions
198
src/main.rs
198
src/main.rs
|
|
@ -51,7 +51,7 @@ impl PageTableEntry {
|
||||||
return self.flags;
|
return self.flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_leaf(&self) -> bool {
|
fn is_pointer(&self) -> bool {
|
||||||
return self.flags & (BIT_V | BIT_R | BIT_W | BIT_X) == BIT_V;
|
return self.flags & (BIT_V | BIT_R | BIT_W | BIT_X) == BIT_V;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -123,100 +123,105 @@ impl MachineState {
|
||||||
return Self::new_with_state(memory, pages);
|
return Self::new_with_state(memory, pages);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_page_table_entry(&self, address: i64) -> PageTableEntry {
|
fn lb_physical(&self, address: i64) -> i64 {
|
||||||
if (address as u64) < (self.memory.len() as u64) {
|
if (address as u64) < (self.memory.len() as u64) {
|
||||||
return PageTableEntry::new(self.ld_physical(address as usize));
|
return self.memory[address as usize] as i8 as i64;
|
||||||
} else {
|
|
||||||
panic!("xxx");
|
|
||||||
}
|
}
|
||||||
|
panic!("@fixme: trap on out of bounds physical read");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_page_table_entry(&mut self, address: i64, entry: PageTableEntry) {
|
fn lbu_physical(&self, address: i64) -> i64 {
|
||||||
if (address as u64) < (self.memory.len() as u64) {
|
if (address as u64) < (self.memory.len() as u64) {
|
||||||
self.sd_physical(address as usize, entry.as_i64());
|
return self.memory[address as usize] as u8 as i64;
|
||||||
} else {
|
|
||||||
panic!("xxx");
|
|
||||||
}
|
}
|
||||||
|
panic!("@fixme: trap on out of bounds physical read");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lb_physical(&self, address: usize) -> i64 {
|
fn lh_physical(&self, address: i64) -> i64 {
|
||||||
return self.memory[address] as i8 as i64;
|
if (address as u64) < (self.memory.len() as u64 - 1) {
|
||||||
|
return (
|
||||||
|
( self.memory[address as usize ] as u16) |
|
||||||
|
((self.memory[address as usize + 1] as u16) << 8)
|
||||||
|
) as i16 as i64;
|
||||||
|
}
|
||||||
|
panic!("@fixme: trap on out of bounds physical read");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lbu_physical(&self, address: usize) -> i64 {
|
fn lhu_physical(&self, address: i64) -> i64 {
|
||||||
return self.memory[address] as u8 as i64;
|
if (address as u64) < (self.memory.len() as u64 - 1) {
|
||||||
|
return (
|
||||||
|
( self.memory[address as usize ] as u16) |
|
||||||
|
((self.memory[address as usize + 1] as u16) << 8)
|
||||||
|
) as i64;
|
||||||
|
}
|
||||||
|
panic!("@fixme: trap on out of bounds physical read");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lh_physical(&self, address: usize) -> i64 {
|
fn lw_physical(&self, address: i64) -> i64 {
|
||||||
return (
|
if (address as u64) < (self.memory.len() as u64 - 3) {
|
||||||
(self.memory[address ] as u16) |
|
return (
|
||||||
((self.memory[address + 1] as u16) << 8)
|
( self.memory[address as usize ] as u32) |
|
||||||
) as i16 as i64;
|
((self.memory[address as usize + 1] as u32) << 8) |
|
||||||
|
((self.memory[address as usize + 2] as u32) << 16) |
|
||||||
|
((self.memory[address as usize + 3] as u32) << 24)
|
||||||
|
) as i32 as i64;
|
||||||
|
}
|
||||||
|
panic!("@fixme: trap on out of bounds physical read");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lhu_physical(&self, address: usize) -> i64 {
|
fn lwu_physical(&self, address: i64) -> i64 {
|
||||||
return (
|
if (address as u64) < (self.memory.len() as u64 - 3) {
|
||||||
(self.memory[address ] as u16) |
|
return (
|
||||||
((self.memory[address + 1] as u16) << 8)
|
( self.memory[address as usize ] as u32) |
|
||||||
) as i64;
|
((self.memory[address as usize + 1] as u32) << 8) |
|
||||||
|
((self.memory[address as usize + 2] as u32) << 16) |
|
||||||
|
((self.memory[address as usize + 3] as u32) << 24)
|
||||||
|
) as u32 as i64;
|
||||||
|
}
|
||||||
|
panic!("@fixme: trap on out of bounds physical read");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lw_physical(&self, address: usize) -> i64 {
|
fn ld_physical(&self, address: i64) -> i64 {
|
||||||
return (
|
if (address as u64) < (self.memory.len() as u64 - 7) {
|
||||||
(self.memory[address ] as u32) |
|
return (
|
||||||
((self.memory[address + 1] as u32) << 8) |
|
( self.memory[address as usize ] as u64) |
|
||||||
((self.memory[address + 2] as u32) << 16) |
|
((self.memory[address as usize + 1] as u64) << 8) |
|
||||||
((self.memory[address + 3] as u32) << 24)
|
((self.memory[address as usize + 2] as u64) << 16) |
|
||||||
) as i32 as i64;
|
((self.memory[address as usize + 3] as u64) << 24) |
|
||||||
|
((self.memory[address as usize + 4] as u64) << 32) |
|
||||||
|
((self.memory[address as usize + 5] as u64) << 40) |
|
||||||
|
((self.memory[address as usize + 6] as u64) << 48) |
|
||||||
|
((self.memory[address as usize + 7] as u64) << 56)
|
||||||
|
) as i64;
|
||||||
|
}
|
||||||
|
panic!("@fixme: trap on out of bounds physical read");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lwu_physical(&self, address: usize) -> i64 {
|
fn sb_physical(&mut self, address: i64, value: i64) {
|
||||||
return (
|
self.memory[address as usize] = value as u8;
|
||||||
(self.memory[address ] as u32) |
|
|
||||||
((self.memory[address + 1] as u32) << 8) |
|
|
||||||
((self.memory[address + 2] as u32) << 16) |
|
|
||||||
((self.memory[address + 3] as u32) << 24)
|
|
||||||
) as u32 as i64;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ld_physical(&self, address: usize) -> i64 {
|
fn sh_physical(&mut self, address: i64, value: i64) {
|
||||||
return (
|
self.memory[address as usize] = value as u8;
|
||||||
(self.memory[address ] as u64) |
|
self.memory[address as usize + 1] = (value >> 8) as u8;
|
||||||
((self.memory[address + 1] as u64) << 8) |
|
|
||||||
((self.memory[address + 2] as u64) << 16) |
|
|
||||||
((self.memory[address + 3] as u64) << 24) |
|
|
||||||
((self.memory[address + 4] as u64) << 32) |
|
|
||||||
((self.memory[address + 5] as u64) << 40) |
|
|
||||||
((self.memory[address + 6] as u64) << 48) |
|
|
||||||
((self.memory[address + 7] as u64) << 56)
|
|
||||||
) as i64;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sb_physical(&mut self, address: usize, value: i64) {
|
fn sw_physical(&mut self, address: i64, value: i64) {
|
||||||
self.memory[address] = value as u8;
|
self.memory[address as usize] = value as u8;
|
||||||
}
|
self.memory[address as usize + 1] = (value >> 8) as u8;
|
||||||
|
self.memory[address as usize + 2] = (value >> 16) as u8;
|
||||||
fn sh_physical(&mut self, address: usize, value: i64) {
|
self.memory[address as usize + 3] = (value >> 24) as u8;
|
||||||
self.memory[address] = value as u8;
|
|
||||||
self.memory[address + 1] = (value >> 8) as u8;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sw_physical(&mut self, address: usize, value: i64) {
|
|
||||||
self.memory[address] = value as u8;
|
|
||||||
self.memory[address + 1] = (value >> 8) as u8;
|
|
||||||
self.memory[address + 2] = (value >> 16) as u8;
|
|
||||||
self.memory[address + 3] = (value >> 24) as u8;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sd_physical(&mut self, address: usize, value: i64) {
|
fn sd_physical(&mut self, address: usize, value: i64) {
|
||||||
self.memory[address] = value as u8;
|
self.memory[address as usize] = value as u8;
|
||||||
self.memory[address + 1] = (value >> 8) as u8;
|
self.memory[address as usize + 1] = (value >> 8) as u8;
|
||||||
self.memory[address + 2] = (value >> 16) as u8;
|
self.memory[address as usize + 2] = (value >> 16) as u8;
|
||||||
self.memory[address + 3] = (value >> 24) as u8;
|
self.memory[address as usize + 3] = (value >> 24) as u8;
|
||||||
self.memory[address + 4] = (value >> 32) as u8;
|
self.memory[address as usize + 4] = (value >> 32) as u8;
|
||||||
self.memory[address + 5] = (value >> 40) as u8;
|
self.memory[address as usize + 5] = (value >> 40) as u8;
|
||||||
self.memory[address + 6] = (value >> 48) as u8;
|
self.memory[address as usize + 6] = (value >> 48) as u8;
|
||||||
self.memory[address + 7] = (value >> 56) as u8;
|
self.memory[address as usize + 7] = (value >> 56) as u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn store_buffer_physical(&mut self, address: usize, bytes: &[u8]) {
|
fn store_buffer_physical(&mut self, address: usize, bytes: &[u8]) {
|
||||||
|
|
@ -228,7 +233,7 @@ impl MachineState {
|
||||||
struct CoreState {
|
struct CoreState {
|
||||||
// Integer registers
|
// Integer registers
|
||||||
x: [i64; 32],
|
x: [i64; 32],
|
||||||
satp_ppn: i64,
|
satp: i64,
|
||||||
|
|
||||||
// Do we need pc? we're passing it around as active state
|
// Do we need pc? we're passing it around as active state
|
||||||
|
|
||||||
|
|
@ -273,7 +278,7 @@ impl CoreState {
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0
|
0, 0, 0, 0, 0, 0, 0, 0
|
||||||
],
|
],
|
||||||
satp_ppn: 0,
|
satp: 0,
|
||||||
f: [
|
f: [
|
||||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
|
||||||
|
|
@ -290,44 +295,39 @@ impl CoreState {
|
||||||
panic!("@fixme implement traps");
|
panic!("@fixme implement traps");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_page_table_entry(&mut self, machine: &mut MachineState, page: i64) -> PageTableEntry {
|
|
||||||
return machine.get_page_table_entry(page)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn dereference(&mut self, machine: &mut MachineState, address: i64) -> (PageTableEntry, usize) {
|
fn dereference(&mut self, machine: &mut MachineState, address: i64) -> (PageTableEntry, usize) {
|
||||||
let raw = (address as u64) as i64;
|
let high = ((address as u64) >> 39) as usize;
|
||||||
let high = ((address as u64) >> 39) as i64;
|
let vpn2 = (((address as u64) << (64 - 39)) >> (64 - 9)) as usize;
|
||||||
let vpn2 = (((address as u64) << (64 - 39)) >> (64 - 9)) as i64;
|
let vpn1 = (((address as u64) << (64 - 39 + 9)) >> (64 - 9 - 9)) as usize;
|
||||||
let vpn1 = (((address as u64) << (64 - 39 + 9)) >> (64 - 9 - 9)) as i64;
|
let vpn0 = (((address as u64) << (64 - 39 + 9 + 9)) >> (64 - 9 - 9)) as usize;
|
||||||
let vpn0 = (((address as u64) << (64 - 39 + 9 + 9)) >> (64 - 9 - 9)) as i64;
|
|
||||||
|
|
||||||
if high != 0 {
|
if high == 0 {
|
||||||
panic!("@fixme: handle trap for kernel address space or invalid SV39 address");
|
let ppn = self.satp << (64 - 44) >> (64 - 44);
|
||||||
}
|
let pte2 = PageTableEntry::new(
|
||||||
|
machine.ld_physical(ppn + (vpn2 << 3))
|
||||||
let pte2 = machine.get_page_table_entry(self.satp_ppn + (vpn2 << 3));
|
);
|
||||||
if !pte2.is_leaf() {
|
if pte2.is_pointer() {
|
||||||
let pte1 = machine.get_page_table_entry(pte2.get_physical() + (vpn1 << 3));
|
let pte1 = PageTableEntry::new(
|
||||||
if !pte1.is_leaf() {
|
machine.ld_physical(pte2.get_physical() + (vpn1 << 3))
|
||||||
let pte0 = machine.get_page_table_entry(pte1.get_physical() + (vpn0 << 3));
|
);
|
||||||
if pte0.is_leaf() {
|
if pte1.is_pointer() {
|
||||||
// 4 KiB pages
|
let pte0 = PageTableEntry::new(machine.ld_physical(pte1.get_physical() + (vpn0 << 3)));
|
||||||
let shift = 64 - 12;
|
if !pte0.is_pointer() {
|
||||||
return (pte0, (raw << shift >> shift) as usize);
|
// 4 KiB pages
|
||||||
} else {
|
let shift = 64 - 12;
|
||||||
panic!("@fixme: trap on leaf node when we're out of levels");
|
return (pte0, (raw << shift >> shift) as usize);
|
||||||
|
}
|
||||||
|
panic!("@fixme: trap on pointer node when we're out of levels");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// 2 MiB megapages
|
// 2 MiB megapages
|
||||||
let shift = 64 - 12 - 9;
|
let shift = 64 - 12 - 9;
|
||||||
return (pte1, (raw << shift >> shift) as usize);
|
return (pte1, (raw << shift >> shift) as usize);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// 1 GiB gigapages
|
// 1 GiB gigapages
|
||||||
let shift = 64 - 12 - 9 - 9;
|
let shift = 64 - 12 - 9 - 9;
|
||||||
return (pte2, (raw << shift >> shift) as usize);
|
return (pte2, (raw << shift >> shift) as usize);
|
||||||
}
|
}
|
||||||
panic!("@fixme: handle unexpected non-leaf node");
|
panic!("@fixme: handle trap for kernel address space or invalid SV39 address");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lb(&mut self, machine: &mut MachineState, pc: i64, rd: usize, rs1: usize, imm: i32) -> i64 {
|
fn lb(&mut self, machine: &mut MachineState, pc: i64, rd: usize, rs1: usize, imm: i32) -> i64 {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue