1 // Copyright © 2023 Cyberus Technology 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 // 5 6 //! Module for [`DebugconState`]. 7 8 use std::io; 9 use std::io::Write; 10 use std::sync::{Arc, Barrier}; 11 12 use vm_device::BusDevice; 13 use vm_migration::{Migratable, MigratableError, Pausable, Snapshot, Snapshottable, Transportable}; 14 15 /// I/O-port. 16 pub const DEFAULT_PORT: u64 = 0xe9; 17 18 #[derive(Default)] 19 pub struct DebugconState {} 20 21 /// Emulates a debug console similar to the QEMU debugcon device. This device 22 /// is stateless and only prints the bytes (usually text) that are written to 23 /// it. 24 /// 25 /// This device is only available on x86. 26 /// 27 /// Reference: 28 /// - https://github.com/qemu/qemu/blob/master/hw/char/debugcon.c 29 /// - https://phip1611.de/blog/how-to-use-qemus-debugcon-feature-and-write-to-a-file/ 30 pub struct DebugConsole { 31 id: String, 32 out: Box<dyn io::Write + Send>, 33 } 34 35 impl DebugConsole { new(id: String, out: Box<dyn io::Write + Send>) -> Self36 pub fn new(id: String, out: Box<dyn io::Write + Send>) -> Self { 37 Self { id, out } 38 } 39 } 40 41 impl BusDevice for DebugConsole { read(&mut self, _base: u64, _offset: u64, _data: &mut [u8])42 fn read(&mut self, _base: u64, _offset: u64, _data: &mut [u8]) {} 43 write(&mut self, _base: u64, _offset: u64, data: &[u8]) -> Option<Arc<Barrier>>44 fn write(&mut self, _base: u64, _offset: u64, data: &[u8]) -> Option<Arc<Barrier>> { 45 if let Err(e) = self.out.write_all(data) { 46 // unlikely 47 error!("debug-console: failed writing data: {e:?}"); 48 } 49 None 50 } 51 } 52 53 impl Snapshottable for DebugConsole { id(&self) -> String54 fn id(&self) -> String { 55 self.id.clone() 56 } 57 snapshot(&mut self) -> Result<Snapshot, MigratableError>58 fn snapshot(&mut self) -> Result<Snapshot, MigratableError> { 59 Snapshot::new_from_state(&()) 60 } 61 } 62 63 impl Pausable for DebugConsole {} 64 impl Transportable for DebugConsole {} 65 impl Migratable for DebugConsole {} 66