mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-11-28 17:44:10 +00:00
devices: pcie: add pcie upstream and downstream port
To support pcie switch, we need to add both pcie upstream and downstream port. This patch adds a new file pcie_switch.rs and add basic implementation for pcie upstream and downstream port. BUG=b:199986018 TEST=./tools/presubmit Change-Id: I7cc40d4fd0f017e06c5a0e8b0e3b68a8df9ee185 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3508737 Commit-Queue: Daniel Verkamp <dverkamp@chromium.org> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
0d8eef2074
commit
61052012a4
1 changed files with 162 additions and 0 deletions
162
devices/src/pci/pcie/pcie_switch.rs
Normal file
162
devices/src/pci/pcie/pcie_switch.rs
Normal file
|
@ -0,0 +1,162 @@
|
|||
// Copyright 2022 The ChromiumOS Authors.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
use crate::pci::pci_configuration::PciCapabilityID;
|
||||
use crate::pci::{PciAddress, PciCapability, PciDeviceError};
|
||||
|
||||
use crate::pci::pcie::pci_bridge::PciBridgeBusRange;
|
||||
use crate::pci::pcie::pcie_device::{PciPmcCap, PcieCap, PcieDevice};
|
||||
use crate::pci::pcie::pcie_port::PciePort;
|
||||
use crate::pci::pcie::*;
|
||||
|
||||
use resources::SystemAllocator;
|
||||
|
||||
const PCIE_UP_DID: u16 = 0x3500;
|
||||
const PCIE_DP_DID: u16 = 0x3510;
|
||||
|
||||
pub struct PcieUpstreamPort {
|
||||
pcie_port: PciePort,
|
||||
}
|
||||
|
||||
impl PcieUpstreamPort {
|
||||
/// Constructs a new PCIE upstream port
|
||||
pub fn new(primary_bus_num: u8, secondary_bus_num: u8) -> Self {
|
||||
PcieUpstreamPort {
|
||||
pcie_port: PciePort::new(
|
||||
PCIE_UP_DID,
|
||||
"PcieUpstreamPort".to_string(),
|
||||
primary_bus_num,
|
||||
secondary_bus_num,
|
||||
false,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_from_host(pcie_host: PcieHostPort) -> Self {
|
||||
PcieUpstreamPort {
|
||||
pcie_port: PciePort::new_from_host(pcie_host, false),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PcieDevice for PcieUpstreamPort {
|
||||
fn get_device_id(&self) -> u16 {
|
||||
self.pcie_port.get_device_id()
|
||||
}
|
||||
|
||||
fn debug_label(&self) -> String {
|
||||
self.pcie_port.debug_label()
|
||||
}
|
||||
|
||||
fn allocate_address(
|
||||
&mut self,
|
||||
resources: &mut SystemAllocator,
|
||||
) -> std::result::Result<PciAddress, PciDeviceError> {
|
||||
self.pcie_port.allocate_address(resources)
|
||||
}
|
||||
|
||||
fn read_config(&self, reg_idx: usize, data: &mut u32) {
|
||||
self.pcie_port.read_config(reg_idx, data);
|
||||
}
|
||||
|
||||
fn write_config(&mut self, reg_idx: usize, offset: u64, data: &[u8]) {
|
||||
self.pcie_port.write_config(reg_idx, offset, data);
|
||||
}
|
||||
|
||||
fn get_caps(&self) -> Vec<Box<dyn PciCapability>> {
|
||||
vec![
|
||||
Box::new(PcieCap::new(PcieDevicePortType::UpstreamPort, false, 0)),
|
||||
Box::new(PciPmcCap::new()),
|
||||
]
|
||||
}
|
||||
|
||||
fn set_capability_reg_idx(&mut self, id: PciCapabilityID, reg_idx: usize) {
|
||||
self.pcie_port.set_capability_reg_idx(id, reg_idx);
|
||||
}
|
||||
|
||||
fn get_bus_range(&self) -> Option<PciBridgeBusRange> {
|
||||
self.pcie_port.get_bus_range()
|
||||
}
|
||||
|
||||
fn hotplug_implemented(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn get_bridge_window_size(&self) -> (u64, u64) {
|
||||
self.pcie_port.get_bridge_window_size()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PcieDownstreamPort {
|
||||
pcie_port: PciePort,
|
||||
}
|
||||
|
||||
impl PcieDownstreamPort {
|
||||
/// Constructs a new PCIE downstream port
|
||||
pub fn new(primary_bus_num: u8, secondary_bus_num: u8) -> Self {
|
||||
PcieDownstreamPort {
|
||||
pcie_port: PciePort::new(
|
||||
PCIE_DP_DID,
|
||||
"PcieDownstreamPort".to_string(),
|
||||
primary_bus_num,
|
||||
secondary_bus_num,
|
||||
false,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_from_host(pcie_host: PcieHostPort) -> Self {
|
||||
PcieDownstreamPort {
|
||||
pcie_port: PciePort::new_from_host(pcie_host, false),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PcieDevice for PcieDownstreamPort {
|
||||
fn get_device_id(&self) -> u16 {
|
||||
self.pcie_port.get_device_id()
|
||||
}
|
||||
|
||||
fn debug_label(&self) -> String {
|
||||
self.pcie_port.debug_label()
|
||||
}
|
||||
|
||||
fn allocate_address(
|
||||
&mut self,
|
||||
resources: &mut SystemAllocator,
|
||||
) -> std::result::Result<PciAddress, PciDeviceError> {
|
||||
self.pcie_port.allocate_address(resources)
|
||||
}
|
||||
|
||||
fn read_config(&self, reg_idx: usize, data: &mut u32) {
|
||||
self.pcie_port.read_config(reg_idx, data);
|
||||
}
|
||||
|
||||
fn write_config(&mut self, reg_idx: usize, offset: u64, data: &[u8]) {
|
||||
self.pcie_port.write_config(reg_idx, offset, data);
|
||||
}
|
||||
|
||||
fn get_caps(&self) -> Vec<Box<dyn PciCapability>> {
|
||||
vec![
|
||||
Box::new(PcieCap::new(PcieDevicePortType::DownstreamPort, false, 0)),
|
||||
Box::new(PciPmcCap::new()),
|
||||
]
|
||||
}
|
||||
|
||||
fn set_capability_reg_idx(&mut self, id: PciCapabilityID, reg_idx: usize) {
|
||||
self.pcie_port.set_capability_reg_idx(id, reg_idx);
|
||||
}
|
||||
|
||||
fn get_bus_range(&self) -> Option<PciBridgeBusRange> {
|
||||
self.pcie_port.get_bus_range()
|
||||
}
|
||||
|
||||
fn hotplug_implemented(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn get_bridge_window_size(&self) -> (u64, u64) {
|
||||
self.pcie_port.get_bridge_window_size()
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue