Alioth Code Coverage

reg.rs30.95%

1// Copyright 2024 Google LLC
2// Copyright © 2019 Intel Corporation
3//
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 at
7//
8// https://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// 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 and
14// limitations under the License.
15
16use std::time::Instant;
17
18use crate::firmware::acpi::bindings::FadtSleepControlReg;
19use crate::mem::Result;
20use crate::mem::emulated::{Action, Mmio};
21
22pub const FADT_RESET_VAL: u8 = b'r';
23
24#[derive(Debug)]
25pub struct FadtReset;
26
27impl Mmio for FadtReset {
28 fn size(&self) -> u64 {
29 1
30 }
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)]
46pub struct FadtSleepControl;
47
48impl Mmio for FadtSleepControl {
49 fn size(&self) -> u64 {
50 1
51 }
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 Corporation
69
70/// Power Management Timer
71///
72/// ACPI v6.5, Sec. 4.8.2.1
73#[derive(Debug)]
74pub struct AcpiPmTimer {
75 start: Instant,
76}
77
78const PM_TIMER_FREQUENCY_HZ: u128 = 3_579_545;
79
80impl AcpiPmTimer {
81 pub fn new() -> Self {1x
82 Self {1x
83 start: Instant::now(),1x
84 }1x
85 }1x
86}
87
88impl Default for AcpiPmTimer {
89 fn default() -> Self {1x
90 Self::new()1x
91 }1x
92}
93
94impl Mmio for AcpiPmTimer {
95 fn read(&self, _offset: u64, _size: u8) -> Result<u64> {2x
96 let nanos = Instant::now().duration_since(self.start).as_nanos();2x
97 let counter = nanos * PM_TIMER_FREQUENCY_HZ / 1_000_000_000;2x
98 Ok(counter as u32 as u64)2x
99 }2x
100
101 fn write(&self, _offset: u64, _size: u8, _val: u64) -> Result<Action> {
102 Ok(Action::None)
103 }
104
105 fn size(&self) -> u64 {
106 4
107 }
108}
109
110#[cfg(test)]
111#[path = "reg_test.rs"]
112mod tests;
113