|
| 1 | +//! A builder for the [`StEmu`] emulator. |
| 2 | +
|
| 3 | +use super::StEmu; |
| 4 | +use crate::{cfg::EmuConfig, elf::load_elf}; |
| 5 | +use alloc::string::String; |
| 6 | +use brisc_hw::{pipeline::PipelineRegister, XWord}; |
| 7 | + |
| 8 | +/// A builder for the [`StEmu`] emulator. |
| 9 | +#[derive(Debug)] |
| 10 | +pub struct StEmuBuilder<Config> |
| 11 | +where |
| 12 | + Config: EmuConfig, |
| 13 | +{ |
| 14 | + /// The starting program counter. |
| 15 | + pub pc: XWord, |
| 16 | + /// The initial memory for the emulator. |
| 17 | + pub memory: Option<Config::Memory>, |
| 18 | + /// The system call interface for the emulator. |
| 19 | + pub kernel: Option<Config::Kernel>, |
| 20 | +} |
| 21 | + |
| 22 | +impl<Config> Default for StEmuBuilder<Config> |
| 23 | +where |
| 24 | + Config: EmuConfig, |
| 25 | +{ |
| 26 | + fn default() -> Self { |
| 27 | + Self { pc: 0, memory: None, kernel: None } |
| 28 | + } |
| 29 | +} |
| 30 | + |
| 31 | +impl<Config> StEmuBuilder<Config> |
| 32 | +where |
| 33 | + Config: EmuConfig, |
| 34 | + Config::Memory: Default, |
| 35 | +{ |
| 36 | + /// Loads an elf file into the emulator builder, initializing the program counter and memory. |
| 37 | + pub fn with_elf(mut self, elf_bytes: &[u8]) -> Result<Self, String> { |
| 38 | + let (memory, entry_pc) = load_elf::<Config::Memory>(elf_bytes)?; |
| 39 | + self.pc = entry_pc; |
| 40 | + self.memory = Some(memory); |
| 41 | + Ok(self) |
| 42 | + } |
| 43 | +} |
| 44 | + |
| 45 | +impl<Config> StEmuBuilder<Config> |
| 46 | +where |
| 47 | + Config: EmuConfig, |
| 48 | +{ |
| 49 | + /// Assigns the entry point of the program. |
| 50 | + pub const fn with_pc(mut self, pc: XWord) -> Self { |
| 51 | + self.pc = pc; |
| 52 | + self |
| 53 | + } |
| 54 | + |
| 55 | + /// Assigns a pre-created memory instance to the emulator. |
| 56 | + pub fn with_memory(mut self, memory: Config::Memory) -> Self { |
| 57 | + self.memory = Some(memory); |
| 58 | + self |
| 59 | + } |
| 60 | + |
| 61 | + /// Assigns the kernel to the emulator. |
| 62 | + pub fn with_kernel(mut self, kernel: Config::Kernel) -> Self { |
| 63 | + self.kernel = Some(kernel); |
| 64 | + self |
| 65 | + } |
| 66 | + |
| 67 | + /// Builds the emulator with the current configuration. |
| 68 | + /// |
| 69 | + /// ## Panics |
| 70 | + /// |
| 71 | + /// Panics if the memory or kernel is not set. |
| 72 | + pub fn build(self) -> StEmu<Config> { |
| 73 | + StEmu { |
| 74 | + register: PipelineRegister::new(self.pc), |
| 75 | + memory: self.memory.expect("Memory not instantiated"), |
| 76 | + kernel: self.kernel.expect("Kernel not instantiated"), |
| 77 | + } |
| 78 | + } |
| 79 | +} |
0 commit comments