firmware_uefi/service/
uefi_watchdog.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use crate::UefiDevice;
5use inspect::Inspect;
6use vmcore::vmtime::VmTimeAccess;
7use watchdog_core::WatchdogServices;
8use watchdog_core::platform::WatchdogPlatform;
9
10#[derive(Inspect)]
11pub struct UefiWatchdogServices {
12    pub watchdog: WatchdogServices,
13}
14
15impl UefiWatchdogServices {
16    pub async fn new(
17        vmtime: VmTimeAccess,
18        platform: Box<dyn WatchdogPlatform>,
19        is_restoring: bool,
20    ) -> UefiWatchdogServices {
21        UefiWatchdogServices {
22            watchdog: WatchdogServices::new("uefi-watchdog", vmtime, platform, is_restoring).await,
23        }
24    }
25}
26
27impl UefiDevice {
28    pub(crate) fn handle_watchdog_read(&mut self, reg: watchdog_core::Register) -> u32 {
29        match self.service.uefi_watchdog.watchdog.read(reg) {
30            Ok(val) => val,
31            Err(err) => {
32                tracelimit::warn_ratelimited!(
33                    error = &err as &dyn std::error::Error,
34                    "Error while reading from watchdog device"
35                );
36                !0
37            }
38        }
39    }
40
41    pub(crate) fn handle_watchdog_write(&mut self, reg: watchdog_core::Register, val: u32) {
42        match self.service.uefi_watchdog.watchdog.write(reg, val) {
43            Ok(()) => (),
44            Err(err) => {
45                tracelimit::warn_ratelimited!(
46                    error = &err as &dyn std::error::Error,
47                    "Error while writing to watchdog device"
48                );
49            }
50        }
51    }
52}
53
54mod save_restore {
55    use super::*;
56    use vmcore::save_restore::RestoreError;
57    use vmcore::save_restore::SaveError;
58    use vmcore::save_restore::SaveRestore;
59
60    mod state {
61        use mesh::payload::Protobuf;
62        use vmcore::save_restore::SaveRestore;
63        use vmcore::save_restore::SavedStateRoot;
64
65        #[derive(Protobuf, SavedStateRoot)]
66        #[mesh(package = "firmware.uefi.watchdog")]
67        pub struct SavedState {
68            #[mesh(1)]
69            pub inner: <watchdog_core::WatchdogServices as SaveRestore>::SavedState,
70        }
71    }
72
73    impl SaveRestore for UefiWatchdogServices {
74        type SavedState = state::SavedState;
75
76        fn save(&mut self) -> Result<Self::SavedState, SaveError> {
77            let saved_state = state::SavedState {
78                inner: self.watchdog.save()?,
79            };
80
81            Ok(saved_state)
82        }
83
84        fn restore(&mut self, state: Self::SavedState) -> Result<(), RestoreError> {
85            let state::SavedState { inner } = state;
86            self.watchdog.restore(inner)?;
87            Ok(())
88        }
89    }
90}