@@ -464,6 +464,91 @@ where
464464 context. contribute_arg ( Argument :: Object ( result) ) ;
465465 context. retire_op ( op) ;
466466 }
467+ Opcode :: Reset => {
468+ let [ Argument :: Object ( sync_object) ] = & op. arguments [ ..] else {
469+ panic ! ( ) ;
470+ } ;
471+ let sync_object = sync_object. clone ( ) . unwrap_reference ( ) ;
472+
473+ if let Object :: Event ( ref counter) = * sync_object {
474+ counter. store ( 0 , Ordering :: Release ) ;
475+ } else {
476+ return Err ( AmlError :: InvalidOperationOnObject {
477+ op : Operation :: ResetEvent ,
478+ typ : sync_object. typ ( ) ,
479+ } ) ;
480+ }
481+ }
482+ Opcode :: Signal => {
483+ let [ Argument :: Object ( sync_object) ] = & op. arguments [ ..] else {
484+ panic ! ( ) ;
485+ } ;
486+ let sync_object = sync_object. clone ( ) . unwrap_reference ( ) ;
487+
488+ if let Object :: Event ( ref counter) = * sync_object {
489+ counter. fetch_add ( 1 , Ordering :: AcqRel ) ;
490+ } else {
491+ return Err ( AmlError :: InvalidOperationOnObject {
492+ op : Operation :: SignalEvent ,
493+ typ : sync_object. typ ( ) ,
494+ } ) ;
495+ }
496+ }
497+ Opcode :: Wait => {
498+ let [ Argument :: Object ( sync_object) , Argument :: Object ( timeout) ] = & op. arguments [ ..] else {
499+ panic ! ( ) ;
500+ } ;
501+ let sync_object = sync_object. clone ( ) . unwrap_reference ( ) ;
502+ let timeout = u64:: min ( timeout. as_integer ( ) ?, 0xffff ) ;
503+
504+ if let Object :: Event ( ref counter) = * sync_object {
505+ /*
506+ * `Wait` returns a non-zero value if a timeout occurs and the event
507+ * was not signaled, and zero if it was. Timeout is specified in
508+ * milliseconds, should relinquish processor control (we use
509+ * `Handler::sleep` to do so) and a value of `0xffff` specifies that
510+ * the operation should wait indefinitely.
511+ */
512+ let mut remaining_sleep = timeout;
513+ let mut timed_out = true ;
514+
515+ ' signaled: while remaining_sleep > 0 {
516+ loop {
517+ /*
518+ * Try to decrement the counter. If it's zero after a load, we
519+ * haven't been signalled and should wait for a bit. If it's
520+ * non-zero, we were signalled and should stop waiting.
521+ */
522+ let value = counter. load ( Ordering :: Acquire ) ;
523+ if value == 0 {
524+ break ;
525+ }
526+ if counter
527+ . compare_exchange ( value, value - 1 , Ordering :: AcqRel , Ordering :: Acquire )
528+ . is_ok ( )
529+ {
530+ timed_out = false ;
531+ break ' signaled;
532+ }
533+ }
534+
535+ let to_sleep = u64:: min ( timeout, 10 ) ;
536+ if timeout < 0xffff {
537+ remaining_sleep -= to_sleep
538+ }
539+ self . handler . sleep ( to_sleep) ;
540+ }
541+
542+ context. contribute_arg ( Argument :: Object (
543+ Object :: Integer ( if timed_out { u64:: MAX } else { 0 } ) . wrap ( ) ,
544+ ) ) ;
545+ } else {
546+ return Err ( AmlError :: InvalidOperationOnObject {
547+ op : Operation :: WaitEvent ,
548+ typ : sync_object. typ ( ) ,
549+ } ) ;
550+ }
551+ }
467552 Opcode :: FromBCD => self . do_from_bcd ( & mut context, op) ?,
468553 Opcode :: ToBCD => self . do_to_bcd ( & mut context, op) ?,
469554 Opcode :: Name => {
@@ -1158,9 +1243,9 @@ where
11581243 Opcode :: Sleep => context. start_in_flight_op ( OpInFlight :: new ( Opcode :: Sleep , 1 ) ) ,
11591244 Opcode :: Acquire => context. start_in_flight_op ( OpInFlight :: new ( opcode, 1 ) ) ,
11601245 Opcode :: Release => context. start_in_flight_op ( OpInFlight :: new ( opcode, 1 ) ) ,
1161- Opcode :: Signal => todo ! ( ) ,
1162- Opcode :: Wait => todo ! ( ) ,
1163- Opcode :: Reset => todo ! ( ) ,
1246+ Opcode :: Signal => context . start_in_flight_op ( OpInFlight :: new ( opcode , 1 ) ) ,
1247+ Opcode :: Wait => context . start_in_flight_op ( OpInFlight :: new ( opcode , 2 ) ) ,
1248+ Opcode :: Reset => context . start_in_flight_op ( OpInFlight :: new ( opcode , 1 ) ) ,
11641249 Opcode :: Notify => todo ! ( ) ,
11651250 Opcode :: FromBCD | Opcode :: ToBCD => context. start_in_flight_op ( OpInFlight :: new ( opcode, 2 ) ) ,
11661251 Opcode :: Revision => {
@@ -3033,6 +3118,10 @@ pub enum Operation {
30333118 LogicalOp ,
30343119 DecodePrt ,
30353120 ParseResource ,
3121+
3122+ ResetEvent ,
3123+ SignalEvent ,
3124+ WaitEvent ,
30363125}
30373126
30383127#[ derive( Clone , PartialEq , Debug ) ]
0 commit comments