11pub  mod  interrupt; 
22
33use  crate :: { 
4-     address:: GenericAddress , 
5-     fadt:: Fadt , 
6-     madt:: { Madt ,  MadtError ,  MpProtectedModeWakeupCommand ,  MultiprocessorWakeupMailbox } , 
7-     AcpiError , 
8-     AcpiHandler , 
9-     AcpiResult , 
10-     AcpiTables , 
11-     ManagedSlice , 
12-     PowerProfile , 
4+     address:: GenericAddress ,  fadt:: Fadt ,  madt:: { Madt ,  MadtError ,  MpProtectedModeWakeupCommand ,  MultiprocessorWakeupMailbox } ,  srat:: Srat ,  AcpiError ,  AcpiHandler ,  AcpiResult ,  AcpiTables ,  ManagedSlice ,  PowerProfile 
135} ; 
146use  core:: { alloc:: Allocator ,  mem,  ptr} ; 
157use  interrupt:: InterruptModel ; 
@@ -35,6 +27,8 @@ pub struct Processor {
3527    /// The ID of the local APIC of the processor. Will be less than `256` if the APIC is being used, but can be 
3628     /// greater than this if the X2APIC is being used. 
3729     pub  local_apic_id :  u32 , 
30+     /// Proximity domain to which the processor belongs to. 
31+      pub  proximity_domain :  Option < u32 > , 
3832
3933    /// The state of this processor. Check that the processor is not `Disabled` before attempting to bring it up! 
4034     pub  state :  ProcessorState , 
@@ -45,6 +39,19 @@ pub struct Processor {
4539     pub  is_ap :  bool , 
4640} 
4741
42+ impl  Processor  { 
43+     fn  attach_affinity < ' a ,  A > ( & mut  self ,  topology :  & ProcessorTopology < ' a ,  A > ) 
44+     where 
45+         A :  Allocator , 
46+     { 
47+         for  affinity in  topology. processor_affinities . iter ( )  { 
48+             if  affinity. local_apic_id  == self . local_apic_id  { 
49+                 self . proximity_domain  = Some ( affinity. proximity_domain ) ; 
50+             } 
51+         } 
52+     } 
53+ } 
54+ 
4855#[ derive( Debug ,  Clone ) ]  
4956pub  struct  ProcessorInfo < ' a ,  A > 
5057where 
6269    pub ( crate )  fn  new ( boot_processor :  Processor ,  application_processors :  ManagedSlice < ' a ,  Processor ,  A > )  -> Self  { 
6370        Self  {  boot_processor,  application_processors } 
6471    } 
72+ 
73+     fn  attach_affinity ( & mut  self ,  topology :  & ProcessorTopology < ' a ,  A > )  { 
74+         self . boot_processor . attach_affinity ( topology) ; 
75+         for  application_processor in  self . application_processors . iter_mut ( )  { 
76+             application_processor. attach_affinity ( topology) ; 
77+         } 
78+     } 
79+ } 
80+ 
81+ pub  struct  ProcessorAffinity  { 
82+     pub  local_apic_id :  u32 , 
83+     pub  proximity_domain :  u32 , 
84+     pub  is_enabled :  bool , 
85+ } 
86+ 
87+ pub  struct  ProcessorTopology < ' a ,  A > 
88+ where 
89+     A :  Allocator , 
90+ { 
91+     pub  processor_affinities :  ManagedSlice < ' a ,  ProcessorAffinity ,  A > , 
92+ } 
93+ 
94+ #[ derive( Debug ,  Clone ) ]  
95+ pub  struct  MemoryRange  { 
96+     pub  base_address :  u64 , 
97+     pub  length :  u64 , 
98+     pub  proximity_domain :  Option < u32 > , 
99+     pub  hot_pluggable :  bool , 
100+     pub  non_volatile :  bool , 
101+     pub  is_enabled :  bool , 
102+ } 
103+ 
104+ #[ derive( Debug ,  Clone ) ]  
105+ pub  struct  MemoryInfo < ' a ,  A > 
106+ where 
107+     A :  Allocator , 
108+ { 
109+     pub  memory_ranges :  ManagedSlice < ' a ,  MemoryRange ,  A > , 
65110} 
66111
67112/// Information about the ACPI Power Management Timer (ACPI PM Timer). 
95140    /// On `x86_64` platforms that support the APIC, the processor topology must also be inferred from the 
96141     /// interrupt model. That information is stored here, if present. 
97142     pub  processor_info :  Option < ProcessorInfo < ' a ,  A > > , 
143+     pub  memory_info :  Option < MemoryInfo < ' a ,  A > > , 
98144    pub  pm_timer :  Option < PmTimer > , 
99145    /* 
100146     * TODO: we could provide a nice view of the hardware register blocks in the FADT here. 
@@ -119,17 +165,34 @@ where
119165    where 
120166        H :  AcpiHandler , 
121167    { 
122-         let  fadt = tables. find_table :: < Fadt > ( ) ?; 
123-         let  power_profile = fadt. power_profile ( ) ; 
168+         let  ( power_profile,  pm_timer)  = { 
169+             let  fadt = tables. find_table :: < Fadt > ( ) ?; 
170+             ( fadt. power_profile ( ) ,  PmTimer :: new ( & fadt) ?) 
171+         } ; 
172+ 
173+         let  ( interrupt_model,  processor_info)  = { 
174+             let  madt = tables. find_table :: < Madt > ( ) ; 
175+             match  madt { 
176+                 Ok ( madt)  => madt. get ( ) . parse_interrupt_model_in ( allocator. clone ( ) ) ?, 
177+                 Err ( _)  => ( InterruptModel :: Unknown ,  None ) , 
178+             } 
179+         } ; 
124180
125-         let  madt = tables. find_table :: < Madt > ( ) ; 
126-         let  ( interrupt_model,  processor_info)  = match  madt { 
127-             Ok ( madt)  => madt. get ( ) . parse_interrupt_model_in ( allocator) ?, 
128-             Err ( _)  => ( InterruptModel :: Unknown ,  None ) , 
181+         let  ( processor_info,  memory_info)  = { 
182+             let  srat = tables. find_table :: < Srat > ( ) ; 
183+             match  srat { 
184+                 Ok ( srat)  => { 
185+                     let  ( processor_topology,  memory_info)  = srat. get ( ) . parse_topology_in ( allocator) ?; 
186+                     ( processor_info. and_then ( |mut  processor_info| { 
187+                         processor_info. attach_affinity ( & processor_topology) ; 
188+                         Some ( processor_info) 
189+                     } ) ,  Some ( memory_info) ) 
190+                 } 
191+                 Err ( _)  => ( processor_info,  None ) , 
192+             } 
129193        } ; 
130-         let  pm_timer = PmTimer :: new ( & fadt) ?; 
131194
132-         Ok ( PlatformInfo  {  power_profile,  interrupt_model,  processor_info,  pm_timer } ) 
195+         Ok ( PlatformInfo  {  power_profile,  interrupt_model,  processor_info,  memory_info ,   pm_timer } ) 
133196    } 
134197} 
135198
0 commit comments