reg.rs30.95%
1
// Copyright 2024 Google LLC2
// Copyright © 2019 Intel Corporation3
//4
// Licensed under the Apache License, Version 2.0 (the "License");5
// you may not use this file except in compliance with the License.6
// You may obtain a copy of the License at7
//8
// https://www.apache.org/licenses/LICENSE-2.09
//10
// Unless required by applicable law or agreed to in writing, software11
// distributed under the License is distributed on an "AS IS" BASIS,12
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13
// See the License for the specific language governing permissions and14
// limitations under the License.15
16
use std::time::Instant;17
18
use crate::firmware::acpi::bindings::FadtSleepControlReg;19
use crate::mem::Result;20
use crate::mem::emulated::{Action, Mmio};21
22
pub const FADT_RESET_VAL: u8 = b'r';23
24
#[derive(Debug)]25
pub struct FadtReset;26
27
impl Mmio for FadtReset {28
fn size(&self) -> u64 {29
130
}31
32
fn read(&self, _offset: u64, _size: u8) -> Result<u64> {33
Ok(0)34
}35
36
fn write(&self, _offset: u64, _size: u8, val: u64) -> Result<Action> {37
if val as u8 == FADT_RESET_VAL {38
Ok(Action::Reset)39
} else {40
Ok(Action::None)41
}42
}43
}44
45
#[derive(Debug)]46
pub struct FadtSleepControl;47
48
impl Mmio for FadtSleepControl {49
fn size(&self) -> u64 {50
151
}52
53
fn read(&self, _offset: u64, _size: u8) -> Result<u64> {54
Ok(0)55
}56
57
fn write(&self, _offset: u64, _size: u8, val: u64) -> Result<Action> {58
let val = FadtSleepControlReg(val as u8);59
if val.slp_en() && val.sle_typx() == 5 {60
Ok(Action::Shutdown)61
} else {62
Ok(Action::None)63
}64
}65
}66
67
// The following AcpiPmTimer implementation is derived from Cloud Hypervisor.68
// Copyright © 2019 Intel Corporation69
70
/// Power Management Timer71
///72
/// ACPI v6.5, Sec. 4.8.2.173
#[derive(Debug)]74
pub struct AcpiPmTimer {75
start: Instant,76
}77
78
const PM_TIMER_FREQUENCY_HZ: u128 = 3_579_545;79
80
impl AcpiPmTimer {81
pub fn new() -> Self {1x82
Self {1x83
start: Instant::now(),1x84
}1x85
}1x86
}87
88
impl Default for AcpiPmTimer {89
fn default() -> Self {1x90
Self::new()1x91
}1x92
}93
94
impl Mmio for AcpiPmTimer {95
fn read(&self, _offset: u64, _size: u8) -> Result<u64> {2x96
let nanos = Instant::now().duration_since(self.start).as_nanos();2x97
let counter = nanos * PM_TIMER_FREQUENCY_HZ / 1_000_000_000;2x98
Ok(counter as u32 as u64)2x99
}2x100
101
fn write(&self, _offset: u64, _size: u8, _val: u64) -> Result<Action> {102
Ok(Action::None)103
}104
105
fn size(&self) -> u64 {106
4107
}108
}109
110
#[cfg(test)]111
#[path = "reg_test.rs"]112
mod tests;113