chipset/i8042/
ps2mouse.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

//! PS/2 mouse. Not currently implemented.

use inspect::Inspect;
use std::collections::VecDeque;

/// Not yet implemented.
#[derive(Inspect)]
pub struct Ps2Mouse {
    #[inspect(bytes)]
    output_buffer: VecDeque<u8>,
}

impl Ps2Mouse {
    pub fn new() -> Self {
        Self {
            output_buffer: VecDeque::new(),
        }
    }

    pub fn reset(&mut self) {
        *self = Self::new();
    }

    pub fn output(&mut self) -> Option<u8> {
        self.output_buffer.pop_front()
    }

    pub fn input(&mut self, data: u8) {
        tracing::trace!(data, "mouse command");

        // RESET
        if data == 0xFF {
            self.output_buffer.push_back(0xFA); // ACKNOWLEDGE
            self.output_buffer.push_back(0xAA); // COMPLETE
            self.output_buffer.push_back(0); // IDENTITY
        } else {
            tracing::debug!(?data, "unimplemented mouse command");
            self.output_buffer.push_back(0xFA); // ACKNOWLEDGE
        }
    }
}

mod save_restore {
    use super::*;
    use vmcore::save_restore::RestoreError;
    use vmcore::save_restore::SaveError;
    use vmcore::save_restore::SaveRestore;

    mod state {
        use mesh::payload::Protobuf;
        use vmcore::save_restore::SavedStateRoot;

        #[derive(Protobuf, SavedStateRoot)]
        #[mesh(package = "chipset.i8042.mouse")]
        pub struct SavedState {
            #[mesh(1)]
            pub output_buffer: Vec<u8>,
        }
    }

    impl SaveRestore for Ps2Mouse {
        type SavedState = state::SavedState;

        fn save(&mut self) -> Result<Self::SavedState, SaveError> {
            let Self { output_buffer } = self;

            let saved_state = state::SavedState {
                output_buffer: output_buffer.iter().copied().collect(),
            };

            Ok(saved_state)
        }

        fn restore(&mut self, state: Self::SavedState) -> Result<(), RestoreError> {
            let state::SavedState { output_buffer } = state;

            *self = Self {
                output_buffer: output_buffer.into(),
            };

            Ok(())
        }
    }
}