35
35
unsafe impl < H > Send for Interpreter < H > where H : Handler + Send { }
36
36
unsafe impl < H > Sync for Interpreter < H > where H : Handler + Send { }
37
37
38
+ /// The value returned by the `Revision` opcode.
39
+ const INTERPRETER_REVISION : u64 = 1 ;
40
+
38
41
impl < H > Interpreter < H >
39
42
where
40
43
H : Handler ,
@@ -153,6 +156,15 @@ where
153
156
let name = name. resolve ( & context. current_scope ) ?;
154
157
self . namespace . lock ( ) . insert ( name, object. clone ( ) ) ?;
155
158
}
159
+ Opcode :: Fatal => {
160
+ let [ Argument :: ByteData ( typ) , Argument :: DWordData ( code) , Argument :: Object ( arg) ] =
161
+ & op. arguments [ ..]
162
+ else {
163
+ panic ! ( )
164
+ } ;
165
+ let Object :: Integer ( arg) = * * arg else { panic ! ( ) } ;
166
+ self . handler . handle_fatal_error ( * typ, * code, arg) ;
167
+ }
156
168
Opcode :: OpRegion => {
157
169
let [
158
170
Argument :: Namestring ( name) ,
@@ -346,7 +358,6 @@ where
346
358
let [ Argument :: Object ( object) ] = & op. arguments [ ..] else { panic ! ( ) } ;
347
359
// TODO: this should technically support scopes as well - this is less easy
348
360
// (they should return `0`)
349
- // TODO: calling this on the debug object should should return `16`
350
361
let typ = match object. typ ( ) {
351
362
ObjectType :: Uninitialized => 0 ,
352
363
ObjectType :: Integer => 1 ,
@@ -364,6 +375,7 @@ where
364
375
ObjectType :: ThermalZone => 13 ,
365
376
ObjectType :: BufferField => 14 ,
366
377
// XXX: 15 is reserved
378
+ ObjectType :: Debug => 16 ,
367
379
ObjectType :: Reference => panic ! ( ) ,
368
380
ObjectType :: RawDataBuffer => todo ! ( ) ,
369
381
} ;
@@ -583,10 +595,26 @@ where
583
595
Opcode :: Release => todo ! ( ) ,
584
596
Opcode :: FromBCD => todo ! ( ) ,
585
597
Opcode :: ToBCD => todo ! ( ) ,
586
- Opcode :: Revision => todo ! ( ) ,
587
- Opcode :: Debug => todo ! ( ) ,
588
- Opcode :: Fatal => todo ! ( ) ,
589
- Opcode :: Timer => todo ! ( ) ,
598
+ Opcode :: Revision => {
599
+ context. contribute_arg ( Argument :: Object ( Arc :: new ( Object :: Integer ( INTERPRETER_REVISION ) ) ) ) ;
600
+ }
601
+ Opcode :: Debug => {
602
+ context. contribute_arg ( Argument :: Object ( Arc :: new ( Object :: Debug ) ) ) ;
603
+ }
604
+ Opcode :: Fatal => {
605
+ let typ = context. next ( ) ?;
606
+ let code = context. next_u32 ( ) ?;
607
+ context. start_in_flight_op ( OpInFlight :: new_with (
608
+ Opcode :: Fatal ,
609
+ vec ! [ Argument :: ByteData ( typ) , Argument :: DWordData ( code) ] ,
610
+ 1 ,
611
+ ) ) ;
612
+ }
613
+ Opcode :: Timer => {
614
+ // Time has to be monotonically-increasing, in 100ns units
615
+ let time = self . handler . nanos_since_boot ( ) / 100 ;
616
+ context. contribute_arg ( Argument :: Object ( Arc :: new ( Object :: Integer ( time) ) ) ) ;
617
+ }
590
618
Opcode :: OpRegion => {
591
619
let name = context. namestring ( ) ?;
592
620
let region_space = context. next ( ) ?;
@@ -1009,10 +1037,16 @@ where
1009
1037
}
1010
1038
_ => panic ! ( ) ,
1011
1039
} ,
1040
+ Object :: Debug => {
1041
+ self . handler . handle_debug ( & * object) ;
1042
+ }
1012
1043
_ => panic ! ( "Stores to objects like {:?} are not yet supported" , target) ,
1013
1044
} ,
1045
+
1014
1046
Argument :: Namestring ( _) => { }
1015
- Argument :: ByteData ( _) | Argument :: TrackedPc ( _) | Argument :: PkgLength ( _) => panic ! ( ) ,
1047
+ Argument :: ByteData ( _) | Argument :: DWordData ( _) | Argument :: TrackedPc ( _) | Argument :: PkgLength ( _) => {
1048
+ panic ! ( )
1049
+ }
1016
1050
}
1017
1051
Ok ( ( ) )
1018
1052
}
@@ -1050,6 +1084,7 @@ enum Argument {
1050
1084
Object ( Arc < Object > ) ,
1051
1085
Namestring ( AmlName ) ,
1052
1086
ByteData ( u8 ) ,
1087
+ DWordData ( u32 ) ,
1053
1088
TrackedPc ( usize ) ,
1054
1089
PkgLength ( usize ) ,
1055
1090
}
@@ -1608,6 +1643,9 @@ pub trait Handler: Send + Sync {
1608
1643
fn write_pci_u16 ( & self , segment : u16 , bus : u8 , device : u8 , function : u8 , offset : u16 , value : u16 ) ;
1609
1644
fn write_pci_u32 ( & self , segment : u16 , bus : u8 , device : u8 , function : u8 , offset : u16 , value : u32 ) ;
1610
1645
1646
+ /// Returns a monotonically-increasing value of nanoseconds.
1647
+ fn nanos_since_boot ( & self ) -> u64 ;
1648
+
1611
1649
/// Stall for at least the given number of **microseconds**. An implementation should not relinquish control of
1612
1650
/// the processor during the stall, and for this reason, firmwares should not stall for periods of more than
1613
1651
/// 100 microseconds.
@@ -1619,9 +1657,11 @@ pub trait Handler: Send + Sync {
1619
1657
1620
1658
fn breakpoint ( & self ) { }
1621
1659
1660
+ fn handle_debug ( & self , _object : & Object ) { }
1661
+
1622
1662
fn handle_fatal_error ( & self , fatal_type : u8 , fatal_code : u32 , fatal_arg : u64 ) {
1623
1663
panic ! (
1624
- "Fatal error while executing AML (encountered DefFatalOp). fatal_type = {:? }, fatal_code = {:? }, fatal_arg = {:? }" ,
1664
+ "Fatal error while executing AML (encountered DefFatalOp). fatal_type = {}, fatal_code = {}, fatal_arg = {}" ,
1625
1665
fatal_type, fatal_code, fatal_arg
1626
1666
) ;
1627
1667
}
@@ -1655,6 +1695,7 @@ mod tests {
1655
1695
fn write_pci_u8 ( & self , _segment : u16 , _bus : u8 , _device : u8 , _function : u8 , _offset : u16 , _value : u8 ) { }
1656
1696
fn write_pci_u16 ( & self , _segment : u16 , _bus : u8 , _device : u8 , _function : u8 , _offset : u16 , _value : u16 ) { }
1657
1697
fn write_pci_u32 ( & self , _segment : u16 , _bus : u8 , _device : u8 , _function : u8 , _offset : u16 , _value : u32 ) { }
1698
+ fn nanos_since_boot ( & self ) -> u64 { 0 }
1658
1699
fn stall ( & self , _microseconds : u64 ) { }
1659
1700
fn sleep ( & self , _milliseconds : u64 ) { }
1660
1701
}
0 commit comments