Bus mastering
This commit is contained in:
49
src/bus.rs
49
src/bus.rs
@@ -1,5 +1,6 @@
|
||||
pub const DRAM_BASE: u32 = 0x80000000;
|
||||
|
||||
use crate::rv32;
|
||||
use crate::ram;
|
||||
|
||||
pub struct Bus {
|
||||
@@ -10,4 +11,52 @@ impl Bus {
|
||||
pub fn new() -> Bus {
|
||||
Bus { memory: ram::RAM::new() }
|
||||
}
|
||||
|
||||
pub fn load_8(&mut self, address: rv32::XLen) -> rv32::Byte {
|
||||
match address {
|
||||
DRAM_BASE.. => {
|
||||
self.memory.read_8(address)
|
||||
}
|
||||
_ => {
|
||||
println!("VM > BUS > Peripheral at 0x{:08x} does not exist", address);
|
||||
rv32::Byte::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_16(&mut self, address: rv32::XLen) -> rv32::HalfWord {
|
||||
match address {
|
||||
DRAM_BASE.. => {
|
||||
self.memory.read_16(address)
|
||||
}
|
||||
_ => {
|
||||
println!("VM > BUS > Peripheral at 0x{:08x} does not exist", address);
|
||||
rv32::HalfWord::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_32(&mut self, address: rv32::XLen) -> rv32::Word {
|
||||
match address {
|
||||
DRAM_BASE.. => {
|
||||
self.memory.read_32(address)
|
||||
}
|
||||
_ => {
|
||||
println!("VM > BUS > Peripheral at 0x{:08x} does not exist", address);
|
||||
rv32::Word::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_64(&mut self, address: rv32::XLen) -> rv32::DoubleWord {
|
||||
match address {
|
||||
DRAM_BASE.. => {
|
||||
self.memory.read_64(address)
|
||||
}
|
||||
_ => {
|
||||
println!("VM > BUS > Peripheral at 0x{:08x} does not exist", address);
|
||||
rv32::DoubleWord::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
15
src/main.rs
15
src/main.rs
@@ -47,7 +47,7 @@ impl VMRV32I {
|
||||
}
|
||||
|
||||
fn dump_prog(&mut self) {
|
||||
println!("VM > Dumping program");
|
||||
println!("VM > Dumping program (virtual addresses)");
|
||||
for i in 0..12 {
|
||||
println!("VM > 0x{:08x}: 0x{:02x}", i, self.bus.memory.0[i]);
|
||||
}
|
||||
@@ -69,8 +69,17 @@ impl VMRV32I {
|
||||
}
|
||||
|
||||
fn exec(&mut self) {
|
||||
let val: u8 = self.bus.memory.read::<rv32::Byte>(0x80000000)
|
||||
println!("VM > WORD at 0x80000000: 0x{:08x}", val);
|
||||
let val: u8 = self.bus.memory.read_8(0x80000000);
|
||||
println!("VM > BYTE at 0x80000000: 0x{:02x}", val);
|
||||
let val = self.bus.memory.read_16(0x80000000);
|
||||
println!("VM > HWORD at 0x80000000: 0x{:04x}", val);
|
||||
let val = self.bus.memory.read_32(0x80000000);
|
||||
println!("VM > WORD at 0x80000000: 0x{:08x}", val);
|
||||
let val = self.bus.memory.read_64(0x80000000);
|
||||
println!("VM > DWORD at 0x80000000: 0x{:016x}", val);
|
||||
|
||||
let val = self.bus.load_8(0x7FFFFFFF);
|
||||
println!("VM > BYTE at 0x80000000: 0x{:02x}", val);
|
||||
|
||||
while self.pc > self.bus.memory.len() as u32 {
|
||||
let inst = self.fetch();
|
||||
|
||||
84
src/ram.rs
84
src/ram.rs
@@ -14,30 +14,68 @@ impl RAM {
|
||||
self.0.len()
|
||||
}
|
||||
|
||||
pub fn read<T>(&mut self, address: rv32::XLen) -> T
|
||||
where
|
||||
T: num::Num
|
||||
+ num::ToPrimitive
|
||||
+ Default
|
||||
+ std::fmt::LowerHex
|
||||
+ std::ops::Shl<T, Output = T>
|
||||
+ std::ops::BitOr<T, Output = T>
|
||||
+ num::cast::NumCast,
|
||||
{
|
||||
let address: usize = (address - bus::DRAM_BASE) as usize;
|
||||
pub fn read_8(&mut self, address: rv32::XLen) -> rv32::Byte {
|
||||
let memory = &self.0;
|
||||
|
||||
(address..)
|
||||
.take(core::mem::size_of::<T>())
|
||||
.enumerate()
|
||||
.fold(T::default(), |mut acc, (i, x)| {
|
||||
println!("VM > Reading from 0x{:08x} to 0x{:08x}", x, acc);
|
||||
println!("VM > Memory: 0x{:02x}", memory[x]);
|
||||
println!("VM > Now Shift: {}", i * 8);
|
||||
|
||||
acc << u32::from(i as u32 * 8) | memory[x].from()
|
||||
})
|
||||
let address = (address - bus::DRAM_BASE) as usize;
|
||||
memory[address]
|
||||
}
|
||||
|
||||
pub fn write<T>(&mut self, address: rv32::XLen, data: T) {}
|
||||
pub fn read_16(&mut self, address: rv32::XLen) -> rv32::HalfWord {
|
||||
let memory = &self.0;
|
||||
let address = (address - bus::DRAM_BASE) as usize;
|
||||
let ret: rv32::HalfWord =
|
||||
memory[address] as rv32::HalfWord | (memory[address + 1] as rv32::HalfWord) << 8;
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn read_32(&mut self, address: rv32::XLen) -> rv32::Word {
|
||||
let memory = &self.0;
|
||||
let address = (address - bus::DRAM_BASE) as usize;
|
||||
let ret: rv32::Word = memory[address] as rv32::Word
|
||||
| (memory[address + 1] as rv32::Word) << 8
|
||||
| (memory[address + 2] as rv32::Word) << 16
|
||||
| (memory[address + 3] as rv32::Word) << 24;
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn read_64(&mut self, address: rv32::XLen) -> rv32::DoubleWord {
|
||||
let memory = &self.0;
|
||||
let address = (address - bus::DRAM_BASE) as usize;
|
||||
let ret: rv32::DoubleWord = memory[address] as rv32::DoubleWord
|
||||
| (memory[address + 1] as rv32::DoubleWord) << 8
|
||||
| (memory[address + 2] as rv32::DoubleWord) << 16
|
||||
| (memory[address + 3] as rv32::DoubleWord) << 24
|
||||
| (memory[address + 4] as rv32::DoubleWord) << 32
|
||||
| (memory[address + 5] as rv32::DoubleWord) << 40
|
||||
| (memory[address + 6] as rv32::DoubleWord) << 48
|
||||
| (memory[address + 7] as rv32::DoubleWord) << 56;
|
||||
ret
|
||||
}
|
||||
|
||||
//pub fn read<T>(&mut self, address: rv32::XLen) -> T
|
||||
//where
|
||||
//T: num::Num
|
||||
//+ num::ToPrimitive
|
||||
//+ Default
|
||||
//+ std::fmt::LowerHex
|
||||
//+ std::ops::Shl<T, Output = T>
|
||||
//+ std::ops::BitOr<T, Output = T>
|
||||
//+ num::cast::NumCast,
|
||||
//{
|
||||
//let address: usize = (address - bus::DRAM_BASE) as usize;
|
||||
//let memory = &self.0;
|
||||
|
||||
//(address..)
|
||||
//.take(core::mem::size_of::<T>())
|
||||
//.enumerate()
|
||||
//.fold(T::default(), |mut acc, (i, x)| {
|
||||
//println!("VM > Reading from 0x{:08x} to 0x{:08x}", x, acc);
|
||||
//println!("VM > Memory: 0x{:02x}", memory[x]);
|
||||
//println!("VM > Now Shift: {}", i * 8);
|
||||
|
||||
//acc << u32::from(i as u32 * 8) | memory[x].from()
|
||||
//})
|
||||
//}
|
||||
|
||||
//pub fn write<T>(&mut self, address: rv32::XLen, data: T) {}
|
||||
}
|
||||
|
||||
13
src/rv32.rs
13
src/rv32.rs
@@ -1,22 +1,15 @@
|
||||
pub const XLEN: usize = 32;
|
||||
pub type XLen = u32;
|
||||
|
||||
enum Data {
|
||||
QuadWord(u128),
|
||||
DoubleWord(u64),
|
||||
Word(u32),
|
||||
HalfWord(u16),
|
||||
Byte(u8),
|
||||
}
|
||||
|
||||
// define words as byte fraction
|
||||
//pub const QUADWORD: usize = 16;
|
||||
pub const QUADWORD: usize = 16;
|
||||
pub const DOUBLEWORD: usize = 8;
|
||||
pub const WORD: usize = 4;
|
||||
pub const HALFWORD: usize = 2;
|
||||
pub const BYTE: usize = 1;
|
||||
|
||||
//pub type DoubleWord = u64;
|
||||
pub type QuadWord = u128;
|
||||
pub type DoubleWord = u64;
|
||||
pub type Word = u32;
|
||||
pub type HalfWord = u16;
|
||||
pub type Byte = u8;
|
||||
|
||||
Reference in New Issue
Block a user