Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
google
GitHub Repository: google/crosvm
Path: blob/main/devices/src/irqchip/aarch64.rs
5394 views
1
// Copyright 2020 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 aarch64_sys_reg::AArch64SysRegId;
6
use aarch64_sys_reg::ICC_AP0R0_EL1;
7
use aarch64_sys_reg::ICC_AP0R1_EL1;
8
use aarch64_sys_reg::ICC_AP0R2_EL1;
9
use aarch64_sys_reg::ICC_AP0R3_EL1;
10
use aarch64_sys_reg::ICC_AP1R0_EL1;
11
use aarch64_sys_reg::ICC_AP1R1_EL1;
12
use aarch64_sys_reg::ICC_AP1R2_EL1;
13
use aarch64_sys_reg::ICC_AP1R3_EL1;
14
use aarch64_sys_reg::ICC_BPR0_EL1;
15
use aarch64_sys_reg::ICC_BPR1_EL1;
16
use aarch64_sys_reg::ICC_IGRPEN0_EL1;
17
use aarch64_sys_reg::ICC_IGRPEN1_EL1;
18
use aarch64_sys_reg::ICC_PMR_EL1;
19
use aarch64_sys_reg::ICC_SRE_EL1;
20
use anyhow::anyhow;
21
use base::Result;
22
use hypervisor::DeviceKind;
23
use snapshot::AnySnapshot;
24
25
use crate::IrqChip;
26
27
pub trait IrqChipAArch64: IrqChip {
28
// Clones this trait as a `Box` version of itself.
29
fn try_box_clone(&self) -> Result<Box<dyn IrqChipAArch64>>;
30
31
// Get this as the super-trait IrqChip.
32
fn as_irq_chip(&self) -> &dyn IrqChip;
33
34
// Get this as the mutable super-trait IrqChip.
35
fn as_irq_chip_mut(&mut self) -> &mut dyn IrqChip;
36
37
/// Get the version of VGIC that this chip is emulating. Currently KVM may either implement
38
/// VGIC version 2 or 3.
39
fn get_vgic_version(&self) -> DeviceKind;
40
41
/// Whether an ITS (Interrupt Translation Service) is provided to the guest.
42
fn has_vgic_its(&self) -> bool;
43
44
/// Once all the VCPUs have been enabled, finalize the irq chip.
45
fn finalize(&self) -> Result<()>;
46
47
// Snapshot irqchip.
48
fn snapshot(&self, _cpus_num: usize) -> anyhow::Result<AnySnapshot> {
49
Err(anyhow!("Snapshot not yet implemented for AArch64"))
50
}
51
52
fn restore(&mut self, _data: AnySnapshot, _vcpus_num: usize) -> anyhow::Result<()> {
53
Err(anyhow!("Restore not yet implemented for AArch64"))
54
}
55
}
56
57
// List of registers taken from https://web.git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/arch/arm64/kvm/vgic-sys-reg-v3.c?h=v6.13.5#n300
58
pub fn icc_regs(prio_bits: u8) -> anyhow::Result<Vec<AArch64SysRegId>> {
59
let mut regs = vec![
60
ICC_PMR_EL1,
61
ICC_BPR0_EL1,
62
ICC_BPR1_EL1,
63
ICC_SRE_EL1,
64
ICC_IGRPEN0_EL1,
65
ICC_IGRPEN1_EL1,
66
];
67
icc_ap0r_regs(&mut regs, prio_bits)?;
68
icc_ap1r_regs(&mut regs, prio_bits)?;
69
Ok(regs)
70
}
71
72
fn icc_ap0r_regs(regs: &mut Vec<AArch64SysRegId>, prio_bits: u8) -> anyhow::Result<()> {
73
if prio_bits > 8 || prio_bits == 0 {
74
return Err(anyhow!("Invalid number of priroity bits: {prio_bits}"));
75
}
76
regs.push(ICC_AP0R0_EL1);
77
if prio_bits >= 6 {
78
regs.push(ICC_AP0R1_EL1);
79
}
80
if prio_bits >= 7 {
81
regs.push(ICC_AP0R2_EL1);
82
regs.push(ICC_AP0R3_EL1);
83
}
84
Ok(())
85
}
86
87
fn icc_ap1r_regs(regs: &mut Vec<AArch64SysRegId>, prio_bits: u8) -> anyhow::Result<()> {
88
if prio_bits > 8 || prio_bits == 0 {
89
return Err(anyhow!("Invalid number of priroity bits: {prio_bits}"));
90
}
91
regs.push(ICC_AP1R0_EL1);
92
if prio_bits >= 6 {
93
regs.push(ICC_AP1R1_EL1);
94
}
95
if prio_bits >= 7 {
96
regs.push(ICC_AP1R2_EL1);
97
regs.push(ICC_AP1R3_EL1);
98
}
99
Ok(())
100
}
101
102
#[cfg(test)]
103
mod tests {
104
use super::*;
105
106
#[test]
107
fn icc_ap0r_1() {
108
let mut regs = Vec::new();
109
icc_ap0r_regs(&mut regs, 4).unwrap();
110
assert_eq!(
111
regs,
112
vec![AArch64SysRegId::new_unchecked(
113
0b11, 0b000, 0b1100, 0b1000, 0b100
114
),]
115
);
116
}
117
118
#[test]
119
fn icc_ap0r_2() {
120
let mut regs = Vec::new();
121
icc_ap0r_regs(&mut regs, 6).unwrap();
122
assert_eq!(
123
regs,
124
vec![
125
AArch64SysRegId::new_unchecked(0b11, 0b000, 0b1100, 0b1000, 0b100),
126
AArch64SysRegId::new_unchecked(0b11, 0b000, 0b1100, 0b1000, 0b101),
127
]
128
);
129
}
130
131
#[test]
132
fn icc_ap0r_4() {
133
let mut regs = Vec::new();
134
icc_ap0r_regs(&mut regs, 7).unwrap();
135
assert_eq!(
136
regs,
137
vec![
138
AArch64SysRegId::new_unchecked(0b11, 0b000, 0b1100, 0b1000, 0b100),
139
AArch64SysRegId::new_unchecked(0b11, 0b000, 0b1100, 0b1000, 0b101),
140
AArch64SysRegId::new_unchecked(0b11, 0b000, 0b1100, 0b1000, 0b110),
141
AArch64SysRegId::new_unchecked(0b11, 0b000, 0b1100, 0b1000, 0b111),
142
]
143
);
144
}
145
146
#[test]
147
#[should_panic]
148
fn icc_ap0r_invalid_0() {
149
let mut regs = Vec::new();
150
icc_ap0r_regs(&mut regs, 0).unwrap();
151
}
152
153
#[test]
154
#[should_panic]
155
fn icc_ap0r_invalid_5() {
156
let mut regs = Vec::new();
157
icc_ap0r_regs(&mut regs, 9).unwrap();
158
}
159
160
#[test]
161
fn icc_ap1r_1() {
162
let mut regs = Vec::new();
163
icc_ap1r_regs(&mut regs, 5).unwrap();
164
assert_eq!(
165
regs,
166
vec![AArch64SysRegId::new_unchecked(
167
0b11, 0b000, 0b1100, 0b1001, 0b000
168
),]
169
);
170
}
171
172
#[test]
173
fn icc_ap1r_2() {
174
let mut regs = Vec::new();
175
icc_ap1r_regs(&mut regs, 6).unwrap();
176
assert_eq!(
177
regs,
178
vec![
179
AArch64SysRegId::new_unchecked(0b11, 0b000, 0b1100, 0b1001, 0b000),
180
AArch64SysRegId::new_unchecked(0b11, 0b000, 0b1100, 0b1001, 0b001),
181
]
182
);
183
}
184
185
#[test]
186
fn icc_ap1r_4() {
187
let mut regs = Vec::new();
188
icc_ap1r_regs(&mut regs, 8).unwrap();
189
assert_eq!(
190
regs,
191
vec![
192
AArch64SysRegId::new_unchecked(0b11, 0b000, 0b1100, 0b1001, 0b000),
193
AArch64SysRegId::new_unchecked(0b11, 0b000, 0b1100, 0b1001, 0b001),
194
AArch64SysRegId::new_unchecked(0b11, 0b000, 0b1100, 0b1001, 0b010),
195
AArch64SysRegId::new_unchecked(0b11, 0b000, 0b1100, 0b1001, 0b011),
196
]
197
);
198
}
199
200
#[test]
201
#[should_panic]
202
fn icc_ap1r_invalid_0() {
203
let mut regs = Vec::new();
204
icc_ap1r_regs(&mut regs, 0).unwrap();
205
}
206
207
#[test]
208
#[should_panic]
209
fn icc_ap1r_invalid_5() {
210
let mut regs = Vec::new();
211
icc_ap1r_regs(&mut regs, 9).unwrap();
212
}
213
214
#[test]
215
fn icc_regs_pribits_8() {
216
let regs = icc_regs(8).unwrap();
217
assert_eq!(
218
regs,
219
[
220
ICC_PMR_EL1,
221
ICC_BPR0_EL1,
222
ICC_BPR1_EL1,
223
ICC_SRE_EL1,
224
ICC_IGRPEN0_EL1,
225
ICC_IGRPEN1_EL1,
226
ICC_AP0R0_EL1,
227
ICC_AP0R1_EL1,
228
ICC_AP0R2_EL1,
229
ICC_AP0R3_EL1,
230
ICC_AP1R0_EL1,
231
ICC_AP1R1_EL1,
232
ICC_AP1R2_EL1,
233
ICC_AP1R3_EL1,
234
]
235
);
236
}
237
}
238
239