GolemComputers/rust/src/component/mod.rs

121 lines
2.6 KiB
Rust

pub mod mmio;
use std::{
cell::RefCell,
mem::offset_of,
ops::{Deref, DerefMut, Range, RangeBounds},
pin::Pin,
rc::Rc,
sync::{
atomic::{AtomicBool, Ordering},
mpsc, Arc, LazyLock, Mutex,
},
};
use bitfield_struct::bitfield;
use jni::objects::GlobalRef;
use unicorn_engine::Unicorn;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{
core::CpuContext, memory_map::RAM_START, overlapping, range_of_field, subtract_range, unsync_cell::UnsyncCell,
unsync_read,
};
#[derive(Default)]
pub enum Component {
#[default]
Empty,
Populated {
own_index: usize,
java_component: GlobalRef,
read_transfer_active: AtomicBool,
write_transfer_active: AtomicBool,
info: ComponentInfo,
interface: UnsyncCell<ComponentInterface>,
},
}
#[derive(Clone, Copy, Default, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C)]
pub struct ComponentInterface {
// read only
pub info: ComponentInfo,
// read-write
control: ComponentControl,
_restart_device: u8,
_reserved: [u8; 6],
read_dma: ComponentDma,
write_dma: ComponentDma,
}
#[bitfield(u8)]
#[derive(FromBytes, IntoBytes, Immutable, KnownLayout)]
pub struct ComponentControl {
interrupt_when_added: bool,
interrupt_when_removed: bool,
#[bits(2)]
_reserved: u8,
#[bits(4)]
interrupt_firing_core: u8,
}
#[derive(Clone, Copy, Default, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C)]
pub struct ComponentDma {
pub upper_word: ComponentDmaUpper,
pub address: u64,
}
impl Deref for ComponentDma {
type Target = ComponentDmaUpper;
fn deref(&self) -> &Self::Target {
&self.upper_word
}
}
impl DerefMut for ComponentDma {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.upper_word
}
}
#[bitfield(u64)]
#[derive(FromBytes, IntoBytes, Immutable, KnownLayout)]
pub struct ComponentDmaUpper {
dma_enabled: bool,
#[bits(3)]
_reserved: u8,
/// read-write, indicates the core to fire interrupts on. indicating an invalid core means no core will receive the interrupt
#[bits(4)]
interrupt_firing_core: u8,
#[bits(56)]
size: u64,
}
#[derive(Clone, Copy, FromBytes, IntoBytes, Immutable, KnownLayout)]
#[repr(C)]
pub struct ComponentInfo {
/// a null terminated string, the type name of the component
pub type_name: [u8; 256],
/// a null terminated string, the protocol identifier for how to talk to the component
pub protocol: [u8; 256],
pub bytes_per_tick: u32,
pub version: u32,
}
impl Default for ComponentInfo {
fn default() -> Self {
Self {
type_name: [0; 256],
protocol: [0; 256],
bytes_per_tick: 0,
version: 0,
}
}
}