Skip to content

Commit

Permalink
Replaces VmmHandler with EventLoopProxy
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon committed Dec 9, 2024
1 parent 348523a commit a695dd6
Show file tree
Hide file tree
Showing 20 changed files with 183 additions and 184 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ find_package(Threads REQUIRED)
# Setup GUI.
add_executable(obliteration WIN32 MACOSX_BUNDLE
main.cpp
main_window.cpp
resources.qrc)
main_window.cpp)

set_target_properties(obliteration PROPERTIES AUTOMOC ON AUTORCC ON)

Expand Down
1 change: 1 addition & 0 deletions gui/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ redb = "2.2.0"
serde = { version = "1.0.209", features = ["derive"] }
thiserror = "2.0.3"
uuid = { version = "1.11.0", features = ["serde", "v4"] }
winit = "0.30.5"

[dependencies.obfw]
git = "https://github.com/obhq/firmware-dumper.git"
Expand Down
2 changes: 0 additions & 2 deletions gui/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ int main(int argc, char *argv[])

QApplication app(argc, argv);

QGuiApplication::setWindowIcon(QIcon(":/resources/obliteration-icon.png"));

// Setup main window.
MainWindow win;

Expand Down
6 changes: 0 additions & 6 deletions gui/resources.qrc

This file was deleted.

