Skip to main content

Cpu

Struct Cpu 

Source
pub struct Cpu { /* private fields */ }

Implementations§

Source§

impl Cpu

Source

pub fn new() -> Cpu

Examples found in repository?
examples/run.rs (line 9)
8fn main() {
9    let mut cpu = Cpu::new();
10
11    // Override the disk content so task B prints something custom.
12    cpu.set_disk_text("hello, aarch64-sim!\n");
13
14    let _retired = cpu.run(4000);
15
16    println!("system steps: {}", cpu.system_steps());
17    println!("timer ticks:  {}", cpu.timer_ticks());
18    println!("atomic ctr:   {}", cpu.atomic_counter());
19
20    let aic = cpu.aic_state();
21    println!("AIC acks:     {}", aic.total_acks);
22    println!("IPIs sent:    {}", aic.total_ipis);
23
24    println!("UART output:  {:?}", cpu.output());
25
26    for c in cpu.state() {
27        println!(
28            "core {}  {}  pc={:#010x}  el={}  wfi={}",
29            c.id, c.kind, c.pc, c.current_el, c.wfi_halted,
30        );
31    }
32}
Source

pub fn reset(&mut self)

Source

pub fn step(&mut self) -> bool

Step every core once. On the way in: bump system_steps; if the timer is due, broadcast IRQ_TIMER to all cores via AIC. Each core then either takes a pending IRQ (when DAIF.I is clear) or executes one instruction.

Source

pub fn step_core(&mut self, idx: u32) -> bool

Step a single core. Honours pending IRQs on that core (set either by the system timer in step() or by another core via IPI MMIO).

Source

pub fn run(&mut self, max: u32) -> u32

Examples found in repository?
examples/run.rs (line 14)
8fn main() {
9    let mut cpu = Cpu::new();
10
11    // Override the disk content so task B prints something custom.
12    cpu.set_disk_text("hello, aarch64-sim!\n");
13
14    let _retired = cpu.run(4000);
15
16    println!("system steps: {}", cpu.system_steps());
17    println!("timer ticks:  {}", cpu.timer_ticks());
18    println!("atomic ctr:   {}", cpu.atomic_counter());
19
20    let aic = cpu.aic_state();
21    println!("AIC acks:     {}", aic.total_acks);
22    println!("IPIs sent:    {}", aic.total_ipis);
23
24    println!("UART output:  {:?}", cpu.output());
25
26    for c in cpu.state() {
27        println!(
28            "core {}  {}  pc={:#010x}  el={}  wfi={}",
29            c.id, c.kind, c.pc, c.current_el, c.wfi_halted,
30        );
31    }
32}
Source

pub fn system_steps(&self) -> u64

Examples found in repository?
examples/run.rs (line 16)
8fn main() {
9    let mut cpu = Cpu::new();
10
11    // Override the disk content so task B prints something custom.
12    cpu.set_disk_text("hello, aarch64-sim!\n");
13
14    let _retired = cpu.run(4000);
15
16    println!("system steps: {}", cpu.system_steps());
17    println!("timer ticks:  {}", cpu.timer_ticks());
18    println!("atomic ctr:   {}", cpu.atomic_counter());
19
20    let aic = cpu.aic_state();
21    println!("AIC acks:     {}", aic.total_acks);
22    println!("IPIs sent:    {}", aic.total_ipis);
23
24    println!("UART output:  {:?}", cpu.output());
25
26    for c in cpu.state() {
27        println!(
28            "core {}  {}  pc={:#010x}  el={}  wfi={}",
29            c.id, c.kind, c.pc, c.current_el, c.wfi_halted,
30        );
31    }
32}
Source

pub fn timer_period(&self) -> u64

Source

pub fn timer_remaining(&self) -> u64

System steps until the next timer IRQ fires (0 if it’s due now).

Source

pub fn timer_ticks(&self) -> u64

Examples found in repository?
examples/run.rs (line 17)
8fn main() {
9    let mut cpu = Cpu::new();
10
11    // Override the disk content so task B prints something custom.
12    cpu.set_disk_text("hello, aarch64-sim!\n");
13
14    let _retired = cpu.run(4000);
15
16    println!("system steps: {}", cpu.system_steps());
17    println!("timer ticks:  {}", cpu.timer_ticks());
18    println!("atomic ctr:   {}", cpu.atomic_counter());
19
20    let aic = cpu.aic_state();
21    println!("AIC acks:     {}", aic.total_acks);
22    println!("IPIs sent:    {}", aic.total_ipis);
23
24    println!("UART output:  {:?}", cpu.output());
25
26    for c in cpu.state() {
27        println!(
28            "core {}  {}  pc={:#010x}  el={}  wfi={}",
29            c.id, c.kind, c.pc, c.current_el, c.wfi_halted,
30        );
31    }
32}
Source

pub fn aic_state(&self) -> AicState

Examples found in repository?
examples/run.rs (line 20)
8fn main() {
9    let mut cpu = Cpu::new();
10
11    // Override the disk content so task B prints something custom.
12    cpu.set_disk_text("hello, aarch64-sim!\n");
13
14    let _retired = cpu.run(4000);
15
16    println!("system steps: {}", cpu.system_steps());
17    println!("timer ticks:  {}", cpu.timer_ticks());
18    println!("atomic ctr:   {}", cpu.atomic_counter());
19
20    let aic = cpu.aic_state();
21    println!("AIC acks:     {}", aic.total_acks);
22    println!("IPIs sent:    {}", aic.total_ipis);
23
24    println!("UART output:  {:?}", cpu.output());
25
26    for c in cpu.state() {
27        println!(
28            "core {}  {}  pc={:#010x}  el={}  wfi={}",
29            c.id, c.kind, c.pc, c.current_el, c.wfi_halted,
30        );
31    }
32}
Source

