panda/plugins/cosi/
osi_statics.rs1use std::ops::Deref;
2
3use crate::guest_ptr::GuestReadFail;
4use crate::prelude::*;
5use crate::GuestType;
6
7use super::{find_per_cpu_address, symbol_addr_from_name};
8
9pub trait OsiType: Sized {
13 type MethodDispatcher;
14
15 fn osi_read(cpu: &mut CPUState, base_ptr: target_ptr_t) -> Result<Self, GuestReadFail>;
17}
18
19#[doc(hidden)]
20pub struct EmptyMethodDelegator(&'static str, bool);
21
22impl EmptyMethodDelegator {
23 pub const fn new(_: &'static str, _: bool) -> Self {
24 Self("", false)
25 }
26}
27
28impl<T: GuestType> OsiType for T {
31 type MethodDispatcher = EmptyMethodDelegator;
32
33 fn osi_read(cpu: &mut CPUState, base_ptr: target_ptr_t) -> Result<Self, GuestReadFail> {
34 T::read_from_guest(cpu, base_ptr)
35 }
36}
37
38#[doc(hidden)]
41pub struct PerCpu<T: OsiType>(pub &'static str, pub T::MethodDispatcher);
42
43impl<T: OsiType> PerCpu<T> {
44 pub fn read(&self, cpu: &mut CPUState) -> Result<T, GuestReadFail> {
45 let ptr = find_per_cpu_address(cpu, self.0)?;
46
47 T::osi_read(cpu, ptr)
48 }
49}
50
51impl<T: OsiType> Deref for PerCpu<T> {
52 type Target = T::MethodDispatcher;
53
54 fn deref(&self) -> &Self::Target {
55 &self.1
56 }
57}
58
59#[doc(hidden)]
62pub struct OsiGlobal<T: OsiType>(pub &'static str, pub T::MethodDispatcher);
63
64impl<T: OsiType> OsiGlobal<T> {
65 pub fn read(&self, cpu: &mut CPUState) -> Result<T, GuestReadFail> {
66 let ptr = symbol_addr_from_name(self.0);
67
68 T::osi_read(cpu, ptr)
69 }
70}
71
72impl<T: OsiType> Deref for OsiGlobal<T> {
73 type Target = T::MethodDispatcher;
74
75 fn deref(&self) -> &Self::Target {
76 &self.1
77 }
78}