mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 12:32:56 +01:00
Added support for habitats.
This commit is contained in:
@@ -298,9 +298,15 @@ namespace Tukija {
|
||||
|
||||
|
||||
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
|
||||
|
||||
@@ -57,27 +57,28 @@ namespace Tukija {
|
||||
* NOVA system-call IDs
|
||||
*/
|
||||
enum Syscall {
|
||||
NOVA_CALL = 0x0,
|
||||
NOVA_REPLY = 0x1,
|
||||
NOVA_CREATE_PD = 0x2,
|
||||
NOVA_CREATE_EC = 0x3,
|
||||
NOVA_CREATE_SC = 0x4,
|
||||
NOVA_CREATE_PT = 0x5,
|
||||
NOVA_CREATE_SM = 0x6,
|
||||
NOVA_REVOKE = 0x7,
|
||||
NOVA_MISC = 0x8, /* lookup, delegate, acpi_suspend */
|
||||
NOVA_EC_CTRL = 0x9,
|
||||
NOVA_SC_CTRL = 0xa,
|
||||
NOVA_PT_CTRL = 0xb,
|
||||
NOVA_SM_CTRL = 0xc,
|
||||
NOVA_ASSIGN_PCI = 0xd,
|
||||
NOVA_ASSIGN_GSI = 0xe,
|
||||
NOVA_PD_CTRL = 0xf,
|
||||
TUKIJA_CREATE_CELL = 0x10,
|
||||
TUKIJA_ALLOCATE = 0x11,
|
||||
TUKIJA_CELL_CTRL = 0x12,
|
||||
TUKIJA_RELEASE = 0x13,
|
||||
TUKIJA_MAP_TIP = 0x14
|
||||
NOVA_CALL = 0x0,
|
||||
NOVA_REPLY = 0x1,
|
||||
NOVA_CREATE_PD = 0x2,
|
||||
NOVA_CREATE_EC = 0x3,
|
||||
NOVA_CREATE_SC = 0x4,
|
||||
NOVA_CREATE_PT = 0x5,
|
||||
NOVA_CREATE_SM = 0x6,
|
||||
NOVA_REVOKE = 0x7,
|
||||
NOVA_MISC = 0x8, /* lookup, delegate, acpi_suspend */
|
||||
NOVA_EC_CTRL = 0x9,
|
||||
NOVA_SC_CTRL = 0xa,
|
||||
NOVA_PT_CTRL = 0xb,
|
||||
NOVA_SM_CTRL = 0xc,
|
||||
NOVA_ASSIGN_PCI = 0xd,
|
||||
NOVA_ASSIGN_GSI = 0xe,
|
||||
NOVA_PD_CTRL = 0xf,
|
||||
TUKIJA_CREATE_CELL = 0x10,
|
||||
TUKIJA_ALLOCATE = 0x11,
|
||||
TUKIJA_CELL_CTRL = 0x12,
|
||||
TUKIJA_RELEASE = 0x13,
|
||||
TUKIJA_MAP_TIP = 0x14,
|
||||
TUKIJA_CREATE_HABITAT = 0x15
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -136,7 +137,11 @@ namespace Tukija {
|
||||
inline mword_t bit_cpu(unsigned const cpu) const {
|
||||
return cpu % CPUS_PER_VALUE;
|
||||
}
|
||||
|
||||
|
||||
inline mword_t values()
|
||||
{
|
||||
return sizeof(raw) / sizeof(raw[0]);
|
||||
}
|
||||
public:
|
||||
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 = 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
|
||||
*
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define _CORE__INCLUDE__CELL_COMPONENT_H_
|
||||
|
||||
/* Genode includes */
|
||||
#include "tukija/stdint.h"
|
||||
#include <base/rpc_server.h>
|
||||
#include <base/session_label.h>
|
||||
#include <pd_session/client.h>
|
||||
@@ -83,7 +84,7 @@ class Ealan::Cell_component : public Genode::Rpc_object<Cell>,
|
||||
|
||||
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 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
|
||||
* 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.");
|
||||
throw Cell_creation_error();
|
||||
}
|
||||
|
||||
@@ -13,6 +13,13 @@
|
||||
#ifndef _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/env.h>
|
||||
#include <base/allocator.h>
|
||||
@@ -24,7 +31,7 @@
|
||||
#include <tukija_native_pd/client.h>
|
||||
#include <pd_session/client.h>
|
||||
#include <cell_component.h>
|
||||
|
||||
#include <tukija/cap_map.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::Sliced_heap _md_alloc;
|
||||
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)
|
||||
{
|
||||
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:
|
||||
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_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);
|
||||
|
||||
|
||||
@@ -93,6 +93,13 @@ class Genode::Affinity
|
||||
return Affinity::Space(node.attribute_value("width", 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));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user