Skip to content

Commit 4673ea1

Browse files
committed
minor fixes
1 parent fee46d5 commit 4673ea1

4 files changed

Lines changed: 116 additions & 26 deletions

File tree

lib/propolis/src/firmware/acpi/dsdt.rs

Lines changed: 111 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,17 @@ const PCI_BUS_END: u16 = 0xff;
201201
const LEGACY_VGA_BASE: u32 = 0x000a_0000;
202202
const LEGACY_VGA_LIMIT: u32 = 0x000b_ffff;
203203

204+
// Byte offset for different fields that are referenced by other structures.
205+
const ADDRESS_SPACE_32_MIN_OFFSET: usize = 0x0a;
206+
const ADDRESS_SPACE_32_MAX_OFFSET: usize = 0x0e;
207+
const ADDRESS_SPACE_32_LEN_OFFSET: usize = 0x16;
208+
209+
const ADDRESS_SPACE_64_MIN_OFFSET: usize = 0x0e;
210+
const ADDRESS_SPACE_64_MAX_OFFSET: usize = 0x16;
211+
const ADDRESS_SPACE_64_LEN_OFFSET: usize = 0x26;
212+
213+
const INTERRUPT_LIST_OFFSET: usize = 0x05;
214+
204215
/// _CRS method for the PCI0 device (\_SB.PCI0._CRS).
205216
///
206217
/// Refer to section 4.3 of the PCI Firmware Specification for more
@@ -351,17 +362,17 @@ impl Aml for PciRootBridgeCrs {
351362
&aml::CreateDWordField::new(
352363
&aml::Path::new("PS32"),
353364
&aml::Path::new("CRES"),
354-
&(mmio32_offset + 0x0a), // Byte offset for min.
365+
&(mmio32_offset + ADDRESS_SPACE_32_MIN_OFFSET),
355366
),
356367
&aml::CreateDWordField::new(
357368
&aml::Path::new("PE32"),
358369
&aml::Path::new("CRES"),
359-
&(mmio32_offset + 0x0e), // Byte offset for max.
370+
&(mmio32_offset + ADDRESS_SPACE_32_MAX_OFFSET),
360371
),
361372
&aml::CreateDWordField::new(
362373
&aml::Path::new("PL32"),
363374
&aml::Path::new("CRES"),
364-
&(mmio32_offset + 0x16), // Byte offset for len.
375+
&(mmio32_offset + ADDRESS_SPACE_32_LEN_OFFSET),
365376
),
366377
// Update the values of mmio32 based on the FWDT.
367378
&aml::Store::new(
@@ -390,17 +401,17 @@ impl Aml for PciRootBridgeCrs {
390401
&aml::CreateQWordField::new(
391402
&aml::Path::new("PS64"),
392403
&aml::Path::new("CR64"),
393-
&(mmio64_offset + 0x0e),
404+
&(mmio64_offset + ADDRESS_SPACE_64_MIN_OFFSET),
394405
),
395406
&aml::CreateQWordField::new(
396407
&aml::Path::new("PE64"),
397408
&aml::Path::new("CR64"),
398-
&(mmio64_offset + 0x16),
409+
&(mmio64_offset + ADDRESS_SPACE_64_MAX_OFFSET),
399410
),
400411
&aml::CreateQWordField::new(
401412
&aml::Path::new("PL64"),
402413
&aml::Path::new("CR64"),
403-
&(mmio64_offset + 0x26),
414+
&(mmio64_offset + ADDRESS_SPACE_64_LEN_OFFSET),
404415
),
405416
// Update the values of mmio64 based on the FWDT.
406417
&aml::Store::new(
@@ -431,10 +442,10 @@ impl Aml for PciRootBridgeCrs {
431442

432443
fn aml_len(vec: &[&dyn Aml]) -> usize {
433444
let mut sink = Vec::new();
434-
vec.iter().fold(0, |_acc, aml| {
445+
for aml in vec {
435446
aml.to_aml_bytes(&mut sink);
436-
sink.len()
437-
})
447+
}
448+
sink.len()
438449
}
439450

440451
/// Number of devices in the PCI0 root bridge.
@@ -596,7 +607,7 @@ impl<'a> Aml for PciRootBridgeLpc<'a> {
596607
&aml::CreateDWordField::new(
597608
&aml::Path::new("IRQW"),
598609
&aml::Path::new("BUF0"),
599-
&0x05_u64, // TODO: document.
610+
&INTERRUPT_LIST_OFFSET,
600611
),
601612
&aml::If::new(
602613
&aml::LogicalNot::new(&aml::And::new(
@@ -1140,35 +1151,32 @@ mod test {
11401151
&MockDsdtGenerator { scope: DsdtScope::Lpc },
11411152
];
11421153

1143-
// Filter by SystemBus.
11441154
let mut got = Vec::new();
1155+
let mut expected = Vec::new();
1156+
1157+
// Filter by SystemBus.
11451158
DsdtGeneratorAml::new(&generators, DsdtScope::SystemBus)
11461159
.to_aml_bytes(&mut got);
1147-
1148-
let mut expected = Vec::new();
11491160
aml::Name::new("TEST".into(), &"SystemBus").to_aml_bytes(&mut expected);
11501161
assert_eq!(expected, got);
1162+
11511163
got.clear();
1164+
expected.clear();
11521165

11531166
// Filter by PciRoot.
1154-
let mut got = Vec::new();
11551167
DsdtGeneratorAml::new(&generators, DsdtScope::PciRoot)
11561168
.to_aml_bytes(&mut got);
1157-
1158-
let mut expected = Vec::new();
11591169
aml::Name::new("TEST".into(), &"PciRoot").to_aml_bytes(&mut expected);
11601170
assert_eq!(expected, got);
1171+
11611172
got.clear();
1173+
expected.clear();
11621174

11631175
// Filter by Lpc.
1164-
let mut got = Vec::new();
11651176
DsdtGeneratorAml::new(&generators, DsdtScope::Lpc)
11661177
.to_aml_bytes(&mut got);
1167-
1168-
let mut expected = Vec::new();
11691178
aml::Name::new("TEST".into(), &"Lpc").to_aml_bytes(&mut expected);
11701179
assert_eq!(expected, got);
1171-
got.clear();
11721180
}
11731181

11741182
#[test]
@@ -1190,4 +1198,87 @@ mod test {
11901198
assert!(aml.windows(4).any(|w| w == b"_PRT"));
11911199
assert!(aml.windows(4).any(|w| w == b"LPC_"));
11921200
}
1201+
1202+
#[test]
1203+
fn field_references() {
1204+
let mut sink = Vec::new();
1205+
1206+
// Validate DWord AddressSpace min, max, and len offsets.
1207+
let min = 0xf800_0000_u32;
1208+
let max = 0xfffb_ffff_u32;
1209+
let len = max - min + 1;
1210+
aml::AddressSpace::new_memory(
1211+
aml::AddressSpaceCacheable::NotCacheable,
1212+
true,
1213+
min,
1214+
max,
1215+
None,
1216+
)
1217+
.to_aml_bytes(&mut sink);
1218+
assert_eq!(
1219+
sink[ADDRESS_SPACE_32_MIN_OFFSET
1220+
..(ADDRESS_SPACE_32_MIN_OFFSET + 4)],
1221+
min.to_le_bytes()
1222+
);
1223+
assert_eq!(
1224+
sink[ADDRESS_SPACE_32_MAX_OFFSET
1225+
..(ADDRESS_SPACE_32_MAX_OFFSET + 4)],
1226+
max.to_le_bytes()
1227+
);
1228+
assert_eq!(
1229+
sink[ADDRESS_SPACE_32_LEN_OFFSET
1230+
..(ADDRESS_SPACE_32_LEN_OFFSET + 4)],
1231+
len.to_le_bytes()
1232+
);
1233+
1234+
sink.clear();
1235+
1236+
// Validate QWord AddressSpace min, max, and len offsets.
1237+
let min = 0x0080_0000_0000_u64;
1238+
let max = 0x0fff_ffff_ffff_u64;
1239+
let len = max - min + 1;
1240+
aml::AddressSpace::new_memory(
1241+
aml::AddressSpaceCacheable::Cacheable,
1242+
true,
1243+
min,
1244+
max,
1245+
None,
1246+
)
1247+
.to_aml_bytes(&mut sink);
1248+
assert_eq!(
1249+
sink[ADDRESS_SPACE_64_MIN_OFFSET
1250+
..(ADDRESS_SPACE_64_MIN_OFFSET + 8)],
1251+
min.to_le_bytes()
1252+
);
1253+
assert_eq!(
1254+
sink[ADDRESS_SPACE_64_MAX_OFFSET
1255+
..(ADDRESS_SPACE_64_MAX_OFFSET + 8)],
1256+
max.to_le_bytes()
1257+
);
1258+
assert_eq!(
1259+
sink[ADDRESS_SPACE_64_LEN_OFFSET
1260+
..(ADDRESS_SPACE_64_LEN_OFFSET + 8)],
1261+
len.to_le_bytes()
1262+
);
1263+
1264+
sink.clear();
1265+
1266+
// Validate Interrupt interrupt list offset.
1267+
aml::Interrupt::new(true, false, false, true, vec![0x05])
1268+
.to_aml_bytes(&mut sink);
1269+
assert_eq!(
1270+
sink[INTERRUPT_LIST_OFFSET..(INTERRUPT_LIST_OFFSET + 4)],
1271+
0x05_u32.to_le_bytes()
1272+
);
1273+
1274+
sink.clear();
1275+
1276+
// Validate FWDT offset address field offset.
1277+
Ssdt::new(0xabc).to_aml_bytes(&mut sink);
1278+
assert_eq!(
1279+
sink[SSDT_FWDT_ADDR_OFFSET
1280+
..(SSDT_FWDT_ADDR_OFFSET + SSDT_FWDT_ADDR_LEN)],
1281+
0xabc_u32.to_le_bytes()
1282+
);
1283+
}
11931284
}

lib/propolis/src/firmware/acpi/fadt.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use super::{OEM_ID, OEM_REVISION, OEM_TABLE_ID, SCI_IRQ};
1111
use acpi_tables::{
1212
// XXX(acpi): Use version 3 to keep FADT table consistent with the original
13-
// EKD2 static tables. The acpi_tables crate also generates the
13+
// EDK2 static tables. The acpi_tables crate also generates the
1414
// MADT table using revision 1, which fwts reports not being
1515
// compatible with FADT 6.5.
1616
fadt_3::{FADTBuilder, Flags},
@@ -102,6 +102,7 @@ impl Aml for Fadt {
102102
fadt.pm_tmr_len = PM_TMR_BLK_LEN;
103103
fadt.gpe0_blk_len = GPE0_BLK_LEN;
104104

105+
// Disable C2 and C3 state support.
105106
fadt.p_lvl2_lat = 101.into();
106107
fadt.p_lvl3_lat = 1001.into();
107108

lib/propolis/src/firmware/acpi/madt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ impl<'a> Aml for Madt<'a> {
5757
.pc_at_compat();
5858

5959
// Processor Local APIC.
60-
// https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#i-o-apic-structure
60+
// https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/05_ACPI_Software_Programming_Model/ACPI_Software_Programming_Model.html#processor-local-apic-structure
6161
for i in 0..self.config.num_cpus {
6262
table.add_structure(madt::ProcessorLocalApic::new(
6363
i,

lib/propolis/src/hw/qemu/fwcfg.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1465,7 +1465,7 @@ pub mod formats {
14651465
let ssdt_offset = self.tables.len();
14661466
ssdt.to_aml_bytes(&mut self.tables);
14671467

1468-
// Mark the FWDT Operatioon offset field as a pointer to the
1468+
// Mark the FWDT OperationRegion offset field as a pointer to the
14691469
// FWDT data.
14701470
self.loader.add_pointer(
14711471
FW_CFG_ACPI_TABLES_PATH,
@@ -1611,9 +1611,7 @@ pub mod formats {
16111611
+ acpi::TABLE_HEADER_CHECKSUM_LEN;
16121612

16131613
// Zero existing checksum so it doesn't affect the new value.
1614-
self.tables[checksum_start..checksum_end]
1615-
.copy_from_slice(&0_u8.to_le_bytes());
1616-
1614+
self.tables[checksum_start..checksum_end].copy_from_slice(&[0u8]);
16171615
self.loader.add_checksum(
16181616
FW_CFG_ACPI_TABLES_PATH,
16191617
checksum_start as u32,

0 commit comments

Comments
 (0)