@@ -201,6 +201,17 @@ const PCI_BUS_END: u16 = 0xff;
201201const LEGACY_VGA_BASE : u32 = 0x000a_0000 ;
202202const 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
432443fn 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}
0 commit comments