Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/devices/src/i8042.rs
5392 views
1
// Copyright 2017 The ChromiumOS Authors
2
// Use of this source code is governed by a BSD-style license that can be
3
// found in the LICENSE file.
4
5
use base::error;
6
use base::SendTube;
7
use base::VmEventType;
8
use snapshot::AnySnapshot;
9
use vm_control::DeviceId;
10
use vm_control::PlatformDeviceId;
11
12
use crate::BusAccessInfo;
13
use crate::BusDevice;
14
use crate::Suspendable;
15
16
/// A i8042 PS/2 controller that emulates just enough to shutdown the machine.
17
pub struct I8042Device {
18
reset_evt_wrtube: SendTube,
19
}
20
21
impl I8042Device {
22
/// Constructs a i8042 device that will signal the given event when the guest requests it.
23
pub fn new(reset_evt_wrtube: SendTube) -> I8042Device {
24
I8042Device { reset_evt_wrtube }
25
}
26
}
27
28
// i8042 device is mapped I/O address 0x61. We partially implement two 8-bit
29
// registers: port 0x61 (I8042_PORT_B_REG), and port 0x64 (I8042_COMMAND_REG).
30
impl BusDevice for I8042Device {
31
fn device_id(&self) -> DeviceId {
32
PlatformDeviceId::I8042.into()
33
}
34
35
fn debug_label(&self) -> String {
36
"i8042".to_owned()
37
}
38
39
fn read(&mut self, info: BusAccessInfo, data: &mut [u8]) {
40
if data.len() == 1 && info.address == 0x64 {
41
data[0] = 0x0;
42
} else if data.len() == 1 && info.address == 0x61 {
43
// Like kvmtool, we return bit 5 set in I8042_PORT_B_REG to
44
// avoid hang in pit_calibrate_tsc() in Linux kernel.
45
data[0] = 0x20;
46
}
47
}
48
49
fn write(&mut self, info: BusAccessInfo, data: &[u8]) {
50
if data.len() == 1 && data[0] == 0xfe && info.address == 0x64 {
51
if let Err(e) = self
52
.reset_evt_wrtube
53
.send::<VmEventType>(&VmEventType::Reset)
54
{
55
error!("failed to trigger i8042 reset event: {}", e);
56
}
57
}
58
}
59
}
60
61
impl Suspendable for I8042Device {
62
fn snapshot(&mut self) -> anyhow::Result<AnySnapshot> {
63
AnySnapshot::to_any(())
64
}
65
66
fn restore(&mut self, _data: AnySnapshot) -> anyhow::Result<()> {
67
Ok(())
68
}
69
70
fn sleep(&mut self) -> anyhow::Result<()> {
71
Ok(())
72
}
73
74
fn wake(&mut self) -> anyhow::Result<()> {
75
Ok(())
76
}
77
}
78
79