tweaks
This commit is contained in:
parent
0e15f55e02
commit
339dbf0c23
1 changed files with 126 additions and 12 deletions
138
src/main.rs
138
src/main.rs
|
|
@ -108,8 +108,7 @@ impl MachineState {
|
||||||
return Self::new_with_state(memory, pages);
|
return Self::new_with_state(memory, pages);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_page_table_entry(&mut self, address: usize) -> PageTableEntry {
|
fn get_page_table_entry(&self, page: usize) -> PageTableEntry {
|
||||||
let page = address >> PAGE_BITS;
|
|
||||||
if page < self.pages.len() {
|
if page < self.pages.len() {
|
||||||
return self.pages[page];
|
return self.pages[page];
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -117,38 +116,37 @@ impl MachineState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_page_table_entry(&mut self, address: usize, entry: PageTableEntry) {
|
fn set_page_table_entry(&mut self, page: usize, entry: PageTableEntry) {
|
||||||
let page = address >> PAGE_BITS;
|
|
||||||
if page < self.pages.len() {
|
if page < self.pages.len() {
|
||||||
self.pages[address >> 12] = entry;
|
self.pages[page] = entry;
|
||||||
} else {
|
} else {
|
||||||
panic!("@fixme: handle attempts to expand address space");
|
panic!("@fixme: handle attempts to expand address space");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lb_physical(&mut self, address: usize) -> i64 {
|
fn lb_physical(&self, address: usize) -> i64 {
|
||||||
return self.memory[address] as i8 as i64;
|
return self.memory[address] as i8 as i64;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lbu_physical(&mut self, address: usize) -> i64 {
|
fn lbu_physical(&self, address: usize) -> i64 {
|
||||||
return self.memory[address] as u8 as i64;
|
return self.memory[address] as u8 as i64;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lh_physical(&mut self, address: usize) -> i64 {
|
fn lh_physical(&self, address: usize) -> i64 {
|
||||||
return (
|
return (
|
||||||
(self.memory[address ] as u16) |
|
(self.memory[address ] as u16) |
|
||||||
((self.memory[address + 1] as u16) << 8)
|
((self.memory[address + 1] as u16) << 8)
|
||||||
) as i16 as i64;
|
) as i16 as i64;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lhu_physical(&mut self, address: usize) -> i64 {
|
fn lhu_physical(&self, address: usize) -> i64 {
|
||||||
return (
|
return (
|
||||||
(self.memory[address ] as u16) |
|
(self.memory[address ] as u16) |
|
||||||
((self.memory[address + 1] as u16) << 8)
|
((self.memory[address + 1] as u16) << 8)
|
||||||
) as i64;
|
) as i64;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lw_physical(&mut self, address: usize) -> i64 {
|
fn lw_physical(&self, address: usize) -> i64 {
|
||||||
return (
|
return (
|
||||||
(self.memory[address ] as u32) |
|
(self.memory[address ] as u32) |
|
||||||
((self.memory[address + 1] as u32) << 8) |
|
((self.memory[address + 1] as u32) << 8) |
|
||||||
|
|
@ -157,7 +155,7 @@ impl MachineState {
|
||||||
) as i32 as i64;
|
) as i32 as i64;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lwu_physical(&mut self, address: usize) -> i64 {
|
fn lwu_physical(&self, address: usize) -> i64 {
|
||||||
return (
|
return (
|
||||||
(self.memory[address ] as u32) |
|
(self.memory[address ] as u32) |
|
||||||
((self.memory[address + 1] as u32) << 8) |
|
((self.memory[address + 1] as u32) << 8) |
|
||||||
|
|
@ -166,7 +164,7 @@ impl MachineState {
|
||||||
) as u32 as i64;
|
) as u32 as i64;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ld_physical(&mut self, address: usize) -> i64 {
|
fn ld_physical(&self, address: usize) -> i64 {
|
||||||
return (
|
return (
|
||||||
(self.memory[address ] as u64) |
|
(self.memory[address ] as u64) |
|
||||||
((self.memory[address + 1] as u64) << 8) |
|
((self.memory[address + 1] as u64) << 8) |
|
||||||
|
|
@ -270,6 +268,122 @@ impl CoreState {
|
||||||
dirty: vec![0u8; machine.memory.len()]
|
dirty: vec![0u8; machine.memory.len()]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn lb(&self, machine: &MachineState, address: i64) -> i64 {
|
||||||
|
let raw_page = (address as u64) >> PAGE_BITS;
|
||||||
|
if raw_page < machine.pages.len() as u64 {
|
||||||
|
let addr = address as usize;
|
||||||
|
let page = raw_page as usize;
|
||||||
|
let entry = machine.get_page_table_entry(page);
|
||||||
|
if entry.is_readable() {
|
||||||
|
return machine.lb_physical(address as usize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("@fixme: trap on read failure on page");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lbu(&self, machine: &MachineState, address: i64) -> i64 {
|
||||||
|
let raw_page = (address as u64) >> PAGE_BITS;
|
||||||
|
if raw_page < machine.pages.len() as u64 {
|
||||||
|
let addr = address as usize;
|
||||||
|
let page = raw_page as usize;
|
||||||
|
let entry = machine.get_page_table_entry(page);
|
||||||
|
if entry.is_readable() {
|
||||||
|
return machine.lbu_physical(addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("@fixme: trap on read failure on page");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lh(&self, machine: &MachineState, address: i64) -> i64 {
|
||||||
|
let raw_page = (address as u64) >> PAGE_BITS;
|
||||||
|
if raw_page < machine.pages.len() as u64 {
|
||||||
|
let addr = address as usize;
|
||||||
|
let page = raw_page as usize;
|
||||||
|
let entry = machine.get_page_table_entry(page);
|
||||||
|
if entry.is_readable() {
|
||||||
|
let offset = addr & (PAGE_SIZE - 1);
|
||||||
|
if offset < (PAGE_SIZE - 2) || machine.get_page_table_entry(page + 1).is_readable() {
|
||||||
|
return machine.lh_physical(addr);
|
||||||
|
} else {
|
||||||
|
panic!("@fixme: trap on read failure on page + 1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("@fixme: trap on read failure on page");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lhu(&self, machine: &MachineState, address: i64) -> i64 {
|
||||||
|
let raw_page = (address as u64) >> PAGE_BITS;
|
||||||
|
if raw_page < machine.pages.len() as u64 {
|
||||||
|
let addr = address as usize;
|
||||||
|
let page = raw_page as usize;
|
||||||
|
let entry = machine.get_page_table_entry(page);
|
||||||
|
if entry.is_readable() {
|
||||||
|
let offset = addr & (PAGE_SIZE - 1);
|
||||||
|
if offset < (PAGE_SIZE - 2) || machine.get_page_table_entry(page + 1).is_readable() {
|
||||||
|
return machine.lhu_physical(addr);
|
||||||
|
} else {
|
||||||
|
panic!("@fixme: trap on read failure on page + 1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("@fixme: trap on read failure on page");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lw(&self, machine: &MachineState, address: i64) -> i64 {
|
||||||
|
let raw_page = (address as u64) >> PAGE_BITS;
|
||||||
|
if raw_page < machine.pages.len() as u64 {
|
||||||
|
let addr = address as usize;
|
||||||
|
let page = raw_page as usize;
|
||||||
|
let entry = machine.get_page_table_entry(page);
|
||||||
|
if entry.is_readable() {
|
||||||
|
let offset = addr & (PAGE_SIZE - 1);
|
||||||
|
if offset < (PAGE_SIZE - 4) || machine.get_page_table_entry(page + 1).is_readable() {
|
||||||
|
return machine.lw_physical(addr);
|
||||||
|
} else {
|
||||||
|
panic!("@fixme: trap on read failure on page + 1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("@fixme: trap on read failure on page");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lwu(&self, machine: &MachineState, address: i64) -> i64 {
|
||||||
|
let raw_page = (address as u64) >> PAGE_BITS;
|
||||||
|
if raw_page < machine.pages.len() as u64 {
|
||||||
|
let addr = address as usize;
|
||||||
|
let page = raw_page as usize;
|
||||||
|
let entry = machine.get_page_table_entry(page);
|
||||||
|
if entry.is_readable() {
|
||||||
|
let offset = addr & (PAGE_SIZE - 1);
|
||||||
|
if offset < (PAGE_SIZE - 4) || machine.get_page_table_entry(page + 1).is_readable() {
|
||||||
|
return machine.lwu_physical(addr);
|
||||||
|
} else {
|
||||||
|
panic!("@fixme: trap on read failure on page + 1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("@fixme: trap on read failure on page");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ld(&self, machine: &MachineState, address: i64) -> i64 {
|
||||||
|
let raw_page = (address as u64) >> PAGE_BITS;
|
||||||
|
if raw_page < machine.pages.len() as u64 {
|
||||||
|
let addr = address as usize;
|
||||||
|
let page = raw_page as usize;
|
||||||
|
let entry = machine.get_page_table_entry(page);
|
||||||
|
if entry.is_readable() {
|
||||||
|
let offset = addr & (PAGE_SIZE - 1);
|
||||||
|
if offset < (PAGE_SIZE - 8) || machine.get_page_table_entry(page + 1).is_readable() {
|
||||||
|
return machine.ld_physical(addr);
|
||||||
|
} else {
|
||||||
|
panic!("@fixme: trap on read failure on page + 1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panic!("@fixme: trap on read failure on page");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue