Skip to content

Commit

Permalink
feat: import @hargoniX hardware diff
Browse files Browse the repository at this point in the history
  • Loading branch information
Henrik Böving committed Nov 14, 2023
1 parent c001d22 commit 37d7f08
Show file tree
Hide file tree
Showing 44 changed files with 1,500 additions and 664 deletions.
4 changes: 2 additions & 2 deletions src/l4/pkg/io/libvbus/include/vbus_interfaces.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@
* the type of the device, i.e. from the point of view of the client
* a device is defined by the kinds of sub-interfaces it supports.
*/
enum l4vbus_iface_type_t {
typedef enum {
L4VBUS_INTERFACE_ICU = 0,
L4VBUS_INTERFACE_GPIO,
L4VBUS_INTERFACE_PCI,
L4VBUS_INTERFACE_PCIDEV,
L4VBUS_INTERFACE_PM,
L4VBUS_INTERFACE_BUS,
L4VBUS_INTERFACE_GENERIC = 0x20
};
} l4vbus_iface_type_t;


enum {
Expand Down
17 changes: 4 additions & 13 deletions src/l4/pkg/l4rust/l4-rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,26 @@
name = "l4"
version = "0.1.0"
authors = ["Sebastian Humenda <shumenda @ gmx . de>"]
edition = "2021"
edition = "2018"

[lib]
path = "lib.rs"

[dependencies]
libc = "0.2.147"
num = "0.2"
libc = "0.2.50"

[dependencies.bitflags]
version = "1.0"
default-features = false

[dependencies.l4_sys]
path = "../l4-sys-rust"

[dependencies.num]
version = "0.4"
default-features = false
features = []

[dependencies.num-traits]
version = "0.2"
default-features = false
features = []

[dependencies.num-derive]
version = "0.4"
version = "0.2.3"
default-features = false
features = []

[features]
default = ["std"]
Expand Down
20 changes: 13 additions & 7 deletions src/l4/pkg/l4rust/l4-rust/cap.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use core::ops::{Deref, DerefMut};
use _core::ops::{Deref, DerefMut};
use l4_sys::{
self,
l4_cap_consts_t::{L4_CAP_SHIFT, L4_INVALID_CAP_BIT},
Expand Down Expand Up @@ -95,6 +95,12 @@ impl<T: Interface + IfaceInit> Cap<T> {
}

impl<T: Interface> Cap<T> {
pub fn from_raw(val : T) -> Cap<T> {
Cap {
interface: val
}
}

pub fn cast<U: Interface + IfaceInit>(self) -> Cap<U> {
Cap {
interface: U::new(self.raw()),
Expand Down Expand Up @@ -141,7 +147,7 @@ impl<T: Interface> Cap<T> {
L4_BASE_TASK_CAP as u64,
L4_BASE_TASK_CAP as u64,
l4_sys::l4_obj_fpage(source.raw(), 0, L4_CAP_FPAGE_RWSD as u8),
self.send_base(L4_MAP_ITEM_GRANT as u32, None) as super::sys::l4_addr_t | 0xe0,
self.send_base(L4_MAP_ITEM_GRANT as u64, None) as super::sys::l4_addr_t | 0xe0,
);
Ok(())
}
Expand All @@ -152,13 +158,11 @@ impl<T: Interface> Cap<T> {
/// itself). If the first parameter is set, the object will be **granted**.
/// In other words, it is possible to specify the object space location of this capability for
/// map operations.
fn send_base(&self, grant: u32, base_cap: Option<l4_cap_idx_t>) -> u64 {
fn send_base(&self, grant: u64, base_cap: Option<l4_cap_idx_t>) -> u64 {
let base_cap = base_cap.unwrap_or_else(|| self.raw());
l4_sys::l4_map_obj_control(base_cap, grant)
}
}

/// Short-hand to construct a Cap from an index.
pub fn from(c: CapIdx) -> Cap<Untyped> {
Cap {
interface: Untyped { 0: c },
Expand All @@ -167,8 +171,10 @@ pub fn from(c: CapIdx) -> Cap<Untyped> {

/// Construct an invalid cap
#[inline]
pub const fn invalid_cap() -> Cap<Untyped> {
pub fn invalid_cap() -> Cap<Untyped> {
Cap {
interface: Untyped(l4_sys::l4_cap_consts_t::L4_INVALID_CAP as u64),
interface: Untyped {
0: L4_INVALID_CAP_BIT as u64,
},
}
}
21 changes: 6 additions & 15 deletions src/l4/pkg/l4rust/l4-rust/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,7 @@ impl TcrErr {
/// Get error from given tag (for current thread)
#[inline]
pub fn from_tag(tag: l4_msgtag_t) -> Result<Self> {
// SAFETY: ToDo, this is unsafe and awaits a generic solution to track usage of the UTCB
unsafe {
Self::from_tag_u(tag, &Utcb::current())
}
Self::from_tag_u(tag, &Utcb::current())
}

/// Get error from given tag and corresponding UTCB.
Expand Down Expand Up @@ -152,8 +149,8 @@ pub enum Error {
InvalidEncoding(Option<core::str::Utf8Error>),
}

impl core::fmt::Display for Error {
fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
impl _core::fmt::Display for Error {
fn fmt(&self, f: &mut Formatter) -> _core::fmt::Result {
match self {
Error::Generic(e) => write!(f, "Generic L4 error code: {}", e.to_i64().unwrap()),
Error::Tcr(i) => write!(f, "IPC error: {}", i.to_i64().unwrap()),
Expand Down Expand Up @@ -230,20 +227,14 @@ impl Error {
}
}

impl core::convert::From<GenericErr> for Error {
fn from(o: GenericErr) -> Self {
Error::Generic(o)
}
}

#[cfg(feature = "std")]
impl core::convert::From<std::string::FromUtf8Error> for Error {
fn from(u: std::string::FromUtf8Error) -> Self {
Error::InvalidEncoding(Some(u.utf8_error()))
}
}

pub type Result<T> = core::result::Result<T, Error>;
pub type Result<T> = ::_core::result::Result<T, Error>;

/// Short-hand macro for several `l4::error::Error` cases
///
Expand All @@ -255,7 +246,7 @@ pub type Result<T> = core::result::Result<T, Error>;
#[macro_export]
macro_rules! l4_err {
(Generic, $err:ident) => {
Err($crate::error::Error::Generic(
return Err($crate::error::Error::Generic(
$crate::error::GenericErr::$err,
))
};
Expand All @@ -274,7 +265,7 @@ macro_rules! l4_err {
macro_rules! l4_err_if {
($condition:expr => $($token:tt)*) => {
if $condition {
return l4_err!($($token)*);
l4_err!($($token)*);
}
}
}
11 changes: 7 additions & 4 deletions src/l4/pkg/l4rust/l4-rust/ipc/iface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,13 @@ macro_rules! derive_functors {
}
}

/// Extract the opcode from a list of function names
///
/// The basic assumption is that all functions share the same opcode type in an IPC interface.
/// Within a macro, it is impossible to separate the first element from a type list, hence this
/// helper macro gets the head and yields the opcode type.
#[macro_export]

macro_rules! derive_ipc_calls {
($proto:expr; $($opcode:expr =>
fn $name:ident($($argname:ident: $type:ty),*) -> $return:ty;)*
Expand All @@ -90,10 +96,7 @@ macro_rules! derive_ipc_calls {
// ToDo: would re-allocate a capability each time; how to control number of
// required slots
let mut caps = $crate::ipc::types::Bufferless { };
// SAFETY: We have to assume that the UTCB is unused, see #5.
let mut mr = unsafe {
$crate::utcb::Utcb::current().mr()
};
let mut mr = $crate::utcb::Utcb::current().mr();
// write opcode
unsafe {
mr.write($opcode)?;
Expand Down
83 changes: 72 additions & 11 deletions src/l4/pkg/l4rust/l4-rust/ipc/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/// L4 IPC framework
///
/// The interplay in a component-based microkernel system and the number of interfaces create
/// inherent complexity. This framework assists the application programmer to implement services
/// easily without the need to understand all low-level details. As a plus, clients can be
/// auto-derived from the IPC interface definition shared between client and server.
/// L4 IPC becomes due to its minimality a comlex affair, which is why this framework assists the
/// application programmer to implement services easily without the need to understand all
/// low-level details. As a plus, clients can be auto-derived from the IPC interface definition
/// shared between client and server.
///
/// # Interface Compatibility
///
Expand All @@ -16,20 +16,20 @@
mod iface;
mod serialise;
pub mod server;
pub mod syscall;
pub mod types;

pub use self::serialise::{Serialisable, Serialiser};
pub use self::server::{server_impl_callback, Callback, Loop, LoopBuilder};
pub use self::types::*;
pub use syscall::*;

use core::{convert::From, mem::transmute};
use l4_sys::{l4_msgtag_flags::*, l4_msgtag_t, msgtag};
use _core::{convert::From, mem::transmute};
use l4_sys::{l4_msgtag_flags::*, l4_msgtag_t, l4_timeout_t, l4_ipc_error, msgtag};
use num_traits::FromPrimitive;

use crate::cap::{Cap, Interface};
use crate::error::{Error, Result};
use crate::types::{Mword, Protocol, UMword};
use crate::utcb::Utcb;

use l4_sys;

Expand Down Expand Up @@ -83,7 +83,6 @@ const L4_MSGTAG_ERROR_I: isize = L4_MSGTAG_ERROR as isize;
/// let _ = msgtag(0, 1, 1, 0);
/// ```
#[derive(Clone)]
#[repr(transparent)]
pub struct MsgTag {
raw: Mword,
}
Expand All @@ -98,7 +97,7 @@ impl MsgTag {
MsgTag {
// the C type is a wrapper type and we reimplement its creation function in
// l4_sys::ipc_basic anyway. We want to safe every cycle here.
raw: msgtag(label, words, items, flags).raw as _,
raw: unsafe { transmute::<l4_msgtag_t, Mword>(msgtag(label, words, items, flags)) },
}
}

Expand Down Expand Up @@ -186,11 +185,17 @@ impl MsgTag {
}

#[inline]
pub fn raw(self) -> l4_msgtag_t {
pub fn raw(&self) -> l4_msgtag_t {
::l4_sys::l4_msgtag_t {
raw: self.raw as i64,
}
}

#[inline]
pub fn has_ipc_error(&self) -> bool {
let err = unsafe { l4_ipc_error(self.raw(), Utcb::current().raw) };
err != 0
}
}

impl From<l4_msgtag_t> for MsgTag {
Expand All @@ -202,6 +207,62 @@ impl From<l4_msgtag_t> for MsgTag {
}
}

/// Simple IPC Call
///
/// Call to given destination and block for answer.
#[inline(always)]
pub fn call<T: Interface>(
dest: &Cap<T>,
utcb: &mut Utcb,
tag: MsgTag,
timeout: l4_timeout_t,
) -> MsgTag {
unsafe {
MsgTag::from(l4_sys::l4_ipc_call(
dest.raw(),
utcb.raw,
tag.raw(),
timeout,
))
}
}

#[inline]
pub unsafe fn receive<T: Interface>(
object: Cap<T>,
utcb: &mut Utcb,
timeout: l4_timeout_t,
) -> l4_msgtag_t {
l4_sys::l4_ipc_receive(object.raw(), utcb.raw, timeout)
}

/*
#[inline]
pub unsafe fn reply_and_wait(utcb: &mut Utcb, tag: l4_msgtag_t,
src: *mut UMword, timeout: l4_timeout_t) -> l4_msgtag_t {
l4_ipc_reply_and_wait_w(utcb.raw, tag, src, timeout)
}
#[inline]
pub unsafe fn l4_ipc_wait(utcb: &mut Utcb, label: *mut l4_umword_t,
timeout: l4_timeout_t) -> l4_msgtag_t {
l4_ipc_wait_w(utcb, label, timeout)
}
#[inline]
pub unsafe fn l4_msgtag(label: ::libc::c_long, words: c_uint,
items: c_uint, flags: c_uint) -> l4_msgtag_t {
l4_msgtag_w(label, words, items, flags)
}
#[inline]
pub unsafe fn l4_rcv_ep_bind_thread(gate: &Cap, thread: &Cap,
label: l4_umword_t) -> l4_msgtag_t {
l4_rcv_ep_bind_thread_w(gate.cap, thread.cap, label)
}
*/

////////////////////////////////////////////////////////////////////////////////
// re-implemented inline functions from l4/sys/ipc.h:

Expand Down
Loading

0 comments on commit 37d7f08

Please sign in to comment.