@@ -538,6 +538,84 @@ fn return_scalar2(
538
538
} )
539
539
}
540
540
541
+ fn return_scalar5 (
542
+ server_pid : PID ,
543
+ server_tid : TID ,
544
+ in_irq : bool ,
545
+ sender : MessageSender ,
546
+ arg1 : usize ,
547
+ arg2 : usize ,
548
+ arg3 : usize ,
549
+ arg4 : usize ,
550
+ arg5 : usize ,
551
+ ) -> SysCallResult {
552
+ SystemServices :: with_mut ( |ss| {
553
+ let sender = SenderID :: from ( sender) ;
554
+
555
+ let server = ss
556
+ . server_from_sidx_mut ( sender. sidx )
557
+ . ok_or ( xous_kernel:: Error :: ServerNotFound ) ?;
558
+ // .expect("Couldn't get server from SIDX");
559
+ if server. pid != server_pid {
560
+ return Err ( xous_kernel:: Error :: ServerNotFound ) ;
561
+ }
562
+ let result = server. take_waiting_message ( sender. idx , None ) ?;
563
+ let ( client_pid, client_tid) = match result {
564
+ WaitingMessage :: ScalarMessage ( pid, tid) => ( pid, tid) ,
565
+ WaitingMessage :: ForgetMemory ( _) => {
566
+ println ! ( "WARNING: Tried to wait on a scalar message that was actually forgetting memory" ) ;
567
+ return Err ( xous_kernel:: Error :: ProcessNotFound ) ;
568
+ }
569
+ WaitingMessage :: BorrowedMemory ( _, _, _, _, _) => {
570
+ println ! (
571
+ "WARNING: Tried to wait on a scalar message that was actually borrowed memory"
572
+ ) ;
573
+ return Err ( xous_kernel:: Error :: ProcessNotFound ) ;
574
+ }
575
+ WaitingMessage :: MovedMemory => {
576
+ println ! (
577
+ "WARNING: Tried to wait on a scalar message that was actually moved memory"
578
+ ) ;
579
+ return Err ( xous_kernel:: Error :: ProcessNotFound ) ;
580
+ }
581
+ WaitingMessage :: None => {
582
+ println ! ( "WARNING: Tried to wait on a message that didn't exist" ) ;
583
+ return Err ( xous_kernel:: Error :: ProcessNotFound ) ;
584
+ }
585
+ } ;
586
+
587
+ let client_is_runnable = ss. runnable ( client_pid, Some ( client_tid) ) ?;
588
+
589
+ if !cfg ! ( baremetal) || in_irq || !client_is_runnable {
590
+ // In a hosted environment, `switch_to_thread()` doesn't continue
591
+ // execution from the new thread. Instead it continues in the old
592
+ // thread. Therefore, we need to instruct the client to resume, and
593
+ // return to the server.
594
+ // In a baremetal environment, the opposite is true -- we instruct
595
+ // the server to resume and return to the client.
596
+ ss. set_thread_result (
597
+ client_pid,
598
+ client_tid,
599
+ xous_kernel:: Result :: Scalar5 ( arg1, arg2, arg3, arg4, arg5) ,
600
+ ) ?;
601
+ if cfg ! ( baremetal) {
602
+ ss. ready_thread ( client_pid, client_tid) ?;
603
+ }
604
+ Ok ( xous_kernel:: Result :: Ok )
605
+ } else {
606
+ // Switch away from the server, but leave it as Runnable
607
+ ss. unschedule_thread ( server_pid, server_tid) ?;
608
+ ss. ready_thread ( server_pid, server_tid) ?;
609
+ ss. set_thread_result ( server_pid, server_tid, xous_kernel:: Result :: Ok ) ?;
610
+
611
+ // Switch to the client
612
+ ss. ready_thread ( client_pid, client_tid) ?;
613
+ ss. switch_to_thread ( client_pid, Some ( client_tid) ) ?;
614
+ Ok ( xous_kernel:: Result :: Scalar5 ( arg1, arg2, arg3, arg4, arg5) )
615
+ }
616
+ } )
617
+ }
618
+
541
619
fn receive_message ( pid : PID , tid : TID , sid : SID , blocking : ExecutionType ) -> SysCallResult {
542
620
SystemServices :: with_mut ( |ss| {
543
621
assert ! (
@@ -855,6 +933,9 @@ pub fn handle_inner(pid: PID, tid: TID, in_irq: bool, call: SysCall) -> SysCallR
855
933
SysCall :: ReturnScalar2 ( sender, arg1, arg2) => {
856
934
return_scalar2 ( pid, tid, in_irq, sender, arg1, arg2)
857
935
}
936
+ SysCall :: ReturnScalar5 ( sender, arg1, arg2, arg3, arg4, arg5) => {
937
+ return_scalar5 ( pid, tid, in_irq, sender, arg1, arg2, arg3, arg4, arg5)
938
+ }
858
939
SysCall :: TrySendMessage ( cid, message) => send_message ( pid, tid, cid, message) ,
859
940
SysCall :: TerminateProcess ( _ret) => SystemServices :: with_mut ( |ss| {
860
941
ss. unschedule_thread ( pid, tid) ?;
@@ -936,7 +1017,7 @@ pub fn handle_inner(pid: PID, tid: TID, in_irq: bool, call: SysCall) -> SysCallR
936
1017
} ) ,
937
1018
_ => Err ( xous_kernel:: Error :: InvalidLimit ) ,
938
1019
} ,
939
- #[ cfg( feature= "v2p" ) ]
1020
+ #[ cfg( feature = "v2p" ) ]
940
1021
SysCall :: VirtToPhys ( vaddr) => {
941
1022
let phys_addr = crate :: arch:: mem:: virt_to_phys ( vaddr as usize ) ;
942
1023
match phys_addr {
0 commit comments