checkpoint

This commit is contained in:
Coraline Sherratt
2017-06-30 20:31:10 -04:00
parent 9f9d02d2a5
commit 1e0ce967ca
5 changed files with 131 additions and 31 deletions

1
.gitignore vendored
View File

@@ -1,2 +1,3 @@
target
*.bk
*.txt

View File

@@ -114,12 +114,13 @@ impl MMU {
let idx = segment_number(addr);
return if let Ok(entry) = memory.read_u32(base + idx * 4) {
/*println!("stb({:x})[{:x}] => {:x}",
self.segment_table_base,
idx,
entry);*/
// check if the entry is invalid
if entry & VALID_BIT != VALID_BIT {
println!("stb({:x})[{:x}] => {:x}",
self.segment_table_base,
idx * 4,
entry);
SegmentEntry::Invalid
// the segment bit will determine if the this is to be
// treated as a single segment, or a page table
@@ -129,6 +130,8 @@ impl MMU {
SegmentEntry::PageTable(PageTable(entry))
}
} else {
println!("stb({:x})[{:x}] (not backed)", self.segment_table_base, idx);
// if the address cannot be loaded we count
// this as an Invalid entry for simplicity
SegmentEntry::Invalid
@@ -148,7 +151,11 @@ impl MMU {
// segment is simple so we can just do it inplace
// check if the segment is not accessible in user mode
if self.user && !segment.user() {
return Err(Error::BusFault { address: addr, mode: Mode::Read, description: BusDescription::KernelSegmentFromUserMode });
return Err(Error::BusFault {
address: addr,
mode: Mode::Read,
description: BusDescription::KernelSegmentFromUserMode,
});
}
// get the offset into the segment
@@ -156,14 +163,22 @@ impl MMU {
// check if segment does not include this address
if off > segment.size() {
return Err(Error::BusFault { address: addr, mode: Mode::Read, description: BusDescription::AddressOutOfSegmentBound });
return Err(Error::BusFault {
address: addr,
mode: Mode::Read,
description: BusDescription::AddressOutOfSegmentBound,
});
}
// calculate the physical address
return Ok(segment.base() + off);
}
SegmentEntry::Invalid => {
return Err(Error::BusFault { address: addr, mode: Mode::Read, description: BusDescription::InvalidSegmentEntry });
return Err(Error::BusFault {
address: addr,
mode: Mode::Read,
description: BusDescription::InvalidSegmentEntry,
});
}
};
@@ -175,17 +190,29 @@ impl MMU {
let page = if let Ok(page) = memory.read_u32(page_address + idx * 4) {
Page(page)
} else {
return return Err(Error::BusFault { address: addr, mode: Mode::Read, description: BusDescription::PageTableIsNotBacked });
return return Err(Error::BusFault {
address: addr,
mode: Mode::Read,
description: BusDescription::PageTableIsNotBacked,
});
};
// check if the page is valid
if !page.valid() {
return Err(Error::BusFault { address: addr, mode: Mode::Read, description: BusDescription::InvalidPageEntry });
return Err(Error::BusFault {
address: addr,
mode: Mode::Read,
description: BusDescription::InvalidPageEntry,
});
}
// check if the page is accessible to the user
if self.user && !page.user() {
return Err(Error::BusFault { address: addr, mode: Mode::Read, description: BusDescription::KernelPageFromUserMode });
return Err(Error::BusFault {
address: addr,
mode: Mode::Read,
description: BusDescription::KernelPageFromUserMode,
});
}
// set the referenced bit, write the value back
@@ -214,7 +241,11 @@ impl MMU {
// segment is simple so we can just do it inplace
// check if the segment is not accessible in user mode
if self.user && !segment.user() {
return Err(Error::BusFault { address: addr, mode: Mode::Write, description: BusDescription::KernelSegmentFromUserMode });
return Err(Error::BusFault {
address: addr,
mode: Mode::Write,
description: BusDescription::KernelSegmentFromUserMode,
});
}
// get the offset into the segment
@@ -222,19 +253,31 @@ impl MMU {
// check if segment does not include this address
if off > segment.size() {
return Err(Error::BusFault { address: addr, mode: Mode::Write, description: BusDescription::AddressOutOfSegmentBound });;
return Err(Error::BusFault {
address: addr,
mode: Mode::Write,
description: BusDescription::AddressOutOfSegmentBound,
});;
}
// check if the segment is writable
if !segment.writeable() {
return Err(Error::BusFault { address: addr, mode: Mode::Write, description: BusDescription::WriteToReadOnlySegment });
return Err(Error::BusFault {
address: addr,
mode: Mode::Write,
description: BusDescription::WriteToReadOnlySegment,
});
}
// calculate the physical address
return Ok(segment.base() + off);
}
SegmentEntry::Invalid => {
return Err(Error::BusFault { address: addr, mode: Mode::Read, description: BusDescription::InvalidSegmentEntry });
return Err(Error::BusFault {
address: addr,
mode: Mode::Write,
description: BusDescription::InvalidSegmentEntry,
});
}
};
@@ -246,22 +289,38 @@ impl MMU {
let page = if let Ok(page) = memory.read_u32(page_address + idx * 4) {
Page(page)
} else {
return Err(Error::BusFault { address: addr, mode: Mode::Read, description: BusDescription::PageTableIsNotBacked });
return Err(Error::BusFault {
address: addr,
mode: Mode::Write,
description: BusDescription::PageTableIsNotBacked,
});
};
// check if the page is valid
if !page.valid() {
return Err(Error::BusFault { address: addr, mode: Mode::Read, description: BusDescription::InvalidPageEntry });
return Err(Error::BusFault {
address: addr,
mode: Mode::Write,
description: BusDescription::InvalidPageEntry,
});
}
// check if the page is accessible to the user
if self.user && !page.user() {
return Err(Error::BusFault { address: addr, mode: Mode::Read, description: BusDescription::KernelPageFromUserMode });
return Err(Error::BusFault {
address: addr,
mode: Mode::Write,
description: BusDescription::KernelPageFromUserMode,
});
}
// check if the segment is writable
if !page.writeable() {
return Err(Error::BusFault { address: addr, mode: Mode::Read, description: BusDescription::WriteToReadOnlyPage });
return Err(Error::BusFault {
address: addr,
mode: Mode::Write,
description: BusDescription::WriteToReadOnlyPage,
});
}
// set the referenced bit, write the value back

View File

@@ -636,6 +636,10 @@ impl Hobbit {
DisasmMode(mode, symbols, Some(self.instruction_pc.0)),
self.pc,
addr);
for i in 0..8 {
let i = i * 4;
println!("R{} = 0x{:08x}", i, memory.read_u32(self.sp.0 + i).unwrap());
}
}
Instruction::Cmp(op, src, dst) => {
@@ -705,7 +709,7 @@ impl Hobbit {
.unwrap());
}
pub fn step<M: Memory>(&mut self, memory: &mut M, _symbols: Option<Symbols>) {
pub fn step<M: Memory>(&mut self, memory: &mut M, symbols: Option<Symbols>) {
// step the timers
self.step_timers();
@@ -715,8 +719,15 @@ impl Hobbit {
let (instruction, next) =
match Instruction::decode(memory, self.pc.0, self.cpu_mode_escape) {
Ok((i, next)) => (i, next),
Err(Error::BusFault { address: addr, mode: mode, description: description }) => {
panic!("Bus fault from {:?} addr: 0x{:x} -- {:?}", mode, addr, description);
Err(Error::BusFault {
address: addr,
mode: mode,
description: description,
}) => {
panic!("Bus fault from {:?} addr: 0x{:x} -- {:?}",
mode,
addr,
description);
}
};
@@ -726,7 +737,7 @@ impl Hobbit {
self.cpu_mode_escape = false;
//let next = next as usize;
/*if let Some(sym) = symbols.as_ref().and_then(|x| x.find(self.instruction_pc.0)) {
if let Some(sym) = symbols.as_ref().and_then(|x| x.find(self.instruction_pc.0)) {
println!("pc: 0x{:x} <{}>", self.instruction_pc.0, sym)
} else {
println!("pc: 0x{:x}", self.instruction_pc.0)
@@ -736,7 +747,7 @@ impl Hobbit {
print!("\t{}\n\t",
Disasm(instruction, symbols, Some(self.instruction_pc.0)));
self.explain(instruction, memory, symbols);*/
self.explain(instruction, memory, symbols);
/*for i in 0..depth {
print!("-");
@@ -801,7 +812,11 @@ impl Hobbit {
}*/
if let Err(Error::BusFault { address: addr, mode: mode, description: description }) = self.execute(instruction, memory) {
if let Err(Error::BusFault {
address: addr,
mode: mode,
description: description,
}) = self.execute(instruction, memory) {
// roll back the pc
self.pc = self.instruction_pc;
@@ -815,7 +830,10 @@ impl Hobbit {
println!("");
}*/
panic!("Bus fault from {:?} addr: 0x{:x} -- {:?}", mode, addr, description);
panic!("Bus fault from {:?} addr: 0x{:x} -- {:?}",
mode,
addr,
description);
}
@@ -1224,7 +1242,6 @@ impl Instruction {
0b01_101 => Instruction::Dyandic3(Dyandic::Add, wai5(src), stk5(dst)),
0b01_110 => Instruction::Dyandic3(Dyandic::And, imm5(src), stk5(dst)),
0b01_111 => Instruction::Dyandic(Dyandic::And, stk5(src), stk5(dst)),
0b10_000 => Instruction::Cmp(CmpMode::Eq, imm5(src), stk5(dst)),
0b10_001 => Instruction::Cmp(CmpMode::Gt, stk5(src), stk5(dst)),
0b10_010 => Instruction::Cmp(CmpMode::Gt, imm5(src), stk5(dst)),

View File

@@ -121,7 +121,7 @@ pub enum BusDescription {
InvalidPageEntry,
PageTableIsNotBacked,
WriteToReadOnlySegment,
WriteToReadOnlyPage
WriteToReadOnlyPage,
}
#[derive(Debug)]
@@ -322,7 +322,11 @@ impl Memory for Vec<u8> {
let from = if start >= 0x800_0000 && end < 0x880_0000 {
&self[start - 0x800_0000..end - 0x800_0000]
} else {
return Result::Err(Error::BusFault { address: addr, mode: Mode::Read, description: BusDescription::BadPhysicalMemoryAddress });
return Result::Err(Error::BusFault {
address: addr,
mode: Mode::Read,
description: BusDescription::BadPhysicalMemoryAddress,
});
};
data.copy_from_slice(from);
@@ -341,7 +345,11 @@ impl Memory for Vec<u8> {
let to = if start >= 0x800_0000 && end < 0x880_0000 {
&mut self[start - 0x800_0000..end - 0x800_0000]
} else {
return Result::Err(Error::BusFault { address: addr, mode: Mode::Write, description: BusDescription::BadPhysicalMemoryAddress });
return Result::Err(Error::BusFault {
address: addr,
mode: Mode::Write,
description: BusDescription::BadPhysicalMemoryAddress,
});
};
to.copy_from_slice(data);
@@ -478,8 +486,11 @@ fn main() {
};
be.boot();
//be.walk();
//return;
//be.cpu1.walk(&mut be.memory, 0x80c0510, 0x80c0510 + 0x800, Some(Symbols::new(&be.symbols)));
//return;
//be.memory.print_str(0x80e125c);
for _ in 0..25_000_000 {
be.step();

View File

@@ -96,7 +96,13 @@ impl Memory for Rtc {
//panic!("todo address={:x}", x);
Ok(())
}
_ => Err(Error::BusFault { address: addr, mode: Mode::Read, description: BusDescription::BadPhysicalMemoryAddress }),
_ => {
Err(Error::BusFault {
address: addr,
mode: Mode::Read,
description: BusDescription::BadPhysicalMemoryAddress,
})
}
}
}
@@ -121,7 +127,13 @@ impl Memory for Rtc {
panic!("todo address={} val={:x}", x, data[0]);
//Ok(())
}
_ => Err(Error::BusFault { address: addr, mode: Mode::Write, description: BusDescription::BadPhysicalMemoryAddress }),
_ => {
Err(Error::BusFault {
address: addr,
mode: Mode::Write,
description: BusDescription::BadPhysicalMemoryAddress,
})
}
}
}
}