summary refs log tree commit diff
diff options
context:
space:
mode:
authorZhuocheng Ding <zhuocheng.ding@intel.corp-partner.google.com>2019-12-02 15:50:10 +0800
committerCommit Bot <commit-bot@chromium.org>2019-12-10 05:08:11 +0000
commit7434c0002022541f34a929d9a8e3bfaaf4dfc2d9 (patch)
tree7940edf9b5ce136b845a01b254e9fe5519778e0b
parent0e8c11e3548e48fb5e59f8006dad0d76c549fb35 (diff)
downloadcrosvm-7434c0002022541f34a929d9a8e3bfaaf4dfc2d9.tar
crosvm-7434c0002022541f34a929d9a8e3bfaaf4dfc2d9.tar.gz
crosvm-7434c0002022541f34a929d9a8e3bfaaf4dfc2d9.tar.bz2
crosvm-7434c0002022541f34a929d9a8e3bfaaf4dfc2d9.tar.lz
crosvm-7434c0002022541f34a929d9a8e3bfaaf4dfc2d9.tar.xz
crosvm-7434c0002022541f34a929d9a8e3bfaaf4dfc2d9.tar.zst
crosvm-7434c0002022541f34a929d9a8e3bfaaf4dfc2d9.zip
crosvm: PIT: use full address and avoid conflict
The PIT implementation has the assumption that addresses are I/O port
numbers, so we should use full address mode. i8042 is also changed to
full address mode to avoid the conflict on port 0x61.

BUG=chromium:908689
TEST=None

Change-Id: Ibbb851e3a46ac7fc71576990a1618196de92e33c
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1945794
Commit-Queue: Zhuocheng Ding <zhuocheng.ding@intel.corp-partner.google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
-rw-r--r--devices/src/i8042.rs9
-rw-r--r--x86_64/src/lib.rs20
2 files changed, 12 insertions, 17 deletions
diff --git a/devices/src/i8042.rs b/devices/src/i8042.rs
index 1f8a837..dfedbf2 100644
--- a/devices/src/i8042.rs
+++ b/devices/src/i8042.rs
@@ -19,17 +19,16 @@ impl I8042Device {
 }
 
 // i8042 device is mapped I/O address 0x61. We partially implement two 8-bit
-// registers: port 0x61 (I8042_PORT_B_REG, offset 0 from base of 0x61), and
-// port 0x64 (I8042_COMMAND_REG, offset 3 from base of 0x61).
+// 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, offset: u64, data: &mut [u8]) {
-        if data.len() == 1 && offset == 3 {
+        if data.len() == 1 && offset == 0x64 {
             data[0] = 0x0;
-        } else if data.len() == 1 && offset == 0 {
+        } else if data.len() == 1 && offset == 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;
@@ -37,7 +36,7 @@ impl BusDevice for I8042Device {
     }
 
     fn write(&mut self, offset: u64, data: &[u8]) {
-        if data.len() == 1 && data[0] == 0xfe && offset == 3 {
+        if data.len() == 1 && data[0] == 0xfe && offset == 0x64 {
             if let Err(e) = self.reset_evt.write(1) {
                 error!("failed to trigger i8042 reset event: {}", e);
             }
diff --git a/x86_64/src/lib.rs b/x86_64/src/lib.rs
index 172a504..bb5b675 100644
--- a/x86_64/src/lib.rs
+++ b/x86_64/src/lib.rs
@@ -653,18 +653,12 @@ impl X8664arch {
                 false,
             )
             .unwrap();
-        io_bus
-            .insert(
-                Arc::new(Mutex::new(devices::I8042Device::new(
-                    exit_evt.try_clone().map_err(Error::CloneEventFd)?,
-                ))),
-                0x061,
-                0x4,
-                false,
-            )
-            .unwrap();
 
         let nul_device = Arc::new(Mutex::new(NoDevice));
+        let i8042 = Arc::new(Mutex::new(devices::I8042Device::new(
+            exit_evt.try_clone().map_err(Error::CloneEventFd)?,
+        )));
+
         if split_irqchip {
             let pit_evt = EventFd::new().map_err(Error::CreateEventFd)?;
             let pit = Arc::new(Mutex::new(
@@ -674,14 +668,16 @@ impl X8664arch {
                 )
                 .map_err(Error::CreatePitDevice)?,
             ));
-            // Reserve from 0x40 to 0x61 (the speaker).
-            io_bus.insert(pit.clone(), 0x040, 0x22, false).unwrap();
+            io_bus.insert(pit.clone(), 0x040, 0x8, true).unwrap();
+            io_bus.insert(pit.clone(), 0x061, 0x1, true).unwrap();
+            io_bus.insert(i8042, 0x062, 0x3, true).unwrap();
             vm.register_irqfd(&pit_evt, 0)
                 .map_err(Error::RegisterIrqfd)?;
         } else {
             io_bus
                 .insert(nul_device.clone(), 0x040, 0x8, false)
                 .unwrap(); // ignore pit
+            io_bus.insert(i8042, 0x061, 0x4, true).unwrap();
         }
 
         io_bus