Added support for habitats.

This commit is contained in:
Michael Mueller
2025-12-08 18:38:02 +01:00
parent 9943716d9b
commit dd0c8b10dc
5 changed files with 105 additions and 32 deletions

View File

@@ -298,9 +298,15 @@ namespace Tukija {
ALWAYS_INLINE ALWAYS_INLINE
inline uint8_t create_cell(mword_t pd, uint8_t prio, mword_t &cip, mword_t &dst) inline uint8_t create_cell(mword_t pd, mword_t hsel, uint8_t prio, mword_t &cip, mword_t &dst)
{ {
return syscall_5(TUKIJA_CREATE_CELL, prio, pd, dst, cip); return syscall_5(TUKIJA_CREATE_CELL, prio, pd, hsel, dst, cip);
}
ALWAYS_INLINE
inline uint8_t create_habitat(mword_t sel, mword_t dst)
{
return syscall_1(TUKIJA_CREATE_HABITAT, 0, sel, dst);
} }
ALWAYS_INLINE ALWAYS_INLINE

View File

@@ -57,27 +57,28 @@ namespace Tukija {
* NOVA system-call IDs * NOVA system-call IDs
*/ */
enum Syscall { enum Syscall {
NOVA_CALL = 0x0, NOVA_CALL = 0x0,
NOVA_REPLY = 0x1, NOVA_REPLY = 0x1,
NOVA_CREATE_PD = 0x2, NOVA_CREATE_PD = 0x2,
NOVA_CREATE_EC = 0x3, NOVA_CREATE_EC = 0x3,
NOVA_CREATE_SC = 0x4, NOVA_CREATE_SC = 0x4,
NOVA_CREATE_PT = 0x5, NOVA_CREATE_PT = 0x5,
NOVA_CREATE_SM = 0x6, NOVA_CREATE_SM = 0x6,
NOVA_REVOKE = 0x7, NOVA_REVOKE = 0x7,
NOVA_MISC = 0x8, /* lookup, delegate, acpi_suspend */ NOVA_MISC = 0x8, /* lookup, delegate, acpi_suspend */
NOVA_EC_CTRL = 0x9, NOVA_EC_CTRL = 0x9,
NOVA_SC_CTRL = 0xa, NOVA_SC_CTRL = 0xa,
NOVA_PT_CTRL = 0xb, NOVA_PT_CTRL = 0xb,
NOVA_SM_CTRL = 0xc, NOVA_SM_CTRL = 0xc,
NOVA_ASSIGN_PCI = 0xd, NOVA_ASSIGN_PCI = 0xd,
NOVA_ASSIGN_GSI = 0xe, NOVA_ASSIGN_GSI = 0xe,
NOVA_PD_CTRL = 0xf, NOVA_PD_CTRL = 0xf,
TUKIJA_CREATE_CELL = 0x10, TUKIJA_CREATE_CELL = 0x10,
TUKIJA_ALLOCATE = 0x11, TUKIJA_ALLOCATE = 0x11,
TUKIJA_CELL_CTRL = 0x12, TUKIJA_CELL_CTRL = 0x12,
TUKIJA_RELEASE = 0x13, TUKIJA_RELEASE = 0x13,
TUKIJA_MAP_TIP = 0x14 TUKIJA_MAP_TIP = 0x14,
TUKIJA_CREATE_HABITAT = 0x15
}; };
/** /**
@@ -137,6 +138,10 @@ namespace Tukija {
return cpu % CPUS_PER_VALUE; return cpu % CPUS_PER_VALUE;
} }
inline mword_t values()
{
return sizeof(raw) / sizeof(raw[0]);
}
public: public:
inline explicit Cpuset(mword_t const v) inline explicit Cpuset(mword_t const v)
{ {
@@ -183,6 +188,16 @@ namespace Tukija {
} }
} }
unsigned first_cpu()
{
long cpu = -1;
for (unsigned i = 0; i < values(); i++) {
cpu = bit_scan_forward(raw[i]);
if (cpu != -1) break;
}
return static_cast<unsigned>(cpu);
}
unsigned count() unsigned count()
{ {
unsigned count = 0; unsigned count = 0;
@@ -201,6 +216,17 @@ namespace Tukija {
} }
}; };
/**
* @brief Habitat Information page
*
*/
struct Habitat_info_page
{
alignas(64) Cpuset reserved_cores{0};
alignas(64) Cpuset current_cores{0};
alignas(64) bool resizable{false};
};
/** /**
* Cell information pages * Cell information pages
* *

View File

@@ -15,6 +15,7 @@
#define _CORE__INCLUDE__CELL_COMPONENT_H_ #define _CORE__INCLUDE__CELL_COMPONENT_H_
/* Genode includes */ /* Genode includes */
#include "tukija/stdint.h"
#include <base/rpc_server.h> #include <base/rpc_server.h>
#include <base/session_label.h> #include <base/session_label.h>
#include <pd_session/client.h> #include <pd_session/client.h>
@@ -83,7 +84,7 @@ class Ealan::Cell_component : public Genode::Rpc_object<Cell>,
public: 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, bool is_brick) : _ep(ep), _session_label(label), _rm(rm), _pd_cap(pd_cap), _pd(pd_cap), _native_pd(_pd.native_pd()), _is_brick(is_brick) { 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, bool is_brick, Tukija::mword_t habitat_sel) : _ep(ep), _session_label(label), _rm(rm), _pd_cap(pd_cap), _pd(pd_cap), _native_pd(_pd.native_pd()), _is_brick(is_brick) {
Tukija::mword_t cell_pd_sel = _native_pd.sel(); Tukija::mword_t cell_pd_sel = _native_pd.sel();
Tukija::mword_t cip_phys = 0; Tukija::mword_t cip_phys = 0;
@@ -101,7 +102,7 @@ class Ealan::Cell_component : public Genode::Rpc_object<Cell>,
* a page frame for the CIP. The CIP will then be mapped by the kernel using the * a page frame for the CIP. The CIP will then be mapped by the kernel using the
* supplied virtual address from the previously allocated region map. * supplied virtual address from the previously allocated region map.
*/ */
if (Tukija::create_cell(cell_pd_sel, static_cast<Genode::uint8_t>(prio), cip_phys, cip_virt)) { if (Tukija::create_cell(cell_pd_sel, habitat_sel, static_cast<Genode::uint8_t>(prio), cip_phys, cip_virt)) {
Genode::error("Failed to create cell at Tukija."); Genode::error("Failed to create cell at Tukija.");
throw Cell_creation_error(); throw Cell_creation_error();
} }

View File

@@ -13,6 +13,13 @@
#ifndef _CORE__HABITAT_SESSION_COMPONENT_H_ #ifndef _CORE__HABITAT_SESSION_COMPONENT_H_
#define _CORE__HABITAT_SESSION_COMPONENT_H_ #define _CORE__HABITAT_SESSION_COMPONENT_H_
#include "base/ram_allocator.h"
#include "base/stdint.h"
#include "dataspace_component.h"
#include "platform_generic.h"
#include "region_map/region_map.h"
#include "tukija/stdint.h"
#include "tukija/syscall-generic.h"
#include <base/rpc_server.h> #include <base/rpc_server.h>
#include <base/env.h> #include <base/env.h>
#include <base/allocator.h> #include <base/allocator.h>
@@ -24,7 +31,7 @@
#include <tukija_native_pd/client.h> #include <tukija_native_pd/client.h>
#include <pd_session/client.h> #include <pd_session/client.h>
#include <cell_component.h> #include <cell_component.h>
#include <tukija/cap_map.h>
#include <nova_util.h> #include <nova_util.h>
@@ -39,11 +46,15 @@ class Core::Habitat_session_component : public Genode::Session_object<Ealan::Hab
Genode::Constrained_ram_allocator _ram_alloc; Genode::Constrained_ram_allocator _ram_alloc;
Genode::Sliced_heap _md_alloc; Genode::Sliced_heap _md_alloc;
Genode::Rpc_entrypoint &_ep; Genode::Rpc_entrypoint &_ep;
Genode::List<Ealan::Cell_component> _managed_cells { }; Genode::List<Ealan::Cell_component> _managed_cells{};
Genode::addr_t _id_base;
void _calculate_mask_for_location(Tukija::Cpuset *coreset, const Genode::Affinity::Location &loc) Genode::addr_t _sel() const { return _id_base; }
void _calculate_mask_for_location(Tukija::Cpuset *coreset, const Genode::Affinity::Space &space)
{ {
const_cast<Genode::Affinity::Location&>(loc).for_each( const_cast<Genode::Affinity::Space&>(space).for_each(
[&](Genode::Affinity::Location const &location) [&](Genode::Affinity::Location const &location)
{ {
unsigned kernel_cpu = Core::platform_specific().kernel_cpu_id(location); unsigned kernel_cpu = Core::platform_specific().kernel_cpu_id(location);
@@ -52,11 +63,33 @@ class Core::Habitat_session_component : public Genode::Session_object<Ealan::Hab
} }
public: public:
Habitat_session_component(Genode::Rpc_entrypoint &ep, Genode::Session::Resources const &resources, Genode::Session_label const &label, Genode::Session::Diag const &diag, Genode::Ram_allocator &ram, Genode::Region_map &rm, Genode::Affinity const &affinity) : Genode::Session_object<Ealan::Habitat_session>(ep, resources, label, diag), _local_rm(rm), _affinity(affinity), _label(label), _ram_alloc(ram, _ram_quota_guard(), _cap_quota_guard()), _md_alloc(_ram_alloc, rm), _ep(ep) {}
Habitat_session_component(Genode::Rpc_entrypoint &ep,
Genode::Session::Resources const &resources,
Genode::Session_label const &label,
Genode::Session::Diag const &diag, Genode::Ram_allocator &ram,
Genode::Region_map &rm, Genode::Affinity const &affinity)
: Genode::Session_object<Ealan::Habitat_session>(ep, resources, label, diag),
_local_rm(rm), _affinity(affinity), _label(label),
_ram_alloc(ram, _ram_quota_guard(), _cap_quota_guard()), _md_alloc(_ram_alloc, rm),
_ep(ep), _id_base(cap_map().insert(1))
{
Genode::log("Habitat's affinity is ", _affinity);
Tukija::Habitat_info_page *haip;
Core::platform().region_alloc().alloc_aligned(Tukija::PAGE_SIZE_BYTE, Tukija::PAGE_SIZE_LOG2).with_result([&](void *ptr) { haip = static_cast<Tukija::Habitat_info_page*>(ptr); }, [&](Genode::Range_allocator::Alloc_error) { haip = nullptr; });
if (!haip) { Genode::error("Failed to allocate Habitat Info Page"); }
Tukija::create_habitat(_sel(), reinterpret_cast<Tukija::mword_t>(haip));
_calculate_mask_for_location(&haip->reserved_cores, _affinity.space());
Genode::log("Created habitat: ", haip->reserved_cores);
}
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, bool is_brick) 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, bool is_brick) override {
Ealan::Cell_component *cell = new (_md_alloc) Ealan::Cell_component(pd_cap, prio, affinity, _ep, _local_rm, label, is_brick); Ealan::Cell_component *cell = new (_md_alloc) Ealan::Cell_component(pd_cap, prio, affinity, _ep, _local_rm, label, is_brick, _sel());
_managed_cells.insert(cell); _managed_cells.insert(cell);

View File

@@ -93,6 +93,13 @@ class Genode::Affinity
return Affinity::Space(node.attribute_value("width", 0U), return Affinity::Space(node.attribute_value("width", 0U),
node.attribute_value("height", 0U)); node.attribute_value("height", 0U));
} }
template <typename FUNC> void for_each(const FUNC &f)
{
for (unsigned i = 0; i < total(); i++) {
f(location_of_index(i));
}
}
}; };