Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/devices/src/pci/pcie/pcie_device.rs
5394 views
1
// Copyright 2021 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 std::sync::Arc;
6
7
use resources::SystemAllocator;
8
use sync::Mutex;
9
use zerocopy::FromBytes;
10
use zerocopy::Immutable;
11
use zerocopy::IntoBytes;
12
use zerocopy::KnownLayout;
13
14
use crate::pci::pci_configuration::PciCapConfig;
15
use crate::pci::pci_configuration::PciCapConfigWriteResult;
16
use crate::pci::pci_configuration::PciCapabilityID;
17
use crate::pci::pcie::pci_bridge::PciBridgeBusRange;
18
use crate::pci::pcie::*;
19
use crate::pci::MsiConfig;
20
use crate::pci::PciAddress;
21
use crate::pci::PciCapability;
22
use crate::pci::PciDeviceError;
23
24
pub trait PcieDevice: Send {
25
fn get_device_id(&self) -> u16;
26
fn debug_label(&self) -> String;
27
fn preferred_address(&self) -> Option<PciAddress> {
28
None
29
}
30
fn allocate_address(
31
&mut self,
32
resources: &mut SystemAllocator,
33
) -> std::result::Result<PciAddress, PciDeviceError>;
34
fn read_config(&self, reg_idx: usize, data: &mut u32);
35
fn write_config(&mut self, reg_idx: usize, offset: u64, data: &[u8]);
36
fn handle_cap_write_result(&mut self, res: Box<dyn PciCapConfigWriteResult>);
37
fn clone_interrupt(&mut self, msi_config: Arc<Mutex<MsiConfig>>);
38
fn get_caps(&self) -> Vec<(Box<dyn PciCapability>, Option<Box<dyn PciCapConfig>>)>;
39
fn get_bus_range(&self) -> Option<PciBridgeBusRange> {
40
None
41
}
42
fn get_removed_devices(&self) -> Vec<PciAddress>;
43
44
/// Hotplug capability is implemented on this bridge or not.
45
/// Return true, the children pci devices could be connected through hotplug
46
/// Return false, the children pci devices should be connected statically
47
fn hotplug_implemented(&self) -> bool;
48
49
/// This function returns true if this pcie device is hotplugged into the system
50
fn hotplugged(&self) -> bool;
51
52
/// Get bridge window size to cover children's mmio size
53
/// (u64, u64) -> (non_prefetchable window size, prefetchable_window_size)
54
fn get_bridge_window_size(&self) -> (u64, u64);
55
}
56
57
#[repr(C)]
58
#[derive(Clone, Copy, FromBytes, Immutable, IntoBytes, KnownLayout)]
59
pub struct PcieCap {
60
_cap_vndr: u8,
61
_cap_next: u8,
62
pcie_cap: u16,
63
dev_cap: u32,
64
dev_control: u16,
65
dev_status: u16,
66
link_cap: u32,
67
link_control: u16,
68
link_status: u16,
69
slot_cap: u32,
70
slot_control: u16,
71
slot_status: u16,
72
root_control: u16,
73
root_cap: u16,
74
root_status: u32,
75
dev_cap_2: u32,
76
dev_control_2: u16,
77
dev_status_2: u16,
78
link_cap_2: u32,
79
link_control_2: u16,
80
link_status_2: u16,
81
slot_cap_2: u32,
82
slot_control_2: u16,
83
slot_status_2: u16,
84
}
85
86
impl PciCapability for PcieCap {
87
fn bytes(&self) -> &[u8] {
88
self.as_bytes()
89
}
90
91
fn id(&self) -> PciCapabilityID {
92
PciCapabilityID::PciExpress
93
}
94
95
fn writable_bits(&self) -> Vec<u32> {
96
vec![
97
0u32,
98
0,
99
0xf_ffff,
100
0,
101
0x3000_0fff,
102
0,
103
0x11f_1fff,
104
0x1f,
105
0,
106
0,
107
0,
108
0,
109
0,
110
0,
111
0,
112
]
113
}
114
}
115
116
impl PcieCap {
117
pub fn new(device_type: PcieDevicePortType, slot: bool, irq_num: u16) -> Self {
118
let mut pcie_cap = PCIE_CAP_VERSION;
119
pcie_cap |= (device_type as u16) << PCIE_TYPE_SHIFT;
120
if slot {
121
pcie_cap |= 1 << PCIE_CAP_SLOT_SHIFT;
122
}
123
pcie_cap |= irq_num << PCIE_CAP_IRQ_NUM_SHIFT;
124
125
let dev_cap = PCIE_DEVCAP_RBER;
126
let link_cap = (PCIE_LINK_X1 | PCIE_LINK_2_5GT) as u32;
127
let link_status = PCIE_LINK_X1 | PCIE_LINK_2_5GT;
128
129
let mut slot_cap: u32 = 0;
130
let mut slot_control: u16 = 0;
131
if slot {
132
slot_cap = PCIE_SLTCAP_ABP
133
| PCIE_SLTCAP_AIP
134
| PCIE_SLTCAP_PIP
135
| PCIE_SLTCAP_HPS
136
| PCIE_SLTCAP_HPC;
137
slot_control = PCIE_SLTCTL_PIC_OFF | PCIE_SLTCTL_AIC_OFF;
138
}
139
140
PcieCap {
141
_cap_vndr: 0,
142
_cap_next: 0,
143
pcie_cap,
144
dev_cap,
145
dev_control: 0,
146
dev_status: 0,
147
link_cap,
148
link_control: 0,
149
link_status,
150
slot_cap,
151
slot_control,
152
slot_status: 0,
153
root_control: 0,
154
root_cap: 0,
155
root_status: 0,
156
dev_cap_2: 0,
157
dev_control_2: 0,
158
dev_status_2: 0,
159
link_cap_2: 0,
160
link_control_2: 0,
161
link_status_2: 0,
162
slot_cap_2: 0,
163
slot_control_2: 0,
164
slot_status_2: 0,
165
}
166
}
167
}
168
169