l4re-base-25.08.0

This commit is contained in:
2025-09-12 15:55:45 +02:00
commit d959eaab98
37938 changed files with 9382688 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
PKGDIR ?= ..
L4DIR ?= $(PKGDIR)/../../..
TARGET = ex_map_irq_client ex_map_irq_server
SRC_CC_ex_map_irq_client = client.cc
SRC_CC_ex_map_irq_server = server.cc
include $(L4DIR)/mk/prog.mk

View File

@@ -0,0 +1 @@
Example showcasing how to map a cap from a client to a server.

View File

@@ -0,0 +1,81 @@
/*
* Example for mapping a capability from a client to a server - client part.
*
* (c) 2014 Steffen Liebergeld <steffen.liebergeld@kernkonzept.com>
*
* This file is licensed under the terms of the GNU General Public License 2.
* See file COPYING-GPL-2 for details.
*/
#include <l4/sys/factory>
#include <l4/sys/irq>
#include <l4/sys/ipc_gate>
#include <l4/cxx/ipc_stream>
#include <l4/re/env>
#include <l4/re/error_helper>
#include <l4/re/util/cap_alloc>
#include <cstdio>
#include "shared.h"
enum { Nr_of_triggers = 3 };
static int run()
{
using L4Re::chksys;
using L4Re::chkcap;
printf("Hello from ex_map_irq_client.\n");
// allocate cap for IRQ
L4::Cap<L4::Irq> irq = chkcap(L4Re::Util::cap_alloc.alloc<L4::Irq>(),
"could not find a free cap slot");
// create IRQ kernel object
chksys(L4Re::Env::env()->factory()->create(irq),
"create a new IRQ kernel object");
// look out for server
L4::Cap<Irq_source> server;
server = chkcap(L4Re::Env::env()->get_cap<Irq_source>("ex_map_irq"),
"get 'ex_map_irq' capability");
// map irq to server
printf("Mapping IRQ cap to server.\n");
chksys(server->map_irq(irq), "map irq");
// bind to IRQ and wait for the server to trigger it
chksys(irq->bind_thread(L4Re::Env::env()->main_thread(), 0),
"bind to IRQ");
// tell the server to start triggering us and how many times it should
// trigger the IRQ
chksys(server->start(Nr_of_triggers), "starting triggers");
for (int i = 0; i < Nr_of_triggers; ++i)
{
chksys(irq->receive(), "receiving IRQ");
printf("Received IRQ.\n");
}
printf("ex_map_irq_client finished.\n");
return 0;
}
int main()
{
try
{
return run();
}
catch (L4::Runtime_error &e)
{
printf("Runtime error: %s.\n", e.str());
}
catch (...)
{
printf("Uncaught error.\n");
}
return 1;
}

View File

@@ -0,0 +1,32 @@
-- (c) 2014 Steffen Liebergeld <steffen.liebergeld@kernkonzept.com>
-- Licensed under the terms of the GNU General Public License 2.
-- See file COPYING-GPL-2 for details.
-- Example config for map_irq
local L4 = require("L4");
-- create a shortcut for L4.default_loader
local l = L4.default_loader;
-- create a communication channel
local channel = l:new_channel();
-- start the server
l:start({
caps = {
-- Give the channel (an IPC gate) to the server
-- The "svr()" directive instructs the loader
-- to supply the capability with server permissions
ex_map_irq = channel:svr()
},
-- configure log output: tag = server, color = magenta
log = { "server", "m" },
}, "rom/ex_map_irq_server");
-- start the client
l:start({
caps = {
ex_map_irq = channel -- give the channel to the client
},
log = {"client", "y"},
}, "rom/ex_map_irq_client");

View File

@@ -0,0 +1,13 @@
# (c) Steffen Liebergeld <steffen.liebergeld@kernkonzept.com>
# Licensed under the terms of the GNU General Public License 2.
# See file COPYING-GPL-2 for details.
#
# Config for loading the ex_map_irq example
entry ex_map_irq
roottask moe rom/ex_map_irq.cfg
module ned
module l4re
module ex_map_irq.cfg
module ex_map_irq_server
module ex_map_irq_client

View File

@@ -0,0 +1,148 @@
/*
* Example for mapping a capability from a client to a server - server part.
*
* (c) 2014 Steffen Liebergeld <steffen.liebergeld@kernkonzept.com>
*
* This file is licensed under the terms of the GNU General Public License 2.
* See file COPYING-GPL-2 for details.
*/
#include <l4/re/error_helper>
#include <l4/sys/cxx/ipc_epiface>
#include <l4/sys/irq>
#include <l4/re/env>
#include <l4/sys/factory>
#include <l4/re/util/object_registry>
#include <l4/re/util/br_manager>
#include <cstdio>
#include <cstring>
#include <unistd.h>
#include <stdlib.h>
#include "shared.h"
// Those are error helpers that simplify our code by hiding error checking.
// Errors flagged through C++ exceptions.
using L4Re::chksys;
using L4Re::chkcap;
// This class reacts on notifications from Server
class Trigger : public L4::Irqep_t<Trigger>
{
public:
void handle_irq()
{
for (unsigned i = 0; i < _nrs; ++i)
{
printf("Triggering IRQ.\n");
_irq->trigger();
sleep(1);
}
printf("ex_map_irq_server finished.\n");
exit(0);
}
void num_triggers(unsigned num);
void irq(L4::Cap<L4::Irq> irq);
void trigger() { _irq->trigger(); }
private:
L4::Cap<L4::Irq> _irq;
unsigned _nrs;
};
void Trigger::num_triggers(unsigned num)
{
_nrs = num;
}
void Trigger::irq(L4::Cap<L4::Irq> irq)
{
_irq = irq;
}
// This class handles the reception of the IRQ cap from the client.
class Server : public L4::Epiface_t<Server, Irq_source>
{
public:
Server(L4::Cap<L4::Irq> irq, Trigger *trigger)
: _trigger_notification(irq), _trigger(trigger)
{}
int op_map_irq(Irq_source::Rights, L4::Ipc::Snd_fpage const &irq);
int op_start(Irq_source::Rights, unsigned nrs);
private:
void do_client_trigger(unsigned);
L4::Cap<L4::Irq> _trigger_notification;
Trigger *_trigger;
};
int
Server::op_map_irq(Irq_source::Rights, L4::Ipc::Snd_fpage const &irq)
{
if (!irq.cap_received())
return -L4_EINVAL;
// We use rcv_cap for receiving only.
// After receiving the cap, we tell the kernel to associate
// the kernel object that rcv_cap points to with irq.
// allocate new cap
_trigger->irq(L4Re::chkcap(server_iface()->rcv_cap<L4::Irq>(0),
"reading receive capability 0"));
L4Re::chksys(server_iface()->realloc_rcv_cap(0),
"allocating new receive capability");
printf("Received IRQ from client.\n");
return L4_EOK;
}
int
Server::op_start(Irq_source::Rights, unsigned nrs)
{
_trigger->num_triggers(nrs);
_trigger_notification->trigger();
return L4_EOK;
}
static L4Re::Util::Registry_server<L4Re::Util::Br_manager_hooks> server;
static int run()
{
printf("Hello from ex_map_irq_server.\n");
Trigger trigger;
L4::Cap<L4::Irq> notification_irq;
notification_irq = chkcap(server.registry()->register_irq_obj(&trigger),
"could not register notification trigger");
Server map_irq_srv(notification_irq, &trigger);
L4Re::chkcap(server.registry()->register_obj(&map_irq_srv, "ex_map_irq"),
"could not register service side");
server.loop();
return 0;
}
int main()
{
try
{
return run();
}
catch (L4::Runtime_error &e)
{
printf("Runtime error: %s.\n", e.str());
}
catch (...)
{
printf("Uncaught error.\n");
}
return 1;
}

View File

@@ -0,0 +1,14 @@
#pragma once
#include <l4/sys/capability>
#include <l4/sys/cxx/ipc_iface>
#include <l4/sys/cxx/ipc_types>
struct Irq_source :
L4::Kobject_t<Irq_source, L4::Kobject, 0x77, L4::Type_info::Demand_t<1> >
{
L4_INLINE_RPC(int, map_irq, (L4::Ipc::Cap<L4::Irq> irq));
L4_INLINE_RPC(int, start, (unsigned nrs));
typedef L4::Typeid::Rpcs<map_irq_t, start_t> Rpcs;
};