pub fn block_state(&self) -> BlockState

Source

pub fn set_disk_text(&mut self, text: &str)

Replace disk sector 0 with the given UTF-8 text (padded with zeros to SECTOR_SIZE bytes). Also patches the live disk-buffer page at PA 0x6000 so task B’s printer reflects the change without a reset.

Examples found in repository?
examples/run.rs (line 12)
8fn main() {
9    let mut cpu = Cpu::new();
10
11    // Override the disk content so task B prints something custom.
12    cpu.set_disk_text("hello, aarch64-sim!\n");
13
14    let _retired = cpu.run(4000);
15
16    println!("system steps: {}", cpu.system_steps());
17    println!("timer ticks:  {}", cpu.timer_ticks());
18    println!("atomic ctr:   {}", cpu.atomic_counter());
19
20    let aic = cpu.aic_state();
21    println!("AIC acks:     {}", aic.total_acks);
22    println!("IPIs sent:    {}", aic.total_ipis);
23
24    println!("UART output:  {:?}", cpu.output());
25
26    for c in cpu.state() {
27        println!(
28            "core {}  {}  pc={:#010x}  el={}  wfi={}",
29            c.id, c.kind, c.pc, c.current_el, c.wfi_halted,
30        );
31    }
32}
Source

pub fn disk_text(&self) -> String

Source

pub fn state(&self) -> Vec<CoreState>

Returns one CoreState per core.

Examples found in repository?
examples/run.rs (line 26)
8fn main() {
9    let mut cpu = Cpu::new();
10
11    // Override the disk content so task B prints something custom.
12    cpu.set_disk_text("hello, aarch64-sim!\n");
13
14    let _retired = cpu.run(4000);
15
16    println!("system steps: {}", cpu.system_steps());
17    println!("timer ticks:  {}", cpu.timer_ticks());
18    println!("atomic ctr:   {}", cpu.atomic_counter());
19
20    let aic = cpu.aic_state();
21    println!("AIC acks:     {}", aic.total_acks);
22    println!("IPIs sent:    {}", aic.total_ipis);
23
24    println!("UART output:  {:?}", cpu.output());
25
26    for c in cpu.state() {
27        println!(
28            "core {}  {}  pc={:#010x}  el={}  wfi={}",
29            c.id, c.kind, c.pc, c.current_el, c.wfi_halted,
30        );
31    }
32}
Source

pub fn mem_slice(&self, start: u32, len: u32) -> Vec<u8>

Source

pub fn output(&self) -> String

Examples found in repository?
examples/run.rs (line 24)
8fn main() {
9    let mut cpu = Cpu::new();
10
11    // Override the disk content so task B prints something custom.
12    cpu.set_disk_text("hello, aarch64-sim!\n");
13
14    let _retired = cpu.run(4000);
15
16    println!("system steps: {}", cpu.system_steps());
17    println!("timer ticks:  {}", cpu.timer_ticks());
18    println!("atomic ctr:   {}", cpu.atomic_counter());
19
20    let aic = cpu.aic_state();
21    println!("AIC acks:     {}", aic.total_acks);
22    println!("IPIs sent:    {}", aic.total_ipis);
23
24    println!("UART output:  {:?}", cpu.output());
25
26    for c in cpu.state() {
27        println!(
28            "core {}  {}  pc={:#010x}  el={}  wfi={}",
29            c.id, c.kind, c.pc, c.current_el, c.wfi_halted,
30        );
31    }
32}
Source

pub fn translate(&self, va: u64, core_idx: u32) -> Option<TranslationResult>

Walk page tables for va using the sysregs of core_idx. Returns None if core_idx is out of range.

Source

pub fn entry_pc(&self) -> u64

Source

pub fn uart_addr(&self) -> u64

Source

pub fn l1_table_pa(&self) -> u64

Source

pub fn num_cores(&self) -> u32

Source

pub fn atomic_counter(&self) -> u64

Reads the shared u64 atomic counter at PA 0x6FF8 — task A’s LDXR/STXR loop bumps it once per scheduling round.

Examples found in repository?
examples/run.rs (line 18)
8fn main() {
9    let mut cpu = Cpu::new();
10
11    // Override the disk content so task B prints something custom.
12    cpu.set_disk_text("hello, aarch64-sim!\n");
13
14    let _retired = cpu.run(4000);
15
16    println!("system steps: {}", cpu.system_steps());
17    println!("timer ticks:  {}", cpu.timer_ticks());
18    println!("atomic ctr:   {}", cpu.atomic_counter());
19
20    let aic = cpu.aic_state();
21    println!("AIC acks:     {}", aic.total_acks);
22    println!("IPIs sent:    {}", aic.total_ipis);
23
24    println!("UART output:  {:?}", cpu.output());
25
26    for c in cpu.state() {
27        println!(
28            "core {}  {}  pc={:#010x}  el={}  wfi={}",
29            c.id, c.kind, c.pc, c.current_el, c.wfi_halted,
30        );
31    }
32}

Trait Implementations§

Source§

impl Default for Cpu

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl Freeze for Cpu

§

impl RefUnwindSafe for Cpu

§

impl Send for Cpu

§

impl Sync for Cpu

§

impl Unpin for Cpu

§

impl UnsafeUnpin for Cpu

§

impl UnwindSafe for Cpu

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.