feat(kernel): shared ABI decoder+proofs, no-panic gate, syscall storm, kani on shrunk kernel
This commit is contained in:
@@ -27,20 +27,8 @@ fn call0(nr: usize) -> Result<[usize; 8]> {
|
||||
raw(nr, [0; 6])
|
||||
}
|
||||
|
||||
fn slot_arg(slot: Option<CapSlot>) -> usize {
|
||||
slot.map_or(NONE, |s| s.value() as usize)
|
||||
}
|
||||
|
||||
fn slot_result(r: usize) -> Option<CapSlot> {
|
||||
if r == NONE {
|
||||
None
|
||||
} else {
|
||||
CapSlot::new(r as u8)
|
||||
}
|
||||
}
|
||||
|
||||
fn slot_of(r: Result<[usize; 8]>) -> Result<CapSlot> {
|
||||
r.and_then(|r| slot_result(r[1]).ok_or(Error::InvalidArgument))
|
||||
reg_slot(r).flatten()
|
||||
}
|
||||
|
||||
/// What a receiving call got.
|
||||
@@ -63,22 +51,14 @@ pub enum Received {
|
||||
}
|
||||
|
||||
impl Received {
|
||||
fn decode(r: [usize; 8]) -> Self {
|
||||
let words = [r[2], r[3], r[4], r[5]];
|
||||
let cap = slot_result(r[6]);
|
||||
match r[7] {
|
||||
KIND_CALL => Received::Call {
|
||||
badge: r[1],
|
||||
words,
|
||||
cap,
|
||||
},
|
||||
KIND_SIGNAL => Received::Signal { bits: r[1] },
|
||||
_ => Received::Message {
|
||||
badge: r[1],
|
||||
words,
|
||||
cap,
|
||||
},
|
||||
}
|
||||
fn decode(r: [usize; 8]) -> Result<Self> {
|
||||
let d = regs_delivery(&r).ok_or(Error::InvalidArgument)?;
|
||||
let (badge, words, cap) = (d.badge, d.words, d.cap);
|
||||
Ok(match d.kind {
|
||||
DeliveryKind::Message => Received::Message { badge, words, cap },
|
||||
DeliveryKind::Call => Received::Call { badge, words, cap },
|
||||
DeliveryKind::Signal => Received::Signal { bits: badge },
|
||||
})
|
||||
}
|
||||
|
||||
pub fn words(&self) -> [usize; 4] {
|
||||
@@ -89,8 +69,8 @@ impl Received {
|
||||
}
|
||||
}
|
||||
|
||||
fn message_args(ep: usize, words: [usize; 4], cap: Option<CapSlot>) -> [usize; 6] {
|
||||
[ep, words[0], words[1], words[2], words[3], slot_arg(cap)]
|
||||
fn slot_of(r: Result<[usize; 8]>) -> Result<CapSlot> {
|
||||
r.and_then(|r| slot_result(r[1]).ok_or(Error::InvalidArgument))
|
||||
}
|
||||
|
||||
// ---- threads, processes, time ----
|
||||
@@ -266,7 +246,7 @@ pub fn send(endpoint: CapSlot, w0: usize, w1: usize, w2: usize, w3: usize) -> us
|
||||
pub fn send_msg(endpoint: CapSlot, words: [usize; 4], cap: Option<CapSlot>) -> Result<()> {
|
||||
raw(
|
||||
SYS_SEND,
|
||||
message_args(endpoint.value() as usize, words, cap),
|
||||
message_regs(endpoint.value() as usize, words, cap),
|
||||
)
|
||||
.map(|_| ())
|
||||
}
|
||||
@@ -278,30 +258,30 @@ pub fn receive(endpoint: CapSlot) -> (usize, usize, usize, usize) {
|
||||
}
|
||||
|
||||
pub fn receive_msg(endpoint: CapSlot) -> Result<Received> {
|
||||
raw(SYS_RECEIVE, [endpoint.value() as usize, 0, 0, 0, 0, 0]).map(Received::decode)
|
||||
raw(SYS_RECEIVE, [endpoint.value() as usize, 0, 0, 0, 0, 0]).and_then(Received::decode)
|
||||
}
|
||||
|
||||
/// Sends and waits for the reply.
|
||||
pub fn call(endpoint: CapSlot, words: [usize; 4], cap: Option<CapSlot>) -> Result<Received> {
|
||||
raw(
|
||||
SYS_CALL,
|
||||
message_args(endpoint.value() as usize, words, cap),
|
||||
message_regs(endpoint.value() as usize, words, cap),
|
||||
)
|
||||
.map(Received::decode)
|
||||
.and_then(Received::decode)
|
||||
}
|
||||
|
||||
/// Answers the last `Call` this thread received.
|
||||
pub fn reply(words: [usize; 4], cap: Option<CapSlot>) -> Result<()> {
|
||||
raw(SYS_REPLY, message_args(0, words, cap)).map(|_| ())
|
||||
raw(SYS_REPLY, message_regs(0, words, cap)).map(|_| ())
|
||||
}
|
||||
|
||||
/// Replies to the pending `Call` (if any), then receives the next message.
|
||||
pub fn reply_recv(endpoint: CapSlot, words: [usize; 4], cap: Option<CapSlot>) -> Result<Received> {
|
||||
raw(
|
||||
SYS_REPLY_RECV,
|
||||
message_args(endpoint.value() as usize, words, cap),
|
||||
message_regs(endpoint.value() as usize, words, cap),
|
||||
)
|
||||
.map(Received::decode)
|
||||
.and_then(Received::decode)
|
||||
}
|
||||
|
||||
// ---- notifications and interrupts ----
|
||||
|
||||
Reference in New Issue
Block a user