Binary file removed gui/resources/obliteration-icon.png
Binary file not shown.
2 changes: 1 addition & 1 deletion gui/src/hv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub trait Cpu {
type Exit<'a>: CpuExit<Cpu = Self>
where
Self: 'a;
type TranslateErr: Error + Send + 'static;
type TranslateErr: Error + Send + Sync + 'static;

fn id(&self) -> usize;

Expand Down
88 changes: 33 additions & 55 deletions gui/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
#![windows_subsystem = "windows"]

use self::data::{DataError, DataMgr};
use self::debug::DebugClient;
use self::graphics::{Graphics, GraphicsError, PhysicalDevice, Screen};
use self::profile::Profile;
use self::setup::{run_setup, SetupError};
use self::ui::{ErrorWindow, MainWindow, ProfileModel, ResolutionModel};
use self::vmm::{Vmm, VmmError};
use self::vmm::{Vmm, VmmArgs, VmmError, VmmEvent};
use clap::{Parser, ValueEnum};
use debug::DebugServer;
use gdbstub::stub::MultiThreadStopReason;
use obconf::ConsoleType;
use slint::{ComponentHandle, ModelRc, SharedString, VecModel};
use std::cell::Cell;
use std::error::Error;
Expand All @@ -20,6 +17,8 @@ use std::process::ExitCode;
use std::rc::Rc;
use std::sync::Arc;
use thiserror::Error;
use winit::error::EventLoopError;
use winit::event_loop::EventLoop;

mod data;
mod debug;
Expand All @@ -39,7 +38,7 @@ fn main() -> ExitCode {
use std::fmt::Write;

// Check program mode.
let args = CliArgs::parse();
let args = ProgramArgs::parse();
let r = match &args.mode {
Some(ProgramMode::PanicHandler) => self::panic::run_handler(),
None => run_vmm(&args),
Expand Down Expand Up @@ -75,23 +74,23 @@ fn main() -> ExitCode {
ExitCode::FAILURE
}

fn run_vmm(args: &CliArgs) -> Result<(), ApplicationError> {
fn run_vmm(args: &ProgramArgs) -> Result<(), ProgramError> {
// Spawn panic handler.
let exe = std::env::current_exe()
.and_then(std::fs::canonicalize)
.map_err(ApplicationError::GetCurrentExePath)?;
.map_err(ProgramError::GetCurrentExePath)?;

self::panic::spawn_handler(&exe)?;

#[cfg(unix)]
rlim::set_rlimit_nofile().map_err(ApplicationError::FdLimit)?;
rlim::set_rlimit_nofile().map_err(ProgramError::FdLimit)?;

// Initialize graphics engine.
let mut graphics = graphics::new().map_err(ApplicationError::InitGraphics)?;
let mut graphics = graphics::new().map_err(ProgramError::InitGraphics)?;

// Run setup wizard. This will simply return the data manager if the user already has required
// settings.
let data = match run_setup().map_err(ApplicationError::Setup)? {
let data = match run_setup().map_err(ProgramError::Setup)? {
Some(v) => Arc::new(v),
None => return Ok(()),
};
Expand Down Expand Up @@ -123,9 +122,9 @@ fn run_vmm(args: &CliArgs) -> Result<(), ApplicationError> {
// Load profiles.
let mut profiles = Vec::new();

for l in data.prof().list().map_err(ApplicationError::ListProfile)? {
let l = l.map_err(ApplicationError::ListProfile)?;
let p = Profile::load(&l).map_err(ApplicationError::LoadProfile)?;
for l in data.prof().list().map_err(ProgramError::ListProfile)? {
let l = l.map_err(ProgramError::ListProfile)?;
let p = Profile::load(&l).map_err(ProgramError::LoadProfile)?;

profiles.push(p);
}
Expand All @@ -137,11 +136,11 @@ fn run_vmm(args: &CliArgs) -> Result<(), ApplicationError> {
let l = data.prof().data(p.id());

if let Err(e) = std::fs::create_dir(&l) {
return Err(ApplicationError::CreateDirectory(l, e));
return Err(ProgramError::CreateDirectory(l, e));
}

// Save.
p.save(&l).map_err(ApplicationError::SaveDefaultProfile)?;
p.save(&l).map_err(ProgramError::SaveDefaultProfile)?;

profiles.push(p);
}
Expand All @@ -165,39 +164,43 @@ fn run_vmm(args: &CliArgs) -> Result<(), ApplicationError> {
// Wait for debugger.
let debugger = if let Some(listen) = debug {
let debug_server =
DebugServer::new(listen).map_err(|e| ApplicationError::StartDebugServer(e, listen))?;
DebugServer::new(listen).map_err(|e| ProgramError::StartDebugServer(e, listen))?;

let debugger = debug_server
.accept()
.map_err(ApplicationError::CreateDebugClient)?;
.map_err(ProgramError::CreateDebugClient)?;

Some(debugger)
} else {
None
};

// Setup VMM screen.
let mut el = EventLoop::<VmmEvent>::with_user_event();

let screen = graphics
.create_screen(&profile)
.map_err(|e| ApplicationError::CreateScreen(Box::new(e)))?;
.map_err(|e| ProgramError::CreateScreen(Box::new(e)))?;

// Start VMM.
let el = el.build().map_err(ProgramError::CreateVmmEventLoop)?;

std::thread::scope(|scope| {
let vmm = Vmm::new(
VmmArgs {
profile: &profile,
kernel,
debugger,
el: el.create_proxy(),
},
VmmHandler {},
scope,
)
.map_err(ApplicationError::StartVmm)?;
.map_err(ProgramError::StartVmm)?;

// Run the screen.
screen
.run()
.map_err(|e| ApplicationError::RunScreen(Box::new(e)))?;
.map_err(|e| ProgramError::RunScreen(Box::new(e)))?;

Ok(())
})
Expand All @@ -207,9 +210,9 @@ fn run_launcher(
graphics: &impl Graphics,
data: &Arc<DataMgr>,
profiles: Vec<Profile>,
) -> Result<Option<(Profile, ExitAction)>, ApplicationError> {
) -> Result<Option<(Profile, ExitAction)>, ProgramError> {
// Create window and register callback handlers.
let win = MainWindow::new().map_err(ApplicationError::CreateMainWindow)?;
let win = MainWindow::new().map_err(ProgramError::CreateMainWindow)?;
let resolutions = Rc::new(ResolutionModel::default());
let profiles = Rc::new(ProfileModel::new(profiles, resolutions.clone()));
let exit = Rc::new(Cell::new(None));
Expand Down Expand Up @@ -293,7 +296,7 @@ fn run_launcher(
profiles.select(row, &win);

// Run the window.
win.run().map_err(ApplicationError::RunMainWindow)?;
win.run().map_err(ProgramError::RunMainWindow)?;

// Update selected profile.
let profile = win.get_selected_profile();
Expand All @@ -318,7 +321,7 @@ fn run_launcher(
/// Program arguments parsed from command line.
#[derive(Parser)]
#[command(about = None)]
struct CliArgs {
struct ProgramArgs {
#[arg(long, value_enum, hide = true)]
mode: Option<ProgramMode>,

Expand All @@ -337,43 +340,15 @@ enum ExitAction {
RunDebug(SocketAddrV4),
}

/// Encapsulates arguments for [`Vmm::new()`].
struct VmmArgs<'a> {
profile: &'a Profile,
kernel: PathBuf,
debugger: Option<DebugClient>,
}

/// Provides method to handle VMM event.
struct VmmHandler {}

impl self::vmm::VmmHandler for VmmHandler {
fn error(&self, cpu: usize, reason: impl Into<Box<dyn Error>>) {
todo!()
}

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

fn log(&self, ty: ConsoleType, msg: &str) {
todo!()
}

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

/// Mode of our program.
#[derive(Clone, ValueEnum)]
enum ProgramMode {
PanicHandler,
}

/// Represents an error when [`run()`] fails.
/// Represents an error when our program fails.
#[derive(Debug, Error)]
enum ApplicationError {
enum ProgramError {
#[error("couldn't spawn panic handler process")]
SpawnPanicHandler(#[source] std::io::Error),

Expand Down Expand Up @@ -420,6 +395,9 @@ enum ApplicationError {
#[error("couldn't create VMM screen")]
CreateScreen(#[source] Box<dyn std::error::Error>),

#[error("couldn't create VMM event loop")]
CreateVmmEventLoop(#[source] EventLoopError),

#[error("couldn't start VMM")]
StartVmm(#[source] VmmError),

Expand Down
10 changes: 5 additions & 5 deletions gui/src/panic/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::ui::ErrorWindow;
use crate::ApplicationError;
use crate::ProgramError;
use serde::{Deserialize, Serialize};
use slint::ComponentHandle;
use std::borrow::Cow;
Expand All @@ -9,13 +9,13 @@ use std::path::Path;
use std::process::{Child, Command, Stdio};
use std::sync::Mutex;

pub fn spawn_handler(exe: &Path) -> Result<(), ApplicationError> {
pub fn spawn_handler(exe: &Path) -> Result<(), ProgramError> {
// Spawn the process in panic handler mode.
let ph = Command::new(exe)
.args(["--mode", "panic-handler"])
.stdin(Stdio::piped())
.spawn()
.map_err(ApplicationError::SpawnPanicHandler)?;
.map_err(ProgramError::SpawnPanicHandler)?;

// Set panic hook to send panic to the handler.
let ph = Mutex::new(Some(PanicHandler(ph)));
Expand All @@ -25,7 +25,7 @@ pub fn spawn_handler(exe: &Path) -> Result<(), ApplicationError> {
Ok(())
}

pub fn run_handler() -> Result<(), ApplicationError> {
pub fn run_handler() -> Result<(), ProgramError> {
use std::io::ErrorKind;

// Wait for panic info.
Expand All @@ -34,7 +34,7 @@ pub fn run_handler() -> Result<(), ApplicationError> {
let info: PanicInfo = match ciborium::from_reader(&mut stdin) {
Ok(v) => v,
Err(ciborium::de::Error::Io(e)) if e.kind() == ErrorKind::UnexpectedEof => return Ok(()),
Err(e) => return Err(ApplicationError::ReadPanicInfo(e)),
Err(e) => return Err(ProgramError::ReadPanicInfo(e)),
};

// Display panic info.
Expand Down
7 changes: 3 additions & 4 deletions gui/src/vmm/cpu/aarch64.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::{CpuManager, GdbError};
use crate::hv::Hypervisor;
use crate::vmm::VmmHandler;
use gdbstub::target::ext::base::BaseOps;
use gdbstub::target::ext::breakpoints::{
Breakpoints, BreakpointsOps, SwBreakpoint, SwBreakpointOps,
Expand All @@ -13,7 +12,7 @@ pub type GdbRegs = gdbstub_arch::aarch64::reg::AArch64CoreRegs;

pub(super) const BREAKPOINT_SIZE: NonZero<usize> = unsafe { NonZero::new_unchecked(4) };

impl<'a, 'b, H: Hypervisor, E: VmmHandler> gdbstub::target::Target for CpuManager<'a, 'b, H, E> {
impl<'a, 'b, H: Hypervisor> gdbstub::target::Target for CpuManager<'a, 'b, H> {
type Arch = gdbstub_arch::aarch64::AArch64;
type Error = GdbError;

Expand All @@ -26,13 +25,13 @@ impl<'a, 'b, H: Hypervisor, E: VmmHandler> gdbstub::target::Target for CpuManage
}
}

impl<'a, 'b, H: Hypervisor, E: VmmHandler> Breakpoints for CpuManager<'a, 'b, H, E> {
impl<'a, 'b, H: Hypervisor> Breakpoints for CpuManager<'a, 'b, H> {
fn support_sw_breakpoint(&mut self) -> Option<SwBreakpointOps<'_, Self>> {
Some(self)
}
}

impl<'a, 'b, H: Hypervisor, E: VmmHandler> SwBreakpoint for CpuManager<'a, 'b, H, E> {
impl<'a, 'b, H: Hypervisor> SwBreakpoint for CpuManager<'a, 'b, H> {
fn add_sw_breakpoint(&mut self, addr: u64, kind: usize) -> TargetResult<bool, Self> {
todo!()
}
Expand Down
Loading

0 comments on commit a695dd6

Please sign in to comment.