Skip to content

Commit

Permalink
Revises CPU exit event
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon committed Dec 29, 2024
1 parent 176a593 commit f56df41
Show file tree
Hide file tree
Showing 11 changed files with 176 additions and 217 deletions.
4 changes: 1 addition & 3 deletions gui/src/hv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub trait Hypervisor: Send + Sync + 'static {
fn create_cpu(&self, id: usize) -> Result<Self::Cpu<'_>, Self::CpuErr>;
}

/// Represents a core of the PS4 CPU.
/// Represents a core of the CPU.
///
/// On AArch64 this represent one Processing Element (PE).
pub trait Cpu {
Expand All @@ -54,9 +54,7 @@ pub trait Cpu {
type TranslateErr: Error + Send + Sync + 'static;

fn id(&self) -> usize;

fn states(&mut self) -> Result<Self::States<'_>, Self::GetStatesErr>;

fn translate(&self, vaddr: usize) -> Result<usize, Self::TranslateErr>;
}

Expand Down
13 changes: 6 additions & 7 deletions gui/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use self::ui::{
MainWindow, PlatformExt, ProfileModel, ResolutionModel, RuntimeExt, SlintBackend,
WaitForDebugger,
};
use self::vmm::{Vmm, VmmError};
use self::vmm::{Vmm, VmmError, VmmEvent};
use async_net::{TcpListener, TcpStream};
use clap::{Parser, ValueEnum};
use erdp::ErrorDisplay;
Expand Down Expand Up @@ -275,12 +275,11 @@ async fn run(args: ProgramArgs, exe: PathBuf) -> Result<(), ProgramError> {

// Process VMM event.
if let Some(vmm) = vmm {
let vmm = match vmm {
Some(v) => v,
None => break,
};

todo!()
match vmm {
VmmEvent::Exit(_, _) => todo!(),
VmmEvent::Log(console_type, _) => todo!(),
VmmEvent::Breakpoint(base_stop_reason) => todo!(),
}
}

// Process debugger requests.
Expand Down
9 changes: 0 additions & 9 deletions gui/src/vmm/channel/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use gdbstub::stub::MultiThreadStopReason;
use obconf::ConsoleType;
use std::error::Error;

/// Provides method to send and receive events from the main thread.
pub struct MainStream {}
Expand All @@ -10,21 +9,13 @@ impl MainStream {
Self {}
}

pub fn error(&self, reason: impl Error + Send + Sync + 'static) {
todo!()
}

pub fn log(&self, ty: ConsoleType, msg: impl Into<String>) {
todo!()
}

pub fn breakpoint(&self, stop: Option<MultiThreadStopReason<u64>>) -> BreakpointLock {
todo!()
}

pub fn exit(&self, success: bool) {
todo!()
}
}

/// This struct will prevent the other CPU from entering a debugger dispatch loop.
Expand Down
32 changes: 0 additions & 32 deletions gui/src/vmm/cpu/controller.rs

This file was deleted.

52 changes: 1 addition & 51 deletions gui/src/vmm/cpu/mod.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,12 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pub use self::controller::*;

use super::channel::MainStream;
use super::hw::{DeviceContext, DeviceTree};
use super::hw::DeviceContext;
use crate::hv::Cpu;
use std::collections::BTreeMap;
use std::error::Error;
use std::num::NonZero;
use std::sync::atomic::AtomicBool;
use std::sync::{Arc, Mutex};
use thiserror::Error;

mod controller;
pub mod debug;

/// Encapsulates arguments for a function to run a CPU.
pub struct Args<H> {
pub hv: Arc<H>,
pub main: Arc<MainStream>,
pub devices: Arc<DeviceTree>,
pub breakpoint: Arc<Mutex<()>>,
pub shutdown: Arc<AtomicBool>,
}

/// Contains instantiated device context for a CPU.
pub struct Device<'a, C: Cpu> {
pub context: Box<dyn DeviceContext<C> + 'a>,
Expand All @@ -47,40 +31,6 @@ impl<'a, C: Cpu> Device<'a, C> {
}
}

