mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-06 10:32:10 +00:00
Offset right now means the offset from base address that the device was accessed at. And address is the absolute address of the device's access in its address space. The port 0x61 and 0x64 is the absolute port number. BUG=None TEST=boot VM and run reboot command Change-Id: I51ee90e51b559254cf76f2bec4d174294961fe1c Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2648858 Reviewed-by: Colin Downs-Razouk <colindr@google.com> Reviewed-by: Alistair Delva <adelva@google.com> Reviewed-by: Dylan Reid <dgreid@chromium.org> Tested-by: Alistair Delva <adelva@google.com> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Dylan Reid <dgreid@chromium.org>
45 lines
1.5 KiB
Rust
45 lines
1.5 KiB
Rust
// Copyright 2017 The Chromium OS Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
use base::{error, Event};
|
|
|
|
use crate::{BusAccessInfo, BusDevice};
|
|
|
|
/// A i8042 PS/2 controller that emulates just enough to shutdown the machine.
|
|
pub struct I8042Device {
|
|
reset_evt: Event,
|
|
}
|
|
|
|
impl I8042Device {
|
|
/// Constructs a i8042 device that will signal the given event when the guest requests it.
|
|
pub fn new(reset_evt: Event) -> I8042Device {
|
|
I8042Device { reset_evt }
|
|
}
|
|
}
|
|
|
|
// i8042 device is mapped I/O address 0x61. We partially implement two 8-bit
|
|
// registers: port 0x61 (I8042_PORT_B_REG), and port 0x64 (I8042_COMMAND_REG).
|
|
impl BusDevice for I8042Device {
|
|
fn debug_label(&self) -> String {
|
|
"i8042".to_owned()
|
|
}
|
|
|
|
fn read(&mut self, info: BusAccessInfo, data: &mut [u8]) {
|
|
if data.len() == 1 && info.address == 0x64 {
|
|
data[0] = 0x0;
|
|
} else if data.len() == 1 && info.address == 0x61 {
|
|
// Like kvmtool, we return bit 5 set in I8042_PORT_B_REG to
|
|
// avoid hang in pit_calibrate_tsc() in Linux kernel.
|
|
data[0] = 0x20;
|
|
}
|
|
}
|
|
|
|
fn write(&mut self, info: BusAccessInfo, data: &[u8]) {
|
|
if data.len() == 1 && data[0] == 0xfe && info.address == 0x64 {
|
|
if let Err(e) = self.reset_evt.write(1) {
|
|
error!("failed to trigger i8042 reset event: {}", e);
|
|
}
|
|
}
|
|
}
|
|
}
|