implement cells and cell conversion for longs

This commit is contained in:
husky 2023-07-20 19:34:02 -07:00
parent 45c097553e
commit 32d86a2a5a
No known key found for this signature in database
GPG key ID: 6B3D8CB511646891
3 changed files with 64 additions and 0 deletions

50
src/cell_conv.rs Normal file
View file

@ -0,0 +1,50 @@
/// A cell is a single FORTH stack value, all arguments and return values given to OpenFirmware
/// must fit in a cell.
pub type Cell = i32;
/// # DoubleWord
/// a structure containing a low and high cell
/// # example
/// ```
/// use ofw::cell_conv::DoubleWord;
/// let value: u64 = 0xabcdef0123456789;
/// let dw: DoubleWord = value.into();
/// assert_eq!(dw.high as u32, 0xabcdef01);
/// assert_eq!(dw.low as u32, 0x23456789);
/// ```
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct DoubleWord {
pub low: Cell,
pub high: Cell,
}
impl From<i64> for DoubleWord {
fn from(dw: i64) -> Self {
Self {
low: dw as Cell,
high: (dw >> 32) as Cell,
}
}
}
impl From<u64> for DoubleWord {
fn from(dw: u64) -> Self {
Self {
low: dw as Cell,
high: (dw >> 32) as Cell,
}
}
}
impl From<DoubleWord> for i64 {
fn from(dw: DoubleWord) -> Self {
(dw.high as i64) << 32 | dw.low as i64
}
}
impl From<DoubleWord> for u64 {
fn from(dw: DoubleWord) -> Self {
(dw.high as u64) << 32 | dw.low as u64
}
}

View file

@ -34,6 +34,9 @@ pub mod ntstr;
/// module for architecture-specific code
pub mod arch;
/// # cell_conv
/// module for converting between OpenFirmware cells and Rust integers
pub mod cell_conv;
#[cfg(test)]
mod tests;

View file

@ -1,5 +1,6 @@
use crate::arch::EntryFunction;
use crate::{Args, call, call_method, IHandle, method_service_result, ntstr, OFW_FALSE, OFW_TRUE, service_result};
use crate::cell_conv::DoubleWord;
use crate::ntstr::NTSTR;
#[test]
@ -9,6 +10,16 @@ fn ntstr_macro() {
assert_eq!(a, b);
}
#[test]
fn doubleword_conversion() {
let a: u64 = 0xabcdef0123456789;
let a_dw: DoubleWord = a.into();
let b: u64 = a_dw.into();
assert_eq!(a, b);
assert_eq!(a_dw.high as u32, 0xabcdef01);
assert_eq!(a_dw.low as u32, 0x23456789);
}
#[test]
fn call_ofw() {
pub extern "C" fn test_entry_function(args: *mut Args) -> i32 {