Nothing to see here, move along
1use crate::cap::cnode;
2use crate::cap::object::ObjectTag;
3use crate::cap::pool::POOL;
4use crate::cap::table::Rights;
5use crate::error::KernelError;
6use crate::ipc::IpcOutcome;
7use crate::ipc::notification;
8use crate::proc::PROCESSES;
9use crate::proc::context::CpuContext;
10use crate::syscall::{SyscallResult, try_syscall};
11
12pub fn sys_notify_signal(ctx: &mut CpuContext) {
13 let cap_addr = ctx.rdi;
14 let bits = ctx.rsi;
15 let pid = crate::arch::syscall::current_pid();
16
17 let mut ptable = PROCESSES.lock();
18 let cap = {
19 let pool = POOL.lock_after(&ptable);
20 try_syscall!(
21 ctx,
22 cnode::resolve_caller_validate(
23 pid,
24 cap_addr,
25 ObjectTag::Notification,
26 Rights::WRITE,
27 &ptable,
28 &pool
29 )
30 )
31 };
32
33 let woke = match notification::do_signal(&cap, bits, &mut ptable) {
34 Ok(woke) => {
35 ctx.rax = SyscallResult::ok().raw();
36 woke
37 }
38 Err(e) => {
39 ctx.rax = SyscallResult::error(e).raw();
40 return;
41 }
42 };
43
44 drop(ptable);
45 if woke {
46 crate::sched::schedule(ctx);
47 }
48}
49
50pub fn sys_notify_wait(ctx: &mut CpuContext) {
51 let cap_addr = ctx.rdi;
52 let pid = crate::arch::syscall::current_pid();
53
54 let mut ptable = PROCESSES.lock();
55 let cap = {
56 let pool = POOL.lock_after(&ptable);
57 try_syscall!(
58 ctx,
59 cnode::resolve_caller_validate(
60 pid,
61 cap_addr,
62 ObjectTag::Notification,
63 Rights::READ,
64 &ptable,
65 &pool
66 )
67 )
68 };
69
70 match notification::do_wait(&cap, pid, &mut ptable) {
71 Ok(IpcOutcome::Done(val)) => {
72 ctx.rax = SyscallResult::ok().raw();
73 ctx.rdx = val;
74 }
75 Ok(IpcOutcome::Blocked) => {
76 ctx.rax = SyscallResult::ok().raw();
77 drop(ptable);
78 crate::sched::schedule(ctx);
79 }
80 Err(e) => ctx.rax = SyscallResult::error(e).raw(),
81 }
82}
83
84pub fn sys_notify_poll(ctx: &mut CpuContext) {
85 let cap_addr = ctx.rdi;
86 let pid = crate::arch::syscall::current_pid();
87
88 let ptable = PROCESSES.lock();
89 let cap = {
90 let pool = POOL.lock_after(&ptable);
91 try_syscall!(
92 ctx,
93 cnode::resolve_caller_validate(
94 pid,
95 cap_addr,
96 ObjectTag::Notification,
97 Rights::READ,
98 &ptable,
99 &pool
100 )
101 )
102 };
103
104 drop(ptable);
105
106 match notification::do_poll(&cap) {
107 Ok(val) => {
108 ctx.rax = SyscallResult::ok().raw();
109 ctx.rdx = val;
110 }
111 Err(e) => ctx.rax = SyscallResult::error(e).raw(),
112 };
113}
114
115pub fn sys_ntfn_bind(ctx: &mut CpuContext) {
116 let cap_addr = ctx.rdi;
117 let pid = crate::arch::syscall::current_pid();
118
119 let mut ptable = PROCESSES.lock();
120 let (notif_id, notif_gen) = {
121 let pool = POOL.lock_after(&ptable);
122 let cap = try_syscall!(
123 ctx,
124 cnode::resolve_caller_validate(
125 pid,
126 cap_addr,
127 ObjectTag::Notification,
128 Rights::READ,
129 &ptable,
130 &pool
131 )
132 );
133 (cap.phys(), cap.generation())
134 };
135
136 match ptable.get_mut(pid) {
137 Some(proc) => {
138 proc.bind_notification(notif_id, notif_gen);
139 ctx.rax = SyscallResult::ok().raw();
140 }
141 None => {
142 ctx.rax = SyscallResult::error(KernelError::InvalidObject).raw();
143 }
144 }
145}
146
147pub fn sys_ntfn_unbind(ctx: &mut CpuContext) {
148 let pid = crate::arch::syscall::current_pid();
149
150 let mut ptable = PROCESSES.lock();
151 match ptable.get_mut(pid) {
152 Some(proc) => {
153 proc.unbind_notification();
154 ctx.rax = SyscallResult::ok().raw();
155 }
156 None => {
157 ctx.rax = SyscallResult::error(KernelError::InvalidObject).raw();
158 }
159 }
160}