/// Represents an error when a vCPU fails.
#[derive(Debug, Error)]
pub enum CpuError {
#[error("couldn't create vCPU")]
Create(#[source] Box<dyn Error + Send + Sync>),

#[error("couldn't setup vCPU")]
Setup(#[source] Box<dyn Error + Send + Sync>),

#[error("couldn't run vCPU")]
Run(#[source] Box<dyn Error + Send + Sync>),

#[error("couldn't execute a VM exited event on a {0}")]
DeviceExitHandler(String, #[source] Box<dyn Error + Send + Sync>),

#[error("the vCPU attempt to execute a memory-mapped I/O on a non-mapped address {0:#x}")]
MmioAddr(usize),

#[error("couldn't execute a memory-mapped I/O on a {0}")]
Mmio(String, #[source] Box<dyn Error + Send + Sync>),

#[error("couldn't get vCPU states")]
GetStates(#[source] Box<dyn Error + Send + Sync>),

#[error("couldn't read {0} register")]
ReadReg(&'static str, #[source] Box<dyn Error + Send + Sync>),

#[error("couldn't translate address {0:#x}")]
TranslateAddr(usize, #[source] Box<dyn Error + Send + Sync>),

#[error("couldn't execute a post VM exit on a {0}")]
DevicePostExitHandler(String, #[source] Box<dyn Error + Send + Sync>),
}

/// Implementation of [`gdbstub::target::Target::Error`].
#[derive(Debug, Error)]
pub enum GdbError {
Expand Down
4 changes: 2 additions & 2 deletions gui/src/vmm/hw/console/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl<H: Hypervisor, C: Cpu> DeviceContext<C> for Context<'_, H> {
fn mmio(
&mut self,
exit: &mut <C::Exit<'_> as CpuExit>::Io,
) -> Result<bool, Box<dyn Error + Send + Sync>> {
) -> Result<Option<bool>, Box<dyn Error + Send + Sync>> {
// Check field.
let off = exit.addr() - self.dev.addr;

Expand Down Expand Up @@ -76,7 +76,7 @@ impl<H: Hypervisor, C: Cpu> DeviceContext<C> for Context<'_, H> {
return Err(Box::new(ExecError::UnknownField(off)));
}

Ok(true)
Ok(None)
}
}

Expand Down
10 changes: 5 additions & 5 deletions gui/src/vmm/hw/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,21 +114,21 @@ pub trait Device: Send + Sync {
/// Context for a CPU to execute operations on a virtual device.
pub trait DeviceContext<C: Cpu> {
/// Execute immeditately after the VM exited.
fn exited(&mut self, cpu: &mut C) -> Result<bool, Box<dyn Error + Send + Sync>> {
fn exited(&mut self, cpu: &mut C) -> Result<Option<bool>, Box<dyn Error + Send + Sync>> {
let _ = cpu;
Ok(true)
Ok(None)
}

/// Execute only if the CPU read or write into this device address.
fn mmio(
&mut self,
exit: &mut <C::Exit<'_> as CpuExit>::Io,
) -> Result<bool, Box<dyn Error + Send + Sync>>;
) -> Result<Option<bool>, Box<dyn Error + Send + Sync>>;

/// Always execute after the exited event has been handled (before enter the VM again).
fn post(&mut self, cpu: &mut C) -> Result<bool, Box<dyn Error + Send + Sync>> {
fn post(&mut self, cpu: &mut C) -> Result<Option<bool>, Box<dyn Error + Send + Sync>> {
let _ = cpu;
Ok(true)
Ok(None)
}
}

Expand Down
12 changes: 4 additions & 8 deletions gui/src/vmm/hw/vmm/context.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
use super::Vmm;
use crate::hv::{Cpu, CpuExit, CpuIo};
use crate::vmm::channel::MainStream;
use crate::vmm::hw::{read_u8, DeviceContext, MmioError};
use obconf::{KernelExit, VmmMemory};
use std::error::Error;
Expand All @@ -11,20 +10,19 @@ use thiserror::Error;
/// Implementation of [`DeviceContext`].
pub struct Context<'a> {
dev: &'a Vmm,
main: &'a MainStream,
}

impl<'a> Context<'a> {
pub fn new(dev: &'a Vmm, main: &'a MainStream) -> Self {
Self { dev, main }
pub fn new(dev: &'a Vmm) -> Self {
Self { dev }
}
}

impl<C: Cpu> DeviceContext<C> for Context<'_> {
fn mmio(
&mut self,
exit: &mut <C::Exit<'_> as CpuExit>::Io,
) -> Result<bool, Box<dyn Error + Send + Sync>> {
) -> Result<Option<bool>, Box<dyn Error + Send + Sync>> {
// Check field.
let off = exit.addr() - self.dev.addr;

Expand All @@ -34,9 +32,7 @@ impl<C: Cpu> DeviceContext<C> for Context<'_> {
.try_into()
.map_err(|_| Box::new(ExecError::InvalidExit(exit)))?;

self.main.exit(exit == KernelExit::Success);

Ok(false)
Ok(Some(exit == KernelExit::Success))
} else {
Err(Box::new(ExecError::UnknownField(off)))
}
Expand Down
8 changes: 2 additions & 6 deletions gui/src/vmm/hw/vmm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
use self::context::Context;
use super::{Device, DeviceContext};
use crate::hv::Cpu;
use crate::vmm::channel::MainStream;
use obconf::VmmMemory;
use std::num::NonZero;

Expand All @@ -24,11 +23,8 @@ impl Vmm {
Self { addr, len }
}

pub fn create_context<'a, C: Cpu>(
&'a self,
main: &'a MainStream,
) -> Box<dyn DeviceContext<C> + 'a> {
Box::new(Context::new(self, main))
pub fn create_context<'a, C: Cpu>(&'a self) -> Box<dyn DeviceContext<C> + 'a> {
Box::new(Context::new(self))
}
}

Expand Down
Loading

0 comments on commit f56df41

Please sign in to comment.