1use crate::devices::{clint::Clint, plic::Plic, uart::Uart, virtio_blk::Virtio};
5use crate::dram::{Dram, DRAM_SIZE};
6use crate::exception::Exception;
7use crate::rom::Rom;
8
9pub const MROM_BASE: u64 = 0x1000;
14const MROM_END: u64 = MROM_BASE + 0xf000;
16
17pub const CLINT_BASE: u64 = 0x200_0000;
20const CLINT_END: u64 = CLINT_BASE + 0x10000;
22
23pub const PLIC_BASE: u64 = 0xc00_0000;
27const PLIC_END: u64 = PLIC_BASE + 0x208000;
29
30pub const UART_BASE: u64 = 0x1000_0000;
32pub const UART_SIZE: u64 = 0x100;
34const UART_END: u64 = UART_BASE + 0x100;
36
37pub const VIRTIO_BASE: u64 = 0x1000_1000;
39const VIRTIO_END: u64 = VIRTIO_BASE + 0x1000;
41
42pub const DRAM_BASE: u64 = 0x8000_0000;
44const DRAM_END: u64 = DRAM_BASE + DRAM_SIZE;
46
47pub struct Bus {
49 pub clint: Clint,
50 plic: Plic,
51 pub uart: Uart,
52 pub virtio: Virtio,
53 dram: Dram,
54 rom: Rom,
55}
56
57impl Bus {
58 pub fn new() -> Bus {
60 Self {
61 clint: Clint::new(),
62 plic: Plic::new(),
63 uart: Uart::new(),
64 virtio: Virtio::new(),
65 dram: Dram::new(),
66 rom: Rom::new(),
67 }
68 }
69
70 pub fn initialize_dram(&mut self, data: Vec<u8>) {
72 self.dram.initialize(data);
73 }
74
75 pub fn initialize_disk(&mut self, data: Vec<u8>) {
77 self.virtio.initialize(data);
78 }
79
80 pub fn read(&mut self, addr: u64, size: u8) -> Result<u64, Exception> {
82 match addr {
83 MROM_BASE..=MROM_END => self.rom.read(addr, size),
84 CLINT_BASE..=CLINT_END => self.clint.read(addr, size),
85 PLIC_BASE..=PLIC_END => self.plic.read(addr, size),
86 UART_BASE..=UART_END => self.uart.read(addr, size),
87 VIRTIO_BASE..=VIRTIO_END => self.virtio.read(addr, size),
88 DRAM_BASE..=DRAM_END => self.dram.read(addr, size),
89 _ => Err(Exception::LoadAccessFault),
90 }
91 }
92
93 pub fn write(&mut self, addr: u64, value: u64, size: u8) -> Result<(), Exception> {
95 match addr {
96 CLINT_BASE..=CLINT_END => self.clint.write(addr, value, size),
97 PLIC_BASE..=PLIC_END => self.plic.write(addr, value, size),
98 UART_BASE..=UART_END => self.uart.write(addr, value as u8, size),
99 VIRTIO_BASE..=VIRTIO_END => self.virtio.write(addr, value as u32, size),
100 DRAM_BASE..=DRAM_END => self.dram.write(addr, value, size),
101 _ => Err(Exception::StoreAMOAccessFault),
102 }
103 }
104}