1
1
use crate :: {
2
2
sdt:: { ExtendedField , SdtHeader , Signature } ,
3
+ AcpiError ,
3
4
AcpiTable ,
4
5
} ;
5
6
use bit_field:: BitField ;
@@ -21,6 +22,7 @@ pub enum MadtError {
21
22
InvalidLocalNmiLine ,
22
23
MpsIntiInvalidPolarity ,
23
24
MpsIntiInvalidTriggerMode ,
25
+ WakeupApsTimeout ,
24
26
}
25
27
26
28
/// Represents the MADT - this contains the MADT header fields. You can then iterate over a `Madt`
@@ -49,6 +51,18 @@ unsafe impl AcpiTable for Madt {
49
51
}
50
52
51
53
impl Madt {
54
+ pub fn get_mpwk_mailbox_addr ( & self ) -> Result < u64 , AcpiError > {
55
+ for entry in self . entries ( ) {
56
+ match entry {
57
+ MadtEntry :: MultiprocessorWakeup ( entry) => {
58
+ return Ok ( entry. mailbox_address ) ;
59
+ }
60
+ _ => { }
61
+ }
62
+ }
63
+ Err ( AcpiError :: InvalidMadt ( MadtError :: UnexpectedEntry ) )
64
+ }
65
+
52
66
#[ cfg( feature = "allocator_api" ) ]
53
67
pub fn parse_interrupt_model_in < ' a , A > (
54
68
& self ,
@@ -102,21 +116,18 @@ impl Madt {
102
116
where
103
117
A : core:: alloc:: Allocator + Clone ,
104
118
{
105
- use crate :: {
106
- platform:: {
107
- interrupt:: {
108
- Apic ,
109
- InterruptSourceOverride ,
110
- IoApic ,
111
- LocalInterruptLine ,
112
- NmiLine ,
113
- NmiProcessor ,
114
- NmiSource ,
115
- } ,
116
- Processor ,
117
- ProcessorState ,
119
+ use crate :: platform:: {
120
+ interrupt:: {
121
+ Apic ,
122
+ InterruptSourceOverride ,
123
+ IoApic ,
124
+ LocalInterruptLine ,
125
+ NmiLine ,
126
+ NmiProcessor ,
127
+ NmiSource ,
118
128
} ,
119
- AcpiError ,
129
+ Processor ,
130
+ ProcessorState ,
120
131
} ;
121
132
122
133
let mut local_apic_address = self . local_apic_address as u64 ;
@@ -630,6 +641,36 @@ pub struct MultiprocessorWakeupEntry {
630
641
pub mailbox_address : u64 ,
631
642
}
632
643
644
+ #[ derive( Debug , PartialEq , Eq ) ]
645
+ pub enum MpProtectedModeWakeupCommand {
646
+ Noop = 0 ,
647
+ Wakeup = 1 ,
648
+ Sleep = 2 ,
649
+ AcceptPages = 3 ,
650
+ }
651
+
652
+ impl From < u16 > for MpProtectedModeWakeupCommand {
653
+ fn from ( value : u16 ) -> Self {
654
+ match value {
655
+ 0 => MpProtectedModeWakeupCommand :: Noop ,
656
+ 1 => MpProtectedModeWakeupCommand :: Wakeup ,
657
+ 2 => MpProtectedModeWakeupCommand :: Sleep ,
658
+ 3 => MpProtectedModeWakeupCommand :: AcceptPages ,
659
+ _ => panic ! ( "Invalid value for MpProtectedModeWakeupCommand" ) ,
660
+ }
661
+ }
662
+ }
663
+
664
+ #[ repr( C ) ]
665
+ pub struct MultiprocessorWakeupMailbox {
666
+ pub command : u16 ,
667
+ _reserved : u16 ,
668
+ pub apic_id : u32 ,
669
+ pub wakeup_vector : u64 ,
670
+ pub reserved_for_os : [ u64 ; 254 ] ,
671
+ reserved_for_firmware : [ u64 ; 256 ] ,
672
+ }
673
+
633
674
#[ cfg( feature = "allocator_api" ) ]
634
675
fn parse_mps_inti_flags ( flags : u16 ) -> crate :: AcpiResult < ( Polarity , TriggerMode ) > {
635
676
let polarity = match flags. get_bits ( 0 ..2 ) {
0 commit comments