Made cells into proper RPC objects.

This commit is contained in:
Michael Mueller
2025-02-24 15:24:06 +01:00
parent 7aeca3aceb
commit 372ca18156
8 changed files with 223 additions and 42 deletions

View File

@@ -0,0 +1,39 @@
/*
* \brief Cell-session interface
* \author Michael Müller
* \date 2025-02-17
*/
/*
* Copyright (C) 2025 Michael Müller, Osnabrück University
*
* This file is part of the EalánOS research operating system, which is distributed
* under the terms of the GNU Affero General Public License version 3.
*/
#ifndef _INCLUDE__CELL__SESSION_H_
#define _INCLUDE__CELL__SESSION_H_
/* Genode includes */
#include <base/affinity.h>
#include <base/capability.h>
#include <base/rpc_args.h>
#include <session/session.h>
namespace Ealan { struct Cell;
using Cell_capability = Genode::Capability<Cell>;
}
struct Ealan::Cell : Genode::Interface
{
enum { CAP_QUOTA = 1 };
virtual void update(Genode::Affinity &affinity) = 0;
virtual bool is_brick() = 0;
GENODE_RPC(Rpc_update, void, update, Genode::Affinity &);
GENODE_RPC(Rpc_is_brick, bool, is_brick);
GENODE_RPC_INTERFACE(Rpc_update, Rpc_is_brick);
};
#endif /* _INCLUDE__CELL__SESSION_H_ */

View File

@@ -0,0 +1,38 @@
/*
* \brief Client-side Cell interface
* \author Michael Müller
* \date 2025-02-24
*/
/*
* Copyright (C) 2025 Michael Müller <michael.mueller@uos.de>, Osnabrück University
*
* This file is part of EalánOS based on the Genode OS framework, which are distributed
* under the terms of the GNU Affero General Public Lisense version 3.
*/
#ifndef _INCLUDE__CELL__CLIENT_H_
#define _INCLUDE__CELL__CLIENT_H_
#include <cell/cell.h>
#include <base/rpc_client.h>
namespace Ealan {
struct Cell_client;
}
struct Ealan::Cell_client : Genode::Rpc_client<Cell>
{
explicit Cell_client(Cell_capability cap)
: Rpc_client<Cell>(cap) {}
void update(Genode::Affinity &affinity) override {
call<Rpc_update>(affinity);
}
bool is_brick() override {
return call<Rpc_is_brick>();
}
};
#endif /* _INCLUDE__CELL__CLIENT_H_ */

View File

@@ -27,8 +27,8 @@ struct Ealan::Habitat_client : Genode::Rpc_client<Ealan::Habitat_session>
{
explicit Habitat_client(Habitat_capability session) : Rpc_client<Habitat_session>(session) {}
void create_cell(Genode::Capability<Genode::Pd_session> pd, Genode::Affinity &affinity, Genode::uint16_t prio) override {
call<Rpc_create_cell>(pd, affinity, prio);
Cell_capability create_cell(Genode::Capability<Genode::Pd_session> pd, Genode::Affinity &affinity, Genode::uint16_t prio, Genode::Session_label const &label) override {
return call<Rpc_create_cell>(pd, affinity, prio, label);
}
};
#endif

View File

@@ -28,8 +28,8 @@ struct Ealan::Habitat_connection : Genode::Connection<Ealan::Habitat_session>, H
Habitat_connection(Genode::Env &env, Genode::Affinity &affinity, Label const &label = Label())
: Connection<Habitat_session>(env, label, Genode::Ram_quota { RAM_QUOTA }, affinity, Args("")), Habitat_client(cap()) {}
void create_cell(Genode::Capability<Genode::Pd_session> pd_cap, Genode::Affinity &affinity, Genode::uint16_t prio) override {
Habitat_client::create_cell(pd_cap, affinity, prio);
Cell_capability create_cell(Genode::Capability<Genode::Pd_session> pd_cap, Genode::Affinity &affinity, Genode::uint16_t prio, Genode::Session_label const &label) override {
return Habitat_client::create_cell(pd_cap, affinity, prio, label);
}
};

View File

@@ -18,6 +18,7 @@
#include <base/rpc_args.h>
#include <session/session.h>
#include <pd_session/pd_session.h>
#include <cell/cell.h>
namespace Ealan { struct Habitat_session; }
@@ -30,9 +31,9 @@ struct Ealan::Habitat_session : Genode::Session
/**
* Attach cell info page to the cells virtual memory space
*/
virtual void create_cell(Genode::Capability<Genode::Pd_session> pd, Genode::Affinity &affinity, Genode::uint16_t prio) = 0;
virtual Cell_capability create_cell(Genode::Capability<Genode::Pd_session> pd, Genode::Affinity &affinity, Genode::uint16_t prio, Genode::Session_label const &label) = 0;
GENODE_RPC(Rpc_create_cell, void, create_cell, Genode::Capability<Genode::Pd_session>, Genode::Affinity&, Genode::uint16_t);
GENODE_RPC(Rpc_create_cell, Cell_capability, create_cell, Genode::Capability<Genode::Pd_session>, Genode::Affinity &, Genode::uint16_t, Genode::Session_label const &);
GENODE_RPC_INTERFACE(Rpc_create_cell);
};
#endif

