161 lines
3.9 KiB
Rust
161 lines
3.9 KiB
Rust
// Copyright (c) 2025 taitep
|
|
// SPDX-License-Identifier: MIT
|
|
//
|
|
// This file is part of TRVE (https://gitea.taitep.se/taitep/trve)
|
|
// See LICENSE file in the project root for full license text.
|
|
|
|
use std::{
|
|
error::Error,
|
|
fs::File,
|
|
io::{self, Read},
|
|
sync::Arc,
|
|
time::Duration,
|
|
};
|
|
|
|
use trve::{
|
|
consts::{Byte, DWord, HWord, Word},
|
|
core::Core,
|
|
mem::{DeviceEntry, MemAccessFault, MemConfig, MemDeviceInterface, PageNum, Ram},
|
|
};
|
|
|
|
use crate::basic_uart::BasicUart;
|
|
|
|
fn read_file_to_buffer(path: &str, buffer: &mut [u8]) -> io::Result<usize> {
|
|
let mut file = File::open(path)?;
|
|
let mut total_read = 0;
|
|
|
|
while total_read < buffer.len() {
|
|
let n = file.read(&mut buffer[total_read..])?;
|
|
if n == 0 {
|
|
return Ok(total_read);
|
|
}
|
|
total_read += n;
|
|
}
|
|
|
|
let mut tmp = [0u8; 1];
|
|
if file.read(&mut tmp)? != 0 {
|
|
return Err(io::Error::other("RAM too small for file"));
|
|
}
|
|
|
|
Ok(total_read)
|
|
}
|
|
|
|
fn main() -> Result<(), Box<dyn Error>> {
|
|
let mut ram = Ram::try_new(1024 * 1024 / 4096)?;
|
|
let buf = ram.buf_mut();
|
|
read_file_to_buffer("./img", buf)?;
|
|
|
|
let uart = BasicUart::new();
|
|
let uart = uart.spawn_poller(Duration::from_millis(10));
|
|
|
|
let mem_cfg = MemConfig {
|
|
ram: Arc::new(ram),
|
|
ram_start: 0x8000_0000 / 4096,
|
|
devices: Box::new([
|
|
DeviceEntry {
|
|
base: 0,
|
|
size: 1,
|
|
interface: Arc::new(DbgOut),
|
|
},
|
|
DeviceEntry {
|
|
base: 1,
|
|
size: 1,
|
|
interface: uart,
|
|
},
|
|
]),
|
|
};
|
|
|
|
let mut core = Core::new(mem_cfg);
|
|
core.reset(0x8000_0000);
|
|
core.run();
|
|
|
|
Ok(())
|
|
}
|
|
|
|
mod basic_uart;
|
|
|
|
struct DbgOut;
|
|
|
|
impl MemDeviceInterface for DbgOut {
|
|
fn write_dword(
|
|
&self,
|
|
page: PageNum,
|
|
offset: u16,
|
|
value: DWord,
|
|
) -> Result<(), trve::mem::MemAccessFault> {
|
|
eprintln!(
|
|
"Wrote DWord {value:016x} to Debug-Out page {page}, offset {offset} (byte {})",
|
|
offset * 8
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
fn write_word(
|
|
&self,
|
|
page: PageNum,
|
|
offset: u16,
|
|
value: Word,
|
|
) -> Result<(), trve::mem::MemAccessFault> {
|
|
eprintln!(
|
|
"Wrote Word {value:08x} to Debug-Out page {page}, offset {offset} (byte {})",
|
|
offset * 4
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
fn write_hword(
|
|
&self,
|
|
page: PageNum,
|
|
offset: u16,
|
|
value: HWord,
|
|
) -> Result<(), trve::mem::MemAccessFault> {
|
|
eprintln!(
|
|
"Wrote HWord {value:04x} to Debug-Out page {page}, offset {offset} (byte {})",
|
|
offset * 2
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
fn write_byte(
|
|
&self,
|
|
page: PageNum,
|
|
offset: u16,
|
|
value: Byte,
|
|
) -> Result<(), trve::mem::MemAccessFault> {
|
|
eprintln!("Wrote Byte {value:02x} to Debug-Out page {page}, offset {offset}");
|
|
Ok(())
|
|
}
|
|
|
|
fn read_dword(&self, _page: PageNum, _offset: u16) -> Result<DWord, trve::mem::MemAccessFault> {
|
|
Err(MemAccessFault)
|
|
}
|
|
|
|
fn read_word(&self, _page: PageNum, _offset: u16) -> Result<Word, trve::mem::MemAccessFault> {
|
|
Err(MemAccessFault)
|
|
}
|
|
|
|
fn read_hword(&self, _page: PageNum, _offset: u16) -> Result<HWord, trve::mem::MemAccessFault> {
|
|
Err(MemAccessFault)
|
|
}
|
|
|
|
fn read_byte(&self, _page: PageNum, _offset: u16) -> Result<Byte, trve::mem::MemAccessFault> {
|
|
Err(MemAccessFault)
|
|
}
|
|
|
|
fn get_atomic_word(
|
|
&self,
|
|
_page: PageNum,
|
|
_offset: u16,
|
|
) -> Result<&std::sync::atomic::AtomicU32, trve::mem::MemAccessFault> {
|
|
Err(MemAccessFault)
|
|
}
|
|
|
|
fn get_atomic_dword(
|
|
&self,
|
|
_page: PageNum,
|
|
_offset: u16,
|
|
) -> Result<&std::sync::atomic::AtomicU64, trve::mem::MemAccessFault> {
|
|
Err(MemAccessFault)
|
|
}
|
|
}
|