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
|
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
|
||||||
|
|||||||
@@ -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
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|
||||||
|
|||||||
@@ -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));
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user