View File

@@ -0,0 +1,103 @@
/*
* \brief Core-specific instance of the Cell interface
* \author Michael Müller
* \date 2025-02-24
*/
/*
* Copyright (C) 2025 Michael Müller <michael.mueller@uos.de>, Osnabrück University
*
* This file is part of EalánOS based on the Genode OS framework, which are distributed
* under the terms of the GNU Affero General Public Lisense version 3.
*/
#ifndef _CORE__INCLUDE__CELL_COMPONENT_H_
#define _CORE__INCLUDE__CELL_COMPONENT_H_
/* Genode includes */
#include <base/rpc_server.h>
#include <base/session_label.h>
#include <pd_session/client.h>
#include <util/list.h>
#include <platform_generic.h>
/* EalánOS includes */
#include <cell/cell.h>
/* Tukija includes */
#include <tukija/syscalls.h>
#include <tukija_native_pd/client.h>
#include <nova_util.h>
namespace Ealan {
class Cell_component;
}
class Ealan::Cell_component : public Genode::Rpc_object<Cell>,
private Genode::List<Cell_component>::Element
{
private:
friend class Genode::List<Cell_component>;
Genode::Rpc_entrypoint &_ep;
Genode::Session_label const _session_label;
Genode::Region_map &_rm;
Genode::Pd_session_capability _pd_cap;
Genode::Pd_session_client _pd;
Genode::Tukija_native_pd_client _native_pd;
Tukija::Cip *_cip{nullptr};
bool _is_brick{false};
void _calculate_mask_for_location(Tukija::Cpuset *coreset, const Genode::Affinity::Location &loc)
{
for (unsigned y = loc.ypos(); y < loc.ypos() + loc.height(); y++)
{
for (unsigned x = loc.xpos(); x < loc.xpos()+loc.width(); x++)
{
unsigned kernel_cpu = Core::platform_specific().kernel_cpu_id(Genode::Affinity::Location(x, y, loc.width(), loc.height()));
coreset->set(kernel_cpu);
}
}
}
Cell_component(const Cell_component &);
Cell_component& operator=(const Cell_component &);
public:
Cell_component(Genode::Pd_session_capability pd_cap, Genode::uint16_t prio, Genode::Affinity &affinity, Genode::Rpc_entrypoint &ep, Genode::Region_map &rm, Genode::Session_label const &label) : _ep(ep), _session_label(label), _rm(rm), _pd_cap(pd_cap), _pd(pd_cap), _native_pd(_pd.native_pd()) {
Tukija::mword_t cell_pd_sel = _native_pd.sel();
Tukija::mword_t cip_phys = 0;
Core::platform().region_alloc().alloc_aligned(4 * Tukija::PAGE_SIZE_BYTE, Tukija::PAGE_SIZE_LOG2).with_result(
[&](void *ptr) { _cip = static_cast<Tukija::Cip*>(ptr); },
[&](Genode::Range_allocator::Alloc_error) { throw Genode::Out_of_ram(); });
Tukija::mword_t cip_virt = reinterpret_cast<Tukija::mword_t>(_cip);
if (Tukija::create_cell(cell_pd_sel, static_cast<Genode::uint8_t>(prio), cip_phys, cip_virt)) {
Genode::error("Failed to create cell at Tukija.");
}
_calculate_mask_for_location(&_cip->cores_reserved, affinity.location());
Genode::log("Cores for <", label, ">: ", _cip->cores_reserved);
}
/********************
** Cell interface **
********************/
void update(Genode::Affinity &affinity) override {
/* TODO: implement */
Genode::log("Changing cell's affinity to ", affinity);
}
bool is_brick() override {
return _is_brick;
}
};
#endif

View File

@@ -14,16 +14,18 @@ namespace Core {
Genode::Ram_allocator &_ram_alloc;
Genode::Region_map &_local_rm;
Genode::Rpc_entrypoint &_session_ep;
protected:
Habitat_session_component *_create_session(char const *, Genode::Affinity const &affinity) override {
Habitat_session_component *_create_session(char const *args, Genode::Affinity const &affinity) override {
if (!affinity.valid()) {
Genode::error("Invalid affinity space: ", affinity);
throw Genode::Service_denied();
}
return new (md_alloc()) Habitat_session_component(_local_rm, affinity.space());
return new (md_alloc()) Habitat_session_component(session_label_from_args(args), _session_ep, _local_rm, _ram_alloc, affinity.space());
}
void _upgrade_session(Habitat_session_component *, const char *) override
@@ -37,7 +39,7 @@ namespace Core {
Genode::Region_map &local_rm,
Genode::Rpc_entrypoint &session_ep,
Genode::Allocator &md_alloc)
: Root_component<Habitat_session_component>(&session_ep, &md_alloc), _ram_alloc(ram_alloc), _local_rm(local_rm) {}
: Root_component<Habitat_session_component>(&session_ep, &md_alloc), _ram_alloc(ram_alloc), _local_rm(local_rm), _session_ep(session_ep) {}
};
}

View File

@@ -1,14 +1,29 @@
/*
* \brief Core-specific instance of a Habitat session
* \author Michael Müller
* \date 2025-02-24
*/
/*
* Copyright (C) 2025 Michael Müller <michael.mueller@uos.de>, Osnabrück University
*
* This file is part of EalánOS based on the Genode OS framework, which are distributed
* under the terms of the GNU Affero General Public Lisense version 3.
*/
#ifndef _CORE__HABITAT_SESSION_COMPONENT_H_
#define _CORE__HABITAT_SESSION_COMPONENT_H_
#include <base/rpc_server.h>
#include <base/env.h>
#include <base/allocator.h>
#include <base/heap.h>
#include <base/session_label.h>
#include <habitat/session.h>
#include <tukija/syscalls.h>
#include <tukija_native_pd/client.h>
#include <pd_session/client.h>
#include <cell_component.h>
#include <nova_util.h>
@@ -20,50 +35,33 @@ class Core::Habitat_session_component : public Genode::Rpc_object<Ealan::Habitat
private:
Genode::Region_map &_local_rm;
Genode::Affinity::Space const &_space;
Genode::Session_label const &_label;
Genode::Sliced_heap _md_alloc;
Genode::Rpc_entrypoint &_ep;
Genode::List<Ealan::Cell_component> _managed_cells { };
void _calculate_mask_for_location(Tukija::Cpuset *coreset, const Affinity::Location &loc)
{
for (unsigned y = loc.ypos(); y < loc.ypos() + loc.height(); y++)
void _calculate_mask_for_location(Tukija::Cpuset *coreset, const Affinity::Location &loc)
{
for (unsigned x = loc.xpos(); x < loc.xpos()+loc.width(); x++)
for (unsigned y = loc.ypos(); y < loc.ypos() + loc.height(); y++)
{
unsigned kernel_cpu = platform_specific().kernel_cpu_id(Affinity::Location(x, y, loc.width(), loc.height()));
coreset->set(kernel_cpu);
for (unsigned x = loc.xpos(); x < loc.xpos() + loc.width(); x++)
{
unsigned kernel_cpu = platform_specific().kernel_cpu_id(Affinity::Location(x, y, loc.width(), loc.height()));
coreset->set(kernel_cpu);
}
}
}
}
public:
Habitat_session_component(Genode::Region_map &rm, Genode::Affinity::Space const &space) : _local_rm(rm), _space(space) {}
Habitat_session_component(Genode::Session_label const &label, Genode::Rpc_entrypoint &session_ep, Genode::Region_map &rm, Genode::Ram_allocator &alloc, Genode::Affinity::Space const &space) : _local_rm(rm), _space(space), _label(label), _md_alloc(alloc, rm), _ep(session_ep) {}
void create_cell(Genode::Capability<Genode::Pd_session> pd_cap, [[maybe_unused]] Genode::Affinity &affinity, Genode::uint16_t prio) override {
Ealan::Cell_capability create_cell(Genode::Capability<Genode::Pd_session> pd_cap, [[maybe_unused]] Genode::Affinity &affinity, Genode::uint16_t prio, Genode::Session_label const &label) override {
Genode::Pd_session_client pd(pd_cap);
Genode::Tukija_native_pd_client cell_pd_client(pd.native_pd());
Genode::log("Attempting to create cell object for ", pd_cap);
Tukija::mword_t cell_pd_sel = cell_pd_client.sel();
Tukija::mword_t cip_phys = 0;
Tukija::mword_t cip_virt = 0;
platform().region_alloc().alloc_aligned(4 * Tukija::PAGE_SIZE_BYTE, Tukija::PAGE_SIZE_LOG2).with_result(
[&](void *ptr) { cip_virt = reinterpret_cast<Tukija::mword_t>(ptr); },
[&](Genode::Range_allocator::Alloc_error) {});
if (Tukija::create_cell(cell_pd_sel, static_cast<Genode::uint8_t>(prio), cip_phys, cip_virt))
{
Genode::error("Failed to create cell");
}
Genode::log("Mapped CIP from ", reinterpret_cast<void *>(cip_phys), " to ", cip_virt);
//*cip = 0xff;
Tukija::Cip *cip = reinterpret_cast<Tukija::Cip *>(cip_virt);
_calculate_mask_for_location(&cip->cores_reserved, affinity.location());
Genode::log("Cores reserved: ", cip->cores_reserved);
Ealan::Cell_component *cell = new (_md_alloc) Ealan::Cell_component(pd_cap, prio, affinity, _ep, _local_rm, label);
_managed_cells.insert(cell);
return cell->cap();
}
};