Add a rust user-space Capability struct.
This is a thin wrapper around a capability ptr that releases the capability when it is done and prevents copying/cloning it. To get a copy a caller must explicitly use duplicate.
This commit is contained in:
parent
19a8ab41d4
commit
7e68c1b641
18 changed files with 215 additions and 152 deletions
|
|
@ -1,5 +1,6 @@
|
|||
extern crate alloc;
|
||||
|
||||
use crate::cap::Capability;
|
||||
use crate::zion;
|
||||
use crate::zion::z_cap_t;
|
||||
use crate::zion::ZError;
|
||||
|
|
@ -41,9 +42,9 @@ pub fn debug(msg: &str) {
|
|||
}
|
||||
|
||||
pub fn process_spawn(
|
||||
proc_cap: z_cap_t,
|
||||
bootstrap_cap: z_cap_t,
|
||||
) -> Result<(z_cap_t, z_cap_t, z_cap_t), ZError> {
|
||||
proc_cap: &Capability,
|
||||
bootstrap_cap: Capability,
|
||||
) -> Result<(Capability, Capability, u64), ZError> {
|
||||
let mut new_proc_cap = 0;
|
||||
let mut new_as_cap = 0;
|
||||
let mut new_bootstrap_cap = 0;
|
||||
|
|
@ -51,15 +52,19 @@ pub fn process_spawn(
|
|||
syscall(
|
||||
zion::kZionProcessSpawn,
|
||||
&zion::ZProcessSpawnReq {
|
||||
proc_cap,
|
||||
bootstrap_cap,
|
||||
proc_cap: proc_cap.raw(),
|
||||
bootstrap_cap: bootstrap_cap.release(),
|
||||
new_proc_cap: &mut new_proc_cap,
|
||||
new_vmas_cap: &mut new_as_cap,
|
||||
new_bootstrap_cap: &mut new_bootstrap_cap,
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok((new_proc_cap, new_as_cap, new_bootstrap_cap))
|
||||
Ok((
|
||||
Capability::take(new_proc_cap),
|
||||
Capability::take(new_as_cap),
|
||||
new_bootstrap_cap,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn process_exit(code: u64) -> ! {
|
||||
|
|
@ -68,39 +73,44 @@ pub fn process_exit(code: u64) -> ! {
|
|||
unreachable!()
|
||||
}
|
||||
|
||||
pub fn process_wait(proc_cap: z_cap_t) -> Result<u64, ZError> {
|
||||
pub fn process_wait(proc_cap: &Capability) -> Result<u64, ZError> {
|
||||
let mut err_code = 0;
|
||||
syscall(
|
||||
zion::kZionProcessWait,
|
||||
&zion::ZProcessWaitReq {
|
||||
proc_cap,
|
||||
proc_cap: proc_cap.raw(),
|
||||
exit_code: &mut err_code,
|
||||
},
|
||||
)?;
|
||||
Ok(err_code)
|
||||
}
|
||||
|
||||
pub fn thread_create(proc_cap: z_cap_t) -> Result<z_cap_t, ZError> {
|
||||
pub fn thread_create(proc_cap: &Capability) -> Result<Capability, ZError> {
|
||||
let mut cap = 0;
|
||||
syscall(
|
||||
zion::kZionThreadCreate,
|
||||
&zion::ZThreadCreateReq {
|
||||
proc_cap,
|
||||
thread_cap: &mut cap as *mut z_cap_t,
|
||||
proc_cap: proc_cap.raw(),
|
||||
thread_cap: &mut cap,
|
||||
},
|
||||
)?;
|
||||
Ok(cap)
|
||||
Ok(Capability::take(cap))
|
||||
}
|
||||
|
||||
pub fn thread_sleep(millis: u64) -> Result<(), ZError> {
|
||||
syscall(zion::kZionThreadSleep, &zion::ZThreadSleepReq { millis })
|
||||
}
|
||||
|
||||
pub fn thread_start(thread_cap: z_cap_t, entry: u64, arg1: u64, arg2: u64) -> Result<(), ZError> {
|
||||
pub fn thread_start(
|
||||
thread_cap: &Capability,
|
||||
entry: u64,
|
||||
arg1: u64,
|
||||
arg2: u64,
|
||||
) -> Result<(), ZError> {
|
||||
syscall(
|
||||
zion::kZionThreadStart,
|
||||
&zion::ZThreadStartReq {
|
||||
thread_cap,
|
||||
thread_cap: thread_cap.raw(),
|
||||
entry,
|
||||
arg1,
|
||||
arg2,
|
||||
|
|
@ -108,8 +118,13 @@ pub fn thread_start(thread_cap: z_cap_t, entry: u64, arg1: u64, arg2: u64) -> Re
|
|||
)
|
||||
}
|
||||
|
||||
pub fn thread_wait(thread_cap: z_cap_t) -> Result<(), ZError> {
|
||||
syscall(zion::kZionThreadWait, &zion::ZThreadWaitReq { thread_cap })
|
||||
pub fn thread_wait(thread_cap: &Capability) -> Result<(), ZError> {
|
||||
syscall(
|
||||
zion::kZionThreadWait,
|
||||
&zion::ZThreadWaitReq {
|
||||
thread_cap: thread_cap.raw(),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn thread_exit() -> ! {
|
||||
|
|
@ -117,17 +132,17 @@ pub fn thread_exit() -> ! {
|
|||
unreachable!();
|
||||
}
|
||||
|
||||
pub fn memory_object_create(size: u64) -> Result<z_cap_t, ZError> {
|
||||
pub fn memory_object_create(size: u64) -> Result<Capability, ZError> {
|
||||
let mut vmmo_cap = 0;
|
||||
let obj_req = zion::ZMemoryObjectCreateReq {
|
||||
size,
|
||||
vmmo_cap: &mut vmmo_cap as *mut u64,
|
||||
};
|
||||
syscall(zion::kZionMemoryObjectCreate, &obj_req)?;
|
||||
Ok(vmmo_cap)
|
||||
Ok(Capability::take(vmmo_cap))
|
||||
}
|
||||
|
||||
pub fn memory_object_direct_physical(paddr: u64, size: u64) -> Result<z_cap_t, ZError> {
|
||||
pub fn memory_object_direct_physical(paddr: u64, size: u64) -> Result<Capability, ZError> {
|
||||
let mut vmmo_cap = 0;
|
||||
syscall(
|
||||
zion::kZionMemoryObjectCreatePhysical,
|
||||
|
|
@ -137,26 +152,26 @@ pub fn memory_object_direct_physical(paddr: u64, size: u64) -> Result<z_cap_t, Z
|
|||
vmmo_cap: &mut vmmo_cap,
|
||||
},
|
||||
)?;
|
||||
Ok(vmmo_cap)
|
||||
Ok(Capability::take(vmmo_cap))
|
||||
}
|
||||
|
||||
pub fn memory_object_inspect(mem_cap: z_cap_t) -> Result<u64, ZError> {
|
||||
pub fn memory_object_inspect(mem_cap: &Capability) -> Result<u64, ZError> {
|
||||
let mut mem_size = 0;
|
||||
syscall(
|
||||
zion::kZionMemoryObjectInspect,
|
||||
&zion::ZMemoryObjectInspectReq {
|
||||
vmmo_cap: mem_cap,
|
||||
vmmo_cap: mem_cap.raw(),
|
||||
size: &mut mem_size,
|
||||
},
|
||||
)?;
|
||||
Ok(mem_size)
|
||||
}
|
||||
|
||||
pub fn address_space_map(vmmo_cap: z_cap_t) -> Result<u64, ZError> {
|
||||
pub fn address_space_map(vmmo_cap: &Capability) -> Result<u64, ZError> {
|
||||
let mut vaddr: u64 = 0;
|
||||
// FIXME: Allow caller to pass these options.
|
||||
let vmas_req = zion::ZAddressSpaceMapReq {
|
||||
vmmo_cap,
|
||||
vmmo_cap: vmmo_cap.raw(),
|
||||
vmas_cap: unsafe { crate::init::SELF_VMAS_CAP },
|
||||
align: 0x2000,
|
||||
vaddr: &mut vaddr as *mut u64,
|
||||
|
|
@ -168,14 +183,14 @@ pub fn address_space_map(vmmo_cap: z_cap_t) -> Result<u64, ZError> {
|
|||
}
|
||||
|
||||
pub fn address_space_map_external(
|
||||
vmas_cap: z_cap_t,
|
||||
vmmo_cap: z_cap_t,
|
||||
vmas_cap: &Capability,
|
||||
vmmo_cap: &Capability,
|
||||
vaddr: u64,
|
||||
) -> Result<(), ZError> {
|
||||
let mut vaddr_throw: u64 = 0;
|
||||
let vmas_req = zion::ZAddressSpaceMapReq {
|
||||
vmmo_cap,
|
||||
vmas_cap,
|
||||
vmas_cap: vmas_cap.raw(),
|
||||
vmmo_cap: vmmo_cap.raw(),
|
||||
align: 0,
|
||||
vaddr: &mut vaddr_throw as *mut u64,
|
||||
vmas_offset: vaddr,
|
||||
|
|
@ -196,7 +211,7 @@ pub fn address_space_unmap(lower_addr: u64, upper_addr: u64) -> Result<(), ZErro
|
|||
)
|
||||
}
|
||||
|
||||
pub fn port_create() -> Result<z_cap_t, ZError> {
|
||||
pub fn port_create() -> Result<Capability, ZError> {
|
||||
let mut port_cap = 0;
|
||||
syscall(
|
||||
zion::kZionPortCreate,
|
||||
|
|
@ -204,14 +219,14 @@ pub fn port_create() -> Result<z_cap_t, ZError> {
|
|||
port_cap: &mut port_cap,
|
||||
},
|
||||
)?;
|
||||
Ok(port_cap)
|
||||
Ok(Capability::take(port_cap))
|
||||
}
|
||||
|
||||
pub fn port_send(port_cap: z_cap_t, bytes: &[u8], caps: &mut [z_cap_t]) -> Result<(), ZError> {
|
||||
pub fn port_send(port_cap: &Capability, bytes: &[u8], caps: &mut [z_cap_t]) -> Result<(), ZError> {
|
||||
syscall(
|
||||
zion::kZionPortSend,
|
||||
&zion::ZPortSendReq {
|
||||
port_cap,
|
||||
port_cap: port_cap.raw(),
|
||||
num_bytes: bytes.len() as u64,
|
||||
data: bytes.as_ptr() as *const c_void,
|
||||
num_caps: caps.len() as u64,
|
||||
|
|
@ -222,7 +237,7 @@ pub fn port_send(port_cap: z_cap_t, bytes: &[u8], caps: &mut [z_cap_t]) -> Resul
|
|||
}
|
||||
|
||||
pub fn port_recv(
|
||||
port_cap: z_cap_t,
|
||||
port_cap: &Capability,
|
||||
bytes: &mut [u8],
|
||||
caps: &mut [u64],
|
||||
) -> Result<(u64, u64), ZError> {
|
||||
|
|
@ -231,7 +246,7 @@ pub fn port_recv(
|
|||
syscall(
|
||||
zion::kZionPortRecv,
|
||||
&zion::ZPortRecvReq {
|
||||
port_cap,
|
||||
port_cap: port_cap.raw(),
|
||||
data: bytes.as_mut_ptr() as *mut c_void,
|
||||
num_bytes: &mut num_bytes as *mut u64,
|
||||
caps: caps.as_mut_ptr(),
|
||||
|
|
@ -242,14 +257,14 @@ pub fn port_recv(
|
|||
}
|
||||
|
||||
pub fn port_poll(
|
||||
port_cap: z_cap_t,
|
||||
port_cap: &Capability,
|
||||
bytes: &mut [u8],
|
||||
caps: &mut [u64],
|
||||
) -> Result<(u64, u64), ZError> {
|
||||
let mut num_bytes = bytes.len() as u64;
|
||||
let mut num_caps = caps.len() as u64;
|
||||
let req = zion::ZPortPollReq {
|
||||
port_cap,
|
||||
port_cap: port_cap.raw(),
|
||||
data: bytes.as_mut_ptr() as *mut c_void,
|
||||
num_bytes: &mut num_bytes as *mut u64,
|
||||
caps: caps.as_mut_ptr(),
|
||||
|
|
@ -259,7 +274,7 @@ pub fn port_poll(
|
|||
Ok((num_bytes, num_caps))
|
||||
}
|
||||
|
||||
pub fn endpoint_create() -> Result<z_cap_t, ZError> {
|
||||
pub fn endpoint_create() -> Result<Capability, ZError> {
|
||||
let mut endpoint_cap: z_cap_t = 0;
|
||||
syscall(
|
||||
zion::kZionEndpointCreate,
|
||||
|
|
@ -267,19 +282,19 @@ pub fn endpoint_create() -> Result<z_cap_t, ZError> {
|
|||
endpoint_cap: &mut endpoint_cap,
|
||||
},
|
||||
)?;
|
||||
Ok(endpoint_cap)
|
||||
Ok(Capability::take(endpoint_cap))
|
||||
}
|
||||
|
||||
pub fn endpoint_send(
|
||||
endpoint_cap: z_cap_t,
|
||||
endpoint_cap: &Capability,
|
||||
bytes: &[u8],
|
||||
caps: &[z_cap_t],
|
||||
) -> Result<z_cap_t, ZError> {
|
||||
) -> Result<Capability, ZError> {
|
||||
let mut reply_port_cap: u64 = 0;
|
||||
let send_req = zion::ZEndpointSendReq {
|
||||
caps: caps.as_ptr(),
|
||||
num_caps: caps.len() as u64,
|
||||
endpoint_cap,
|
||||
endpoint_cap: endpoint_cap.raw(),
|
||||
data: bytes.as_ptr() as *const c_void,
|
||||
num_bytes: bytes.len() as u64,
|
||||
reply_port_cap: &mut reply_port_cap,
|
||||
|
|
@ -287,19 +302,19 @@ pub fn endpoint_send(
|
|||
|
||||
syscall(zion::kZionEndpointSend, &send_req)?;
|
||||
|
||||
Ok(reply_port_cap)
|
||||
Ok(Capability::take(reply_port_cap))
|
||||
}
|
||||
|
||||
pub fn endpoint_recv(
|
||||
endpoint_cap: z_cap_t,
|
||||
endpoint_cap: &Capability,
|
||||
bytes: &mut [u8],
|
||||
caps: &mut [z_cap_t],
|
||||
) -> Result<(u64, u64, z_cap_t), ZError> {
|
||||
) -> Result<(u64, u64, Capability), ZError> {
|
||||
let mut num_bytes = bytes.len() as u64;
|
||||
let mut num_caps = caps.len() as u64;
|
||||
let mut reply_port_cap = 0;
|
||||
let recv_req = zion::ZEndpointRecvReq {
|
||||
endpoint_cap,
|
||||
endpoint_cap: endpoint_cap.raw(),
|
||||
data: bytes.as_mut_ptr() as *mut c_void,
|
||||
num_bytes: &mut num_bytes,
|
||||
caps: caps.as_mut_ptr(),
|
||||
|
|
@ -309,18 +324,18 @@ pub fn endpoint_recv(
|
|||
|
||||
syscall(zion::kZionEndpointRecv, &recv_req)?;
|
||||
|
||||
Ok((num_bytes, num_caps, reply_port_cap))
|
||||
Ok((num_bytes, num_caps, Capability::take(reply_port_cap)))
|
||||
}
|
||||
|
||||
pub fn reply_port_send(
|
||||
reply_port_cap: z_cap_t,
|
||||
reply_port_cap: Capability,
|
||||
bytes: &[u8],
|
||||
caps: &[z_cap_t],
|
||||
) -> Result<(), ZError> {
|
||||
syscall(
|
||||
zion::kZionReplyPortSend,
|
||||
&zion::ZReplyPortSendReq {
|
||||
reply_port_cap,
|
||||
reply_port_cap: reply_port_cap.raw(),
|
||||
data: bytes.as_ptr() as *const c_void,
|
||||
num_bytes: bytes.len() as u64,
|
||||
caps: caps.as_ptr(),
|
||||
|
|
@ -330,14 +345,14 @@ pub fn reply_port_send(
|
|||
}
|
||||
|
||||
pub fn reply_port_recv(
|
||||
reply_port_cap: z_cap_t,
|
||||
reply_port_cap: Capability,
|
||||
bytes: &mut [u8],
|
||||
caps: &mut [z_cap_t],
|
||||
) -> Result<(u64, u64), ZError> {
|
||||
let mut num_bytes = bytes.len() as u64;
|
||||
let mut num_caps = caps.len() as u64;
|
||||
let recv_req = zion::ZReplyPortRecvReq {
|
||||
reply_port_cap,
|
||||
reply_port_cap: reply_port_cap.raw(),
|
||||
caps: caps.as_mut_ptr(),
|
||||
num_caps: &mut num_caps,
|
||||
data: bytes.as_mut_ptr() as *mut c_void,
|
||||
|
|
@ -348,20 +363,3 @@ pub fn reply_port_recv(
|
|||
|
||||
Ok((num_bytes, num_caps))
|
||||
}
|
||||
|
||||
pub fn cap_duplicate(cap: z_cap_t, perm_mask: u64) -> Result<z_cap_t, ZError> {
|
||||
let mut new_cap = 0;
|
||||
syscall(
|
||||
zion::kZionCapDuplicate,
|
||||
&zion::ZCapDuplicateReq {
|
||||
cap_in: cap,
|
||||
perm_mask,
|
||||
cap_out: &mut new_cap,
|
||||
},
|
||||
)?;
|
||||
Ok(new_cap)
|
||||
}
|
||||
|
||||
pub fn cap_release(cap: z_cap_t) -> Result<(), ZError> {
|
||||
syscall(zion::kZionCapRelease, &zion::ZCapReleaseReq { cap })
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue