Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: import @hargonix hardware diff #11

Open
wants to merge 65 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
55890b1
fix: Rust builds
hargoniX Jun 15, 2023
849fda3
doc: update README
hargoniX Jun 15, 2023
a65042b
feat: bind l4vbus + pci in l4-sys
hargoniX Jun 18, 2023
664b05b
feat: bind more IO things in l4-sys
Jun 21, 2023
8686c51
feat: initial support for Rust hardware APIs
hargoniX Jun 27, 2023
c8278e5
feat: Rust IO APIs
hargoniX Jun 29, 2023
6e4a54a
feat: type safe DMA API
hargoniX Jul 1, 2023
e41cca2
fix: unmasking can only throw IPC errors
hargoniX Jul 1, 2023
3a16fc3
feat: verix qemu config
hargoniX Jul 25, 2023
3f93b12
feat: libvbus Rust C bindings
hargoniX Jul 25, 2023
e87f867
chore: prepare typified Rust io/mem bindings
hargoniX Jul 25, 2023
b28505c
feat: typified Rust IO bindings
hargoniX Jul 25, 2023
901fd0f
feat: typified Rust mem bindings
hargoniX Jul 25, 2023
d96d2e7
feat: typified Rust factory bindings
hargoniX Jul 25, 2023
2e51628
feat: initial version of the verix vision
hargoniX Jul 25, 2023
19798ff
feat: PoC for svd2rust style macros
hargoniX Jul 25, 2023
3813118
feat: WO MMIO in pc-hal-util
hargoniX Jul 26, 2023
20ed79d
feat: generic map_bar
hargoniX Jul 26, 2023
ade2b93
feat: verix: disable interrupts
hargoniX Jul 26, 2023
475ccd5
feat: the easy steps of initializing the NIC
hargoniX Jul 26, 2023
e5ea315
feat: verix basic RX setup
hargoniX Jul 27, 2023
25cef06
feat: verix TX initialization
hargoniX Jul 28, 2023
1e475ef
feat: mempool + descriptor API and interrupt setup
hargoniX Jul 28, 2023
17c200a
feat: enable PCI bus mastering
hargoniX Jul 29, 2023
cdb5055
feat: first working TX implementation
hargoniX Jul 31, 2023
61ac5be
feat: more precise MM types
hargoniX Aug 4, 2023
7a16baf
fix: TODOs and cleanup of the code in general
hargoniX Aug 4, 2023
90cb619
chore: format
hargoniX Aug 4, 2023
9e661d8
feat: basic PMD rx routine + echo demo
hargoniX Aug 4, 2023
48d1ac4
feat: RX working
hargoniX Aug 10, 2023
2c1892e
feat: TX working
hargoniX Aug 10, 2023
51a8226
feat: inlining + RefCell reduction
hargoniX Aug 14, 2023
ea0ef04
WIP perf
hargoniX Aug 15, 2023
850bf61
feat: huge pages
hargoniX Aug 17, 2023
82e5e45
chore: remove features we don't need
hargoniX Aug 17, 2023
6926c6c
chore: clean up too pub code
hargoniX Aug 18, 2023
80008aa
style: format verix
hargoniX Aug 18, 2023
4596ef5
feat: mix supports PCI emulation
hargoniX Aug 18, 2023
243ce78
feat: mix supports initialization up to RX/TX
Aug 23, 2023
1592da3
feat: lifetimes over Rc
Sep 5, 2023
e2e9ba2
feat: single queue
hargoniX Sep 6, 2023
240ec0a
chore: get rid of resources on BasicDevice
hargoniX Sep 8, 2023
c68fbc2
feat: first invariant for queues
hargoniX Sep 13, 2023
be2ea87
WIP
hargoniX Sep 14, 2023
606d2b9
feat: small queues kani, big queues prod
Sep 30, 2023
4ee9eb4
feat: no different behavior on smaller queue sizes
hargoniX Oct 1, 2023
3a90c2e
feat: specify valid rx queue and prove the initial queue is valid
Oct 4, 2023
cf43d6c
feat: first attempt at using the queue spec
hargoniX Oct 6, 2023
28eca6a
dedup
hargoniX Oct 6, 2023
7ca5a7d
feat: basic initialized device emulation
Oct 10, 2023
3ad3777
feat: induction step
Oct 12, 2023
ca507d4
feat: fully verify rx
Oct 17, 2023
a932134
feat: descriptors as bitfields
Oct 18, 2023
6313c5d
feat: tx verification
Oct 18, 2023
a5a039b
style: cargo fmt
hargoniX Oct 18, 2023
4f697fb
style: fix warnings
hargoniX Oct 18, 2023
1377b4b
style: fix warnings in kani
hargoniX Oct 18, 2023
ee7c5f0
fix: nail down overly public APIs again
hargoniX Oct 19, 2023
20d8338
fix: more precise rx queue spec
hargoniX Oct 19, 2023
3b95c57
feat: more precise tx specification
Oct 24, 2023
116e931
chore: remove finished and wontfix TODOs
Oct 24, 2023
5e83150
feat: proper tx specification tm
Oct 24, 2023
2d3c44b
feat: negative tests
Oct 24, 2023
9c1730f
chore: queue size to 16 again
Oct 24, 2023
710e9ed
fix: merge stuff
Nov 14, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 22 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,71 +7,47 @@ efficiently develop Rust clients and servers running on top of a highly
configurable, secure and performant OS. Rust services and clients can
communicate without adaptation with C++ server and clients from L4Re.

