3535unsafe impl < H > Send for Interpreter < H > where H : Handler + Send { }
3636unsafe impl < H > Sync for Interpreter < H > where H : Handler + Send { }
3737
38+ /// The value returned by the `Revision` opcode.
39+ const INTERPRETER_REVISION : u64 = 1 ;
40+
3841impl < H > Interpreter < H >
3942where
4043 H : Handler ,
@@ -153,6 +156,15 @@ where
153156 let name = name. resolve ( & context. current_scope ) ?;
154157 self . namespace . lock ( ) . insert ( name, object. clone ( ) ) ?;
155158 }
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+ }
156168 Opcode :: OpRegion => {
157169 let [
158170 Argument :: Namestring ( name) ,
@@ -346,7 +358,6 @@ where
346358 let [ Argument :: Object ( object) ] = & op. arguments [ ..] else { panic ! ( ) } ;
347359 // TODO: this should technically support scopes as well - this is less easy
348360 // (they should return `0`)
349- // TODO: calling this on the debug object should should return `16`
350361 let typ = match object. typ ( ) {
351362 ObjectType :: Uninitialized => 0 ,
352363 ObjectType :: Integer => 1 ,
@@ -364,6 +375,7 @@ where
364375 ObjectType :: ThermalZone => 13 ,
365376 ObjectType :: BufferField => 14 ,
366377 // XXX: 15 is reserved
378+ ObjectType :: Debug => 16 ,
367379 ObjectType :: Reference => panic ! ( ) ,
368380 ObjectType :: RawDataBuffer => todo ! ( ) ,
369381 } ;
@@ -583,10 +595,26 @@ where
583595 Opcode :: Release => todo ! ( ) ,
584596 Opcode :: FromBCD => todo ! ( ) ,
585597 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+ }
590618 Opcode :: OpRegion => {
591619 let name = context. namestring ( ) ?;
592620 let region_space = context. next ( ) ?;
@@ -1009,10 +1037,16 @@ where
10091037 }
10101038 _ => panic ! ( ) ,
10111039 } ,
1040+ Object :: Debug => {
1041+ self . handler . handle_debug ( & * object) ;
1042+ }
10121043 _ => panic ! ( "Stores to objects like {:?} are not yet supported" , target) ,
10131044 } ,
1045+
10141046 Argument :: Namestring ( _) => { }
1015- Argument :: ByteData ( _) | Argument :: TrackedPc ( _) | Argument :: PkgLength ( _) => panic ! ( ) ,
1047+ Argument :: ByteData ( _) | Argument :: DWordData ( _) | Argument :: TrackedPc ( _) | Argument :: PkgLength ( _) => {
1048+ panic ! ( )
1049+ }
10161050 }
10171051 Ok ( ( ) )
10181052 }
@@ -1050,6 +1084,7 @@ enum Argument {
10501084 Object ( Arc < Object > ) ,
10511085 Namestring ( AmlName ) ,
10521086 ByteData ( u8 ) ,
1087+ DWordData ( u32 ) ,
10531088 TrackedPc ( usize ) ,
10541089 PkgLength ( usize ) ,
10551090}
@@ -1608,6 +1643,9 @@ pub trait Handler: Send + Sync {
16081643 fn write_pci_u16 ( & self , segment : u16 , bus : u8 , device : u8 , function : u8 , offset : u16 , value : u16 ) ;
16091644 fn write_pci_u32 ( & self , segment : u16 , bus : u8 , device : u8 , function : u8 , offset : u16 , value : u32 ) ;
16101645
1646+ /// Returns a monotonically-increasing value of nanoseconds.
1647+ fn nanos_since_boot ( & self ) -> u64 ;
1648+
16111649 /// Stall for at least the given number of **microseconds**. An implementation should not relinquish control of
16121650 /// the processor during the stall, and for this reason, firmwares should not stall for periods of more than
16131651 /// 100 microseconds.
@@ -1619,9 +1657,11 @@ pub trait Handler: Send + Sync {
16191657
16201658 fn breakpoint ( & self ) { }
16211659
1660+ fn handle_debug ( & self , _object : & Object ) { }
1661+
16221662 fn handle_fatal_error ( & self , fatal_type : u8 , fatal_code : u32 , fatal_arg : u64 ) {
16231663 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 = {}" ,
16251665 fatal_type, fatal_code, fatal_arg
16261666 ) ;
16271667 }
@@ -1655,6 +1695,7 @@ mod tests {
16551695 fn write_pci_u8 ( & self , _segment : u16 , _bus : u8 , _device : u8 , _function : u8 , _offset : u16 , _value : u8 ) { }
16561696 fn write_pci_u16 ( & self , _segment : u16 , _bus : u8 , _device : u8 , _function : u8 , _offset : u16 , _value : u16 ) { }
16571697 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 }
16581699 fn stall ( & self , _microseconds : u64 ) { }
16591700 fn sleep ( & self , _milliseconds : u64 ) { }
16601701 }
0 commit comments