3
3
// SPDX-License-Identifier: Apache-2.0
4
4
//
5
5
6
- use zerocopy:: AsBytes ;
6
+ use zerocopy:: { byteorder , byteorder :: LE , AsBytes } ;
7
7
8
8
extern crate alloc;
9
9
use alloc:: { boxed:: Box , vec:: Vec } ;
10
10
11
- use crate :: { u8sum, Aml , AmlSink , Checksum , TableHeader } ;
11
+ use crate :: { aml_as_bytes, u8sum, Aml , AmlSink , Checksum , TableHeader } ;
12
+
13
+ type U16 = byteorder:: U16 < LE > ;
14
+ type U32 = byteorder:: U32 < LE > ;
12
15
13
16
// SRAT is the place where proximity domains are defined, and _PXM
14
17
// (found in DSDT and/or SSDT) provides a mechanism to associate a
@@ -69,6 +72,11 @@ impl SRAT {
69
72
self . update_header ( GenericInitiator :: len ( ) as u32 , st. u8sum ( ) ) ;
70
73
self . structures . push ( Box :: new ( st) ) ;
71
74
}
75
+
76
+ pub fn add_rintc_affinity ( & mut self , ra : RintcAffinity ) {
77
+ self . update_header ( RintcAffinity :: len ( ) as u32 , ra. u8sum ( ) ) ;
78
+ self . structures . push ( Box :: new ( ra) ) ;
79
+ }
72
80
}
73
81
74
82
impl Aml for SRAT {
@@ -90,6 +98,7 @@ impl Aml for SRAT {
90
98
enum SratStructureType {
91
99
MemoryAffinity = 1 ,
92
100
GenericInitiator = 5 ,
101
+ RintcAffinity = 7 ,
93
102
}
94
103
95
104
#[ repr( u32 ) ]
@@ -280,6 +289,47 @@ impl Aml for GenericInitiator {
280
289
}
281
290
}
282
291
292
+ #[ repr( C , packed) ]
293
+ #[ derive( Clone , Copy , Debug , Default , AsBytes ) ]
294
+ pub struct RintcAffinity {
295
+ r#type : u8 ,
296
+ length : u8 ,
297
+ reserved : U16 ,
298
+ acpi_processor_uid : [ u8 ; 4 ] ,
299
+ flags : U32 ,
300
+ clock_domain : U32 ,
301
+ }
302
+
303
+ impl RintcAffinity {
304
+ const FLAGS_ENABLED : u32 = 1 << 0 ;
305
+
306
+ fn len ( ) -> usize {
307
+ core:: mem:: size_of :: < Self > ( )
308
+ }
309
+
310
+ pub fn new ( acpi_processor_uid : [ u8 ; 4 ] , clock_domain : u32 ) -> Self {
311
+ Self {
312
+ r#type : SratStructureType :: RintcAffinity as u8 ,
313
+ length : 20 ,
314
+ reserved : 0 . into ( ) ,
315
+ acpi_processor_uid,
316
+ flags : 0 . into ( ) ,
317
+ clock_domain : clock_domain. into ( ) ,
318
+ }
319
+ }
320
+
321
+ pub fn enabled ( mut self ) -> Self {
322
+ self . flags = ( self . flags . get ( ) | Self :: FLAGS_ENABLED ) . into ( ) ;
323
+ self
324
+ }
325
+
326
+ fn u8sum ( & self ) -> u8 {
327
+ u8sum ( self )
328
+ }
329
+ }
330
+
331
+ aml_as_bytes ! ( RintcAffinity ) ;
332
+
283
333
#[ cfg( test) ]
284
334
mod tests {
285
335
use super :: * ;
@@ -344,4 +394,15 @@ mod tests {
344
394
let sum = bytes. iter ( ) . fold ( 0u8 , |acc, x| acc. wrapping_add ( * x) ) ;
345
395
assert_eq ! ( sum, 0 ) ;
346
396
}
397
+
398
+ #[ test]
399
+ fn test_rintc_affinity ( ) {
400
+ let mut srat = SRAT :: new ( * b"FOOBAR" , * b"SRATSRAT" , 0xdead_beef ) ;
401
+ srat. add_rintc_affinity ( RintcAffinity :: new ( [ 0x42 , 0x37 , 0x58 , 0xde ] , 0xde583742 ) . enabled ( ) ) ;
402
+
403
+ let mut bytes = Vec :: new ( ) ;
404
+ srat. to_aml_bytes ( & mut bytes) ;
405
+ let sum = bytes. iter ( ) . fold ( 0u8 , |acc, x| acc. wrapping_add ( * x) ) ;
406
+ assert_eq ! ( sum, 0 ) ;
407
+ }
347
408
}
0 commit comments