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);
|
||||
}
|
||||
|
||||
fn get_page_table_entry(&mut self, address: usize) -> PageTableEntry {
|
||||
let page = address >> PAGE_BITS;
|
||||
fn get_page_table_entry(&self, page: usize) -> PageTableEntry {
|
||||
if page < self.pages.len() {
|
||||
return self.pages[page];
|
||||
} else {
|
||||
|
|
@ -117,38 +116,37 @@ impl MachineState {
|
|||
}
|
||||
}
|
||||
|
||||
fn set_page_table_entry(&mut self, address: usize, entry: PageTableEntry) {
|
||||
let page = address >> PAGE_BITS;
|
||||
fn set_page_table_entry(&mut self, page: usize, entry: PageTableEntry) {
|
||||
if page < self.pages.len() {
|
||||
self.pages[address >> 12] = entry;
|
||||
self.pages[page] = entry;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
fn lbu_physical(&mut self, address: usize) -> i64 {
|
||||
fn lbu_physical(&self, address: usize) -> 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 (
|
||||
(self.memory[address ] as u16) |
|
||||
((self.memory[address + 1] as u16) << 8)
|
||||
) as i16 as i64;
|
||||
}
|
||||
|
||||
fn lhu_physical(&mut self, address: usize) -> i64 {
|
||||
fn lhu_physical(&self, address: usize) -> i64 {
|
||||
return (
|
||||
(self.memory[address ] as u16) |
|
||||
((self.memory[address + 1] as u16) << 8)
|
||||
) as i64;
|
||||
}
|
||||
|
||||
fn lw_physical(&mut self, address: usize) -> i64 {
|
||||
fn lw_physical(&self, address: usize) -> i64 {
|
||||
return (
|
||||
(self.memory[address ] as u32) |
|
||||
((self.memory[address + 1] as u32) << 8) |
|
||||
|
|
@ -157,7 +155,7 @@ impl MachineState {
|
|||
) as i32 as i64;
|
||||
}
|
||||
|
||||
fn lwu_physical(&mut self, address: usize) -> i64 {
|
||||
fn lwu_physical(&self, address: usize) -> i64 {
|
||||
return (
|
||||
(self.memory[address ] as u32) |
|
||||
((self.memory[address + 1] as u32) << 8) |
|
||||
|
|
@ -166,7 +164,7 @@ impl MachineState {
|
|||
) as u32 as i64;
|
||||
}
|
||||
|
||||
fn ld_physical(&mut self, address: usize) -> i64 {
|
||||
fn ld_physical(&self, address: usize) -> i64 {
|
||||
return (
|
||||
(self.memory[address ] as u64) |
|
||||
((self.memory[address + 1] as u64) << 8) |
|
||||
|
|
@ -270,6 +268,122 @@ impl CoreState {
|
|||
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