Add methods to get FuncId and bit width from Interface.
Change-Id: I147e7fa9a5c57742167c996a485588073ecead88
Signed-off-by: Andrew Walbran <qwandor@google.com>
diff --git a/src/lib.rs b/src/lib.rs
index afb1f34..8865d61 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -511,15 +511,124 @@
}
impl Interface {
+ /// Returns the function ID for the call, if it has one.
+ pub fn function_id(&self) -> Option<FuncId> {
+ match self {
+ Interface::Error { .. } => Some(FuncId::Error),
+ Interface::Success {
+ is_32bit: false, ..
+ } => Some(FuncId::Success64),
+ Interface::Success { is_32bit: true, .. } => Some(FuncId::Success32),
+ Interface::Interrupt { .. } => Some(FuncId::Interrupt),
+ Interface::Version { .. } => Some(FuncId::Version),
+ Interface::VersionOut { .. } => None,
+ Interface::Features { .. } => Some(FuncId::Features),
+ Interface::RxAcquire { .. } => Some(FuncId::RxAcquire),
+ Interface::RxRelease { .. } => Some(FuncId::RxRelease),
+ Interface::RxTxMap {
+ is_32bit: false, ..
+ } => Some(FuncId::RxTxMap64),
+ Interface::RxTxMap { is_32bit: true, .. } => Some(FuncId::RxTxMap32),
+ Interface::RxTxUnmap { .. } => Some(FuncId::RxTxUnmap),
+ Interface::PartitionInfoGet { .. } => Some(FuncId::PartitionInfoGet),
+ Interface::IdGet => Some(FuncId::IdGet),
+ Interface::SpmIdGet => Some(FuncId::SpmIdGet),
+ Interface::MsgWait => Some(FuncId::MsgWait),
+ Interface::Yield => Some(FuncId::Yield),
+ Interface::Run { .. } => Some(FuncId::Run),
+ Interface::NormalWorldResume => Some(FuncId::NormalWorldResume),
+ Interface::MsgSend2 { .. } => Some(FuncId::MsgSend2),
+ Interface::MsgSendDirectReq {
+ is_32bit: false, ..
+ } => Some(FuncId::MsgSendDirectReq64),
+ Interface::MsgSendDirectReq { is_32bit: true, .. } => Some(FuncId::MsgSendDirectReq32),
+ Interface::MsgSendDirectResp {
+ is_32bit: false, ..
+ } => Some(FuncId::MsgSendDirectResp64),
+ Interface::MsgSendDirectResp { is_32bit: true, .. } => {
+ Some(FuncId::MsgSendDirectResp32)
+ }
+ Interface::MemDonate {
+ is_32bit: false, ..
+ } => Some(FuncId::MemDonate64),
+ Interface::MemDonate { is_32bit: true, .. } => Some(FuncId::MemDonate32),
+ Interface::MemLend {
+ is_32bit: false, ..
+ } => Some(FuncId::MemLend64),
+ Interface::MemLend { is_32bit: true, .. } => Some(FuncId::MemLend32),
+ Interface::MemShare {
+ is_32bit: false, ..
+ } => Some(FuncId::MemShare64),
+ Interface::MemShare { is_32bit: true, .. } => Some(FuncId::MemShare32),
+ Interface::MemRetrieveReq {
+ is_32bit: false, ..
+ } => Some(FuncId::MemRetrieveReq64),
+ Interface::MemRetrieveReq { is_32bit: true, .. } => Some(FuncId::MemRetrieveReq32),
+ Interface::MemRetrieveResp { .. } => Some(FuncId::MemRetrieveResp),
+ Interface::MemRelinquish => Some(FuncId::MemRelinquish),
+ Interface::MemReclaim { .. } => Some(FuncId::MemReclaim),
+ Interface::MemPermGet {
+ is_32bit: false, ..
+ } => Some(FuncId::MemPermGet64),
+ Interface::MemPermGet { is_32bit: true, .. } => Some(FuncId::MemPermGet32),
+ Interface::MemPermSet {
+ is_32bit: false, ..
+ } => Some(FuncId::MemPermSet64),
+ Interface::MemPermSet { is_32bit: true, .. } => Some(FuncId::MemPermSet32),
+ Interface::ConsoleLog {
+ is_32bit: false, ..
+ } => Some(FuncId::ConsoleLog64),
+ Interface::ConsoleLog { is_32bit: true, .. } => Some(FuncId::ConsoleLog32),
+ }
+ }
+
+ /// Returns true if this is a 32-bit call, or false if it is a 64-bit call.
+ pub fn is_32bit(&self) -> bool {
+ match self {
+ Interface::Error { .. }
+ | Interface::Interrupt { .. }
+ | Interface::Version { .. }
+ | Interface::VersionOut { .. }
+ | Interface::Features { .. }
+ | Interface::RxAcquire { .. }
+ | Interface::RxRelease { .. }
+ | Interface::RxTxUnmap { .. }
+ | Interface::PartitionInfoGet { .. }
+ | Interface::IdGet
+ | Interface::SpmIdGet
+ | Interface::MsgWait
+ | Interface::Yield
+ | Interface::Run { .. }
+ | Interface::NormalWorldResume
+ | Interface::MsgSend2 { .. }
+ | Interface::MemRetrieveResp { .. }
+ | Interface::MemRelinquish
+ | Interface::MemReclaim { .. } => true,
+ Interface::Success { is_32bit, .. }
+ | Interface::RxTxMap { is_32bit, .. }
+ | Interface::MsgSendDirectReq { is_32bit, .. }
+ | Interface::MsgSendDirectResp { is_32bit, .. }
+ | Interface::MemDonate { is_32bit, .. }
+ | Interface::MemLend { is_32bit, .. }
+ | Interface::MemShare { is_32bit, .. }
+ | Interface::MemRetrieveReq { is_32bit, .. }
+ | Interface::MemPermGet { is_32bit, .. }
+ | Interface::MemPermSet { is_32bit, .. }
+ | Interface::ConsoleLog { is_32bit, .. } => *is_32bit,
+ }
+ }
+
pub fn copy_to_array(&self, a: &mut [u64; 8]) {
a.fill(0);
+ if let Some(function_id) = self.function_id() {
+ a[0] = function_id as u64;
+ }
match *self {
Interface::Error {
target_info,
error_code,
} => {
- a[0] = FuncId::Error as u64;
a[1] = target_info as u64;
a[2] = error_code as u32 as u64;
}
@@ -530,7 +639,6 @@
} => {
a[1] = target_info as u64;
if is_32bit {
- a[0] = FuncId::Success32 as u64;
a[2] = result_regs[0] & u32::MAX as u64;
a[3] = result_regs[1] & u32::MAX as u64;
a[4] = result_regs[2] & u32::MAX as u64;
@@ -538,7 +646,6 @@
a[6] = result_regs[4] & u32::MAX as u64;
a[7] = result_regs[5] & u32::MAX as u64;
} else {
- a[0] = FuncId::Success64 as u64;
a[2] = result_regs[0];
a[3] = result_regs[1];
a[4] = result_regs[2];
@@ -551,12 +658,10 @@
endpoint_id,
interrupt_id,
} => {
- a[0] = FuncId::Interrupt as u64;
a[1] = endpoint_id as u64;
a[2] = interrupt_id as u64;
}
Interface::Version { input_version } => {
- a[0] = FuncId::Version as u64;
a[1] = input_version as u64;
}
Interface::VersionOut { output_version } => {
@@ -566,16 +671,13 @@
feat_id,
input_properties,
} => {
- a[0] = FuncId::Features as u64;
a[1] = feat_id as u64;
a[2] = input_properties as u64;
}
Interface::RxAcquire { vm_id } => {
- a[0] = FuncId::RxAcquire as u64;
a[1] = vm_id as u64;
}
Interface::RxRelease { vm_id } => {
- a[0] = FuncId::RxRelease as u64;
a[1] = vm_id as u64;
}
Interface::RxTxMap {
@@ -586,42 +688,33 @@
} => {
a[3] = page_cnt as u64;
if is_32bit {
- a[0] = FuncId::RxTxMap32 as u64;
a[1] = tx_addr & u32::MAX as u64;
a[2] = rx_addr & u32::MAX as u64;
} else {
- a[0] = FuncId::RxTxMap64 as u64;
a[1] = tx_addr;
a[2] = rx_addr;
}
}
Interface::RxTxUnmap { id } => {
- a[0] = FuncId::RxTxUnmap as u64;
a[1] = id as u64;
}
Interface::PartitionInfoGet { uuid, flags } => {
let bytes = uuid.to_bytes_le();
- a[0] = FuncId::PartitionInfoGet as u64;
a[1] = u32::from_le_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]) as u64;
a[2] = u32::from_le_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]) as u64;
a[3] = u32::from_le_bytes([bytes[8], bytes[9], bytes[10], bytes[11]]) as u64;
a[4] = u32::from_le_bytes([bytes[12], bytes[13], bytes[14], bytes[15]]) as u64;
a[5] = flags as u64;
}
- Interface::IdGet => a[0] = FuncId::IdGet as u64,
- Interface::SpmIdGet => a[0] = FuncId::SpmIdGet as u64,
- Interface::MsgWait => a[0] = FuncId::MsgWait as u64,
- Interface::Yield => a[0] = FuncId::Yield as u64,
+ Interface::IdGet | Interface::SpmIdGet | Interface::MsgWait | Interface::Yield => {}
Interface::Run { target_info } => {
- a[0] = FuncId::Run as u64;
a[1] = target_info as u64;
}
- Interface::NormalWorldResume => a[0] = FuncId::NormalWorldResume as u64,
+ Interface::NormalWorldResume => {}
Interface::MsgSend2 {
sender_vm_id,
flags,
} => {
- a[0] = FuncId::MsgSend2 as u64;
a[1] = sender_vm_id as u64;
a[2] = flags as u64;
}
@@ -635,14 +728,12 @@
a[1] = (src_id as u64) << 16 | dst_id as u64;
a[2] = flags as u64;
if is_32bit {
- a[0] = FuncId::MsgSendDirectReq32 as u64;
a[3] = args[0] & u32::MAX as u64;
a[4] = args[1] & u32::MAX as u64;
a[5] = args[2] & u32::MAX as u64;
a[6] = args[3] & u32::MAX as u64;
a[7] = args[4] & u32::MAX as u64;
} else {
- a[0] = FuncId::MsgSendDirectReq64 as u64;
a[3] = args[0];
a[4] = args[1];
a[5] = args[2];
@@ -660,14 +751,12 @@
a[1] = (src_id as u64) << 16 | dst_id as u64;
a[2] = flags as u64;
if is_32bit {
- a[0] = FuncId::MsgSendDirectResp32 as u64;
a[3] = args[0] & u32::MAX as u64;
a[4] = args[1] & u32::MAX as u64;
a[5] = args[2] & u32::MAX as u64;
a[6] = args[3] & u32::MAX as u64;
a[7] = args[4] & u32::MAX as u64;
} else {
- a[0] = FuncId::MsgSendDirectResp64 as u64;
a[3] = args[0];
a[4] = args[1];
a[5] = args[2];
@@ -686,10 +775,8 @@
a[2] = frag_len as u64;
a[4] = page_cnt as u64;
if is_32bit {
- a[0] = FuncId::MemDonate32 as u64;
a[3] = address & u32::MAX as u64;
} else {
- a[0] = FuncId::MemDonate64 as u64;
a[3] = address;
}
}
@@ -704,10 +791,8 @@
a[2] = frag_len as u64;
a[4] = page_cnt as u64;
if is_32bit {
- a[0] = FuncId::MemLend32 as u64;
a[3] = address & u32::MAX as u64;
} else {
- a[0] = FuncId::MemLend64 as u64;
a[3] = address;
}
}
@@ -722,10 +807,8 @@
a[2] = frag_len as u64;
a[4] = page_cnt as u64;
if is_32bit {
- a[0] = FuncId::MemShare32 as u64;
a[3] = address & u32::MAX as u64;
} else {
- a[0] = FuncId::MemShare64 as u64;
a[3] = address;
}
}
@@ -740,10 +823,8 @@
a[2] = frag_len as u64;
a[4] = page_cnt as u64;
if is_32bit {
- a[0] = FuncId::MemRetrieveReq32 as u64;
a[3] = address & u32::MAX as u64;
} else {
- a[0] = FuncId::MemRetrieveReq64 as u64;
a[3] = address;
}
}
@@ -751,14 +832,12 @@
total_len,
frag_len,
} => {
- a[0] = FuncId::MemRetrieveResp as u64;
a[1] = total_len as u64;
a[2] = frag_len as u64;
}
- Interface::MemRelinquish => a[0] = FuncId::MemRelinquish as u64,
+ Interface::MemRelinquish => {}
Interface::MemReclaim { handle, flags } => {
let handle_regs: [u32; 2] = handle.into();
- a[0] = FuncId::MemReclaim as u64;
a[1] = handle_regs[0] as u64;
a[2] = handle_regs[1] as u64;
a[3] = flags as u64;
@@ -768,10 +847,8 @@
is_32bit,
} => {
if is_32bit {
- a[0] = FuncId::MemPermGet32 as u64;
a[1] = base_addr & u32::MAX as u64;
} else {
- a[0] = FuncId::MemPermGet64 as u64;
a[1] = base_addr;
}
}
@@ -785,10 +862,8 @@
a[3] = mem_perm as u64;
if is_32bit {
- a[0] = FuncId::MemPermSet32 as u64;
a[1] = base_addr & u32::MAX as u64;
} else {
- a[0] = FuncId::MemPermSet64 as u64;
a[1] = base_addr;
}
}
@@ -799,7 +874,6 @@
} => {
a[1] = char_cnt as u64;
if is_32bit {
- a[0] = FuncId::ConsoleLog32 as u64;
a[2] = char_lists[0] & u32::MAX as u64;
a[3] = char_lists[1] & u32::MAX as u64;
a[4] = char_lists[2] & u32::MAX as u64;
@@ -807,7 +881,6 @@
a[6] = char_lists[4] & u32::MAX as u64;
a[7] = char_lists[5] & u32::MAX as u64;
} else {
- a[0] = FuncId::ConsoleLog64 as u64;
a[2] = char_lists[0];
a[3] = char_lists[1];
a[4] = char_lists[2];