Suggestions, criticism and everything else is welcome, contact me on IRC as
Moomoc in the Mozilla, Freenode or OFTC network.

L4Re Setup
----------

This is better explained in [RL4Re's README](EADME.l4re), but in short you need
(GNU) make, gcc, libgcc, bison and flex. Execute `make setup` and `make -j4`
(GNU) make, gcc, libgcc, bison and flex. Execute `make setup` and `make -j8`
afterwards. If compilation aborts with "failed to build l4linux", you
successfully build everything except l4linux which isn't required.

This L4Re snapshot needs to reside in a path without any spaces, thanks to Makes
inability to treat those appropriately. Enter the L4Re source tree root and type
`make ssetup` to choose the build target. Then type make, followed by half a
`make setup` to choose the build target. Then type make, followed by half a
dozen tea breaks.

Now you need to configure the object directory for your build. Open a new file
called `obj/l4/amd64/conf/Makeconf.local` and specify the object directory; substitute
amd64 through the chosen architecture. Assuming you are
on `x86_64` (AKA amd64) and the source tree is below `/home/user/l4re`, the
content might look like this:

OBJ_BASE=/home/USER/rustl4re/obj/l4/amd64

Rust Compilation
----------------

Rust doesn't ship binary versions of the cross-compiled `std` crate. There is
also a minor deficiency in passing linker arguments containing spaces, so you
need a slightly patched Rust compiler yourself. Grab the source from
<https://github.com/humenda/rust> and follow these steps:
<https://github.com/hargonix/rust/tree/l4re_fix> (this is in the process of getting upstreamed)
and follow these steps:

- Create a file `config.toml` in the repository root with this content:

````
[llvm]
optimize = true
[build]
build = "x86_64-unknown-linux-gnu" # defaults to your host platform
target = ["x86_64-unknown-l4re-uclibc"] # defaults to just the build triple
docs = false
[install]
prefix = '/your/preferred/path'
[rust]
optimize = true
use-jemalloc = false
backtrace = false

You should adjust both prefix and potentially the `build =`-line, if you
don't use Linux on a `x86_64` machine.
- For building Rust with std:

$ python3 x.py --host=x86_64-unknown-linux-gnu --target=x86_64-unknown-l4re-uclibc

```
changelog-seen = 2
[build]
build = "x86_64-unknown-linux-gnu"
# We need both linux and l4re because we have build.rs scripts in our libraries
target = ["x86_64-unknown-l4re-uclibc", "x86_64-unknown-linux-gnu"]
docs = false
extended = true
[install]
prefix = '/your/prefix/path'
[rust]
optimize = true
jemalloc = false
backtrace = false
```
- `$ python3 x.py build && python3 x.py install`
- `$ rustup toolchain link l4re /your/prefix/path`
- `$ rustup default l4re`

Then you can proceed to building the L4Re source tree, see the linked
instructions above or with hacking, see below.

Branch setup
------------

The branch `upstream` contains the original L4Re snapshot. The patches to the
build system BID are in `bid_changes` which is rebased on upstream if a new
version comes out. `master` is based on bid_changes and contains all the library
implementation of `l4rust` and a few sample applications, see `pkg/l4rust` and `pkg/oxisamples`.

The branch `bench` contains some hackish benchmarking applications. These are
are not guaranteed to run in all environments, patches welcome.
10 changes: 10 additions & 0 deletions src/l4/conf/modules.list
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,13 @@ module[arch=arm64,fname=linux] https://l4re.org/download/Linux-kernel
module[arch=arm,fname=ramdisk-arm.rd] https://os.inf.tu-dresden.de/~adam/dl/ramdisks/ramdisk-armv7.rd
module[arch=arm64,fname=ramdisk-arm64.rd] https://os.inf.tu-dresden.de/~adam/dl/ramdisks/ramdisk-armv8-64.rd
# TODO: Add x86 and MIPS

entry verix
kernel fiasco -serial_esc -esc
roottask moe rom/verix.ned
module l4re
module ned
module verix
module verix.ned
module nic.vbus
module io
10 changes: 10 additions & 0 deletions src/l4/conf/nic.vbus
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Io.add_vbusses
{
nic = Io.Vi.System_bus(function ()
Property.num_msis = 20;
PCI0 = Io.Vi.PCI_bus(function ()
pci_nic = wrap(Io.system_bus():match("PCI/VEN_8086&DEV_10fb"));
end);
end);
};

42 changes: 42 additions & 0 deletions src/l4/conf/verix.ned
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package.path = "rom/?.lua";

local L4 = require "L4";
local l = L4.default_loader;

local busses = {
nic = 1,
}

local io_caps = {
sigma0 = L4.cast(L4.Proto.Factory, L4.Env.sigma0):create(L4.Proto.Sigma0);
icu = L4.Env.icu;
iommu = L4.Env.iommu;
};

local files = "";

for k, v in pairs(busses) do
local c = l:new_channel();
busses[k] = c
io_caps[k] = c:svr();
files = files .. " rom/" .. k .. ".vbus";
end

l:start({
log = { "io", "red" },
caps = io_caps
}, "rom/io " .. "-vvvvv" .. files);


l:start(
{
log = { "verix", "blue" },
caps =
{
vbus = busses.nic,
jdb = L4.Env.jdb,
},
},
"rom/verix"
);

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
6 changes: 6 additions & 0 deletions src/l4/pkg/l4rust/l4-rust/cap.rs
Original file line number Diff line number Diff line change
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
11 changes: 9 additions & 2 deletions src/l4/pkg/l4rust/l4-rust/ipc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,12 @@ pub use self::types::*;
pub use syscall::*;

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

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

use l4_sys;

Expand Down Expand Up @@ -186,11 +187,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 Down
2 changes: 1 addition & 1 deletion src/l4/pkg/l4rust/l4-sys-rust/Control
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
provides: l4-sys-rust
requires: l4sys libpthread libl4re-wrapper
requires: l4sys libpthread libl4re-wrapper libio libio-vbus
Maintainer: [email protected]
2 changes: 1 addition & 1 deletion src/l4/pkg/l4rust/l4-sys-rust/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ TARGET = libl4_sys-rust.rlib
SRC_RS = lib.rs

DEPENDS_PKGS = l4sys
REQUIRES_LIBS = l4sys libl4re-wrapper
REQUIRES_LIBS = l4sys libl4re-wrapper libio libio-vbus
include $(L4DIR)/mk/lib.mk
8 changes: 7 additions & 1 deletion src/l4/pkg/l4rust/l4-sys-rust/bindgen.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@
#include <l4/re/c/util/cap_alloc.h>
#include <l4/re/env.h>
#include <pthread-l4.h>
#include <l4/vbus/vbus.h>
#include <l4/vbus/vbus_pci.h>
#include <l4/sys/icu.h>
#include <l4/sys/irq.h>

// custom wrapper to make inlined C functions visible
#include <l4/l4rust/ipc.h>
#include <l4/l4rust/env.h>
#include <l4/l4rust/scheduler.h>

#include <l4/l4rust/icu.h>
#include <l4/l4rust/irq.h>
#include <l4/l4rust/fpage.h>
4 changes: 3 additions & 1 deletion src/l4/pkg/l4rust/l4-sys-rust/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ fn main() {
.blocklist_type("strtod")
.blocklist_type("max_align_t")
.blocklist_file(".*/stdlib.h")
.ctypes_prefix("core::ffi");
.ctypes_prefix("core::ffi")
.blocklist_type("l4_addr_t")
.ctypes_prefix("::libc");
if let Ok(include_dirs) = ::std::env::var("L4_INCLUDE_DIRS") {
for item in include_dirs.split(" ") {
bindings = bindings.clang_arg(item);
Expand Down
7 changes: 7 additions & 0 deletions src/l4/pkg/l4rust/l4re-rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,12 @@ path = "../l4-rust"
# ToDo: make this conditional
default-features = false

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

[dependencies.l4_derive]
path = "../l4_derive-rust"

[dependencies.bitflags]
version = "1.0"
default-features = false
4 changes: 4 additions & 0 deletions src/l4/pkg/l4rust/l4re-rust/bindgen.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
#include <l4/re/c/mem_alloc.h>
#include <l4/re/c/rm.h>
#include <l4/re/c/util/cap_alloc.h>
#include <l4/re/c/dma_space.h>
#include <l4/re/protocols.h>
#include <l4/io/io.h>
#include <l4/io/types.h>
#include <l4/l4rust/env.h>
#include <l4/l4rust/mem.h>
#include <l4/l4rust/vbus.h>
10 changes: 5 additions & 5 deletions src/l4/pkg/l4rust/l4re-rust/cap.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use core::ops::{Deref, DerefMut};

use l4::{
cap::{Cap, IfaceInit},
cap::{Cap, IfaceInit, Interface},
error::{Error, Result},
};

use crate::sys;

pub struct OwnedCap<T: IfaceInit>(Cap<T>);
pub struct OwnedCap<T: Interface>(pub(crate) Cap<T>);

impl<T: IfaceInit> OwnedCap<T> {
/// Allocate new capability slot
Expand All @@ -32,20 +32,20 @@ impl<T: IfaceInit> OwnedCap<T> {
}
}

impl<T: IfaceInit> Deref for OwnedCap<T> {
impl<T: Interface> Deref for OwnedCap<T> {
type Target = Cap<T>;
fn deref(&self) -> &Self::Target {
&self.0
}
}

impl<T: IfaceInit> DerefMut for OwnedCap<T> {
impl<T: Interface> DerefMut for OwnedCap<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}

impl<T: IfaceInit> Drop for OwnedCap<T> {
impl<T: Interface> Drop for OwnedCap<T> {
fn drop(&mut self) {
unsafe {
// free allocated capability index
Expand Down
Loading