Skip to content

Commit da56475

Browse files
committed
kernel: syscall: add support for return_scalar5
Add kernel support for returning 5 scalars. Signed-off-by: Sean Cross <[email protected]>
1 parent c8bb039 commit da56475

File tree

1 file changed

+82
-1
lines changed

1 file changed

+82
-1
lines changed

kernel/src/syscall.rs

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,84 @@ fn return_scalar2(
538538
})
539539
}
540540

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+
541619
fn receive_message(pid: PID, tid: TID, sid: SID, blocking: ExecutionType) -> SysCallResult {
542620
SystemServices::with_mut(|ss| {
543621
assert!(
@@ -855,6 +933,9 @@ pub fn handle_inner(pid: PID, tid: TID, in_irq: bool, call: SysCall) -> SysCallR
855933
SysCall::ReturnScalar2(sender, arg1, arg2) => {
856934
return_scalar2(pid, tid, in_irq, sender, arg1, arg2)
857935
}
936+
SysCall::ReturnScalar5(sender, arg1, arg2, arg3, arg4, arg5) => {
937+
return_scalar5(pid, tid, in_irq, sender, arg1, arg2, arg3, arg4, arg5)
938+
}
858939
SysCall::TrySendMessage(cid, message) => send_message(pid, tid, cid, message),
859940
SysCall::TerminateProcess(_ret) => SystemServices::with_mut(|ss| {
860941
ss.unschedule_thread(pid, tid)?;
@@ -936,7 +1017,7 @@ pub fn handle_inner(pid: PID, tid: TID, in_irq: bool, call: SysCall) -> SysCallR
9361017
}),
9371018
_ => Err(xous_kernel::Error::InvalidLimit),
9381019
},
939-
#[cfg(feature="v2p")]
1020+
#[cfg(feature = "v2p")]
9401021
SysCall::VirtToPhys(vaddr) => {
9411022
let phys_addr = crate::arch::mem::virt_to_phys(vaddr as usize);
9421023
match phys_addr {

0 commit comments

Comments
 (0)