commit 5725341d729f2aed83a90abe56c9fb8eb097c17e Author: vilaureu Date: Tue Jan 20 10:34:58 2026 +0100 add pipeline solution Co-authored-by: Nils Asmussen diff --git a/boot/ipc.xml b/boot/ipc.xml index 6085c9667..cee41fc27 100644 --- a/boot/ipc.xml +++ b/boot/ipc.xml @@ -6,11 +6,13 @@ + + diff --git a/src/apps/ipc/ipcrecv/src/ipcrecv.rs b/src/apps/ipc/ipcrecv/src/ipcrecv.rs index ed40a4201..4b78c0920 100644 --- a/src/apps/ipc/ipcrecv/src/ipcrecv.rs +++ b/src/apps/ipc/ipcrecv/src/ipcrecv.rs @@ -3,24 +3,22 @@ #[allow(unused_extern_crates)] extern crate m3; +use m3::com::{recv_msg, RecvGate}; use m3::errors::Error; +use m3::reply_vmsg; #[no_mangle] pub fn main() -> Result<(), Error> { - /* // We get the named receive gate, which has been configured in our boot XML. - let recv_gate = todo!().expect("unable to get RecvGate chan"); + let recv_gate = RecvGate::new_named("chan").expect("unable to get RecvGate chan"); loop { // Receive one message. - let mut gate_stream = todo!().expect("receive failed"); + let mut gate_stream = recv_msg(&recv_gate).expect("receive failed"); // Unmarshall the message. - let argument = todo!().expect("unable to get value"); + let argument = gate_stream.pop::().expect("unable to get value"); let result = 100 * argument + 42; // Reply with the result. - todo!().expect("reply failed"); + reply_vmsg!(gate_stream, result).expect("reply failed"); } - */ - - Ok(()) } diff --git a/src/apps/ipc/ipcsend/src/ipcsend.rs b/src/apps/ipc/ipcsend/src/ipcsend.rs index 443907d75..653d73c3f 100644 --- a/src/apps/ipc/ipcsend/src/ipcsend.rs +++ b/src/apps/ipc/ipcsend/src/ipcsend.rs @@ -3,29 +3,31 @@ #[allow(unused_extern_crates)] extern crate m3; +use m3::com::{RecvGate, SendGate}; use m3::errors::Error; +use m3::util::math; +use m3::{println, send_recv}; #[no_mangle] pub fn main() -> Result<(), Error> { - /* // We get the named send gate, which has been configured in our boot XML. - let send_gate = todo!().expect("unable to get SendGate chan"); + let send_gate = SendGate::new_named("chan").expect("unable to get SendGate chan"); // We need to set a message size large enough for the TCU header and the reply payload. let msg_order = math::next_log2(64); let buf_order = msg_order; // We create a receive gate, which receives the replies to our messages. - let reply_gate = todo!().expect("unable to create RecvGate"); + let reply_gate = RecvGate::new(buf_order, msg_order).expect("unable to create RecvGate"); for i in 0..64 { let payload: u32 = i; // We send the payload to the other side and wait for the reply. - let mut gate_stream = todo!().expect("send/receive failed"); + let mut gate_stream = + send_recv!(send_gate, &reply_gate, payload).expect("send/receive failed"); // Unmarshall the reply. - let reply = todo!().expect("unmarshalling failed"); + let reply = gate_stream.pop::().expect("unmarshalling failed"); println!("{}", reply); } - */ Ok(()) } commit a424b55d585c9e0ab2d9d4c71b1a4df551cb2017 Author: vilaureu Date: Wed Jan 21 17:08:04 2026 +0100 add read file solution Co-authored-by: Nils Asmussen diff --git a/boot/rdfile.xml b/boot/rdfile.xml new file mode 100644 index 000000000..3169803b4 --- /dev/null +++ b/boot/rdfile.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/apps/rdfile/src/rdfile.rs b/src/apps/rdfile/src/rdfile.rs index 7b8317b65..45d03448f 100644 --- a/src/apps/rdfile/src/rdfile.rs +++ b/src/apps/rdfile/src/rdfile.rs @@ -1,19 +1,37 @@ #![no_std] use m3::errors::Error; +use m3::io::Read; use m3::io::Write; -use m3::vec; +use m3::vfs::{OpenFlags, VFS}; +use m3::{env, println, vec}; #[no_mangle] pub fn main() -> Result<(), Error> { + let filename = env::args() + .nth(1) + .unwrap_or_else(|| panic!("Usage: {} ", env::args().next().unwrap_or("rdfile"))); + + let mut file = + VFS::open(filename, OpenFlags::R).unwrap_or_else(|_| panic!("Unable to open {}", filename)); + + println!("Contents of {}:", filename); // Create an empty vector to store the read file contents. - let buf = vec![0u8; 512]; - let count = 0; - // Write the binary data directly to STDOUT. - m3::io::stdout() - .get_mut() - .write_all(&buf[0..count]) - .unwrap(); + let mut buf = vec![0u8; 512]; + loop { + let count = file + .read(&mut buf) + .unwrap_or_else(|_| panic!("Read of {} failed", filename)); + if count == 0 { + break; + } + + // Write the binary data directly to STDOUT. + m3::io::stdout() + .get_mut() + .write_all(&buf[0..count]) + .unwrap(); + } Ok(()) } commit 3342deafaa3fe026f46a70323238112f90f70005 Author: vilaureu Date: Wed Jan 21 17:36:17 2026 +0100 add std-based read file solution diff --git a/boot/rdfilestd.xml b/boot/rdfilestd.xml new file mode 100644 index 000000000..b3788c350 --- /dev/null +++ b/boot/rdfilestd.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Cargo.lock b/src/Cargo.lock index c6562c6a9..967fd444e 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -726,6 +726,14 @@ dependencies = [ "m3", ] +[[package]] +name = "rdfilestd" +version = "0.1.0" +dependencies = [ + "m3core", + "m3files", +] + [[package]] name = "repeater" version = "0.1.0" diff --git a/src/Cargo.toml b/src/Cargo.toml index 6b43d39ad..134893f6f 100644 --- a/src/Cargo.toml +++ b/src/Cargo.toml @@ -37,6 +37,7 @@ members = [ "apps/raser", "apps/rasertest", "apps/rdfile", + "apps/rdfilestd", "apps/repeater", "apps/resmngtest", "apps/rusthello", diff --git a/src/apps/build.py b/src/apps/build.py index 913f3282b..d32209c61 100644 --- a/src/apps/build.py +++ b/src/apps/build.py @@ -26,6 +26,7 @@ dirs = [ 'raser', 'rasertest', 'rdfile', + 'rdfilestd', 'repeater', 'resmngtest', 'rusthello', diff --git a/src/apps/rdfilestd/Cargo.toml b/src/apps/rdfilestd/Cargo.toml new file mode 100644 index 000000000..313bccb3e --- /dev/null +++ b/src/apps/rdfilestd/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "rdfilestd" +version = "0.1.0" +edition = "2021" + +[lib] +path = "src/rdfilestd.rs" +crate-type = ["staticlib"] + +[dependencies] +m3core = { path = "../../libs/rust/m3core" } +m3files = { path = "../../libs/rust/m3files" } diff --git a/src/apps/rdfilestd/build.py b/src/apps/rdfilestd/build.py new file mode 100644 index 000000000..cd53ed670 --- /dev/null +++ b/src/apps/rdfilestd/build.py @@ -0,0 +1,2 @@ +def build(gen, env): + env.m3_rust_exe(gen, out='rdfilestd', std=True) diff --git a/src/apps/rdfilestd/src/rdfilestd.rs b/src/apps/rdfilestd/src/rdfilestd.rs new file mode 100644 index 000000000..689494511 --- /dev/null +++ b/src/apps/rdfilestd/src/rdfilestd.rs @@ -0,0 +1,59 @@ +#![feature(io_error_more)] + +extern crate m3core as m3; + +#[allow(unused_extern_crates)] +extern crate m3files; + +use core::ptr; +use m3::{env, errors::Error}; +use std::{ + fs::File, + io::{stdout, Read, Write}, +}; + +extern "C" { + fn __m3_init_libc(argc: i32, argv: *const *const u8, envp: *const *const u8, tls: bool); +} + +// This env_run function is necessary because this crate does *not* use the +// normal, outward-facing m3 crate. That crate ties together the internals and +// provides the runtime initializers. Thus this crate must provide them +// itself. +#[no_mangle] +pub extern "C" fn env_run() -> ! { + unsafe { + __m3_init_libc(0, ptr::null(), ptr::null(), false); + } + + m3files::vfs_init().expect("Couldn't init vfs subsystem."); + m3core::env::init(); + + m3core::env::run(); +} + +#[no_mangle] +pub fn main() -> Result<(), Error> { + let filename = env::args() + .nth(1) + .unwrap_or_else(|| panic!("Usage: {} ", env::args().next().unwrap_or("rdfile"))); + + let mut file = File::open(filename).unwrap_or_else(|_| panic!("Unable to open {}", filename)); + + println!("Contents of {}:", filename); + // Create an empty vector to store the read file contents. + let mut buf = vec![0u8; 512]; + loop { + let count = file + .read(&mut buf) + .unwrap_or_else(|_| panic!("Read of {} failed", filename)); + if count == 0 { + break; + } + + // Write the binary data directly to STDOUT. + stdout().write_all(&buf[0..count]).unwrap(); + } + + Ok(()) +} commit 006c138644c0f9cac03e829f1d985a82e526fcdf Author: vilaureu Date: Fri Feb 13 10:49:39 2026 +0100 add solution for accelerator demonstration diff --git a/boot/acceldemo.xml b/boot/acceldemo.xml index e2b8e6fbe..6b66518fe 100644 --- a/boot/acceldemo.xml +++ b/boot/acceldemo.xml @@ -11,7 +11,7 @@ - + diff --git a/src/apps/acceldemo/src/acceldemo.rs b/src/apps/acceldemo/src/acceldemo.rs index 60449a350..0fa8ca12f 100644 --- a/src/apps/acceldemo/src/acceldemo.rs +++ b/src/apps/acceldemo/src/acceldemo.rs @@ -1,41 +1,53 @@ #![no_std] -use m3::errors::Error; +use accel::StreamAccel; +use m3::col::String; +use m3::com::MemCap; +use m3::errors::{Code, Error}; +use m3::io::{Read, Write}; +use m3::kif::Perm; +use m3::tiles::{ChildActivity, OwnActivity, Tile}; +use m3::vfs::File; +use m3::{env, println, vec}; +use pipecli::{IndirectPipe, Pipes}; #[no_mangle] pub fn main() -> Result<(), Error> { - /* - - // Read all program arguments into a single input string: - let input = todo!(); + let input = env::args() + .skip(1) + .enumerate() + .fold(String::new(), |input, (i, arg)| { + input + if i == 0 { "" } else { " " } + arg + }); println!("Original input: {}", input); let input = input.as_bytes(); - // Create a new pipes session. + let pipes = Pipes::new("pipes").expect("failed to create pipes session"); const MEM_SIZE: u64 = 32; let in_mem = MemCap::new(MEM_SIZE, Perm::RW).expect("failed to get memory capability"); + let in_pipe = IndirectPipe::new(&pipes, in_mem).expect("failed to create pipe"); let out_mem = MemCap::new(MEM_SIZE, Perm::RW).expect("failed to get memory capability"); - - // Create two indirect pipes using the memory capabilities above. - - // Get the tile capability and use it to create a new child activity: - let act = todo!(); - - // Create a new streaming accelerator from the activity. Set the tee parameter to false. - - // Attach the correct pipe reader/writer to the streaming accelerator input/output. - + let out_pipe = IndirectPipe::new(&pipes, out_mem).expect("failed to create pipe"); + + let tile = Tile::get("rot13").expect("failed to get rot13 tile"); + let act = ChildActivity::new(tile, "rot13").expect("failed to start rot13 activity"); + + let mut accel = StreamAccel::new(&act, false).expect("failed to create streaming accelerator"); + accel + .attach_input(&mut in_pipe.reader().expect("failed to get pipe reader")) + .expect("failed to attach pipe"); + accel + .attach_output(&mut out_pipe.writer().expect("failed to get pipe writer")) + .expect("failed to attach pipe"); let _act = act.start().expect("failed to start accelerator"); - // Get the other reader/writer ends of the two pipes: - let mut write_end = todo!(); - let mut read_end = todo!(); - + let mut write_end = in_pipe.writer().expect("failed to get pipe writer"); write_end .set_blocking(false) .expect("could not set pipe end non-blocking"); + let mut read_end = out_pipe.reader().expect("failed to get pipe reader"); write_end .set_blocking(false) .expect("could not set pipe end non-blocking"); @@ -44,34 +56,30 @@ pub fn main() -> Result<(), Error> { let mut in_pos = 0; let mut out_pos = 0; while out_pos < output.len() { - // Try to write input data if there is any data left: - match write_end.write(todo!()) { - Err(e) if e.code() == Code::WouldBlock => {}, - r => { - let number_of_written_bytes = r.expect("writing input failed"); - todo!("use number_of_written_bytes"); - if in_pos >= input.len() { - in_pipe.close_writer(); - } - }, + if in_pos < input.len() { + match write_end.write(&input[in_pos..]) { + Err(e) if e.code() == Code::WouldBlock => {}, + r => { + in_pos += r.expect("writing input failed"); + if in_pos >= input.len() { + in_pipe.close_writer(); + } + continue; + }, + } } - // Try to read into output: - match read_end.read(todo!()) { + match read_end.read(&mut output[out_pos..]) { Err(e) if e.code() == Code::WouldBlock => {}, r => { - let number_of_read_bytes = r.expect("reading output failed"); - todo!("use number_of_read_bytes"); + out_pos += r.expect("reading output failed"); continue; }, } OwnActivity::sleep().expect("could not wait for next message"); } - println!("Transformed output: {}", &String::from_utf8_lossy(&output)); - */ - Ok(()) } commit 1fa7b871f410e054ecd9f13b711377ec047acb2e Author: vilaureu Date: Mon Feb 16 14:58:17 2026 +0100 add solution for session task diff --git a/src/apps/sessions/client/src/client.rs b/src/apps/sessions/client/src/client.rs index 29b1f39bd..b2d8dc15e 100644 --- a/src/apps/sessions/client/src/client.rs +++ b/src/apps/sessions/client/src/client.rs @@ -4,7 +4,6 @@ use m3::errors::Error; #[no_mangle] pub fn main() -> Result<(), Error> { - /* use m3::client::ClientSession; use m3::col::String; use m3::com::MemGate; @@ -13,7 +12,15 @@ pub fn main() -> Result<(), Error> { // Get the client session that was configured in the boot XML. let session = ClientSession::new("sessions").expect("failed to get session"); - let crd = todo!("obtain memory capability via session"); + let crd = session + .obtain( + 1, + |os| { + os.push(0usize); + }, + |_| Ok(()), + ) + .expect("failed to get object"); // Bind the memory capability to a memory gate at our own TCU. let mem = MemGate::new_bind(crd.start()).expect("failed to activate memory gate"); @@ -26,7 +33,6 @@ pub fn main() -> Result<(), Error> { "Data from server (via memory capability): {}", String::from_utf8_lossy(&data) ); - */ Ok(()) } diff --git a/src/apps/sessions/server/src/server.rs b/src/apps/sessions/server/src/server.rs index 6002538ad..159e43514 100644 --- a/src/apps/sessions/server/src/server.rs +++ b/src/apps/sessions/server/src/server.rs @@ -17,7 +17,6 @@ struct Session { // We hold onto the server’s session object. _serv: ServerSession, // The memory capability that we can send to the client on request. - #[allow(dead_code)] mem: MemCap, } @@ -37,7 +36,6 @@ impl RequestSession for Session { } } -/* use m3::kif::CapRngDesc; use m3::kif::CapType; use m3::server::CapExchange; @@ -56,12 +54,11 @@ impl Session { // We get the corresponding session of this request from the client manager. let sess: &mut Session = cli.get_mut(sid).expect("session not found"); - todo!("Send memory capability to client!"); + xchg.out_caps(CapRngDesc::new_single(CapType::Object, sess.mem.sel())); Ok(()) } } -*/ #[no_mangle] pub fn main() -> Result<(), Error> { @@ -72,7 +69,7 @@ pub fn main() -> Result<(), Error> { // Server that creates new sessions. let srv = Server::new("sessions", &mut hdl).expect("Unable to create service"); - /* todo!("Register handler function!"); */ + hdl.reg_cap_handler(0usize, ExcType::Obt(1), Session::get_mem); // Endless sever loop reacting to new messages. server_loop(|| {