summaryrefslogtreecommitdiff
path: root/src/main.rs
blob: 53c29383593a07257c4997aa6f350dbd470af9cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// Copyright (c) 2025 taitep
// SPDX-License-Identifier: BSD-2-Clause
//
// 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::{path::PathBuf, sync::Arc, time::Duration};

use clap::Parser;

use trve::{
    consts::{Addr, Byte, DWord, HWord, Word},
    core::Core,
    exceptions::MemoryExceptionType,
    gdb,
    mem::{MemConfig, MemDeviceInterface, MmioRoot, Ram},
};

use anyhow::Result;

use crate::basic_uart::BasicUart;

mod execload;

#[derive(Parser)]
struct Args {
    executable: PathBuf,
    #[arg(long)]
    wait: bool,
}

fn main() -> Result<()> {
    let args = Args::parse();

    let mut ram = Ram::try_new(16 * 1024 * 1024)?;
    let buf = ram.buf_mut();

    let entry_point = execload::load(args.executable, buf)?;

    let mut mmio_root = MmioRoot::default();
    mmio_root.insert(0, Arc::new(DbgOut));

    let uart = BasicUart::new();
    let uart = uart.spawn_poller(Duration::from_millis(10));
    mmio_root.insert(0x10000, uart);

    let mem_cfg = MemConfig {
        ram: Arc::new(ram),
        mmio_root,
    };

    let (cmd_sender, cmd_reciever) = std::sync::mpsc::channel();

    gdb::run_stub(cmd_sender.clone());

    let mut core = Core::new(mem_cfg, cmd_reciever);
    core.reset(entry_point);

    if args.wait {
        core.run_waiting_for_cmd();
    } else {
        core.run();
    }

    Ok(())
}

mod basic_uart;

struct DbgOut;

impl MemDeviceInterface for DbgOut {
    fn write_dword(&self, addr: Addr, value: DWord) -> Result<(), MemoryExceptionType> {
        eprintln!("Wrote DWord {value:016x} to Debug-Out address {addr:x}");
        Ok(())
    }

    fn write_word(&self, addr: Addr, value: Word) -> Result<(), MemoryExceptionType> {
        eprintln!("Wrote Word {value:08x} to Debug-Out address {addr:x}");
        Ok(())
    }

    fn write_hword(&self, addr: Addr, value: HWord) -> Result<(), MemoryExceptionType> {
        eprintln!("Wrote HWord {value:04x} to Debug-Out address {addr:x}");
        Ok(())
    }

    fn write_byte(&self, addr: Addr, value: Byte) -> Result<(), MemoryExceptionType> {
        eprintln!("Wrote Byte {value:02x} to Debug-Out address {addr:x}");
        Ok(())
    }
}