From 1d15851b275b72aa08d13ac7bde9dd8464cfeed0 Mon Sep 17 00:00:00 2001 From: Zide Chen Date: Fri, 13 Sep 2019 14:21:05 -0700 Subject: devices: implement msix capability structure The MSI-X feature is ported from Cloud-hypervisor commit 69e27288a2e. (https://github.com/intel/cloud-hypervisor.git) In this commit: - add a new "msix" module to the pci crate. - implement the MSI-X Capability Structure. - implement per virtio device msix_vectors() function which represents the supported MSI-X vector for this device. BUG=chromium:854765 TEST=launch Crosvm on eve and Linux TEST=cargo test -p devices TEST=./bin/clippy TEST=./build_test.py --x86_64-sysroot /build/eve Change-Id: I5498b15a3bf115e34764e6610407b3ba204dae7f Signed-off-by: Sebastien Boeuf Signed-off-by: Zide Chen Signed-off-by: Sainath Grandhi Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1873356 Reviewed-by: Daniel Verkamp Tested-by: kokoro Commit-Queue: Stephen Barber --- devices/src/pci/msix.rs | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 devices/src/pci/msix.rs (limited to 'devices/src/pci/msix.rs') diff --git a/devices/src/pci/msix.rs b/devices/src/pci/msix.rs new file mode 100644 index 0000000..55e71ba --- /dev/null +++ b/devices/src/pci/msix.rs @@ -0,0 +1,69 @@ +// Copyright 2019 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 crate::pci::{PciCapability, PciCapabilityID}; + +use data_model::DataInit; + +const MAX_MSIX_VECTORS_PER_DEVICE: u16 = 2048; + +// It is safe to implement DataInit; all members are simple numbers and any value is valid. +unsafe impl DataInit for MsixCap {} + +#[allow(dead_code)] +#[repr(C)] +#[derive(Clone, Copy, Default)] +/// MSI-X Capability Structure +pub struct MsixCap { + // To make add_capability() happy + _cap_vndr: u8, + _cap_next: u8, + // Message Control Register + // 10-0: MSI-X Table size + // 13-11: Reserved + // 14: Mask. Mask all MSI-X when set. + // 15: Enable. Enable all MSI-X when set. + msg_ctl: u16, + // Table. Contains the offset and the BAR indicator (BIR) + // 2-0: Table BAR indicator (BIR). Can be 0 to 5. + // 31-3: Table offset in the BAR pointed by the BIR. + table: u32, + // Pending Bit Array. Contains the offset and the BAR indicator (BIR) + // 2-0: PBA BAR indicator (BIR). Can be 0 to 5. + // 31-3: PBA offset in the BAR pointed by the BIR. + pba: u32, +} + +impl PciCapability for MsixCap { + fn bytes(&self) -> &[u8] { + self.as_slice() + } + + fn id(&self) -> PciCapabilityID { + PciCapabilityID::MSIX + } +} + +impl MsixCap { + pub fn new( + table_pci_bar: u8, + table_size: u16, + table_off: u32, + pba_pci_bar: u8, + pba_off: u32, + ) -> Self { + assert!(table_size < MAX_MSIX_VECTORS_PER_DEVICE); + + // Set the table size and enable MSI-X. + let msg_ctl: u16 = 0x8000u16 + table_size - 1; + + MsixCap { + _cap_vndr: 0, + _cap_next: 0, + msg_ctl, + table: (table_off & 0xffff_fff8u32) | u32::from(table_pci_bar & 0x7u8), + pba: (pba_off & 0xffff_fff8u32) | u32::from(pba_pci_bar & 0x7u8), + } + } +} -- cgit 1.4.1