mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 05:35:20 +00:00
devices: cmos: Implement CMOS based reset
If EFI reset fails on the Linux kernel then it will fallthrough to CMOS reset. Implement this as one of our reset solutions. Fixes: #3912 Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
4529bd8d0e
commit
e0d3efec6e
@ -7,6 +7,7 @@ use std::cmp::min;
|
||||
use std::mem;
|
||||
use std::sync::{Arc, Barrier};
|
||||
use vm_device::BusDevice;
|
||||
use vmm_sys_util::eventfd::EventFd;
|
||||
|
||||
// https://github.com/rust-lang/libc/issues/1848
|
||||
#[cfg_attr(target_env = "musl", allow(deprecated))]
|
||||
@ -21,13 +22,14 @@ const DATA_LEN: usize = 128;
|
||||
pub struct Cmos {
|
||||
index: u8,
|
||||
data: [u8; DATA_LEN],
|
||||
reset_evt: EventFd,
|
||||
}
|
||||
|
||||
impl Cmos {
|
||||
/// Constructs a CMOS/RTC device with initial data.
|
||||
/// `mem_below_4g` is the size of memory in bytes below the 32-bit gap.
|
||||
/// `mem_above_4g` is the size of memory in bytes above the 32-bit gap.
|
||||
pub fn new(mem_below_4g: u64, mem_above_4g: u64) -> Cmos {
|
||||
pub fn new(mem_below_4g: u64, mem_above_4g: u64, reset_evt: EventFd) -> Cmos {
|
||||
let mut data = [0u8; DATA_LEN];
|
||||
|
||||
// Extended memory from 16 MB to 4 GB in units of 64 KB
|
||||
@ -44,7 +46,11 @@ impl Cmos {
|
||||
data[0x5c] = (high_mem >> 8) as u8;
|
||||
data[0x5d] = (high_mem >> 16) as u8;
|
||||
|
||||
Cmos { index: 0, data }
|
||||
Cmos {
|
||||
index: 0,
|
||||
data,
|
||||
reset_evt,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,8 +62,15 @@ impl BusDevice for Cmos {
|
||||
}
|
||||
|
||||
match offset {
|
||||
INDEX_OFFSET => self.index = data[0] & INDEX_MASK,
|
||||
DATA_OFFSET => self.data[self.index as usize] = data[0],
|
||||
INDEX_OFFSET => self.index = data[0],
|
||||
DATA_OFFSET => {
|
||||
if self.index == 0x8f && data[0] == 0 {
|
||||
info!("CMOS reset");
|
||||
self.reset_evt.write(1).unwrap();
|
||||
} else {
|
||||
self.data[(self.index & INDEX_MASK) as usize] = data[0]
|
||||
}
|
||||
}
|
||||
o => warn!("bad write offset on CMOS device: {}", o),
|
||||
};
|
||||
None
|
||||
|
@ -1459,7 +1459,9 @@ impl DeviceManager {
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
fn add_legacy_devices(&mut self, reset_evt: EventFd) -> DeviceManagerResult<()> {
|
||||
// Add a shutdown device (i8042)
|
||||
let i8042 = Arc::new(Mutex::new(devices::legacy::I8042Device::new(reset_evt)));
|
||||
let i8042 = Arc::new(Mutex::new(devices::legacy::I8042Device::new(
|
||||
reset_evt.try_clone().unwrap(),
|
||||
)));
|
||||
|
||||
self.bus_devices
|
||||
.push(Arc::clone(&i8042) as Arc<Mutex<dyn BusDevice>>);
|
||||
@ -1486,6 +1488,7 @@ impl DeviceManager {
|
||||
let cmos = Arc::new(Mutex::new(devices::legacy::Cmos::new(
|
||||
mem_below_4g,
|
||||
mem_above_4g,
|
||||
reset_evt,
|
||||
)));
|
||||
|
||||
self.bus_devices
|
||||
|
Loading…
Reference in New Issue
Block a user