mirror of
https://github.com/csherratt/BillBe.git
synced 2026-02-04 05:34:45 +00:00
checkpoint
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
target
|
||||
*.bk
|
||||
*.txt
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)),
|
||||
|
||||
17
src/main.rs
17
src/main.rs
@@ -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();
|
||||
|
||||
16
src/rtc.rs
16
src/rtc.rs
@@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user