mirror of
https://github.com/mmueller41/genode.git
synced 2026-01-21 12:32:56 +01:00
Merge branch 'ealan' into genode-24
This commit is contained in:
78
.vscode/c_cpp_properties.json
vendored
Normal file
78
.vscode/c_cpp_properties.json
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "EalánOS",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/depot/genodelabs/api/libc/**",
|
||||
"${workspaceFolder}/depot/genodelabs/api/stdcxx/**",
|
||||
"${workspaceFolder}/repos/**",
|
||||
"${workspaceFolder}/repos/mml/**",
|
||||
"${workspaceFolder}/repos/libports/include/**",
|
||||
"${workspaceFolder}/contrib/mxtasking-07a3844690ae8eb15832d93e29567a5a8e6e45af/include/**",
|
||||
"${workspaceFolder}/contrib/libpfm4-b0ec09148c2be9f4a96203a3d2de4ebed6ce2da0/include/**",
|
||||
"${workspaceFolder}/contrib/libc-c7cd230b11ca71979f32950803bc78b45adfa0ce/include/libc/**",
|
||||
"${workspaceFolder}/contrib/libc-c7cd230b11ca71979f32950803bc78b45adfa0ce/include/spec/x86_64/libc",
|
||||
"${workspaceFolder}/contrib/libc-c7cd230b11ca71979f32950803bc78b45adfa0ce/include/libc/sys/**",
|
||||
"${workspaceFolder}/contrib/stdcxx-d2865c41fafbbf66051d38e7b742c4d5bc2f05a3/include/stdcxx/",
|
||||
"${workspaceFolder}/contrib/stdcxx-d2865c41fafbbf66051d38e7b742c4d5bc2f05a3/include/stdcxx/std",
|
||||
"${workspaceFolder}/contrib/stdcxx-d2865c41fafbbf66051d38e7b742c4d5bc2f05a3/include/stdcxx/c_std",
|
||||
"${workspaceFolder}/repos/libports/include/spec/x86_64/stdcxx",
|
||||
"${workspaceFolder}/repos/base-nova/src/core/include/**",
|
||||
"${workspaceFolder}/repos/base-nova/src/include/**",
|
||||
"${workspaceFolder}/repos/base-nova/include/**",
|
||||
"${workspaceFolder}/repos/base/src/core/include/**",
|
||||
"${workspaceFolder}/repos/base/src/include/**",
|
||||
"${workspaceFolder}/repos/base/include/**",
|
||||
"/usr/local/genode/tool/21.05/lib/gcc/x86_64-pc-elf/10.3.0/include",
|
||||
"/home/mml/loopbench/**"
|
||||
],
|
||||
"defines": [
|
||||
"__GENODE__",
|
||||
"__FreeBSD__=12",
|
||||
"_GLIBCXX_HAVE_MBSTATE_T",
|
||||
"_GLIBCXX_ATOMIC_BUILTINS_4",
|
||||
"_GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC"
|
||||
],
|
||||
"compilerPath": "/usr/local/genode/tool/21.05/bin/genode-x86-gcc",
|
||||
"cStandard": "gnu17",
|
||||
"cppStandard": "gnu++17",
|
||||
"intelliSenseMode": "linux-gcc-x64",
|
||||
"compilerArgs": [
|
||||
"-nostdinc",
|
||||
"-m64"
|
||||
],
|
||||
"configurationProvider": "ms-vscode.makefile-tools",
|
||||
"forcedInclude": [
|
||||
"${workspaceFolder}/contrib/libc-c7cd230b11ca71979f32950803bc78b45adfa0ce/include/libc/stdint.h"
|
||||
],
|
||||
"mergeConfigurations": true,
|
||||
"browse": {
|
||||
"limitSymbolsToIncludedHeaders": true,
|
||||
"path": [
|
||||
"${workspaceFolder}/contrib/libc-c7cd230b11ca71979f32950803bc78b45adfa0ce/include/libc/**",
|
||||
"${workspaceFolder}/contrib/libc-c7cd230b11ca71979f32950803bc78b45adfa0ce/include/spec/x86_64/libc",
|
||||
"${workspaceFolder}/contrib/libc-c7cd230b11ca71979f32950803bc78b45adfa0ce/include/libc/sys/**",
|
||||
"${workspaceFolder}/contrib/stdcxx-d2865c41fafbbf66051d38e7b742c4d5bc2f05a3/include/stdcxx/",
|
||||
"${workspaceFolder}/contrib/stdcxx-d2865c41fafbbf66051d38e7b742c4d5bc2f05a3/include/stdcxx/std",
|
||||
"${workspaceFolder}/contrib/stdcxx-d2865c41fafbbf66051d38e7b742c4d5bc2f05a3/include/stdcxx/c_std",
|
||||
"${workspaceFolder}/repos/libports/include/spec/x86_64/stdcxx"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Genode",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"${workspaceFolder}/repos/base/**"
|
||||
],
|
||||
"defines": [],
|
||||
"compilerPath": "/usr/local/genode/tool/21.05/bin/genode-x86-gcc",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++20",
|
||||
"intelliSenseMode": "${default}",
|
||||
"configurationProvider": "ms-vscode.makefile-tools",
|
||||
"mergeConfigurations": true
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
||||
167
.vscode/settings.json
vendored
Normal file
167
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"*.rasi": "css",
|
||||
"*.bbmodel": "json",
|
||||
"*.sublime-snippet": "xml",
|
||||
"*.hbs": "html",
|
||||
"*.ejs": "html",
|
||||
"*.emu": "html",
|
||||
"lesskey": "lesskey",
|
||||
"*.Xresources": "xdefaults",
|
||||
"i3/config": "i3",
|
||||
"i3/*.conf": "i3",
|
||||
"polybar/config": "ini",
|
||||
"polybar/*.conf": "ini",
|
||||
"*.S": "gas",
|
||||
"*.html.en": "html",
|
||||
"*.html.de": "html",
|
||||
"stop_token": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"tuple": "cpp",
|
||||
"memory": "cpp",
|
||||
"*.def": "cpp",
|
||||
"array": "cpp",
|
||||
"deque": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"list": "cpp",
|
||||
"string": "cpp",
|
||||
"vector": "cpp",
|
||||
"any": "cpp",
|
||||
"executor": "cpp",
|
||||
"internet": "cpp",
|
||||
"io_context": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"socket": "cpp",
|
||||
"string_view": "cpp",
|
||||
"timer": "cpp",
|
||||
"functional": "cpp",
|
||||
"rope": "cpp",
|
||||
"slist": "cpp",
|
||||
"coroutine": "cpp",
|
||||
"future": "cpp",
|
||||
"scoped_allocator": "cpp",
|
||||
"valarray": "cpp",
|
||||
"regex": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"bitset": "cpp",
|
||||
"random": "cpp",
|
||||
"optional": "cpp",
|
||||
"dynamic_bitset": "cpp",
|
||||
"mutex": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"cassert": "cpp",
|
||||
"cctype": "cpp",
|
||||
"cerrno": "cpp",
|
||||
"chrono": "cpp",
|
||||
"ciso646": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"map": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"exception": "cpp",
|
||||
"fstream": "cpp",
|
||||
"ios": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"iterator": "cpp",
|
||||
"limits": "cpp",
|
||||
"new": "cpp",
|
||||
"numeric": "cpp",
|
||||
"ostream": "cpp",
|
||||
"queue": "cpp",
|
||||
"ranges": "cpp",
|
||||
"ratio": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"system_error": "cpp",
|
||||
"thread": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"utility": "cpp",
|
||||
"variant": "cpp",
|
||||
"charconv": "cpp",
|
||||
"cfenv": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"csetjmp": "cpp",
|
||||
"csignal": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cuchar": "cpp",
|
||||
"set": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"*.run": "xml",
|
||||
"span": "cpp",
|
||||
"config.h": "c",
|
||||
"bench.h": "c",
|
||||
"hash_map": "cpp",
|
||||
"hash_set": "cpp",
|
||||
"strstream": "cpp",
|
||||
"decimal": "cpp",
|
||||
"buffer": "cpp",
|
||||
"netfwd": "cpp",
|
||||
"propagate_const": "cpp",
|
||||
"source_location": "cpp",
|
||||
"complex": "cpp",
|
||||
"numbers": "cpp",
|
||||
"typeindex": "cpp",
|
||||
"bool_set": "cpp"
|
||||
},
|
||||
"vscode-as-git-mergetool.settingsAssistantOnStartup": false,
|
||||
"makefile.makeDirectory": "build/x86_64",
|
||||
"C_Cpp.errorSquiggles": "enabledIfIncludesResolve",
|
||||
"C_Cpp.default.cppStandard": "gnu++17",
|
||||
"C_Cpp.default.cStandard": "gnu17",
|
||||
"C_Cpp.workspaceSymbols": "Just My Code",
|
||||
"C_Cpp.inlayHints.parameterNames.enabled": true,
|
||||
"C_Cpp.inlayHints.autoDeclarationTypes.showOnLeft": true,
|
||||
"C_Cpp.intelliSenseMemoryLimit": 16384,
|
||||
"makefile.makefilePath": "",
|
||||
"makefile.dryrunSwitches": [
|
||||
"--keep-going",
|
||||
"--print-directory",
|
||||
"KERNEL=nova",
|
||||
"BOARD=pc",
|
||||
"run/vscode",
|
||||
"VERBOSE="
|
||||
],
|
||||
"C_Cpp.default.intelliSenseMode": "linux-gcc-x64",
|
||||
"C_Cpp.default.mergeConfigurations": true,
|
||||
"C_Cpp.autocompleteAddParentheses": true,
|
||||
"C_Cpp.intelliSenseCacheSize": 20480,
|
||||
"makefile.buildBeforeLaunch": false,
|
||||
"makefile.extensionOutputFolder": ".vscode",
|
||||
"makefile.configurationCachePath": ".vscode/configurationCache.log",
|
||||
"explorer.excludeGitIgnore": true,
|
||||
"makefile.buildLog": ".vscode/build.log",
|
||||
"definition-autocompletion.update_index_on_change": true,
|
||||
"definition-autocompletion.update_index_interval": 5,
|
||||
"C_Cpp.intelliSenseEngineFallback": "enabled",
|
||||
"makefile.extensionLog": ".vscode/extension.log",
|
||||
"makefile.ignoreDirectoryCommands": false,
|
||||
"html.format.wrapLineLength": 80,
|
||||
"editor.wordWrap": "bounded",
|
||||
"editor.wordWrapColumn": 90,
|
||||
"editor.fontSize": 13,
|
||||
"terminal.integrated.shellIntegration.suggestEnabled": true,
|
||||
"git.mergeEditor": true,
|
||||
"merge-conflict.autoNavigateNextConflict.enabled": true,
|
||||
"git.ignoreLimitWarning": true,
|
||||
"customizeUI.statusBarPosition": "under-panel"
|
||||
}
|
||||
24
README.md
Normal file
24
README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# EalánOS — An Operating System for Heterogeneous Many-core Systems
|
||||
|
||||
EalánOS is a research operating system, based on the [Genode OS Framework](https://genode.org/), that explores new architectural designs and resource management strategies for many-core systems with heterogeneous computing and memory resources. It is a reference implementation of the [MxKernel](https://mxkernel.org/) architecture.
|
||||
|
||||
## MxKernel Architecture
|
||||
The MxKernel is a new operating system architecture inspired by many-core operating systems, such as [FOS](https://dl.acm.org/doi/abs/10.1145/1531793.1531805) and [Tesselation](https://www.usenix.org/event/hotpar09/tech/full_papers/liu/liu_html/), as well as hypervisors, exokernels and unikernels.
|
||||
Novel approaches of the MxKernel include the use of tasks, short-lived closed units of work, instead of threads as control-flow abstraction, and the concept of elastic cells as process abstraction. The architecture has first been described in the paper [MxKernel: Rethinking Operating System Architecture for Many-core Hardware](https://ess.cs.uos.de/research/projects/MxKernel/sfma-mxkernel.pdf) presented at the [9th Workshop on Systems for Multi-core and Heterogeneous Architectures](https://sites.google.com/site/sfma2019eurosys/).
|
||||
|
||||
## Task-based programming
|
||||
EalánOS promotes task-parallel programming by including the [MxTasking](https://github.com/jmuehlig/mxtasking.git) task-parallel runtime library. MxTasking improves on the common task-parallel programming paradigm by allowing tasks to be annotated with hints about the tasks behavior, such as memory accesses. These annotations are used by the runtime environment to implement advanced features, like automatic prefetching of data and automatic synchronization of concurrent memory accesses.
|
||||
|
||||
## Documentation
|
||||
Because EalánOS is based on Genode, the primary documentation, for now, can be found in the book [Genode Foundations](https://genode.org/documentation/genode-foundations-22-05.pdf).
|
||||
|
||||
## Features added to Genode
|
||||
EalánOS extends the Genode OS framework by functionality needed and helpful for many-core systems with non-uniform memory access (NUMA), such as
|
||||
- A topology service that allows to query NUMA information from within a Genode component.
|
||||
- A port of [MxTasking](https://github.com/jmuehlig/mxtasking.git), a task-based framework designed to aid in developing parallel applications.
|
||||
- (WiP) A extension of Genode's RAM service that enables applications to allocate memory from a specific NUMA region, similar to libnuma's `numa_alloc_on_node`, and thus improve NUMA-locality of internal data objects.
|
||||
- (WiP) An interface for using Hardware Performance Monitoring Counters inside Genode components. Currently, performance counters are only implemented for AMD's Zen1 microarchitecture.
|
||||
|
||||
### Acknowledgement
|
||||
The work on EalánOS and the MxKernel architecture is supported by the German Research Foundation (DFG) as part of the priority program 2037 "[Scalable Data Management on Future Hardware](https://dfg-spp2037.de/)" under Grant numbers SP968/9-1 and SP968/9-2.
|
||||
The MxTasking framework is developed as part of the same DFG project at the [DBIS group at TU Dortmund Universitiy](http://dbis.cs.tu-dortmund.de/cms/de/home/index.html) and funded under Grant numbers TE1117/2-1.
|
||||
@@ -10,6 +10,7 @@ SRC_CC += lib/base/allocator_avl.cc
|
||||
SRC_CC += lib/base/avl_tree.cc
|
||||
SRC_CC += lib/base/elf_binary.cc
|
||||
SRC_CC += lib/base/heap.cc
|
||||
SRC_CC += lib/base/regional_heap.cc
|
||||
SRC_CC += lib/base/registry.cc
|
||||
SRC_CC += lib/base/log.cc
|
||||
SRC_CC += lib/base/output.cc
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
|
||||
#include <base/mutex.h>
|
||||
|
||||
#include <base/log.h>
|
||||
|
||||
#include <util/avl_tree.h>
|
||||
#include <util/noncopyable.h>
|
||||
|
||||
@@ -36,9 +38,10 @@ namespace Genode {
|
||||
addr_t _base = 0;
|
||||
addr_t _last = 0;
|
||||
|
||||
enum {
|
||||
enum
|
||||
{
|
||||
HEADER = sizeof(_base) + sizeof(_mutex) + sizeof(_last),
|
||||
CAP_RANGE_SIZE = 4096,
|
||||
CAP_RANGE_SIZE = 131072,
|
||||
WORDS = (CAP_RANGE_SIZE - HEADER - sizeof(Avl_node<Cap_range>)) / sizeof(addr_t),
|
||||
};
|
||||
|
||||
@@ -51,8 +54,8 @@ namespace Genode {
|
||||
|
||||
Cap_range(addr_t base) : _base(base)
|
||||
{
|
||||
static_assert(sizeof(*this) == CAP_RANGE_SIZE,
|
||||
"Cap_range misconfigured");
|
||||
//static_assert(sizeof(*this) == CAP_RANGE_SIZE,
|
||||
//"Cap_range misconfigured");
|
||||
|
||||
for (unsigned i = 0; i < elements(); i++)
|
||||
_cap_array[i] = 0;
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
* \author Norman Feske
|
||||
* \author Sebastian Sumpf
|
||||
* \author Alexander Boettcher
|
||||
* \author Michael Müller
|
||||
* \author Benjamin Lamowski
|
||||
* \date 2009-12-27
|
||||
* \date 2022-12-13
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -36,6 +37,7 @@
|
||||
#define _INCLUDE__NOVA__SYSCALL_GENERIC_H_
|
||||
|
||||
#include <nova/stdint.h>
|
||||
#include <base/log.h>
|
||||
|
||||
namespace Nova {
|
||||
|
||||
@@ -65,6 +67,16 @@ namespace Nova {
|
||||
NOVA_ASSIGN_PCI = 0xd,
|
||||
NOVA_ASSIGN_GSI = 0xe,
|
||||
NOVA_PD_CTRL = 0xf,
|
||||
NOVA_YIELD = 0x10,
|
||||
NOVA_MXINIT = 0x11,
|
||||
NOVA_ALLOC_CORES= 0x12,
|
||||
NOVA_CORE_ALLOC = 0x13,
|
||||
NOVA_CREATE_CELL= 0x14,
|
||||
NOVA_CELL_CTRL = 0x15,
|
||||
NOVA_CONS_CTRL = 0x16,
|
||||
NOVA_CPUID = 0x17,
|
||||
NOVA_RESERVE_CPU= 0x18,
|
||||
NOVA_CREATE_HAB = 0x19,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -135,11 +147,19 @@ namespace Nova {
|
||||
bool has_feature_svm() const { return feature_flags & (1 << 2); }
|
||||
|
||||
struct Cpu_desc {
|
||||
enum Vendor
|
||||
{
|
||||
UNKNOWN,
|
||||
INTEL,
|
||||
AMD
|
||||
};
|
||||
|
||||
uint8_t flags;
|
||||
uint8_t thread;
|
||||
uint8_t core;
|
||||
uint8_t package;
|
||||
uint8_t acpi_id;
|
||||
uint8_t vendor;
|
||||
uint8_t family;
|
||||
uint8_t model;
|
||||
uint8_t stepping:4;
|
||||
@@ -179,6 +199,36 @@ namespace Nova {
|
||||
return desc ? desc->flags & 0x1 : false;
|
||||
}
|
||||
|
||||
unsigned numa_nodes() const {
|
||||
unsigned node_num = 1;
|
||||
unsigned long nodes = 0x0;
|
||||
unsigned long last_node = 0;
|
||||
|
||||
for (unsigned cpu = 0; cpu < cpu_max(); cpu++) {
|
||||
Cpu_desc const *c = cpu_desc_of_cpu(cpu);
|
||||
if (c->numa_id != last_node && !(nodes & (1<<c->numa_id))) {
|
||||
node_num++;
|
||||
nodes |= (1 << c->numa_id);
|
||||
}
|
||||
}
|
||||
return node_num;
|
||||
}
|
||||
|
||||
unsigned numa_nodes() const {
|
||||
unsigned node_num = 1;
|
||||
unsigned long nodes = 0x0;
|
||||
unsigned long last_node = 0;
|
||||
|
||||
for (unsigned cpu = 0; cpu < cpu_max(); cpu++) {
|
||||
Cpu_desc const *c = cpu_desc_of_cpu(cpu);
|
||||
if (c->numa_id != last_node && !(nodes & (1<<c->numa_id))) {
|
||||
node_num++;
|
||||
nodes |= (1 << c->numa_id);
|
||||
}
|
||||
}
|
||||
return node_num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resort CPU ids such, that
|
||||
* - the boot CPU id is ever logical CPU id 0
|
||||
@@ -196,12 +246,7 @@ namespace Nova {
|
||||
unsigned const num_cpus = cpus();
|
||||
bool too_many_cpus = false;
|
||||
unsigned cpu_i = 0;
|
||||
|
||||
/* fallback lambda in case re-ordering fails */
|
||||
auto remap_failure = [&] {
|
||||
for (uint16_t i = 0; i < max_cpus; i++) { map_cpus[i] = i; }
|
||||
return false;
|
||||
};
|
||||
unsigned const num_nodes = numa_nodes();
|
||||
|
||||
/* assign boot cpu ever the virtual cpu id 0 */
|
||||
Cpu_desc const * const boot = cpu_desc_of_cpu(boot_cpu);
|
||||
@@ -211,45 +256,25 @@ namespace Nova {
|
||||
map_cpus[cpu_i++] = (uint8_t)boot_cpu;
|
||||
if (cpu_i >= num_cpus)
|
||||
return true;
|
||||
if (cpu_i >= max_cpus)
|
||||
return remap_failure();
|
||||
|
||||
/* assign cores + SMT threads first and skip E-cores */
|
||||
bool done = for_all_cpus([&](auto const &cpu, auto const kernel_cpu_id) {
|
||||
if (kernel_cpu_id == boot_cpu)
|
||||
return false;
|
||||
for (uint8_t node = 0; node < num_nodes; node++) {
|
||||
for (unsigned i = 0; i < num_cpus; i++) {
|
||||
if (i == boot_cpu || !is_cpu_enabled(i))
|
||||
continue;
|
||||
|
||||
/* handle normal or P-core */
|
||||
if (cpu.e_core())
|
||||
return false;
|
||||
Cpu_desc const *c = cpu_desc_of_cpu(i);
|
||||
if (!(c->numa_id == node))
|
||||
continue;
|
||||
|
||||
map_cpus[cpu_i++] = (uint8_t)kernel_cpu_id;
|
||||
cpu_numa_map[i] = c->numa_id;
|
||||
map_cpus[cpu_i++] = (uint8_t)i;
|
||||
|
||||
too_many_cpus = !!(cpu_i >= max_cpus);
|
||||
if (cpu_i >= num_cpus)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return (cpu_i >= num_cpus || too_many_cpus);
|
||||
});
|
||||
|
||||
if (done)
|
||||
return too_many_cpus ? remap_failure() : true;
|
||||
|
||||
/* assign remaining E-cores */
|
||||
done = for_all_cpus([&](auto &cpu, auto &kernel_cpu_id) {
|
||||
if (kernel_cpu_id == boot_cpu)
|
||||
return false;
|
||||
|
||||
/* handle solely E-core */
|
||||
if (!cpu.e_core())
|
||||
return false;
|
||||
|
||||
map_cpus[cpu_i++] = (uint16_t)kernel_cpu_id;
|
||||
|
||||
too_many_cpus = !!(cpu_i >= max_cpus);
|
||||
|
||||
return (cpu_i >= num_cpus || too_many_cpus);
|
||||
});
|
||||
|
||||
return too_many_cpus ? remap_failure() : done;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -323,6 +348,28 @@ namespace Nova {
|
||||
SC_EC_TIME = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* Hpc operations
|
||||
*
|
||||
*/
|
||||
enum Hpc_op
|
||||
{
|
||||
HPC_SETUP = 6U,
|
||||
HPC_START = 7U,
|
||||
HPC_STOP = 8U,
|
||||
HPC_RESET = 9U,
|
||||
HPC_READ = 10U,
|
||||
};
|
||||
|
||||
/**
|
||||
* Cell operations
|
||||
*/
|
||||
enum Cell_op
|
||||
{
|
||||
SHRINK = 0,
|
||||
GROW = 1,
|
||||
};
|
||||
|
||||
/**
|
||||
* Pd operations
|
||||
*/
|
||||
@@ -612,7 +659,7 @@ namespace Nova {
|
||||
|
||||
public:
|
||||
|
||||
enum { DEFAULT_QUANTUM = 10000, DEFAULT_PRIORITY = 64 };
|
||||
enum { DEFAULT_QUANTUM = 1500, DEFAULT_PRIORITY = 64 };
|
||||
|
||||
Qpd(mword_t quantum = DEFAULT_QUANTUM,
|
||||
mword_t priority = DEFAULT_PRIORITY)
|
||||
@@ -891,5 +938,13 @@ namespace Nova {
|
||||
SM_SEL_EC = 0x1d, /* convention on Genode */
|
||||
};
|
||||
|
||||
/**
|
||||
* Console operations
|
||||
*/
|
||||
enum Cons_op
|
||||
{
|
||||
LOCK = 0,
|
||||
UNLOCK = 1,
|
||||
};
|
||||
}
|
||||
#endif /* _INCLUDE__NOVA__SYSCALL_GENERIC_H_ */
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
|
||||
#include <nova/stdint.h>
|
||||
#include <nova/syscall-generic.h>
|
||||
#include <base/trace/types.h>
|
||||
|
||||
#define ALWAYS_INLINE __attribute__((always_inline))
|
||||
|
||||
@@ -45,7 +46,7 @@ namespace Nova {
|
||||
ALWAYS_INLINE
|
||||
inline mword_t rdi(Syscall s, uint8_t flags, mword_t sel)
|
||||
{
|
||||
return sel << 8 | (flags & 0xf) << 4 | s;
|
||||
return sel << 9 | (flags & 0xf) << 5 | s;
|
||||
}
|
||||
|
||||
|
||||
@@ -155,7 +156,7 @@ namespace Nova {
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t call(mword_t pt)
|
||||
{
|
||||
return syscall_1(NOVA_CALL, 0, pt, 0);
|
||||
return syscall_1(NOVA_CALL, 0, 0, pt);
|
||||
}
|
||||
|
||||
|
||||
@@ -254,6 +255,36 @@ namespace Nova {
|
||||
return util_time(NOVA_EC_CTRL, ec, Ec_op::EC_TIME, time);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t hpc_ctrl(Hpc_op op, mword_t sel, mword_t type, mword_t &p1, mword_t &p2, mword_t &p3)
|
||||
{
|
||||
uint8_t res = syscall_6(NOVA_EC_CTRL, op, sel, type, p1, p2, p3);
|
||||
return res;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t hpc_read(mword_t sel, mword_t type, mword_t &value)
|
||||
{
|
||||
return syscall_5(NOVA_EC_CTRL, HPC_READ, sel, type, value);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t hpc_start(mword_t sel, mword_t type)
|
||||
{
|
||||
return syscall_1(NOVA_EC_CTRL, HPC_START, sel, type);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t hpc_stop(mword_t sel, mword_t type)
|
||||
{
|
||||
return syscall_1(NOVA_EC_CTRL, HPC_STOP, sel, type);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t hpc_reset(mword_t sel, mword_t type, mword_t val)
|
||||
{
|
||||
return syscall_2(NOVA_EC_CTRL, HPC_RESET, sel, type, val);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t create_sc(mword_t sc, mword_t pd, mword_t ec, Qpd qpd)
|
||||
@@ -416,5 +447,76 @@ namespace Nova {
|
||||
msi_data = cpu;
|
||||
return syscall_5(NOVA_ASSIGN_GSI, flags.value(), sm, msi_addr, msi_data, si);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t yield(bool release_core = true, bool block = true)
|
||||
{
|
||||
Nova::uint8_t flags = block ? release_core : 3;
|
||||
return syscall_0(NOVA_YIELD, flags, 0);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t mxinit(mword_t rip, mword_t id, mword_t channel)
|
||||
{
|
||||
return syscall_2(NOVA_MXINIT, 0, id, rip, channel);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t alloc_cores(mword_t count, mword_t &allocated, mword_t &remainder)
|
||||
{
|
||||
Nova::mword_t rest = 0;
|
||||
Nova::mword_t null = 0;
|
||||
Nova::uint8_t res = syscall_6(NOVA_ALLOC_CORES, 0, 0, count, allocated, rest, null);
|
||||
remainder = rest;
|
||||
return res;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t wake_core(mword_t core)
|
||||
{
|
||||
return syscall_1(NOVA_RESERVE_CPU, 0, 0, core);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t core_allocation(mword_t &allocation, bool mask = false)
|
||||
{
|
||||
return syscall_5(NOVA_CORE_ALLOC, static_cast<Nova::uint8_t>(mask), 0, allocation, allocation);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t cpu_id(mword_t &cpuid)
|
||||
{
|
||||
return syscall_5(NOVA_CPUID, 0, 0, cpuid, cpuid);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t create_cell(mword_t pd, mword_t prio, mword_t mask, mword_t start, mword_t count)
|
||||
{
|
||||
return syscall_5(NOVA_CREATE_CELL, static_cast<Nova::uint8_t>(prio), pd, mask, start, count);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t update_cell(mword_t pd, mword_t mask, mword_t index)
|
||||
{
|
||||
return syscall_2(NOVA_CELL_CTRL, Cell_op::GROW, pd, mask, index);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t create_habitat(mword_t start_cpu, mword_t size)
|
||||
{
|
||||
return syscall_2(NOVA_CREATE_HAB, 0, 0, start_cpu, size);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t acquire_console()
|
||||
{
|
||||
return syscall_0(NOVA_CONS_CTRL, Nova::Cons_op::LOCK);
|
||||
}
|
||||
|
||||
ALWAYS_INLINE
|
||||
inline uint8_t release_console()
|
||||
{
|
||||
return syscall_0(NOVA_CONS_CTRL, Nova::Cons_op::UNLOCK);
|
||||
}
|
||||
}
|
||||
#endif /* _INCLUDE__SPEC__64BIT__NOVA__SYSCALLS_H_ */
|
||||
|
||||
@@ -14,6 +14,7 @@ SRC_CC += stack_area_addr.cc
|
||||
SRC_CC += cap_map.cc
|
||||
SRC_CC += capability.cc
|
||||
SRC_CC += signal_transmitter.cc
|
||||
SRC_CC += perf.cc
|
||||
|
||||
#
|
||||
# Prevent the compiler from deleting null pointer checks related to 'this == 0'
|
||||
|
||||
@@ -43,7 +43,8 @@ SRC_CC += stack_area.cc \
|
||||
signal_receiver.cc \
|
||||
vm_session_component.cc \
|
||||
vm_session_common.cc \
|
||||
heartbeat.cc
|
||||
heartbeat.cc \
|
||||
topo_session_component.cc
|
||||
|
||||
INC_DIR += $(REP_DIR)/src/core/include \
|
||||
$(REP_DIR)/src/include \
|
||||
@@ -77,4 +78,5 @@ vpath platform_rom_modules.cc $(GEN_CORE_DIR)
|
||||
vpath stack_area.cc $(GEN_CORE_DIR)
|
||||
vpath heartbeat.cc $(GEN_CORE_DIR)
|
||||
vpath vm_session_common.cc $(GEN_CORE_DIR)
|
||||
vpath topo_session_component.cc $(GEN_CORE_DIR)
|
||||
vpath %.cc $(REP_DIR)/src/core
|
||||
|
||||
@@ -1 +1 @@
|
||||
d58086480d6a21a06bbd956e2d2e605d0f39b6b2
|
||||
968b205c5c1b6a93846626cf7307b19eb6bac891
|
||||
|
||||
@@ -2,9 +2,9 @@ LICENSE := GPLv2
|
||||
VERSION := git
|
||||
DOWNLOADS := nova.git
|
||||
|
||||
# r10 branch
|
||||
URL(nova) := https://github.com/alex-ab/NOVA.git
|
||||
REV(nova) := fc9ad04ecec3911302451fcbf6cd87063be66ad0
|
||||
# feature/numa branch
|
||||
URL(nova) := https://github.com/mmueller41/NOVA.git
|
||||
REV(nova) := tukija
|
||||
DIR(nova) := src/kernel/nova
|
||||
|
||||
PATCHES := $(sort $(wildcard $(REP_DIR)/patches/*.patch))
|
||||
|
||||
@@ -1 +1 @@
|
||||
2024-10-07 d1a751a3b41d145c3a97b3431ae1f006050fee10
|
||||
2024-09-13 1567ef314f1b68c8871e29ffc0ba19e9dbaaee8a
|
||||
|
||||
@@ -1 +1 @@
|
||||
2024-12-10 bb446406fbb1173c3f243fe323d5cad8423ff958
|
||||
2024-11-26 12d153ce5fc0661b11808621eaffeed3a18aa460
|
||||
|
||||
@@ -18,13 +18,13 @@
|
||||
#include <bios_data_area.h>
|
||||
#include <drivers/uart/x86_pc.h>
|
||||
|
||||
void Core::Core_log::out(char const c)
|
||||
void Genode::Core_log::out(char const c)
|
||||
{
|
||||
enum { CLOCK = 0, BAUDRATE = 115200 };
|
||||
|
||||
static X86_uart uart(0x3f8/*Bios_data_area::singleton()->serial_port()*/,
|
||||
static X86_uart uart(0x2f8/*Bios_data_area::singleton()->serial_port()*/,
|
||||
CLOCK, BAUDRATE);
|
||||
if (c == '\n')
|
||||
uart.put_char('\r');
|
||||
uart.put_char(c);
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,8 @@
|
||||
#include <platform_generic.h>
|
||||
#include <core_mem_alloc.h>
|
||||
#include <address_space.h>
|
||||
#include <base/allocator.h>
|
||||
#include <nova/syscall-generic.h>
|
||||
|
||||
namespace Core { class Platform; }
|
||||
|
||||
@@ -51,7 +53,10 @@ class Core::Platform : public Platform_generic
|
||||
|
||||
/* map of virtual cpu ids in Genode to kernel cpu ids */
|
||||
uint16_t map_cpu_ids[MAX_SUPPORTED_CPUS];
|
||||
uint8_t cpu_numa_map[MAX_SUPPORTED_CPUS];
|
||||
uint8_t cpu_numa_map[MAX_SUPPORTED_CPUS];
|
||||
/* map of kernel NUMA region to Genode memory ranges */
|
||||
Genode::Range_allocator::Range numa_mem_ranges[MAX_SUPPORTED_CPUS]; // TODO: Add new macro for max of numa regions
|
||||
|
||||
|
||||
addr_t _map_pages(addr_t phys_page, addr_t pages,
|
||||
bool guard_page = false);
|
||||
@@ -121,10 +126,27 @@ class Core::Platform : public Platform_generic
|
||||
unsigned pager_index(Affinity::Location location) const;
|
||||
unsigned kernel_cpu_id(Affinity::Location location) const;
|
||||
|
||||
/**
|
||||
* @brief ID of NUMA region the CPU belongs to
|
||||
*
|
||||
* @param kernel_cpu_id id of CPU
|
||||
* @return unsigned ID of corresponding NUMA region
|
||||
*/
|
||||
unsigned domain_of_cpu(unsigned kernel_cpu_id) const {
|
||||
return cpu_numa_map[kernel_cpu_id];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return memory range of a given NUMA region
|
||||
*
|
||||
* @param numa_id ID of NUMA region
|
||||
* @return Genode::Range_allocator::Range physical address range for this NUMA region
|
||||
*/
|
||||
|
||||
Genode::Range_allocator::Range &mem_range(unsigned numa_id) {
|
||||
return numa_mem_ranges[numa_id];
|
||||
}
|
||||
|
||||
Affinity::Location sanitize(Affinity::Location location) {
|
||||
return Affinity::Location(location.xpos() % _cpus.width(),
|
||||
location.ypos() % _cpus.height(),
|
||||
@@ -136,15 +158,17 @@ class Core::Platform : public Platform_generic
|
||||
*/
|
||||
unsigned core_pd_sel() const { return _core_pd_sel; }
|
||||
|
||||
void for_each_location(auto const &fn)
|
||||
{
|
||||
for (unsigned x = 0; x < _cpus.width(); x++) {
|
||||
for (unsigned y = 0; y < _cpus.height(); y++) {
|
||||
Affinity::Location location(x, y, 1, 1);
|
||||
fn(location);
|
||||
template <typename FUNC>
|
||||
void for_each_location(FUNC const &fn)
|
||||
{
|
||||
for (unsigned x = 0; x < _cpus.width(); x++) {
|
||||
for (unsigned y = 0; y < _cpus.height(); y++) {
|
||||
Affinity::Location location(x, y, 1, 1);
|
||||
fn(location);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* _CORE__INCLUDE__PLATFORM_H_ */
|
||||
|
||||
@@ -108,6 +108,58 @@ Pd_session::Map_result Pd_session_component::map(Pd_session::Virt_range const vi
|
||||
return Map_result::OK;
|
||||
}
|
||||
|
||||
void _calculate_mask_for_location(Nova::mword_t *core_mask, const 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 = platform_specific().kernel_cpu_id(Affinity::Location(x, y, loc.width(), loc.height()));
|
||||
unsigned i = kernel_cpu / (sizeof(Nova::mword_t) * 8);
|
||||
unsigned b = kernel_cpu % (sizeof(Nova::mword_t) * 8);
|
||||
core_mask[i] |= (1UL << b);
|
||||
|
||||
Genode::log("core_mask[", i, "]=", core_mask[i], " i=", i, "b=", b, "kernel_cpu=", kernel_cpu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Pd_session_component::create_cell(long prioritiy, const Affinity::Location &loc)
|
||||
{
|
||||
Nova::uint8_t err = Nova::NOVA_OK;
|
||||
unsigned num_cpus = platform_specific().MAX_SUPPORTED_CPUS;
|
||||
unsigned num_vect = num_cpus / (sizeof(Nova::mword_t) * 8);
|
||||
Nova::mword_t core_mask[num_vect];
|
||||
|
||||
Genode::memset(core_mask, 0, sizeof(core_mask));
|
||||
|
||||
_calculate_mask_for_location(core_mask, loc);
|
||||
|
||||
log("Requested to create new cell for <", this->label(), "> of priority ", prioritiy, " at ", loc);
|
||||
for (unsigned i = 0; i < num_vect; i++) {
|
||||
if ((err = Nova::create_cell(_pd->pd_sel(), prioritiy, core_mask[i], i, 1) != Nova::NOVA_OK))
|
||||
{
|
||||
error("Could not create new cell: ", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Pd_session_component::update_cell(const Affinity::Location &loc)
|
||||
{
|
||||
Nova::uint8_t err = Nova::NOVA_OK;
|
||||
unsigned num_cpus = platform_specific().affinity_space().total();
|
||||
unsigned num_vect = num_cpus / (sizeof(Nova::mword_t) * 8);
|
||||
Nova::mword_t core_mask[num_vect];
|
||||
|
||||
_calculate_mask_for_location(core_mask, loc);
|
||||
|
||||
for (unsigned i = 0; i < num_vect; i++) {
|
||||
if ((err = Nova::update_cell(_pd->pd_sel(), core_mask[i], i))) {
|
||||
error("Failed to update cell <", label(), ">: ", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
using State = Genode::Pd_session::Managing_system_state;
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ addr_t Core::Platform::_map_pages(addr_t const phys_addr, addr_t const pages,
|
||||
*****************************/
|
||||
|
||||
|
||||
enum { CORE_PAGER_UTCB_ADDR = 0xbff02000 };
|
||||
enum { CORE_PAGER_UTCB_ADDR = 0xfff02000 };
|
||||
|
||||
|
||||
/**
|
||||
@@ -200,7 +200,7 @@ static void page_fault_handler()
|
||||
|
||||
static addr_t core_pager_stack_top()
|
||||
{
|
||||
enum { STACK_SIZE = 4*1024 };
|
||||
enum { STACK_SIZE = 8*1024 };
|
||||
static char stack[STACK_SIZE];
|
||||
return (addr_t)&stack[STACK_SIZE - sizeof(addr_t)];
|
||||
}
|
||||
@@ -445,6 +445,7 @@ Core::Platform::Platform()
|
||||
size_t kernel_memory = 0;
|
||||
|
||||
log("Found ", num_mem_desc, " memory entries in HIP");
|
||||
memset(numa_mem_ranges, 0, sizeof(Genode::Range_allocator::Range) * MAX_SUPPORTED_CPUS);
|
||||
/*
|
||||
* All "available" ram must be added to our physical allocator before all
|
||||
* non "available" regions that overlaps with ram get removed.
|
||||
@@ -476,6 +477,11 @@ Core::Platform::Platform()
|
||||
|
||||
_io_mem_alloc.remove_range((addr_t)base, (size_t)size);
|
||||
ram_alloc().add_range((addr_t)base, (size_t)size);
|
||||
log("Add mem range ", reinterpret_cast<void*>(base), "-", reinterpret_cast<void*>(base + size), " for node ", mem_desc->domain);
|
||||
if (numa_mem_ranges[mem_desc->domain].start == 0)
|
||||
numa_mem_ranges[mem_desc->domain] = {base, base + size};
|
||||
else if (base > numa_mem_ranges[mem_desc->domain].end)
|
||||
numa_mem_ranges[mem_desc->domain].end = base + size;
|
||||
}
|
||||
|
||||
addr_t hyp_log = 0;
|
||||
@@ -795,13 +801,13 @@ Core::Platform::Platform()
|
||||
log(Number_of_bytes(kernel_memory), " kernel memory"); log("");
|
||||
|
||||
/* add capability selector ranges to map */
|
||||
unsigned const first_index = 0x2000;
|
||||
unsigned const first_index = 0x0000;
|
||||
unsigned index = first_index;
|
||||
for (unsigned i = 0; i < 32; i++)
|
||||
{
|
||||
void * phys_ptr = nullptr;
|
||||
|
||||
ram_alloc().alloc_aligned(get_page_size(), get_page_size_log2()).with_result(
|
||||
ram_alloc().alloc_aligned(128*get_page_size(), get_page_size_log2()).with_result(
|
||||
[&] (void *ptr) { phys_ptr = ptr; },
|
||||
[&] (Range_allocator::Alloc_error) { /* covered by nullptr test below */ });
|
||||
|
||||
@@ -809,7 +815,7 @@ Core::Platform::Platform()
|
||||
break;
|
||||
|
||||
addr_t phys_addr = reinterpret_cast<addr_t>(phys_ptr);
|
||||
addr_t core_local_addr = _map_pages(phys_addr, 1);
|
||||
addr_t core_local_addr = _map_pages(phys_addr, 128);
|
||||
|
||||
if (!core_local_addr) {
|
||||
ram_alloc().free(phys_ptr);
|
||||
@@ -895,6 +901,7 @@ Core::Platform::Platform()
|
||||
(unsigned)(sc_idle_base + kernel_cpu_id),
|
||||
"killed");
|
||||
});
|
||||
log("Added idle ECs to trace sources");
|
||||
|
||||
/* add exception handler EC for core and EC root thread to trace sources */
|
||||
struct Core_trace_source : public Trace::Source::Info_accessor,
|
||||
@@ -943,6 +950,7 @@ Core::Platform::Platform()
|
||||
registry.insert(this);
|
||||
}
|
||||
};
|
||||
log("Added exception handler EC");
|
||||
|
||||
new (core_mem_alloc())
|
||||
Core_trace_source(Trace::sources(),
|
||||
@@ -953,6 +961,7 @@ Core::Platform::Platform()
|
||||
Core_trace_source(Trace::sources(),
|
||||
Affinity::Location(0, 0, _cpus.width(), 1),
|
||||
hip.sel_exc + 1, "root");
|
||||
log("Created trace sources");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -56,29 +56,35 @@ static inline void * alloc_region(Dataspace_component &ds, const size_t size)
|
||||
|
||||
void Ram_dataspace_factory::_clear_ds(Dataspace_component &ds)
|
||||
{
|
||||
|
||||
size_t const page_rounded_size = align_addr(ds.size(), get_page_size_log2());
|
||||
|
||||
size_t memset_count = page_rounded_size / 4;
|
||||
size_t memset_count = page_rounded_size / 32;
|
||||
addr_t memset_ptr = ds.core_local_addr();
|
||||
|
||||
if ((memset_count * 4 == page_rounded_size) && !(memset_ptr & 0x3))
|
||||
asm volatile ("rep stosl" : "+D" (memset_ptr), "+c" (memset_count)
|
||||
if ((memset_count * 32 == page_rounded_size) && !(memset_ptr & 0x3))
|
||||
{
|
||||
asm volatile ("rep stosq" : "+D" (memset_ptr), "+c" (memset_count)
|
||||
: "a" (0) : "memory");
|
||||
else
|
||||
} else
|
||||
memset(reinterpret_cast<void *>(memset_ptr), 0, page_rounded_size);
|
||||
}
|
||||
|
||||
void Ram_dataspace_factory::_unmap_ds_from_core(Dataspace_component &ds)
|
||||
{
|
||||
size_t const page_rounded_size = align_addr(ds.size(), get_page_size_log2());
|
||||
|
||||
/* we don't keep any core-local mapping */
|
||||
unmap_local(*reinterpret_cast<Nova::Utcb *>(Thread::myself()->utcb()),
|
||||
ds.core_local_addr(),
|
||||
page_rounded_size >> get_page_size_log2());
|
||||
ds.core_local_addr(),
|
||||
page_rounded_size >> get_page_size_log2());
|
||||
|
||||
platform().region_alloc().free((void*)ds.core_local_addr(),
|
||||
page_rounded_size);
|
||||
platform().region_alloc().free((void *)ds.core_local_addr(),
|
||||
page_rounded_size);
|
||||
|
||||
ds.assign_core_local_addr(nullptr);
|
||||
}
|
||||
|
||||
|
||||
void Ram_dataspace_factory::_export_ram_ds(Dataspace_component &ds) {
|
||||
|
||||
size_t page_rounded_size = align_addr(ds.size(), get_page_size_log2());
|
||||
|
||||
86
repos/base-nova/src/lib/base/perf.cc
Normal file
86
repos/base-nova/src/lib/base/perf.cc
Normal file
@@ -0,0 +1,86 @@
|
||||
|
||||
/*
|
||||
* \brief Performance Counter infrastructure, NOVA-specific implemantation
|
||||
* \author Michael Müller
|
||||
* \date 2022-12-15
|
||||
*/
|
||||
|
||||
#include <base/trace/perf.h>
|
||||
|
||||
#include <nova/syscall-generic.h>
|
||||
#include <nova/syscalls.h>
|
||||
#include <base/log.h>
|
||||
|
||||
unsigned long Genode::Trace::Performance_counter::private_freemask { 0xffff };
|
||||
unsigned long Genode::Trace::Performance_counter::shared_freemask { 0xffff0000 };
|
||||
|
||||
void Genode::Trace::Performance_counter::_init_masks()
|
||||
{
|
||||
Nova::Hip::Cpu_desc::Vendor vendor = Nova::Hip::Cpu_desc::AMD;
|
||||
if (vendor == Nova::Hip::Cpu_desc::AMD)
|
||||
{
|
||||
private_freemask = 0x3f; // 6 core performance counters
|
||||
shared_freemask = 0x1f0000; // 5 L3 complex performance counters
|
||||
}
|
||||
else if (vendor == Nova::Hip::Cpu_desc::INTEL)
|
||||
{
|
||||
private_freemask = 0x7fff;
|
||||
shared_freemask = 0x7fff0000; // 15 CBO performance counters
|
||||
}
|
||||
}
|
||||
|
||||
void Genode::Trace::Performance_counter::setup(unsigned counter, uint64_t event, uint64_t mask, uint64_t flags)
|
||||
{
|
||||
Nova::mword_t evt = event;
|
||||
Nova::mword_t msk = mask;
|
||||
Nova::mword_t flg = flags;
|
||||
Nova::uint8_t rc;
|
||||
Nova::mword_t type = (counter >>4);
|
||||
Nova::mword_t sel = type == Performance_counter::CORE ? counter : counter & 0xf;
|
||||
|
||||
if ((rc = (Nova::hpc_ctrl(Nova::HPC_SETUP, sel, type, evt, msk, flg))) != Nova::NOVA_OK)
|
||||
throw Genode::Trace::Pfc_access_error(rc);
|
||||
}
|
||||
|
||||
void Genode::Trace::Performance_counter::start(unsigned counter)
|
||||
{
|
||||
Nova::uint8_t rc;
|
||||
Nova::mword_t type = (counter >> 4);
|
||||
Nova::mword_t sel = type == Performance_counter::CORE ? counter : counter & 0xf;
|
||||
|
||||
if ((rc = Nova::hpc_start(sel, type)) != Nova::NOVA_OK)
|
||||
throw Genode::Trace::Pfc_access_error(rc);
|
||||
}
|
||||
|
||||
void Genode::Trace::Performance_counter::stop(unsigned counter)
|
||||
{
|
||||
Nova::uint8_t rc;
|
||||
Nova::mword_t type = (counter >>4);
|
||||
Nova::mword_t sel = type == Performance_counter::CORE ? counter : counter & 0xf;
|
||||
|
||||
if ((rc = Nova::hpc_stop(sel, type)) != Nova::NOVA_OK)
|
||||
throw Genode::Trace::Pfc_access_error(rc);
|
||||
}
|
||||
|
||||
void Genode::Trace::Performance_counter::reset(unsigned counter, unsigned val)
|
||||
{
|
||||
Nova::uint8_t rc;
|
||||
Nova::mword_t type = (counter >>4);
|
||||
Nova::mword_t sel = type == Performance_counter::CORE ? counter : counter & 0xf;
|
||||
|
||||
if ((rc = Nova::hpc_reset(sel, type, val)) != Nova::NOVA_OK)
|
||||
throw Genode::Trace::Pfc_access_error(rc);
|
||||
}
|
||||
|
||||
Genode::uint64_t Genode::Trace::Performance_counter::read(unsigned counter)
|
||||
{
|
||||
Nova::uint8_t rc;
|
||||
Nova::mword_t value = 0;
|
||||
Nova::mword_t type = (counter >>4);
|
||||
Nova::mword_t sel = type == Performance_counter::CORE ? counter : counter & 0xf;
|
||||
|
||||
if ((rc = Nova::hpc_read(sel, type, value)) != Nova::NOVA_OK)
|
||||
throw Genode::Trace::Pfc_access_error(rc);
|
||||
|
||||
return static_cast<Genode::uint64_t>(value);
|
||||
}
|
||||
@@ -93,6 +93,7 @@ class Genode::Affinity
|
||||
return Affinity::Space(node.attribute_value("width", 0U),
|
||||
node.attribute_value("height", 0U));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -166,6 +167,13 @@ class Genode::Affinity
|
||||
node.attribute_value("height", default_height));
|
||||
}
|
||||
|
||||
bool operator==(Location const &rhs) {
|
||||
return this->_xpos == rhs._xpos && this->_ypos == rhs._ypos && this->height() == rhs.height() && this->width() == rhs.width();
|
||||
}
|
||||
|
||||
bool operator!=(Location const &rhs) {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
@@ -236,6 +244,30 @@ class Genode::Affinity
|
||||
}
|
||||
};
|
||||
|
||||
namespace Genode {
|
||||
static inline void print(Output &out, const Affinity::Space &space)
|
||||
{
|
||||
Genode::print(out, "(");
|
||||
Genode::print(out, space.width());
|
||||
Genode::print(out, ",");
|
||||
Genode::print(out, space.height());
|
||||
Genode::print(out, ")");
|
||||
}
|
||||
|
||||
static inline void print(Output &out, const Affinity::Location &loc)
|
||||
{
|
||||
Genode::print(out, "(");
|
||||
Genode::print(out, loc.xpos());
|
||||
Genode::print(out, ",");
|
||||
Genode::print(out, loc.ypos());
|
||||
Genode::print(out, ",");
|
||||
Genode::print(out, loc.width());
|
||||
Genode::print(out, "×");
|
||||
Genode::print(out, loc.height());
|
||||
Genode::print(out, ")");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Genode::Affinity::Location Genode::Affinity::Space::location_of_index(int index) const
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#ifndef _INCLUDE__BASE__ATTACHED_RAM_DATASPACE_H_
|
||||
#define _INCLUDE__BASE__ATTACHED_RAM_DATASPACE_H_
|
||||
|
||||
#include <util/string.h>
|
||||
#include <util/touch.h>
|
||||
#include <base/ram_allocator.h>
|
||||
#include <base/env.h>
|
||||
@@ -112,6 +113,7 @@ class Genode::Attached_ram_dataspace
|
||||
_size(size), _ram(&ram), _rm(&rm), _cache(cache)
|
||||
{
|
||||
_alloc_and_attach();
|
||||
memset(_local_addr, 0, _size);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <cpu_session/connection.h>
|
||||
#include <log_session/connection.h>
|
||||
#include <rom_session/connection.h>
|
||||
#include <topo_session/connection.h>
|
||||
#include <cpu_thread/client.h>
|
||||
#include <parent/capability.h>
|
||||
|
||||
@@ -334,6 +335,8 @@ class Genode::Child : protected Rpc_object<Parent>,
|
||||
/* arguments fetched by the child in response to a yield signal */
|
||||
Mutex _yield_request_mutex { };
|
||||
Resource_args _yield_request_args { };
|
||||
Mutex _resource_gain_mutex { };
|
||||
Resource_args _gained_resources { };
|
||||
|
||||
/* number of unanswered heartbeat signals */
|
||||
unsigned _outstanding_heartbeats = 0;
|
||||
@@ -613,6 +616,7 @@ class Genode::Child : protected Rpc_object<Parent>,
|
||||
Env_connection<Cpu_connection> _cpu { *this, Env::cpu(), _policy.name() };
|
||||
Env_connection<Log_connection> _log { *this, Env::log(), _policy.name() };
|
||||
Env_connection<Rom_connection> _binary { *this, Env::binary(), _policy.binary_name() };
|
||||
Env_connection<Topo_connection> _topo { *this, Env::topo(), _policy.name() };
|
||||
|
||||
Constructible<Env_connection<Rom_connection> > _linker { };
|
||||
|
||||
@@ -764,6 +768,7 @@ class Genode::Child : protected Rpc_object<Parent>,
|
||||
Ram_allocator &ram() { return _pd.session(); }
|
||||
Ram_allocator const &ram() const { return _pd.session(); }
|
||||
Cpu_session &cpu() { return _cpu.session(); }
|
||||
Topo_session &topo() { return _topo.session(); }
|
||||
Pd_session &pd() { return _pd.session(); }
|
||||
Pd_session const &pd() const { return _pd.session(); }
|
||||
|
||||
@@ -782,6 +787,14 @@ class Genode::Child : protected Rpc_object<Parent>,
|
||||
*/
|
||||
void yield(Resource_args const &args);
|
||||
|
||||
/**
|
||||
* Bestow resources on the child
|
||||
*
|
||||
* By calling this method, the child will be notified about
|
||||
* the having gained the specified amount of resources.
|
||||
*/
|
||||
void accept(Resource_args const &args);
|
||||
|
||||
/**
|
||||
* Notify the child about newly available resources
|
||||
*/
|
||||
@@ -818,6 +831,7 @@ class Genode::Child : protected Rpc_object<Parent>,
|
||||
void resource_request(Resource_args const &) override;
|
||||
void yield_sigh(Signal_context_capability) override;
|
||||
Resource_args yield_request() override;
|
||||
Resource_args gained_resources() override;
|
||||
void yield_response() override;
|
||||
void heartbeat_sigh(Signal_context_capability) override;
|
||||
void heartbeat_response() override;
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <base/entrypoint.h>
|
||||
#include <cpu_session/capability.h>
|
||||
#include <pd_session/capability.h>
|
||||
#include <topo_session/capability.h>
|
||||
|
||||
namespace Genode { struct Env; }
|
||||
|
||||
@@ -48,6 +49,12 @@ struct Genode::Env : Interface
|
||||
*/
|
||||
Ram_allocator &ram() { return pd(); }
|
||||
|
||||
/**
|
||||
* @brief Topology model
|
||||
*
|
||||
*/
|
||||
virtual Topo_session &topo() = 0;
|
||||
|
||||
/**
|
||||
* Entrypoint for handling RPC requests and signals
|
||||
*/
|
||||
@@ -63,6 +70,12 @@ struct Genode::Env : Interface
|
||||
*/
|
||||
virtual Pd_session_capability pd_session_cap() = 0;
|
||||
|
||||
/**
|
||||
* @brief Return the Topo-session capability
|
||||
*
|
||||
*/
|
||||
virtual Topo_session_capability topo_session_cap() = 0;
|
||||
|
||||
/**
|
||||
* ID space of sessions obtained from the parent
|
||||
*/
|
||||
|
||||
@@ -93,8 +93,15 @@ struct Genode::Local_connection_base : Noncopyable
|
||||
|
||||
if (_session_state->phase == Session_state::INSUFFICIENT_RAM_QUOTA
|
||||
|| _session_state->phase == Session_state::INSUFFICIENT_CAP_QUOTA)
|
||||
warning("giving up to increase session quota for ", service.name(), " session "
|
||||
{
|
||||
warning("[", label, "] giving up to increase session quota for ", service.name(), " session "
|
||||
"after ", (int)NUM_ATTEMPTS, " attempts");
|
||||
if (_session_state->phase == Session_state::INSUFFICIENT_RAM_QUOTA)
|
||||
warning("Insufficient RAM quota: ", resources.ram_quota.value);
|
||||
|
||||
if (_session_state->phase == Session_state::INSUFFICIENT_CAP_QUOTA)
|
||||
warning("Insufficient CAP quota ", resources.cap_quota.value);
|
||||
}
|
||||
}
|
||||
|
||||
void close()
|
||||
|
||||
@@ -40,6 +40,8 @@ struct Genode::Ram_allocator : Interface
|
||||
|
||||
struct Denied : Exception { };
|
||||
|
||||
typedef unsigned Numa_id;
|
||||
|
||||
/**
|
||||
* Allocate RAM dataspace
|
||||
*
|
||||
@@ -50,6 +52,7 @@ struct Genode::Ram_allocator : Interface
|
||||
* \return capability to RAM dataspace, or error code of type 'Alloc_error'
|
||||
*/
|
||||
virtual Alloc_result try_alloc(size_t size, Cache cache = CACHED) = 0;
|
||||
virtual Alloc_result try_alloc(size_t size, Numa_id numa_id, Cache cache = CACHED) = 0;
|
||||
|
||||
/**
|
||||
* Allocate RAM dataspace
|
||||
@@ -154,6 +157,10 @@ class Genode::Constrained_ram_allocator : public Ram_allocator
|
||||
);
|
||||
}
|
||||
|
||||
Alloc_result try_alloc(size_t size, Numa_id, Cache cache = CACHED) override {
|
||||
return this->Constrained_ram_allocator::try_alloc(size, cache); /* overriden in platform specific code */
|
||||
}
|
||||
|
||||
void free(Ram_dataspace_capability ds) override
|
||||
{
|
||||
size_t const size = _ram_alloc.dataspace_size(ds);
|
||||
|
||||
230
repos/base/include/base/regional_heap.h
Normal file
230
repos/base/include/base/regional_heap.h
Normal file
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* \brief Heap partition
|
||||
* \author Norman Feske
|
||||
* \date 2006-05-15
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
* Copyright (C) 2006-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__BASE__REGIONAL_HEAP_H_
|
||||
#define _INCLUDE__BASE__REGIONAL_HEAP_H_
|
||||
|
||||
#include <util/list.h>
|
||||
#include <util/reconstructible.h>
|
||||
#include <base/ram_allocator.h>
|
||||
#include <region_map/region_map.h>
|
||||
#include <base/allocator_avl.h>
|
||||
#include <base/mutex.h>
|
||||
#include <topo_session/node.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Regional_heap;
|
||||
class Sliced_regional_heap;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Heap that uses dataspaces as backing store and has a physical memory range limited to a single NUMA region
|
||||
*
|
||||
* The heap class provides an allocator that uses a list of dataspaces of a RAM
|
||||
* allocator as backing store. One dataspace may be used for holding multiple
|
||||
* blocks.
|
||||
*/
|
||||
class Genode::Regional_heap : public Allocator
|
||||
{
|
||||
private:
|
||||
|
||||
class Dataspace : public List<Dataspace>::Element
|
||||
{
|
||||
private:
|
||||
|
||||
/*
|
||||
* Noncopyable
|
||||
*/
|
||||
Dataspace(Dataspace const &);
|
||||
Dataspace &operator = (Dataspace const &);
|
||||
|
||||
public:
|
||||
|
||||
Ram_dataspace_capability cap;
|
||||
void *local_addr;
|
||||
size_t size;
|
||||
|
||||
Dataspace(Ram_dataspace_capability c, void *local_addr, size_t size)
|
||||
: cap(c), local_addr(local_addr), size(size) { }
|
||||
};
|
||||
|
||||
/*
|
||||
* This structure exists only to make sure that the dataspaces are
|
||||
* destroyed after the AVL allocator.
|
||||
*/
|
||||
class Dataspace_pool : public List<Dataspace>
|
||||
{
|
||||
private:
|
||||
|
||||
/*
|
||||
* Noncopyable
|
||||
*/
|
||||
Dataspace_pool(Dataspace_pool const &);
|
||||
Dataspace_pool &operator = (Dataspace_pool const &);
|
||||
|
||||
public:
|
||||
|
||||
Ram_allocator *ram_alloc; /* backing store */
|
||||
Region_map *region_map;
|
||||
|
||||
Dataspace_pool(Ram_allocator *ram, Region_map *rm)
|
||||
: ram_alloc(ram), region_map(rm) { }
|
||||
|
||||
~Dataspace_pool();
|
||||
|
||||
void remove_and_free(Dataspace &);
|
||||
|
||||
void reassign_resources(Ram_allocator *ram, Region_map *rm) {
|
||||
ram_alloc = ram, region_map = rm; }
|
||||
};
|
||||
|
||||
Mutex mutable _mutex { };
|
||||
Reconstructible<Allocator_avl> _alloc; /* local allocator */
|
||||
Dataspace_pool _ds_pool; /* list of dataspaces */
|
||||
size_t _quota_limit { 0 };
|
||||
size_t _quota_used { 0 };
|
||||
size_t _chunk_size { 0 };
|
||||
Ram_allocator::Numa_id _numa_id; /* ID of NUMA region to serve allocations from */
|
||||
|
||||
using Alloc_ds_result = Attempt<Dataspace *, Alloc_error>;
|
||||
|
||||
/**
|
||||
* Allocate a new dataspace of the specified size
|
||||
*
|
||||
* \param size number of bytes to allocate
|
||||
* \param enforce_separate_metadata if true, the new dataspace
|
||||
* will not contain any meta data
|
||||
*/
|
||||
Alloc_ds_result _allocate_dataspace(size_t size, bool enforce_separate_metadata);
|
||||
|
||||
/**
|
||||
* Try to allocate block at our local allocator
|
||||
*/
|
||||
Alloc_result _try_local_alloc(size_t size);
|
||||
|
||||
/**
|
||||
* Unsynchronized implementation of 'try_alloc'
|
||||
*/
|
||||
Alloc_result _unsynchronized_alloc(size_t size);
|
||||
|
||||
public:
|
||||
|
||||
enum { UNLIMITED = ~0 };
|
||||
|
||||
Regional_heap(Ram_allocator *ram_allocator,
|
||||
Region_map *region_map,
|
||||
Topology::Numa_region ®ion,
|
||||
size_t quota_limit = UNLIMITED,
|
||||
void *static_addr = 0,
|
||||
size_t static_size = 0);
|
||||
|
||||
Regional_heap(Ram_allocator &ram, Region_map &rm, Topology::Numa_region ®ion) : Regional_heap(&ram, &rm, region) { }
|
||||
|
||||
~Regional_heap();
|
||||
|
||||
/**
|
||||
* Reconfigure quota limit
|
||||
*
|
||||
* \return negative error code if new quota limit is higher than
|
||||
* currently used quota.
|
||||
*/
|
||||
int quota_limit(size_t new_quota_limit);
|
||||
|
||||
/**
|
||||
* Re-assign RAM allocator and region map
|
||||
*/
|
||||
void reassign_resources(Ram_allocator *ram, Region_map *rm) {
|
||||
_ds_pool.reassign_resources(ram, rm); }
|
||||
|
||||
/**
|
||||
* Call 'fn' with the start and size of each backing-store region
|
||||
*/
|
||||
template <typename FN>
|
||||
void for_each_region(FN const &fn) const
|
||||
{
|
||||
Mutex::Guard guard(_mutex);
|
||||
for (Dataspace const *ds = _ds_pool.first(); ds; ds = ds->next())
|
||||
fn(ds->local_addr, ds->size);
|
||||
}
|
||||
|
||||
|
||||
/*************************
|
||||
** Allocator interface **
|
||||
*************************/
|
||||
|
||||
Alloc_result try_alloc(size_t) override;
|
||||
void free(void *, size_t) override;
|
||||
size_t consumed() const override { return _quota_used; }
|
||||
size_t overhead(size_t size) const override { return _alloc->overhead(size); }
|
||||
bool need_size_for_free() const override { return false; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Heap that allocates each block at a separate dataspace
|
||||
*/
|
||||
class Genode::Sliced_regional_heap : public Allocator
|
||||
{
|
||||
private:
|
||||
|
||||
/**
|
||||
* Meta-data header placed in front of each allocated block
|
||||
*/
|
||||
struct Block : List<Block>::Element
|
||||
{
|
||||
Ram_dataspace_capability const ds;
|
||||
size_t const size;
|
||||
|
||||
Block(Ram_dataspace_capability ds, size_t size) : ds(ds), size(size)
|
||||
{ }
|
||||
};
|
||||
|
||||
Ram_allocator &_ram_alloc; /* RAM allocator for backing store */
|
||||
Region_map &_region_map; /* region map of the address space */
|
||||
size_t _consumed = 0; /* number of allocated bytes */
|
||||
List<Block> _blocks { }; /* list of allocated blocks */
|
||||
Mutex _mutex { }; /* serialize allocations */
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Return size of header prepended to each allocated block in bytes
|
||||
*/
|
||||
static constexpr size_t meta_data_size() { return sizeof(Block); }
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
Sliced_regional_heap(Ram_allocator &ram_alloc, Region_map ®ion_map);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
~Sliced_regional_heap();
|
||||
|
||||
|
||||
/*************************
|
||||
** Allocator interface **
|
||||
*************************/
|
||||
|
||||
Alloc_result try_alloc(size_t) override;
|
||||
void free(void *, size_t) override;
|
||||
size_t consumed() const override { return _consumed; }
|
||||
size_t overhead(size_t size) const override;
|
||||
bool need_size_for_free() const override { return false; }
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__BASE__HEAP_H_ */
|
||||
@@ -48,6 +48,7 @@ class Genode::Thread
|
||||
using Location = Affinity::Location;
|
||||
using Name = Cpu_session::Name;
|
||||
using Weight = Cpu_session::Weight;
|
||||
typedef unsigned Numa_id;
|
||||
|
||||
struct Stack_info { addr_t base; addr_t top;
|
||||
addr_t libc_tls_pointer_offset; };
|
||||
@@ -432,6 +433,8 @@ class Genode::Thread
|
||||
* Thread affinity
|
||||
*/
|
||||
Affinity::Location affinity() const { return _affinity; }
|
||||
|
||||
void pin(Affinity::Location &loc);
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__BASE__THREAD_H_ */
|
||||
|
||||
93
repos/base/include/base/trace/perf.h
Normal file
93
repos/base/include/base/trace/perf.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* \brief Performance Counter infrastructure
|
||||
* \author Michael Müller
|
||||
* \date 2022-12-15
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <base/stdint.h>
|
||||
|
||||
namespace Genode { namespace Trace {
|
||||
|
||||
class Pfc_no_avail {
|
||||
};
|
||||
|
||||
class Performance_counter
|
||||
{
|
||||
|
||||
private:
|
||||
static unsigned long private_freemask;
|
||||
static unsigned long shared_freemask;
|
||||
|
||||
static unsigned _alloc(unsigned long *free_mask)
|
||||
{
|
||||
unsigned long current_mask, new_mask;
|
||||
unsigned bit;
|
||||
|
||||
do
|
||||
{
|
||||
current_mask = *free_mask;
|
||||
bit = __builtin_ffsl(current_mask);
|
||||
new_mask = current_mask & ~(1 << (bit - 1));
|
||||
} while (!__atomic_compare_exchange(free_mask, ¤t_mask, &new_mask, true, __ATOMIC_ACQ_REL, __ATOMIC_RELAXED));
|
||||
|
||||
if (!bit) // Allocation failed
|
||||
throw Pfc_no_avail();
|
||||
|
||||
return bit - 1; // number of the allocated counter
|
||||
}
|
||||
|
||||
static void _init_masks();
|
||||
|
||||
public:
|
||||
typedef unsigned int Counter;
|
||||
|
||||
enum Type
|
||||
{
|
||||
CORE = 0,
|
||||
CACHE = 1
|
||||
};
|
||||
|
||||
static unsigned acquire(Type type) {
|
||||
return (type == Type::CORE) ? alloc_core() : alloc_cbo();
|
||||
}
|
||||
|
||||
static unsigned alloc_cbo() {
|
||||
if (shared_freemask == 0xffff0000)
|
||||
_init_masks();
|
||||
return _alloc(&shared_freemask);
|
||||
}
|
||||
|
||||
static unsigned alloc_core() {
|
||||
if (private_freemask == 0xffff)
|
||||
_init_masks();
|
||||
return _alloc(&private_freemask);
|
||||
}
|
||||
|
||||
static void release(unsigned counter) {
|
||||
bool core = static_cast<bool>(counter >> 4);
|
||||
if (core)
|
||||
private_freemask |= (1 << counter);
|
||||
else
|
||||
shared_freemask |= (1 << counter);
|
||||
}
|
||||
|
||||
static void setup(unsigned counter, Genode::uint64_t event, Genode::uint64_t mask, Genode::uint64_t flags);
|
||||
static void start(unsigned counter);
|
||||
static void stop(unsigned counter);
|
||||
static void reset(unsigned counter, unsigned val=0);
|
||||
static uint64_t read(unsigned counter);
|
||||
};
|
||||
|
||||
class Pfc_access_error {
|
||||
private:
|
||||
Genode::uint8_t _rc;
|
||||
|
||||
public:
|
||||
Pfc_access_error(uint8_t rc) : _rc(rc) {}
|
||||
Genode::uint8_t error_code() { return _rc; }
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
@@ -33,12 +33,19 @@ struct Genode::Cpu_session_client : Rpc_client<Cpu_session>
|
||||
void kill_thread(Thread_capability thread) override {
|
||||
call<Rpc_kill_thread>(thread); }
|
||||
|
||||
void migrate_thread(Thread_capability thread, Affinity::Location loc) override {
|
||||
call<Rpc_migrate_thread>(thread, loc); }
|
||||
|
||||
void exception_sigh(Signal_context_capability sigh) override {
|
||||
call<Rpc_exception_sigh>(sigh); }
|
||||
|
||||
Affinity::Space affinity_space() const override {
|
||||
return call<Rpc_affinity_space>(); }
|
||||
|
||||
void move(const Affinity::Location loc) override {
|
||||
call<Rpc_move>(loc);
|
||||
}
|
||||
|
||||
Dataspace_capability trace_control() override {
|
||||
return call<Rpc_trace_control>(); }
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ namespace Genode { struct Cpu_connection; }
|
||||
|
||||
struct Genode::Cpu_connection : Connection<Cpu_session>, Cpu_session_client
|
||||
{
|
||||
enum { RAM_QUOTA = 72*1024 };
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <session/session.h>
|
||||
#include <dataspace/capability.h>
|
||||
#include <pd_session/pd_session.h>
|
||||
#include <base/affinity.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
@@ -105,6 +106,14 @@ struct Genode::Cpu_session : Session
|
||||
*/
|
||||
virtual void kill_thread(Thread_capability thread) = 0;
|
||||
|
||||
/**
|
||||
* Migrate a thread to a new location
|
||||
*
|
||||
* \param thread capability of the thread to migrate
|
||||
* \param loc component-local location to migrate the thread to
|
||||
*/
|
||||
virtual void migrate_thread(Thread_capability thread, Genode::Affinity::Location loc) = 0;
|
||||
|
||||
/**
|
||||
* Register default signal handler for exceptions
|
||||
*
|
||||
@@ -125,6 +134,12 @@ struct Genode::Cpu_session : Session
|
||||
*/
|
||||
virtual Affinity::Space affinity_space() const = 0;
|
||||
|
||||
/**
|
||||
* @brief Update affinity location of this CPU session
|
||||
*
|
||||
*/
|
||||
virtual void move(const Genode::Affinity::Location ) = 0;
|
||||
|
||||
/**
|
||||
* Translate generic priority value to kernel-specific priority levels
|
||||
*
|
||||
@@ -231,8 +246,10 @@ struct Genode::Cpu_session : Session
|
||||
Capability<Pd_session>, Name const &, Affinity::Location,
|
||||
Weight, addr_t);
|
||||
GENODE_RPC(Rpc_kill_thread, void, kill_thread, Thread_capability);
|
||||
GENODE_RPC(Rpc_migrate_thread, void, migrate_thread, Thread_capability, Affinity::Location);
|
||||
GENODE_RPC(Rpc_exception_sigh, void, exception_sigh, Signal_context_capability);
|
||||
GENODE_RPC(Rpc_affinity_space, Affinity::Space, affinity_space);
|
||||
GENODE_RPC(Rpc_move, void, move, Affinity::Location);
|
||||
GENODE_RPC(Rpc_trace_control, Dataspace_capability, trace_control);
|
||||
GENODE_RPC(Rpc_ref_account, int, ref_account, Cpu_session_capability);
|
||||
GENODE_RPC(Rpc_transfer_quota, int, transfer_quota, Cpu_session_capability, size_t);
|
||||
@@ -241,7 +258,7 @@ struct Genode::Cpu_session : Session
|
||||
|
||||
GENODE_RPC_INTERFACE(Rpc_create_thread, Rpc_kill_thread, Rpc_exception_sigh,
|
||||
Rpc_affinity_space, Rpc_trace_control, Rpc_ref_account,
|
||||
Rpc_transfer_quota, Rpc_quota, Rpc_native_cpu);
|
||||
Rpc_transfer_quota, Rpc_quota, Rpc_native_cpu, Rpc_migrate_thread, Rpc_move);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -67,6 +67,8 @@ struct Genode::Parent_client : Rpc_client<Parent>
|
||||
call<Rpc_yield_sigh>(sigh); }
|
||||
|
||||
Resource_args yield_request() override { return call<Rpc_yield_request>(); }
|
||||
|
||||
Resource_args gained_resources() override { return call<Rpc_gained_resources>(); }
|
||||
|
||||
void yield_response() override { call<Rpc_yield_response>(); }
|
||||
|
||||
|
||||
@@ -71,7 +71,8 @@ class Genode::Parent
|
||||
static Client::Id log() { return { 3 }; }
|
||||
static Client::Id binary() { return { 4 }; }
|
||||
static Client::Id linker() { return { 5 }; }
|
||||
static Client::Id last() { return { 5 }; }
|
||||
static Client::Id topo() { return { 6 }; }
|
||||
static Client::Id last() { return { 6 }; }
|
||||
|
||||
/**
|
||||
* True if session ID refers to an environment session
|
||||
@@ -283,6 +284,12 @@ class Genode::Parent
|
||||
*/
|
||||
virtual void yield_response() = 0;
|
||||
|
||||
/**
|
||||
* Obtain information about the resources gained, e.g. from a resource request
|
||||
*
|
||||
*/
|
||||
virtual Resource_args gained_resources() = 0;
|
||||
|
||||
/*
|
||||
* Health monitoring
|
||||
*/
|
||||
@@ -328,6 +335,7 @@ class Genode::Parent
|
||||
Resource_args const &);
|
||||
GENODE_RPC(Rpc_yield_sigh, void, yield_sigh, Signal_context_capability);
|
||||
GENODE_RPC(Rpc_yield_request, Resource_args, yield_request);
|
||||
GENODE_RPC(Rpc_gained_resources, Resource_args, gained_resources);
|
||||
GENODE_RPC(Rpc_yield_response, void, yield_response);
|
||||
GENODE_RPC(Rpc_heartbeat_sigh, void, heartbeat_sigh, Signal_context_capability);
|
||||
GENODE_RPC(Rpc_heartbeat_response, void, heartbeat_response);
|
||||
@@ -337,7 +345,7 @@ class Genode::Parent
|
||||
Rpc_close, Rpc_session_response, Rpc_main_thread,
|
||||
Rpc_deliver_session_cap, Rpc_resource_avail_sigh,
|
||||
Rpc_resource_request, Rpc_yield_sigh,
|
||||
Rpc_yield_request, Rpc_yield_response,
|
||||
Rpc_yield_request, Rpc_yield_response, Rpc_gained_resources,
|
||||
Rpc_heartbeat_sigh, Rpc_heartbeat_response);
|
||||
};
|
||||
|
||||
|
||||
@@ -80,6 +80,11 @@ struct Genode::Pd_session_client : Rpc_client<Pd_session>
|
||||
{
|
||||
return call<Rpc_try_alloc>(size, cache);
|
||||
}
|
||||
|
||||
Alloc_result try_alloc(size_t size, Ram_allocator::Numa_id numa_id, Cache cache = CACHED) override
|
||||
{
|
||||
return call<Rpc_try_alloc_numa>(size, numa_id, cache);
|
||||
}
|
||||
|
||||
void free(Ram_dataspace_capability ds) override { call<Rpc_free>(ds); }
|
||||
|
||||
@@ -106,6 +111,16 @@ struct Genode::Pd_session_client : Rpc_client<Pd_session>
|
||||
|
||||
Attach_dma_result attach_dma(Dataspace_capability ds, addr_t at) override {
|
||||
return call<Rpc_attach_dma>(ds, at); }
|
||||
|
||||
void create_cell(long prioritiy, const Affinity::Location &loc) override
|
||||
{
|
||||
call<Rpc_create_cell>(prioritiy, loc);
|
||||
}
|
||||
|
||||
void update_cell(const Affinity::Location &loc) override
|
||||
{
|
||||
call<Rpc_update_cell>(loc);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__PD_SESSION__CLIENT_H_ */
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include <session/session.h>
|
||||
#include <region_map/region_map.h>
|
||||
#include <base/ram_allocator.h>
|
||||
|
||||
#include <base/affinity.h>
|
||||
namespace Genode {
|
||||
struct Pd_session;
|
||||
struct Pd_session_client;
|
||||
@@ -29,7 +29,6 @@ namespace Genode {
|
||||
struct Signal_context;
|
||||
}
|
||||
|
||||
|
||||
struct Genode::Pd_session : Session, Ram_allocator
|
||||
{
|
||||
/**
|
||||
@@ -273,6 +272,11 @@ struct Genode::Pd_session : Session, Ram_allocator
|
||||
*/
|
||||
Ram_quota avail_ram() const { return { ram_quota().value - used_ram().value }; }
|
||||
|
||||
/**
|
||||
* \brief Create new dataspace factory for given NUMA node
|
||||
* \param
|
||||
*/
|
||||
|
||||
|
||||
/*****************************************
|
||||
** Access to kernel-specific interface **
|
||||
@@ -345,6 +349,12 @@ struct Genode::Pd_session : Session, Ram_allocator
|
||||
*/
|
||||
virtual Attach_dma_result attach_dma(Dataspace_capability, addr_t at) = 0;
|
||||
|
||||
/*
|
||||
* Create a new cell at the kernel for this protection domain
|
||||
*/
|
||||
virtual void create_cell(long prioritiy, const Affinity::Location &loc) = 0;
|
||||
|
||||
virtual void update_cell(const Affinity::Location &loc) = 0;
|
||||
|
||||
/*********************
|
||||
** RPC declaration **
|
||||
@@ -370,6 +380,7 @@ struct Genode::Pd_session : Session, Ram_allocator
|
||||
GENODE_RPC(Rpc_cap_quota, Cap_quota, cap_quota);
|
||||
GENODE_RPC(Rpc_used_caps, Cap_quota, used_caps);
|
||||
GENODE_RPC(Rpc_try_alloc, Alloc_result, try_alloc, size_t, Cache);
|
||||
GENODE_RPC(Rpc_try_alloc_numa, Alloc_result, try_alloc, size_t, Ram_allocator::Numa_id, Cache);
|
||||
GENODE_RPC(Rpc_free, void, free, Ram_dataspace_capability);
|
||||
GENODE_RPC(Rpc_transfer_ram_quota, Transfer_ram_quota_result, transfer_quota,
|
||||
Capability<Pd_session>, Ram_quota);
|
||||
@@ -382,16 +393,21 @@ struct Genode::Pd_session : Session, Ram_allocator
|
||||
GENODE_RPC(Rpc_attach_dma, Attach_dma_result, attach_dma,
|
||||
Dataspace_capability, addr_t);
|
||||
|
||||
GENODE_RPC(Rpc_create_cell, void, create_cell, long, Affinity::Location const &);
|
||||
|
||||
GENODE_RPC(Rpc_update_cell, void, update_cell, Affinity::Location const &);
|
||||
|
||||
GENODE_RPC_INTERFACE(Rpc_assign_parent, Rpc_assign_pci, Rpc_map,
|
||||
Rpc_signal_source, Rpc_free_signal_source,
|
||||
Rpc_alloc_context, Rpc_free_context, Rpc_submit,
|
||||
Rpc_alloc_rpc_cap, Rpc_free_rpc_cap, Rpc_address_space,
|
||||
Rpc_stack_area, Rpc_linker_area, Rpc_ref_account,
|
||||
Rpc_transfer_cap_quota, Rpc_cap_quota, Rpc_used_caps,
|
||||
Rpc_try_alloc, Rpc_free,
|
||||
Rpc_try_alloc, Rpc_try_alloc_numa, Rpc_free,
|
||||
Rpc_transfer_ram_quota, Rpc_ram_quota, Rpc_used_ram,
|
||||
Rpc_native_pd, Rpc_system_control_cap,
|
||||
Rpc_dma_addr, Rpc_attach_dma);
|
||||
Rpc_dma_addr, Rpc_attach_dma,
|
||||
Rpc_create_cell, Rpc_update_cell);
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE__PD_SESSION__PD_SESSION_H_ */
|
||||
|
||||
22
repos/base/include/topo_session/capability.h
Normal file
22
repos/base/include/topo_session/capability.h
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* \brief Topo-session capability type
|
||||
* \author Michael Müller
|
||||
* \date 2022-10-06
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is part of EalanOS, witch is based on Genode OS framework
|
||||
* distributed under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <base/capability.h>
|
||||
#include <topo_session/topo_session.h>
|
||||
|
||||
namespace Genode
|
||||
{
|
||||
typedef Capability<Topo_session> Topo_session_capability;
|
||||
} // namespace Genode
|
||||
59
repos/base/include/topo_session/client.h
Normal file
59
repos/base/include/topo_session/client.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* \brief Client-side topology session interface
|
||||
* \author Michael Müller
|
||||
* \date 2022-10-06
|
||||
*
|
||||
* A topology session stores the component's view on the hardware topology, i.e. it's location within the NUMA topology.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is part of EalánOS which is based on the Genode OS framework
|
||||
* released under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <topo_session/capability.h>
|
||||
#include <topo_session/node.h>
|
||||
#include <base/rpc_client.h>
|
||||
#include <base/affinity.h>
|
||||
|
||||
namespace Genode {
|
||||
struct Topo_session_client;
|
||||
struct Node;
|
||||
}
|
||||
|
||||
struct Genode::Topo_session_client : Rpc_client<Topo_session>
|
||||
{
|
||||
explicit Topo_session_client(Topo_session_capability session)
|
||||
: Rpc_client<Topo_session>(session) { }
|
||||
|
||||
Topology::Numa_region node_affinity_of(Affinity::Location const &loc) override {
|
||||
return call<Rpc_node_affinity>(loc);
|
||||
}
|
||||
|
||||
Topology::Numa_region node_at_id(unsigned node_id) override {
|
||||
return call<Rpc_node_id>(node_id);
|
||||
}
|
||||
|
||||
unsigned node_count() override {
|
||||
return call<Rpc_node_count>();
|
||||
}
|
||||
|
||||
void reconstruct(const Affinity affinity) override
|
||||
{
|
||||
call<Rpc_reconstruct>(affinity);
|
||||
}
|
||||
|
||||
unsigned phys_id(const Affinity::Location &loc) override
|
||||
{
|
||||
return call<Rpc_phys_id>(loc);
|
||||
}
|
||||
|
||||
Affinity::Space const global_affinity_space() override
|
||||
{
|
||||
return call<Rpc_total_core_count>();
|
||||
}
|
||||
};
|
||||
50
repos/base/include/topo_session/connection.h
Normal file
50
repos/base/include/topo_session/connection.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* \brief Topology session interface
|
||||
* \author Michael Müller
|
||||
* \date 2022-10-06
|
||||
*
|
||||
* A topology session stores the component's view on the hardware topology, i.e. it's location within the NUMA topology.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is part of EalánOS which is based on the Genode OS framework
|
||||
* released under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <topo_session/client.h>
|
||||
#include <topo_session/node.h>
|
||||
#include <base/connection.h>
|
||||
|
||||
namespace Genode {
|
||||
struct Topo_connection;
|
||||
}
|
||||
|
||||
struct Genode::Topo_connection : Connection<Topo_session>, Topo_session_client
|
||||
{
|
||||
enum
|
||||
{
|
||||
RAM_QUOTA = 2097152UL
|
||||
};
|
||||
|
||||
Topo_connection(Env &env, const char *label = "", Affinity const &affinity = Affinity())
|
||||
:
|
||||
Connection<Topo_session>(env,
|
||||
session(env.parent(), affinity, "ram_quota=%u, cap_quota=%u, label=\"%s\"", RAM_QUOTA, CAP_QUOTA, label)),
|
||||
Topo_session_client(cap()) {}
|
||||
|
||||
Topology::Numa_region node_affinity_of(Affinity::Location const &loc) override {
|
||||
return Topo_session_client::node_affinity_of(loc);
|
||||
}
|
||||
|
||||
Topology::Numa_region node_at_id(unsigned node_id) override {
|
||||
return Topo_session_client::node_at_id(node_id);
|
||||
}
|
||||
|
||||
unsigned node_count() override {
|
||||
return Topo_session_client::node_count();
|
||||
}
|
||||
};
|
||||
58
repos/base/include/topo_session/node.h
Normal file
58
repos/base/include/topo_session/node.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* \brief Representation of a NUMA node
|
||||
* \author Michael Müller
|
||||
* \date 2022-10-06
|
||||
*
|
||||
* A topology session stores the component's view on the hardware topology, i.e. it's location within the NUMA topology.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is part of EalánOS which is based on the Genode OS framework
|
||||
* released under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <util/list.h>
|
||||
|
||||
namespace Topology {
|
||||
struct Numa_region;
|
||||
}
|
||||
|
||||
struct Topology::Numa_region : Genode::List<Topology::Numa_region>::Element
|
||||
{
|
||||
/* ID presented to component */
|
||||
unsigned _id;
|
||||
|
||||
unsigned _core_count;
|
||||
Genode::List<Topology::Numa_region> neighbours;
|
||||
|
||||
/* Physical NUMA node ID */
|
||||
unsigned _native_id;
|
||||
|
||||
Numa_region() : _id(0), _core_count(0), neighbours(), _native_id(0) { }
|
||||
Numa_region(unsigned id, unsigned native_id) : _id(id), _core_count(0), neighbours(), _native_id(native_id) {}
|
||||
Numa_region(Numa_region ©) : _id(copy.id()), _core_count(copy.core_count()), neighbours(), _native_id(copy.native_id()) {
|
||||
}
|
||||
|
||||
unsigned native_id() { return _native_id; }
|
||||
unsigned id() { return _id; }
|
||||
unsigned core_count() { return _core_count; }
|
||||
void core_count(unsigned count) { _core_count = count; }
|
||||
void increment_core_count() { _core_count++; }
|
||||
Numa_region &operator=(const Numa_region ©) {
|
||||
if (this == ©)
|
||||
return *this;
|
||||
|
||||
this->_id = copy._id;
|
||||
this->_core_count = copy._core_count;
|
||||
this->_native_id = copy._native_id;
|
||||
|
||||
/* At the moment, we do not copy the list of neighbours, as it is not used by any our applications. */
|
||||
/* TODO: Copy list onf neighbours, as soons as any application is going to use that information. */
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
64
repos/base/include/topo_session/topo_session.h
Normal file
64
repos/base/include/topo_session/topo_session.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* \brief Topology session interface
|
||||
* \author Michael Müller
|
||||
* \date 2022-10-06
|
||||
*
|
||||
* A topology session stores the component's view on the hardware topology, i.e. it's location within the NUMA topology.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is part of EalánOS which is based on the Genode OS framework
|
||||
* released under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <session/session.h>
|
||||
#include <base/affinity.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
struct Topo_session;
|
||||
struct Topo_session_client;
|
||||
}
|
||||
|
||||
namespace Topology
|
||||
{
|
||||
struct Numa_region;
|
||||
} // namespace EalanOS
|
||||
|
||||
struct Genode::Topo_session : Session
|
||||
{
|
||||
/**
|
||||
* \nooapi
|
||||
*
|
||||
*/
|
||||
static const char *service_name() { return "TOPO"; }
|
||||
|
||||
enum
|
||||
{
|
||||
CAP_QUOTA = 2
|
||||
};
|
||||
|
||||
typedef Topo_session_client Client;
|
||||
|
||||
virtual ~Topo_session() { }
|
||||
|
||||
virtual Topology::Numa_region node_affinity_of(Affinity::Location const &) = 0;
|
||||
virtual Topology::Numa_region node_at_id(unsigned node_id) = 0;
|
||||
virtual unsigned node_count() = 0;
|
||||
virtual void reconstruct(const Affinity) = 0;
|
||||
virtual unsigned phys_id(Affinity::Location const &) = 0;
|
||||
virtual Affinity::Space const global_affinity_space() = 0;
|
||||
|
||||
GENODE_RPC(Rpc_node_affinity, Topology::Numa_region, node_affinity_of, Affinity::Location const &);
|
||||
GENODE_RPC(Rpc_node_id, Topology::Numa_region, node_at_id, unsigned);
|
||||
GENODE_RPC(Rpc_node_count, unsigned, node_count);
|
||||
GENODE_RPC(Rpc_reconstruct, void, reconstruct, Affinity);
|
||||
GENODE_RPC(Rpc_phys_id, unsigned, phys_id, Affinity::Location const &);
|
||||
GENODE_RPC(Rpc_total_core_count, Affinity::Space const, global_affinity_space);
|
||||
|
||||
GENODE_RPC_INTERFACE(Rpc_node_affinity, Rpc_node_id, Rpc_node_count, Rpc_reconstruct, Rpc_phys_id, Rpc_total_core_count);
|
||||
};
|
||||
@@ -8,6 +8,7 @@ SRC_CC += avl_tree.cc
|
||||
SRC_CC += slab.cc
|
||||
SRC_CC += allocator_avl.cc
|
||||
SRC_CC += heap.cc sliced_heap.cc
|
||||
SRC_CC += regional_heap.cc
|
||||
SRC_CC += registry.cc
|
||||
SRC_CC += output.cc
|
||||
SRC_CC += child.cc
|
||||
|
||||
@@ -38,6 +38,13 @@
|
||||
# under the terms of the GNU Affero General Public License version 3.
|
||||
#
|
||||
|
||||
__atomic_store T
|
||||
__atomic_load T
|
||||
_Unwind_GetLanguageSpecificData T
|
||||
_Unwind_GetRegionStart T
|
||||
_Unwind_GetIP T
|
||||
_Unwind_SetGR T
|
||||
_Unwind_SetIP T
|
||||
_Z11genode_exiti T
|
||||
_Z16main_thread_utcbv T
|
||||
_Z22__ldso_raise_exceptionv T
|
||||
@@ -45,6 +52,9 @@ _ZN5Timer10Connection11set_timeoutEN6Genode12MicrosecondsERNS1_15Timeout_handler
|
||||
_ZN5Timer10Connection9curr_timeEv T
|
||||
_ZN5Timer10ConnectionC1ERN6Genode3EnvERNS1_10EntrypointERKNS1_13Session_labelE T
|
||||
_ZN5Timer10ConnectionC2ERN6Genode3EnvERNS1_10EntrypointERKNS1_13Session_labelE T
|
||||
_ZN6Genode5Trace19Performance_counter15shared_freemaskE D 8
|
||||
_ZN6Genode5Trace19Performance_counter16private_freemaskE D 8
|
||||
_ZN6Genode5Trace19Performance_counter11_init_masksEv T
|
||||
_ZN6Genode10Entrypoint16_dispatch_signalERNS_6SignalE T
|
||||
_ZN6Genode10Entrypoint22Signal_proxy_component6signalEv T
|
||||
_ZN6Genode10Entrypoint25_process_incoming_signalsEv T
|
||||
@@ -142,6 +152,26 @@ _ZN6Genode17Region_map_client6detachEm T
|
||||
_ZN6Genode17Region_map_client9dataspaceEv T
|
||||
_ZN6Genode17Region_map_clientC1ENS_10CapabilityINS_10Region_mapEEE T
|
||||
_ZN6Genode17Region_map_clientC2ENS_10CapabilityINS_10Region_mapEEE T
|
||||
_ZN6Genode13Regional_heap11quota_limitEm T
|
||||
_ZN6Genode13Regional_heap14Dataspace_pool15remove_and_freeERNS0_9DataspaceE T
|
||||
_ZN6Genode13Regional_heap14Dataspace_poolD1Ev T
|
||||
_ZN6Genode13Regional_heap14Dataspace_poolD2Ev T
|
||||
_ZN6Genode13Regional_heap16_try_local_allocEm T
|
||||
_ZN6Genode13Regional_heap19_allocate_dataspaceEmb T
|
||||
_ZN6Genode13Regional_heap21_unsynchronized_allocEm T
|
||||
_ZN6Genode13Regional_heap4freeEPvm T
|
||||
_ZN6Genode13Regional_heap9try_allocEm T
|
||||
_ZN6Genode13Regional_heapC1EPNS_13Ram_allocatorEPNS_10Region_mapERN8Topology11Numa_regionEmPvm T
|
||||
_ZN6Genode13Regional_heapC2EPNS_13Ram_allocatorEPNS_10Region_mapERN8Topology11Numa_regionEmPvm T
|
||||
_ZN6Genode13Regional_heapD0Ev T
|
||||
_ZN6Genode13Regional_heapD1Ev T
|
||||
_ZN6Genode13Regional_heapD2Ev T
|
||||
_ZNK6Genode13Regional_heap18need_size_for_freeEv T
|
||||
_ZNK6Genode13Regional_heap8consumedEv T
|
||||
_ZNK6Genode13Regional_heap8overheadEm T
|
||||
_ZTIN6Genode13Regional_heapE T
|
||||
_ZTSN6Genode13Regional_heapE T
|
||||
_ZTVN6Genode13Regional_heapE T
|
||||
_ZN6Genode17Rm_session_client6createEm T
|
||||
_ZN6Genode17Rm_session_client7destroyENS_10CapabilityINS_10Region_mapEEE T
|
||||
_ZN6Genode17Rm_session_clientC1ENS_10CapabilityINS_10Rm_sessionEEE T
|
||||
@@ -174,6 +204,8 @@ _ZN6Genode18Signal_transmitterC1ENS_10CapabilityINS_14Signal_contextEEE T
|
||||
_ZN6Genode18Signal_transmitterC2ENS_10CapabilityINS_14Signal_contextEEE T
|
||||
_ZN6Genode20env_session_id_spaceEv T
|
||||
_ZN6Genode21cache_invalidate_dataEmm T
|
||||
_ZN6Genode22Topo_session_component11reconstructENS_8AffinityE W
|
||||
_ZThn136_N6Genode22Topo_session_component11reconstructENS_8AffinityE W
|
||||
_ZN6Genode25env_stack_area_region_mapE B 8
|
||||
_ZN6Genode27cache_clean_invalidate_dataEmm T
|
||||
_ZN6Genode28env_stack_area_ram_allocatorE B 8
|
||||
@@ -223,6 +255,7 @@ _ZN6Genode5Child23initiate_env_pd_sessionEv T
|
||||
_ZN6Genode5Child4exitEi T
|
||||
_ZN6Genode5Child5closeENS_8Id_spaceINS_6Parent6ClientEE2IdE T
|
||||
_ZN6Genode5Child5yieldERKNS_6StringILm160EEE T
|
||||
_ZN6Genode5Child6acceptERKNS_6StringILm160EEE T
|
||||
_ZN6Genode5Child7sessionENS_8Id_spaceINS_6Parent6ClientEE2IdERKNS_13Rpc_in_bufferILm64EEERKNS6_ILm160EEERKNS_8AffinityE T
|
||||
_ZN6Genode5Child7upgradeENS_8Id_spaceINS_6Parent6ClientEE2IdERKNS_13Rpc_in_bufferILm160EEE T
|
||||
_ZN6Genode5Child8announceERKNS_13Rpc_in_bufferILm64EEE T
|
||||
@@ -239,6 +272,11 @@ _ZN6Genode5Trace6Logger17_evaluate_controlEv T
|
||||
_ZN6Genode5Trace6Logger3logEPKcm T
|
||||
_ZN6Genode5Trace6LoggerC1Ev T
|
||||
_ZN6Genode5Trace6LoggerC2Ev T
|
||||
_ZN6Genode5Trace19Performance_counter4readEj T
|
||||
_ZN6Genode5Trace19Performance_counter4stopEj T
|
||||
_ZN6Genode5Trace19Performance_counter5resetEjj T
|
||||
_ZN6Genode5Trace19Performance_counter5setupEjyyy T
|
||||
_ZN6Genode5Trace19Performance_counter5startEj T
|
||||
_ZN6Genode5Trace18Partitioned_buffer4initEm T
|
||||
_ZN6Genode5Trace18Partitioned_buffer6commitEm T
|
||||
_ZN6Genode5Trace18Partitioned_buffer7reserveEm T
|
||||
@@ -271,6 +309,7 @@ _ZN6Genode6Thread23stack_area_virtual_baseEv T
|
||||
_ZN6Genode6Thread23stack_area_virtual_sizeEv T
|
||||
_ZN6Genode6Thread4joinEv T
|
||||
_ZN6Genode6Thread4nameEPcm T
|
||||
_ZN6Genode6Thread3pinERNS_8Affinity8LocationE T
|
||||
_ZN6Genode6Thread4utcbEv T
|
||||
_ZN6Genode6Thread5startEv T
|
||||
_ZN6Genode6Thread6myselfEv T
|
||||
@@ -374,7 +413,7 @@ _ZTVN6Genode18Allocator_avl_baseE D 128
|
||||
_ZTVN6Genode4HeapE D 72
|
||||
_ZTVN6Genode4SlabE D 72
|
||||
_ZTVN6Genode5Child14Initial_threadE D 48
|
||||
_ZTVN6Genode5ChildE D 440
|
||||
_ZTVN6Genode5ChildE D 456
|
||||
_ZTVN6Genode6OutputE D 48
|
||||
_ZTVN6Genode6ThreadE D 48
|
||||
_ZTVN6Genode7ConsoleE D 48
|
||||
@@ -599,8 +638,12 @@ _ZTVSt8bad_cast D 40
|
||||
_ZTVSt9bad_alloc D 40
|
||||
_ZTVSt9exception D 40
|
||||
_ZTVSt9type_info D 64
|
||||
_ZdaPvSt11align_val_t W
|
||||
_ZdlPv W
|
||||
_ZdlPvm W
|
||||
_ZdlPvSt11align_val_t W
|
||||
_ZdlPvmSt11align_val_t W
|
||||
_ZnwmSt11align_val_t W
|
||||
__aeabi_atexit W
|
||||
__aeabi_unwind_cpp_pr0 T
|
||||
__aeabi_unwind_cpp_pr1 T
|
||||
|
||||
@@ -257,7 +257,7 @@ ALL_INC_DIR += $(LIBGCC_INC_DIR)
|
||||
ALL_INC_DIR += $(HOST_INC_DIR)
|
||||
|
||||
VERBOSE ?= @
|
||||
VERBOSE_DIR ?= --no-print-directory
|
||||
VERBOSE_DIR ?= --print-directory
|
||||
|
||||
MSG_LINK ?= @$(ECHO) " LINK "
|
||||
MSG_COMP ?= @$(ECHO) " COMPILE "
|
||||
|
||||
@@ -51,8 +51,10 @@ void Core::init_core_log(Core_log_range const &r) { range = r; }
|
||||
|
||||
void Core::Core_log::output(char const * str)
|
||||
{
|
||||
acquire();
|
||||
for (unsigned i = 0; i < Genode::strlen(str); i++) {
|
||||
out(str[i]);
|
||||
out_mem(str[i]);
|
||||
}
|
||||
release();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <util/arg_string.h>
|
||||
#include <cpu_thread/client.h>
|
||||
|
||||
/* core includes */
|
||||
#include <cpu_session_component.h>
|
||||
@@ -22,6 +23,7 @@
|
||||
#include <pd_session_component.h>
|
||||
#include <platform_generic.h>
|
||||
|
||||
|
||||
using namespace Core;
|
||||
|
||||
|
||||
@@ -149,6 +151,10 @@ void Cpu_session_component::kill_thread(Thread_capability thread_cap)
|
||||
}
|
||||
}
|
||||
|
||||
void Cpu_session_component::migrate_thread(Thread_capability thread_cap, Affinity::Location loc)
|
||||
{
|
||||
_thread_ep.apply(thread_cap, [&] (Cpu_thread_component *t) { t->affinity(_thread_affinity(loc)); });
|
||||
}
|
||||
|
||||
void Cpu_session_component::exception_sigh(Signal_context_capability sigh)
|
||||
{
|
||||
@@ -170,6 +176,10 @@ Affinity::Space Cpu_session_component::affinity_space() const
|
||||
return Affinity::Space(_location.width(), _location.height());
|
||||
}
|
||||
|
||||
void Cpu_session_component::move(const Affinity::Location destination)
|
||||
{
|
||||
_location = destination;
|
||||
}
|
||||
|
||||
Dataspace_capability Cpu_session_component::trace_control()
|
||||
{
|
||||
|
||||
@@ -149,11 +149,16 @@ class Core::Account
|
||||
|
||||
/* make sure to stay within the initial limit */
|
||||
if (amount.value > _transferrable_quota().value)
|
||||
{
|
||||
Genode::log("Limit exceeded : ", _label);
|
||||
throw Limit_exceeded();
|
||||
}
|
||||
|
||||
/* downgrade from this account */
|
||||
if (!_quota_guard.try_downgrade(amount))
|
||||
throw Limit_exceeded();
|
||||
/* downgrade from this account */
|
||||
if (!_quota_guard.try_downgrade(amount)) {
|
||||
Genode::log("Limit exceeded: ", _label);
|
||||
throw Limit_exceeded();
|
||||
}
|
||||
}
|
||||
|
||||
/* credit to 'other' */
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/env.h>
|
||||
#include <topo_session/capability.h>
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/globals.h>
|
||||
@@ -92,6 +93,8 @@ class Core::Core_env : public Noncopyable
|
||||
Pd_session *pd_session() { return &_pd_session; }
|
||||
Cpu_session *cpu_session() { ASSERT_NEVER_CALLED; }
|
||||
Cpu_session_capability cpu_session_cap() { ASSERT_NEVER_CALLED; }
|
||||
Topo_session *topo_session() override { ASSERT_NEVER_CALLED; }
|
||||
Topo_session_capability topo_session_cap() override { ASSERT_NEVER_CALLED; }
|
||||
Pd_session_capability pd_session_cap() { return _pd_session.cap(); }
|
||||
};
|
||||
|
||||
|
||||
@@ -33,6 +33,10 @@ namespace Core {
|
||||
|
||||
struct Core::Core_log
|
||||
{
|
||||
void acquire();
|
||||
|
||||
void release();
|
||||
|
||||
void out(char const c);
|
||||
|
||||
void output(char const * str);
|
||||
|
||||
@@ -169,8 +169,10 @@ class Core::Cpu_session_component : public Session_object<Cpu_session>,
|
||||
Create_thread_result create_thread(Capability<Pd_session>, Name const &,
|
||||
Affinity::Location, Weight, addr_t) override;
|
||||
void kill_thread(Thread_capability) override;
|
||||
void migrate_thread(Thread_capability, Affinity::Location) override;
|
||||
void exception_sigh(Signal_context_capability) override;
|
||||
Affinity::Space affinity_space() const override;
|
||||
void move(const Affinity::Location) override;
|
||||
Dataspace_capability trace_control() override;
|
||||
int ref_account(Cpu_session_capability c) override;
|
||||
int transfer_quota(Cpu_session_capability, size_t) override;
|
||||
|
||||
@@ -174,6 +174,7 @@ class Core::Cpu_thread_component : public Rpc_object<Cpu_thread>,
|
||||
|
||||
_address_space_region_map.add_client(_rm_client);
|
||||
_platform_thread.pager(_rm_client);
|
||||
_platform_thread.affinity(location);
|
||||
_trace_sources.insert(&_trace_source);
|
||||
}
|
||||
|
||||
|
||||
@@ -340,6 +340,8 @@ class Core::Pd_session_component : public Session_object<Pd_session>
|
||||
|
||||
Alloc_result try_alloc(size_t, Cache) override;
|
||||
|
||||
Alloc_result try_alloc(size_t, Ram_allocator::Numa_id, Cache) override;
|
||||
|
||||
void free(Ram_dataspace_capability) override;
|
||||
|
||||
size_t dataspace_size(Ram_dataspace_capability) const override;
|
||||
@@ -372,6 +374,13 @@ class Core::Pd_session_component : public Session_object<Pd_session>
|
||||
addr_t dma_addr(Ram_dataspace_capability) override;
|
||||
|
||||
Attach_dma_result attach_dma(Dataspace_capability, addr_t) override;
|
||||
|
||||
/******************************************
|
||||
** Support for EalánOS cells **
|
||||
******************************************/
|
||||
void create_cell(long prioritiy, const Affinity::Location &loc) override;
|
||||
|
||||
void update_cell(const Affinity::Location &loc) override;
|
||||
};
|
||||
|
||||
#endif /* _CORE__INCLUDE__PD_SESSION_COMPONENT_H_ */
|
||||
|
||||
@@ -45,7 +45,7 @@ class Core::Ram_dataspace_factory : public Ram_allocator,
|
||||
Rpc_entrypoint &_ep;
|
||||
|
||||
Range_allocator &_phys_alloc;
|
||||
Phys_range const _phys_range;
|
||||
Phys_range _phys_range;
|
||||
|
||||
|
||||
/*
|
||||
@@ -82,6 +82,11 @@ class Core::Ram_dataspace_factory : public Ram_allocator,
|
||||
*/
|
||||
void _clear_ds(Dataspace_component &ds);
|
||||
|
||||
/**
|
||||
* Remove core-local mappings of dataspace
|
||||
*/
|
||||
void _unmap_ds_from_core(Dataspace_component &ds);
|
||||
|
||||
public:
|
||||
|
||||
Ram_dataspace_factory(Rpc_entrypoint &ep,
|
||||
@@ -109,6 +114,7 @@ class Core::Ram_dataspace_factory : public Ram_allocator,
|
||||
*****************************/
|
||||
|
||||
Alloc_result try_alloc(size_t, Cache) override;
|
||||
Alloc_result try_alloc(size_t, Ram_allocator::Numa_id, Cache) override;
|
||||
void free(Ram_dataspace_capability) override;
|
||||
size_t dataspace_size(Ram_dataspace_capability ds) const override;
|
||||
};
|
||||
|
||||
@@ -41,6 +41,12 @@ class Core::Synced_ram_allocator : public Ram_allocator
|
||||
Mutex::Guard mutex_guard(_mutex);
|
||||
return _alloc.try_alloc(size, cache);
|
||||
}
|
||||
|
||||
Alloc_result try_alloc(size_t size, Ram_allocator::Numa_id numa_id, Cache cache) override
|
||||
{
|
||||
Mutex::Guard mutex_guard(_mutex);
|
||||
return _alloc.try_alloc(size, numa_id, cache);
|
||||
}
|
||||
|
||||
void free(Ram_dataspace_capability ds) override
|
||||
{
|
||||
|
||||
71
repos/base/src/core/include/topo_root.h
Normal file
71
repos/base/src/core/include/topo_root.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* \brief Topology service root component
|
||||
* \author Michael Müller
|
||||
* \date 2022-10-06
|
||||
*
|
||||
* A topology session stores the component's view on the hardware topology, i.e. it's location within the NUMA topology.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is part of EalánOS which is based on the Genode OS framework
|
||||
* released under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <root/component.h>
|
||||
|
||||
#include <topo_session_component.h>
|
||||
|
||||
#include <base/log.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
class Topo_root : public Root_component<Topo_session_component>
|
||||
{
|
||||
private:
|
||||
Ram_allocator &_ram_alloc;
|
||||
Region_map &_local_rm;
|
||||
|
||||
protected:
|
||||
|
||||
Topo_session_component *_create_session(char const *args, Affinity const &affinity) override {
|
||||
size_t ram_quota = Arg_string::find_arg(args, "ram_quota").ulong_value(0);
|
||||
|
||||
if (ram_quota < Trace::Control_area::SIZE)
|
||||
throw Insufficient_ram_quota();
|
||||
|
||||
if (!affinity.valid()) {
|
||||
log("Location ", affinity.location(), " not within space ", affinity.space());
|
||||
throw Service_denied();
|
||||
}
|
||||
|
||||
return new (md_alloc())
|
||||
Topo_session_component(*this->ep(),
|
||||
session_resources_from_args(args),
|
||||
session_label_from_args(args),
|
||||
session_diag_from_args(args),
|
||||
_ram_alloc, _local_rm,
|
||||
const_cast<Affinity&>(affinity));
|
||||
}
|
||||
|
||||
void _upgrade_session(Topo_session_component *topo, const char *args) override
|
||||
{
|
||||
topo->upgrade(ram_quota_from_args(args));
|
||||
topo->upgrade(cap_quota_from_args(args));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Topo_root(Ram_allocator &ram_alloc,
|
||||
Region_map &local_rm,
|
||||
Rpc_entrypoint &session_ep,
|
||||
Allocator &md_alloc)
|
||||
:
|
||||
Root_component<Topo_session_component>(&session_ep, &md_alloc),
|
||||
_ram_alloc(ram_alloc), _local_rm(local_rm)
|
||||
{ }
|
||||
};
|
||||
}
|
||||
86
repos/base/src/core/include/topo_session_component.h
Normal file
86
repos/base/src/core/include/topo_session_component.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* \brief Topology session interface
|
||||
* \author Michael Müller
|
||||
* \date 2022-10-06
|
||||
*
|
||||
* A topology session stores the component's view on the hardware topology, i.e. it's location within the NUMA topology.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is part of EalánOS which is based on the Genode OS framework
|
||||
* released under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/session_object.h>
|
||||
#include <base/affinity.h>
|
||||
#include <base/heap.h>
|
||||
#include <topo_session/topo_session.h>
|
||||
#include <platform.h>
|
||||
#include <topo_session/node.h>
|
||||
|
||||
namespace Genode {
|
||||
class Topo_session_component;
|
||||
}
|
||||
|
||||
class Genode::Topo_session_component : public Session_object<Topo_session>
|
||||
{
|
||||
private:
|
||||
Genode::Affinity _affinity;
|
||||
Sliced_heap _md_alloc;
|
||||
|
||||
Topology::Numa_region _node_affinities[Genode::Platform::MAX_SUPPORTED_CPUS][Genode::Platform::MAX_SUPPORTED_CPUS];
|
||||
unsigned _node_count;
|
||||
Topology::Numa_region _nodes[64];
|
||||
|
||||
public:
|
||||
Topo_session_component(Rpc_entrypoint &session_ep,
|
||||
Resources const &resources,
|
||||
Label const &label,
|
||||
Diag const &diag,
|
||||
Ram_allocator &ram_alloc,
|
||||
Region_map &local_rm,
|
||||
Affinity affinity
|
||||
);
|
||||
|
||||
void construct();
|
||||
|
||||
/**
|
||||
* @brief Topology session interface
|
||||
*/
|
||||
|
||||
Topology::Numa_region node_affinity_of(Affinity::Location const &loc) override
|
||||
{
|
||||
return _node_affinities[loc.xpos()][loc.ypos()];
|
||||
}
|
||||
|
||||
Topology::Numa_region node_at_id(unsigned numa_id) override
|
||||
{
|
||||
return _nodes[numa_id];
|
||||
}
|
||||
|
||||
unsigned node_count() override
|
||||
{
|
||||
return _node_count;
|
||||
}
|
||||
|
||||
void reconstruct(Affinity affinity) override
|
||||
{
|
||||
_affinity = affinity;
|
||||
construct();
|
||||
}
|
||||
|
||||
unsigned phys_id(const Affinity::Location &loc) override
|
||||
{
|
||||
return platform_specific().kernel_cpu_id(loc);
|
||||
}
|
||||
|
||||
Affinity::Space const global_affinity_space() override
|
||||
{
|
||||
return platform_specific().affinity_space();
|
||||
}
|
||||
};
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <io_mem_root.h>
|
||||
#include <irq_root.h>
|
||||
#include <trace/root.h>
|
||||
#include <topo_root.h>
|
||||
#include <platform_services.h>
|
||||
|
||||
using namespace Core;
|
||||
@@ -184,7 +185,7 @@ class Core_child : public Child_policy
|
||||
Pd_session &ref_pd() override { return _core_pd; }
|
||||
Pd_session_capability ref_pd_cap() const override { return _core_pd_cap; }
|
||||
|
||||
size_t session_alloc_batch_size() const override { return 128; }
|
||||
size_t session_alloc_batch_size() const override { return 2*128; }
|
||||
|
||||
Id_space<Parent::Server> &server_id_space() override { return _server_ids; }
|
||||
};
|
||||
@@ -278,6 +279,7 @@ void Genode::bootstrap_component(Genode::Platform &)
|
||||
platform().irq_alloc(), sliced_heap);
|
||||
static Trace_root trace_root (core_ram_alloc, local_rm, ep, sliced_heap,
|
||||
Core::Trace::sources(), trace_policies);
|
||||
static Topo_root topo_root(core_ram_alloc, local_rm, ep, sliced_heap);
|
||||
|
||||
static Core_service<Rom_session_component> rom_service (services, rom_root);
|
||||
static Core_service<Rm_session_component> rm_service (services, rm_root);
|
||||
@@ -287,6 +289,7 @@ void Genode::bootstrap_component(Genode::Platform &)
|
||||
static Core_service<Io_mem_session_component> io_mem_service (services, io_mem_root);
|
||||
static Core_service<Irq_session_component> irq_service (services, irq_root);
|
||||
static Core_service<Trace_session_component> trace_service (services, trace_root);
|
||||
static Core_service<Topo_session_component> topo_service(services, topo_root);
|
||||
|
||||
/* make platform-specific services known to service pool */
|
||||
platform_add_local_services(ep, sliced_heap, services, Core::Trace::sources(), core_ram_alloc);
|
||||
@@ -294,7 +297,7 @@ void Genode::bootstrap_component(Genode::Platform &)
|
||||
size_t const avail_ram_quota = core_pd.avail_ram().value;
|
||||
size_t const avail_cap_quota = core_pd.avail_caps().value;
|
||||
|
||||
size_t const preserved_ram_quota = 224*1024;
|
||||
size_t const preserved_ram_quota = 224*1024+(1<<20);
|
||||
size_t const preserved_cap_quota = 1000;
|
||||
|
||||
if (avail_ram_quota < preserved_ram_quota) {
|
||||
|
||||
@@ -71,6 +71,58 @@ Pd_session_component::try_alloc(size_t ds_size, Cache cache)
|
||||
);
|
||||
}
|
||||
|
||||
Ram_allocator::Alloc_result
|
||||
Pd_session_component::try_alloc(size_t ds_size, Ram_allocator::Numa_id numa_id, Cache cache)
|
||||
{
|
||||
/* zero-sized dataspaces are not allowed */
|
||||
if (!ds_size)
|
||||
return Alloc_error::DENIED;
|
||||
|
||||
/* dataspace allocation granularity is page size */
|
||||
ds_size = align_addr(ds_size, 12);
|
||||
|
||||
using Result = Ram_allocator::Alloc_result;
|
||||
using Reservation = Genode::Reservation;
|
||||
|
||||
/* track quota use */
|
||||
return _ram_quota_guard().with_reservation<Result>(Ram_quota{ds_size},
|
||||
|
||||
[&] (Reservation &ram_reservation) -> Result {
|
||||
|
||||
/*
|
||||
* In the worst case, we need to allocate a new slab block for
|
||||
* the meta data of the dataspace to be created. Therefore, we
|
||||
* temporarily withdraw the slab block size here to trigger an
|
||||
* exception if the account does not have enough room for the meta
|
||||
* data.
|
||||
*/
|
||||
Ram_quota const overhead { Ram_dataspace_factory::SLAB_BLOCK_SIZE };
|
||||
|
||||
if (!_ram_quota_guard().have_avail(overhead)) {
|
||||
ram_reservation.cancel();
|
||||
return Ram_allocator::Alloc_error::OUT_OF_RAM;
|
||||
}
|
||||
|
||||
/*
|
||||
* Each dataspace is an RPC object and thereby consumes a
|
||||
* capability.
|
||||
*/
|
||||
return _cap_quota_guard().with_reservation<Result>(Cap_quota{1},
|
||||
|
||||
[&] (Genode::Reservation &) -> Result {
|
||||
return _ram_ds_factory.try_alloc(ds_size, numa_id, cache);
|
||||
},
|
||||
[&] () -> Result {
|
||||
ram_reservation.cancel();
|
||||
return Ram_allocator::Alloc_error::OUT_OF_CAPS;
|
||||
}
|
||||
);
|
||||
},
|
||||
[&] () -> Result {
|
||||
return Ram_allocator::Alloc_error::OUT_OF_RAM;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void Pd_session_component::free(Ram_dataspace_capability ds_cap)
|
||||
{
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
|
||||
/* core includes */
|
||||
#include <ram_dataspace_factory.h>
|
||||
#include <platform_generic.h>
|
||||
#include <platform.h>
|
||||
|
||||
using namespace Core;
|
||||
|
||||
@@ -126,6 +128,7 @@ Ram_dataspace_factory::try_alloc(size_t ds_size, Cache cache)
|
||||
Dataspace_component &ds = *ds_ptr;
|
||||
|
||||
/* create native shared memory representation of dataspace */
|
||||
#ifdef ZERO_AT_ALLOC
|
||||
try { _export_ram_ds(ds); }
|
||||
catch (Core_virtual_memory_exhausted) {
|
||||
warning("could not export RAM dataspace of size ", ds.size());
|
||||
@@ -140,8 +143,8 @@ Ram_dataspace_factory::try_alloc(size_t ds_size, Cache cache)
|
||||
* function must also make sure to flush all cache lines related to the
|
||||
* address range used by the dataspace.
|
||||
*/
|
||||
_clear_ds(ds);
|
||||
|
||||
_unmap_ds_from_core(ds);
|
||||
#endif
|
||||
Dataspace_capability ds_cap = _ep.manage(&ds);
|
||||
|
||||
phys_alloc_guard.keep = true;
|
||||
@@ -149,6 +152,14 @@ Ram_dataspace_factory::try_alloc(size_t ds_size, Cache cache)
|
||||
return static_cap_cast<Ram_dataspace>(ds_cap);
|
||||
}
|
||||
|
||||
Ram_allocator::Alloc_result Ram_dataspace_factory::try_alloc(size_t size, Ram_allocator::Numa_id numa_id, Cache cached=CACHED)
|
||||
{
|
||||
Ram_dataspace_factory::Phys_range old = {_phys_range.start, _phys_range.end};
|
||||
_phys_range = {platform_specific().mem_range(numa_id).start, platform_specific().mem_range(numa_id).end};
|
||||
Ram_allocator::Alloc_result result = Ram_dataspace_factory::try_alloc(size, cached);
|
||||
_phys_range = {old.start, old.end};
|
||||
return result;
|
||||
}
|
||||
|
||||
void Ram_dataspace_factory::free(Ram_dataspace_capability ds_cap)
|
||||
{
|
||||
@@ -176,8 +187,25 @@ void Ram_dataspace_factory::free(Ram_dataspace_capability ds_cap)
|
||||
});
|
||||
|
||||
/* call dataspace destructor and free memory */
|
||||
if (ds)
|
||||
if (ds) {
|
||||
try { _export_ram_ds(*ds); }
|
||||
catch (Core_virtual_memory_exhausted) {
|
||||
warning("could not export RAM dataspace of size ", ds->size());
|
||||
|
||||
/* cleanup unneeded resources */
|
||||
destroy(_ds_slab, ds);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill new dataspaces with zeros. For non-cached RAM dataspaces, this
|
||||
* function must also make sure to flush all cache lines related to the
|
||||
* address range used by the dataspace.
|
||||
*/
|
||||
_clear_ds(*ds);
|
||||
_unmap_ds_from_core(*ds);
|
||||
destroy(_ds_slab, ds);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -132,6 +132,10 @@ struct Stack_area_ram_allocator : Ram_allocator
|
||||
Alloc_result try_alloc(size_t, Cache) override {
|
||||
return reinterpret_cap_cast<Ram_dataspace>(Native_capability()); }
|
||||
|
||||
Alloc_result try_alloc(size_t, Ram_allocator::Numa_id, Cache) override {
|
||||
return reinterpret_cap_cast<Ram_dataspace>(Native_capability()); }
|
||||
|
||||
|
||||
void free(Ram_dataspace_capability) override { }
|
||||
|
||||
size_t dataspace_size(Ram_dataspace_capability) const override { return 0; }
|
||||
|
||||
80
repos/base/src/core/topo_session_component.cc
Normal file
80
repos/base/src/core/topo_session_component.cc
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* \brief Topology session interface
|
||||
* \author Michael Müller
|
||||
* \date 2022-10-06
|
||||
*
|
||||
* A topology session stores the component's view on the hardware topology, i.e. it's location within the NUMA topology.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is part of EalánOS which is based on the Genode OS framework
|
||||
* released under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
#include <topo_session_component.h>
|
||||
#include <platform_generic.h>
|
||||
#include <platform.h>
|
||||
#include <base/log.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
Topo_session_component::Topo_session_component(Rpc_entrypoint &session_ep,
|
||||
Resources const &resources,
|
||||
Label const &label,
|
||||
Diag const &diag,
|
||||
Ram_allocator &ram_alloc,
|
||||
Region_map &local_rm,
|
||||
Affinity affinity)
|
||||
: Session_object(session_ep, resources, label, diag),
|
||||
_affinity(affinity),
|
||||
_md_alloc(ram_alloc, local_rm),
|
||||
_node_count(0)
|
||||
{
|
||||
construct();
|
||||
}
|
||||
|
||||
void Topo_session_component::construct()
|
||||
{
|
||||
Affinity::Location location = _affinity.location();
|
||||
const unsigned height = location.height();
|
||||
unsigned width = location.width();
|
||||
unsigned curr_node_id = 0;
|
||||
Topology::Numa_region *node_created = new (_md_alloc) Topology::Numa_region[64]();
|
||||
|
||||
//Genode::log("[", label(), "] Creating new topology model of size ", width, "x", height);
|
||||
|
||||
for (unsigned x = 0; x < width; x++)
|
||||
{
|
||||
for (unsigned y = 0; y < height; y++)
|
||||
{
|
||||
/* Map component's affinity matrix to its position in the affinity space.
|
||||
* In order to get the correct physical CPU id for a coordinate in the affinity matrix of a component,
|
||||
* we need the global coordination for it relative to the whole affinity space.
|
||||
* But, every component's maintains a local view on its affinity matrix starting by (0,0), since
|
||||
* affinity locations can have arbitrary coordinates in the affinity space, we need to transpose the
|
||||
* component's affinity matrix to the global view of the affinity space. */
|
||||
Affinity::Location loc = location.transpose(x, y);
|
||||
unsigned cpu_id = platform_specific().kernel_cpu_id(loc);
|
||||
unsigned native_id = platform_specific().domain_of_cpu(cpu_id);
|
||||
|
||||
//log("[", label(), "] CPU (", x, "x", y, ") is native CPU ", cpu_id, " on node ", native_id);
|
||||
|
||||
if (node_created[native_id].core_count() == 0)
|
||||
{
|
||||
_nodes[curr_node_id] = _node_affinities[x][y] = Topology::Numa_region(curr_node_id, native_id);
|
||||
_node_affinities[x][y].increment_core_count();
|
||||
node_created[native_id] = _node_affinities[x][y];
|
||||
//log("[", label(), "] Found new native NUMA region ", native_id, " for CPU (", x, "x", y, ")");
|
||||
_node_count++;
|
||||
curr_node_id++;
|
||||
}
|
||||
else
|
||||
{
|
||||
(_node_affinities[x][y] = node_created[native_id]).increment_core_count();
|
||||
_nodes[curr_node_id].increment_core_count();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* \brief Topology session client that upgrades its session quota on demand
|
||||
* \author Michael Müller
|
||||
* \date 2022-10-06
|
||||
*
|
||||
* A topology session stores the component's view on the hardware topology, i.e. it's location within the NUMA topology.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Müller
|
||||
*
|
||||
* This file is part of EalánOS which is based on the Genode OS framework
|
||||
* released under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <util/retry.h>
|
||||
#include <topo_session/client.h>
|
||||
|
||||
#include <base/internal/upgradeable_client.h>
|
||||
|
||||
namespace Genode {
|
||||
struct Expanding_topo_session_client;
|
||||
}
|
||||
|
||||
struct Genode::Expanding_topo_session_client : Upgradeable_client<Genode::Topo_session_client>
|
||||
{
|
||||
Expanding_topo_session_client(Parent &parent, Genode::Topo_session_capability cap, Parent::Client::Id id)
|
||||
:
|
||||
Upgradeable_client<Genode::Topo_session_client>
|
||||
(parent, static_cap_cast<Genode::Topo_session_client::Rpc_interface>(cap), id)
|
||||
{ }
|
||||
|
||||
Topology::Numa_region node_affinity_of(Affinity::Location const &loc) override
|
||||
{
|
||||
return retry<Out_of_ram>(
|
||||
[&]()
|
||||
{
|
||||
return retry<Out_of_caps>(
|
||||
[&]()
|
||||
{
|
||||
return Topo_session_client::node_affinity_of(loc);
|
||||
},
|
||||
[&]()
|
||||
{ upgrade_caps(2); });
|
||||
},
|
||||
[&]()
|
||||
{ upgrade_ram(8 * 1024); });
|
||||
}
|
||||
};
|
||||
@@ -45,6 +45,15 @@ void Child::yield(Resource_args const &args)
|
||||
Signal_transmitter(_yield_sigh).submit();
|
||||
}
|
||||
|
||||
void Child::accept(Resource_args const &args)
|
||||
{
|
||||
Mutex::Guard guard{_resource_gain_mutex};
|
||||
|
||||
_gained_resources = args;
|
||||
|
||||
if (_resource_avail_sigh.valid())
|
||||
Signal_transmitter(_resource_avail_sigh).submit();
|
||||
}
|
||||
|
||||
void Child::notify_resource_avail() const
|
||||
{
|
||||
@@ -690,6 +699,12 @@ Parent::Resource_args Child::yield_request()
|
||||
return _yield_request_args;
|
||||
}
|
||||
|
||||
Parent::Resource_args Child::gained_resources()
|
||||
{
|
||||
Mutex::Guard guard(_resource_gain_mutex);
|
||||
|
||||
return _gained_resources;
|
||||
}
|
||||
|
||||
void Child::yield_response() { _policy.yield_response(); }
|
||||
|
||||
@@ -734,7 +749,7 @@ void Child::_try_construct_env_dependent_members()
|
||||
{
|
||||
/* check if the environment sessions are complete */
|
||||
if (!_pd.cap().valid() || !_cpu.cap().valid() || !_log.cap().valid()
|
||||
|| !_binary.cap().valid())
|
||||
|| !_binary.cap().valid() || !_topo.cap().valid())
|
||||
return;
|
||||
|
||||
/*
|
||||
@@ -803,6 +818,7 @@ void Child::initiate_env_sessions()
|
||||
_cpu .initiate();
|
||||
_log .initiate();
|
||||
_binary.initiate();
|
||||
_topo.initiate();
|
||||
|
||||
/*
|
||||
* Issue environment-session request for obtaining the linker binary. We
|
||||
@@ -885,6 +901,7 @@ void Child::close_all_sessions()
|
||||
* Issue close requests to the providers of the environment sessions,
|
||||
* which may be async services.
|
||||
*/
|
||||
_topo.close();
|
||||
_log.close();
|
||||
_binary.close();
|
||||
if (_linker.constructed())
|
||||
@@ -898,6 +915,7 @@ void Child::close_all_sessions()
|
||||
_discard_env_session(Env::log());
|
||||
_discard_env_session(Env::binary());
|
||||
_discard_env_session(Env::linker());
|
||||
_discard_env_session(Env::topo());
|
||||
|
||||
/*
|
||||
* Remove dynamically created sessions from the child's ID space.
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
/* base-internal includes */
|
||||
#include <base/internal/globals.h>
|
||||
#include <topo_session/capability.h>
|
||||
#include <base/internal/platform.h>
|
||||
|
||||
namespace Genode { struct Component_env; }
|
||||
@@ -86,6 +87,7 @@ struct Genode::Component_env : Env
|
||||
Region_map &rm() override { return _rm; }
|
||||
Pd_session &pd() override { return _pd; }
|
||||
Entrypoint &ep() override { return _ep; }
|
||||
Genode::Topo_session &topo() override { return *Genode::env_deprecated()->topo_session(); }
|
||||
|
||||
Cpu_session_capability cpu_session_cap() override { return _cpu_cap; }
|
||||
Pd_session_capability pd_session_cap() override { return _pd_cap; }
|
||||
|
||||
@@ -34,7 +34,8 @@ Id_space<Parent::Client> &Genode::env_session_id_space()
|
||||
cpu { dummy, id_space, Parent::Env::cpu() },
|
||||
log { dummy, id_space, Parent::Env::log() },
|
||||
binary { dummy, id_space, Parent::Env::binary() },
|
||||
linker { dummy, id_space, Parent::Env::linker() };
|
||||
linker { dummy, id_space, Parent::Env::linker() },
|
||||
topo { dummy, id_space, Parent::Env::topo() };
|
||||
|
||||
return id_space;
|
||||
}
|
||||
|
||||
348
repos/base/src/lib/base/regional_heap.cc
Normal file
348
repos/base/src/lib/base/regional_heap.cc
Normal file
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
* \brief Implementation of Genode heap partition
|
||||
* \author Norman Feske
|
||||
* \date 2006-05-17
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2006-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#include <util/construct_at.h>
|
||||
#include <base/env.h>
|
||||
#include <base/log.h>
|
||||
#include <base/regional_heap.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
enum {
|
||||
MIN_CHUNK_SIZE = 4*1024, /* in machine words */
|
||||
MAX_CHUNK_SIZE = 256*1024,
|
||||
/*
|
||||
* Allocation sizes >= this value are considered as big
|
||||
* allocations, which get their own dataspace. In contrast
|
||||
* to smaller allocations, this memory is released to
|
||||
* the RAM session when 'free()' is called.
|
||||
*/
|
||||
BIG_ALLOCATION_THRESHOLD = 64*1024 /* in bytes */
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
void Regional_heap::Dataspace_pool::remove_and_free(Dataspace &ds)
|
||||
{
|
||||
/*
|
||||
* read dataspace capability and modify _ds_list before detaching
|
||||
* possible backing store for Dataspace - we rely on LIFO list
|
||||
* manipulation here!
|
||||
*/
|
||||
|
||||
Ram_dataspace_capability ds_cap = ds.cap;
|
||||
void *ds_local_addr = ds.local_addr;
|
||||
|
||||
remove(&ds);
|
||||
|
||||
/*
|
||||
* Call 'Dataspace' destructor to properly release the RAM dataspace
|
||||
* capabilities. Note that we don't free the 'Dataspace' object at the
|
||||
* local allocator because this is already done by the 'Regional_heap'
|
||||
* destructor prior executing the 'Dataspace_pool' destructor.
|
||||
*/
|
||||
ds.~Dataspace();
|
||||
|
||||
region_map->detach(ds_local_addr);
|
||||
ram_alloc->free(ds_cap);
|
||||
}
|
||||
|
||||
|
||||
Regional_heap::Dataspace_pool::~Dataspace_pool()
|
||||
{
|
||||
/* free all ram_dataspaces */
|
||||
for (Dataspace *ds; (ds = first()); )
|
||||
remove_and_free(*ds);
|
||||
}
|
||||
|
||||
|
||||
int Regional_heap::quota_limit(size_t new_quota_limit)
|
||||
{
|
||||
if (new_quota_limit < _quota_used) return -1;
|
||||
_quota_limit = new_quota_limit;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Regional_heap::Alloc_ds_result
|
||||
Regional_heap::_allocate_dataspace(size_t size, bool enforce_separate_metadata)
|
||||
{
|
||||
using Result = Alloc_ds_result;
|
||||
|
||||
return _ds_pool.ram_alloc->try_alloc(size, _numa_id).convert<Result>(
|
||||
|
||||
[&] (Ram_dataspace_capability ds_cap) -> Result {
|
||||
|
||||
struct Alloc_guard
|
||||
{
|
||||
Ram_allocator &ram;
|
||||
Ram_dataspace_capability ds;
|
||||
bool keep = false;
|
||||
|
||||
Alloc_guard(Ram_allocator &ram, Ram_dataspace_capability ds)
|
||||
: ram(ram), ds(ds) { }
|
||||
|
||||
~Alloc_guard() { if (!keep) ram.free(ds); }
|
||||
|
||||
} alloc_guard(*_ds_pool.ram_alloc, ds_cap);
|
||||
|
||||
struct Attach_guard
|
||||
{
|
||||
Region_map &rm;
|
||||
struct { void *ptr = nullptr; };
|
||||
bool keep = false;
|
||||
|
||||
Attach_guard(Region_map &rm) : rm(rm) { }
|
||||
|
||||
~Attach_guard() { if (!keep && ptr) rm.detach(ptr); }
|
||||
|
||||
} attach_guard(*_ds_pool.region_map);
|
||||
|
||||
try {
|
||||
attach_guard.ptr = _ds_pool.region_map->attach(ds_cap);
|
||||
}
|
||||
catch (Out_of_ram) { return Alloc_error::OUT_OF_RAM; }
|
||||
catch (Out_of_caps) { return Alloc_error::OUT_OF_CAPS; }
|
||||
catch (Region_map::Invalid_dataspace) { return Alloc_error::DENIED; }
|
||||
catch (Region_map::Region_conflict) { return Alloc_error::DENIED; }
|
||||
|
||||
Alloc_result metadata = Alloc_error::DENIED;
|
||||
|
||||
/* allocate the 'Dataspace' structure */
|
||||
if (enforce_separate_metadata) {
|
||||
metadata = _unsynchronized_alloc(sizeof(Regional_heap::Dataspace));
|
||||
|
||||
} else {
|
||||
|
||||
/* add new local address range to our local allocator */
|
||||
_alloc->add_range((addr_t)attach_guard.ptr, size).with_result(
|
||||
[&] (Range_allocator::Range_ok) {
|
||||
metadata = _alloc->alloc_aligned(sizeof(Regional_heap::Dataspace), log2(64U)); },
|
||||
[&] (Alloc_error error) {
|
||||
metadata = error; });
|
||||
}
|
||||
|
||||
return metadata.convert<Result>(
|
||||
[&] (void *md_ptr) -> Result {
|
||||
Dataspace &ds = *construct_at<Dataspace>(md_ptr, ds_cap,
|
||||
attach_guard.ptr, size);
|
||||
_ds_pool.insert(&ds);
|
||||
alloc_guard.keep = attach_guard.keep = true;
|
||||
return &ds;
|
||||
},
|
||||
[&] (Alloc_error error) {
|
||||
return error; });
|
||||
},
|
||||
[&] (Alloc_error error) {
|
||||
return error; });
|
||||
}
|
||||
|
||||
|
||||
Allocator::Alloc_result Regional_heap::_try_local_alloc(size_t size)
|
||||
{
|
||||
return _alloc->alloc_aligned(size, log2(64U)).convert<Alloc_result>(
|
||||
|
||||
[&] (void *ptr) {
|
||||
_quota_used += size;
|
||||
return ptr; },
|
||||
|
||||
[&] (Alloc_error error) {
|
||||
return error; });
|
||||
}
|
||||
|
||||
|
||||
Allocator::Alloc_result Regional_heap::_unsynchronized_alloc(size_t size)
|
||||
{
|
||||
if (size >= BIG_ALLOCATION_THRESHOLD) {
|
||||
|
||||
/*
|
||||
* big allocation
|
||||
*
|
||||
* In this case, we allocate one dataspace without any meta data in it
|
||||
* and return its local address without going through the allocator.
|
||||
*/
|
||||
|
||||
/* align to 4K page */
|
||||
size_t const dataspace_size = align_addr(size, 12);
|
||||
|
||||
return _allocate_dataspace(dataspace_size, true).convert<Alloc_result>(
|
||||
|
||||
[&] (Dataspace *ds_ptr) {
|
||||
_quota_used += ds_ptr->size;
|
||||
return ds_ptr->local_addr; },
|
||||
|
||||
[&] (Alloc_error error) {
|
||||
return error; });
|
||||
}
|
||||
|
||||
/* try allocation at our local allocator */
|
||||
{
|
||||
Alloc_result result = _try_local_alloc(size);
|
||||
if (result.ok())
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t dataspace_size = size
|
||||
+ Allocator_avl::slab_block_size()
|
||||
+ sizeof(Regional_heap::Dataspace);
|
||||
/* align to 4K page */
|
||||
dataspace_size = align_addr(dataspace_size, 12);
|
||||
|
||||
/*
|
||||
* '_chunk_size' is a multiple of 4K, so 'dataspace_size' becomes
|
||||
* 4K-aligned, too.
|
||||
*/
|
||||
size_t const request_size = _chunk_size * sizeof(umword_t);
|
||||
|
||||
Alloc_ds_result result = Alloc_error::DENIED;
|
||||
|
||||
if (dataspace_size < request_size) {
|
||||
|
||||
result = _allocate_dataspace(request_size, false);
|
||||
if (result.ok()) {
|
||||
|
||||
/*
|
||||
* Exponentially increase chunk size with each allocated chunk until
|
||||
* we hit 'MAX_CHUNK_SIZE'.
|
||||
*/
|
||||
_chunk_size = min(2*_chunk_size, (size_t)MAX_CHUNK_SIZE);
|
||||
}
|
||||
} else {
|
||||
result = _allocate_dataspace(dataspace_size, false);
|
||||
}
|
||||
|
||||
if (result.failed())
|
||||
return result.convert<Alloc_result>(
|
||||
[&] (Dataspace *) { return Alloc_error::DENIED; },
|
||||
[&] (Alloc_error error) { return error; });
|
||||
|
||||
/* allocate originally requested block */
|
||||
return _try_local_alloc(size);
|
||||
}
|
||||
|
||||
|
||||
Allocator::Alloc_result Regional_heap::try_alloc(size_t size)
|
||||
{
|
||||
|
||||
if (size == 0)
|
||||
error("attempt to allocate zero-size block from heap");
|
||||
|
||||
/* serialize access of heap functions */
|
||||
Mutex::Guard guard(_mutex);
|
||||
|
||||
/* check requested allocation against quota limit */
|
||||
if (size + _quota_used > _quota_limit)
|
||||
return Alloc_error::DENIED;
|
||||
|
||||
return _unsynchronized_alloc(size);
|
||||
}
|
||||
|
||||
|
||||
void Regional_heap::free(void *addr, size_t)
|
||||
{
|
||||
/* serialize access of heap functions */
|
||||
Mutex::Guard guard(_mutex);
|
||||
|
||||
using Size_at_error = Allocator_avl::Size_at_error;
|
||||
|
||||
Allocator_avl::Size_at_result size_at_result = _alloc->size_at(addr);
|
||||
|
||||
if (size_at_result.ok()) {
|
||||
/* forward request to our local allocator */
|
||||
size_at_result.with_result(
|
||||
[&] (size_t size) {
|
||||
/* forward request to our local allocator */
|
||||
_alloc->free(addr, size);
|
||||
_quota_used -= size;
|
||||
},
|
||||
[&] (Size_at_error) { });
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (size_at_result == Size_at_error::MISMATCHING_ADDR) {
|
||||
/* address was found in local allocator but is not a block start address */
|
||||
error("heap could not free memory block: given address ", addr,
|
||||
" is not a block start adress");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Block could not be found in local allocator. So it is either a big
|
||||
* allocation or invalid address.
|
||||
*/
|
||||
|
||||
Regional_heap::Dataspace *ds = nullptr;
|
||||
for (ds = _ds_pool.first(); ds; ds = ds->next())
|
||||
if (((addr_t)addr >= (addr_t)ds->local_addr) &&
|
||||
((addr_t)addr <= (addr_t)ds->local_addr + ds->size - 1))
|
||||
break;
|
||||
|
||||
if (!ds) {
|
||||
//warning("heap could not free memory block: invalid address");
|
||||
throw Region_map::Invalid_dataspace();
|
||||
return;
|
||||
}
|
||||
|
||||
_quota_used -= ds->size;
|
||||
|
||||
_ds_pool.remove_and_free(*ds);
|
||||
_alloc->free(ds);
|
||||
}
|
||||
|
||||
|
||||
Regional_heap::Regional_heap(Ram_allocator *ram_alloc,
|
||||
Region_map *region_map,
|
||||
Topology::Numa_region ®ion,
|
||||
size_t quota_limit,
|
||||
void *static_addr,
|
||||
size_t static_size)
|
||||
:
|
||||
_alloc(nullptr),
|
||||
_ds_pool(ram_alloc, region_map),
|
||||
_quota_limit(quota_limit), _quota_used(0),
|
||||
_chunk_size(MIN_CHUNK_SIZE),
|
||||
_numa_id(region.native_id())
|
||||
{
|
||||
if (static_addr)
|
||||
_alloc->add_range((addr_t)static_addr, static_size);
|
||||
}
|
||||
|
||||
|
||||
Regional_heap::~Regional_heap()
|
||||
{
|
||||
/*
|
||||
* Revert allocations of heap-internal 'Dataspace' objects. Otherwise, the
|
||||
* subsequent destruction of the 'Allocator_avl' would detect those blocks
|
||||
* as dangling allocations.
|
||||
*
|
||||
* Since no new allocations can occur at the destruction time of the
|
||||
* 'Regional_heap', it is safe to release the 'Dataspace' objects at the allocator
|
||||
* yet still access them afterwards during the destruction of the
|
||||
* 'Allocator_avl'.
|
||||
*/
|
||||
for (Regional_heap::Dataspace *ds = _ds_pool.first(); ds; ds = ds->next())
|
||||
_alloc->free(ds, sizeof(Dataspace));
|
||||
|
||||
/*
|
||||
* Destruct 'Allocator_avl' before destructing the dataspace pool. This
|
||||
* order is important because some dataspaces of the dataspace pool are
|
||||
* used as backing store for the allocator's meta data. If we destroyed
|
||||
* the object pool before the allocator, the subsequent attempt to destruct
|
||||
* the allocator would access no-longer-present backing store.
|
||||
*/
|
||||
_alloc.destruct();
|
||||
}
|
||||
@@ -241,6 +241,11 @@ size_t Thread::stack_area_virtual_size()
|
||||
return Genode::stack_area_virtual_size();
|
||||
}
|
||||
|
||||
void Thread::pin(Affinity::Location &loc)
|
||||
{
|
||||
_cpu_session->migrate_thread(_thread_cap, loc);
|
||||
_affinity = loc;
|
||||
}
|
||||
|
||||
Thread::Thread(size_t weight, const char *name, size_t stack_size,
|
||||
Type type, Cpu_session *cpu_session, Affinity::Location affinity)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<service name="LOG"/>
|
||||
<service name="Timer"/>
|
||||
<service name="Uplink"/>
|
||||
<service name="TOPO"/>
|
||||
</parent-provides>
|
||||
|
||||
<default caps="100"/>
|
||||
@@ -18,8 +19,8 @@
|
||||
<service name="Nic">
|
||||
<default-policy> <child name="nic"/> </default-policy> </service>
|
||||
|
||||
<start name="acpi" caps="300">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<start name="acpi_drv" caps="300">
|
||||
<resource name="RAM" quantum="16M"/>
|
||||
<route>
|
||||
<service name="IO_MEM"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
@@ -27,12 +28,13 @@
|
||||
<service name="RM"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="TOPO"> <parent/> </service>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="report_rom">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<resource name="RAM" quantum="16M"/>
|
||||
<provides>
|
||||
<service name="ROM" />
|
||||
<service name="Report" />
|
||||
@@ -45,26 +47,28 @@
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="TOPO"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="pci_decode">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<resource name="RAM" quantum="16M"/>
|
||||
<route>
|
||||
<service name="Report"> <child name="report_rom"/> </service>
|
||||
<service name="ROM" label="system"> <child name="report_rom"/> </service>
|
||||
<service name="IO_MEM"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="TOPO"> <parent/> </service>
|
||||
<service name="RM"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="platform" caps="200" managing_system="yes">
|
||||
<resource name="RAM" quantum="3M"/>
|
||||
<start name="platform_drv" caps="200" managing_system="yes">
|
||||
<resource name="RAM" quantum="24M"/>
|
||||
<provides>
|
||||
<service name="Platform"/>
|
||||
<service name="Acpi"/>
|
||||
@@ -77,6 +81,7 @@
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="TOPO"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="Timer"> <parent/> </service>
|
||||
</route>
|
||||
@@ -85,32 +90,15 @@
|
||||
</config>
|
||||
</start>
|
||||
|
||||
<start name="mac_report_rom">
|
||||
<binary name="report_rom"/>
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<provides>
|
||||
<service name="ROM" />
|
||||
<service name="Report" />
|
||||
</provides>
|
||||
<config verbose="yes">
|
||||
<policy label="nic -> devices" report="nic -> devices"/>
|
||||
</config>
|
||||
<route>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
</route>
|
||||
</start>
|
||||
|
||||
<start name="nic" caps="250">
|
||||
<binary name="pc_nic"/>
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<start name="nic_drv" caps="200">
|
||||
<binary name="ipxe_nic_drv"/>
|
||||
<resource name="RAM" quantum="256M"/>
|
||||
<route>
|
||||
<service name="Platform"> <child name="platform"/> </service>
|
||||
<service name="ROM"> <parent/> </service>
|
||||
<service name="PD"> <parent/> </service>
|
||||
<service name="RM"> <parent/> </service>
|
||||
<service name="TOPO"> <parent/> </service>
|
||||
<service name="CPU"> <parent/> </service>
|
||||
<service name="LOG"> <parent/> </service>
|
||||
<service name="Timer"> <parent/> </service>
|
||||
|
||||
1
repos/libports/lib/import/import-libpfm4.mk
Normal file
1
repos/libports/lib/import/import-libpfm4.mk
Normal file
@@ -0,0 +1 @@
|
||||
INC_DIR += $(call select_from_ports,libpfm4)/include
|
||||
@@ -36,7 +36,7 @@ include $(call select_from_repositories,lib/import/import-libc.mk)
|
||||
CC_OPT += -D_GLIBCXX_HAVE_MBSTATE_T
|
||||
|
||||
# use compiler-builtin atomic operations
|
||||
CC_OPT += -D_GLIBCXX_ATOMIC_BUILTINS_4
|
||||
CC_OPT += -D_GLIBCXX_ATOMIC_BUILTINS_8 -D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
|
||||
|
||||
# No isinf isnan
|
||||
CC_OPT += -D_GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC
|
||||
|
||||
204
repos/libports/lib/mk/libpfm4.mk
Normal file
204
repos/libports/lib/mk/libpfm4.mk
Normal file
@@ -0,0 +1,204 @@
|
||||
LIBPFM4_DIR := $(call select_from_ports,libpfm4)/src/lib/libpfm4
|
||||
|
||||
CC_OPT += -D_REENTRANT -fvisibility=hidden
|
||||
|
||||
SRC_CC = $(LIBPFM4_DIR)/lib/pfmlib_common.c
|
||||
|
||||
# build libpfm only for x86_64 for now
|
||||
CONFIG_PFMLIB_ARCH_X86_64=y
|
||||
CONFIG_PFMLIB_ARCH_X86=y
|
||||
|
||||
CONFIG_PFMLIB_SHARED?=n
|
||||
CONFIG_PFMLIB_DEBUG?=y
|
||||
CONFIG_PFMLIB_NOPYTHON?=y
|
||||
|
||||
#
|
||||
# list all library support modules
|
||||
#
|
||||
ifeq ($(CONFIG_PFMLIB_ARCH_IA64),y)
|
||||
INCARCH = $(INC_IA64)
|
||||
#SRCS += pfmlib_gen_ia64.c pfmlib_itanium.c pfmlib_itanium2.c pfmlib_montecito.c
|
||||
CFLAGS += -DCONFIG_PFMLIB_ARCH_IA64
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PFMLIB_ARCH_X86),y)
|
||||
|
||||
ifeq ($(SYS),Linux)
|
||||
SRCS += pfmlib_intel_x86_perf_event.c pfmlib_amd64_perf_event.c \
|
||||
pfmlib_intel_netburst_perf_event.c \
|
||||
pfmlib_intel_snbep_unc_perf_event.c
|
||||
endif
|
||||
|
||||
INCARCH = $(INC_X86)
|
||||
SRCS += pfmlib_amd64.c pfmlib_intel_core.c pfmlib_intel_x86.c \
|
||||
pfmlib_intel_x86_arch.c pfmlib_intel_atom.c \
|
||||
pfmlib_intel_nhm_unc.c pfmlib_intel_nhm.c \
|
||||
pfmlib_intel_wsm.c \
|
||||
pfmlib_intel_snb.c pfmlib_intel_snb_unc.c \
|
||||
pfmlib_intel_ivb.c pfmlib_intel_ivb_unc.c \
|
||||
pfmlib_intel_hsw.c \
|
||||
pfmlib_intel_bdw.c \
|
||||
pfmlib_intel_skl.c \
|
||||
pfmlib_intel_icl.c \
|
||||
pfmlib_intel_spr.c \
|
||||
pfmlib_intel_rapl.c \
|
||||
pfmlib_intel_snbep_unc.c \
|
||||
pfmlib_intel_snbep_unc_cbo.c \
|
||||
pfmlib_intel_snbep_unc_ha.c \
|
||||
pfmlib_intel_snbep_unc_imc.c \
|
||||
pfmlib_intel_snbep_unc_pcu.c \
|
||||
pfmlib_intel_snbep_unc_qpi.c \
|
||||
pfmlib_intel_snbep_unc_ubo.c \
|
||||
pfmlib_intel_snbep_unc_r2pcie.c \
|
||||
pfmlib_intel_snbep_unc_r3qpi.c \
|
||||
pfmlib_intel_ivbep_unc_cbo.c \
|
||||
pfmlib_intel_ivbep_unc_ha.c \
|
||||
pfmlib_intel_ivbep_unc_imc.c \
|
||||
pfmlib_intel_ivbep_unc_pcu.c \
|
||||
pfmlib_intel_ivbep_unc_qpi.c \
|
||||
pfmlib_intel_ivbep_unc_ubo.c \
|
||||
pfmlib_intel_ivbep_unc_r2pcie.c \
|
||||
pfmlib_intel_ivbep_unc_r3qpi.c \
|
||||
pfmlib_intel_ivbep_unc_irp.c \
|
||||
pfmlib_intel_hswep_unc_cbo.c \
|
||||
pfmlib_intel_hswep_unc_ha.c \
|
||||
pfmlib_intel_hswep_unc_imc.c \
|
||||
pfmlib_intel_hswep_unc_pcu.c \
|
||||
pfmlib_intel_hswep_unc_qpi.c \
|
||||
pfmlib_intel_hswep_unc_ubo.c \
|
||||
pfmlib_intel_hswep_unc_r2pcie.c \
|
||||
pfmlib_intel_hswep_unc_r3qpi.c \
|
||||
pfmlib_intel_hswep_unc_irp.c \
|
||||
pfmlib_intel_hswep_unc_sbo.c \
|
||||
pfmlib_intel_bdx_unc_cbo.c \
|
||||
pfmlib_intel_bdx_unc_ubo.c \
|
||||
pfmlib_intel_bdx_unc_sbo.c \
|
||||
pfmlib_intel_bdx_unc_ha.c \
|
||||
pfmlib_intel_bdx_unc_imc.c \
|
||||
pfmlib_intel_bdx_unc_irp.c \
|
||||
pfmlib_intel_bdx_unc_pcu.c \
|
||||
pfmlib_intel_bdx_unc_qpi.c \
|
||||
pfmlib_intel_bdx_unc_r2pcie.c \
|
||||
pfmlib_intel_bdx_unc_r3qpi.c \
|
||||
pfmlib_intel_skx_unc_cha.c \
|
||||
pfmlib_intel_skx_unc_iio.c \
|
||||
pfmlib_intel_skx_unc_imc.c \
|
||||
pfmlib_intel_skx_unc_irp.c \
|
||||
pfmlib_intel_skx_unc_m2m.c \
|
||||
pfmlib_intel_skx_unc_m3upi.c \
|
||||
pfmlib_intel_skx_unc_pcu.c \
|
||||
pfmlib_intel_skx_unc_ubo.c \
|
||||
pfmlib_intel_skx_unc_upi.c \
|
||||
pfmlib_intel_knc.c \
|
||||
pfmlib_intel_slm.c \
|
||||
pfmlib_intel_tmt.c \
|
||||
pfmlib_intel_knl.c \
|
||||
pfmlib_intel_knl_unc_imc.c \
|
||||
pfmlib_intel_knl_unc_edc.c \
|
||||
pfmlib_intel_knl_unc_cha.c \
|
||||
pfmlib_intel_knl_unc_m2pcie.c \
|
||||
pfmlib_intel_glm.c \
|
||||
pfmlib_intel_netburst.c \
|
||||
pfmlib_amd64_k7.c pfmlib_amd64_k8.c pfmlib_amd64_fam10h.c \
|
||||
pfmlib_amd64_fam11h.c pfmlib_amd64_fam12h.c \
|
||||
pfmlib_amd64_fam14h.c pfmlib_amd64_fam15h.c \
|
||||
pfmlib_amd64_fam17h.c pfmlib_amd64_fam16h.c \
|
||||
pfmlib_amd64_fam19h.c pfmlib_amd64_rapl.c \
|
||||
pfmlib_amd64_fam19h_l3.c
|
||||
|
||||
CFLAGS += -DCONFIG_PFMLIB_ARCH_X86
|
||||
|
||||
ifeq ($(CONFIG_PFMLIB_ARCH_I386),y)
|
||||
SRCS += pfmlib_intel_coreduo.c pfmlib_intel_p6.c
|
||||
CFLAGS += -DCONFIG_PFMLIB_ARCH_I386
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PFMLIB_ARCH_X86_64),y)
|
||||
CFLAGS += -DCONFIG_PFMLIB_ARCH_X86_64
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PFMLIB_ARCH_POWERPC),y)
|
||||
|
||||
ifeq ($(SYS),Linux)
|
||||
SRCS += pfmlib_powerpc_perf_event.c
|
||||
endif
|
||||
|
||||
INCARCH = $(INC_POWERPC)
|
||||
SRCS += pfmlib_powerpc.c pfmlib_power4.c pfmlib_ppc970.c pfmlib_power5.c \
|
||||
pfmlib_power6.c pfmlib_power7.c pfmlib_torrent.c pfmlib_power8.c \
|
||||
pfmlib_power9.c pfmlib_powerpc_nest.c pfmlib_power10.c
|
||||
CFLAGS += -DCONFIG_PFMLIB_ARCH_POWERPC
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PFMLIB_ARCH_S390X),y)
|
||||
|
||||
ifeq ($(SYS),Linux)
|
||||
SRCS += pfmlib_s390x_perf_event.c
|
||||
endif
|
||||
|
||||
INCARCH = $(INC_S390X)
|
||||
SRCS += pfmlib_s390x_cpumf.c
|
||||
CFLAGS += -DCONFIG_PFMLIB_ARCH_S390X
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PFMLIB_ARCH_SPARC),y)
|
||||
|
||||
ifeq ($(SYS),Linux)
|
||||
SRCS += pfmlib_sparc_perf_event.c
|
||||
endif
|
||||
|
||||
INCARCH = $(INC_SPARC)
|
||||
SRCS += pfmlib_sparc.c pfmlib_sparc_ultra12.c pfmlib_sparc_ultra3.c pfmlib_sparc_ultra4.c pfmlib_sparc_niagara.c
|
||||
CFLAGS += -DCONFIG_PFMLIB_ARCH_SPARC
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PFMLIB_ARCH_ARM),y)
|
||||
|
||||
ifeq ($(SYS),Linux)
|
||||
SRCS += pfmlib_arm_perf_event.c
|
||||
endif
|
||||
|
||||
INCARCH = $(INC_ARM)
|
||||
SRCS += pfmlib_arm.c pfmlib_arm_armv7_pmuv1.c pfmlib_arm_armv6.c pfmlib_arm_armv8.c pfmlib_tx2_unc_perf_event.c pfmlib_kunpeng_unc_perf_event.c
|
||||
CFLAGS += -DCONFIG_PFMLIB_ARCH_ARM
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PFMLIB_ARCH_ARM64),y)
|
||||
|
||||
ifeq ($(SYS),Linux)
|
||||
SRCS += pfmlib_arm_perf_event.c
|
||||
endif
|
||||
|
||||
INCARCH = $(INC_ARM64)
|
||||
SRCS += pfmlib_arm.c pfmlib_arm_armv8.c pfmlib_tx2_unc_perf_event.c pfmlib_kunpeng_unc_perf_event.c
|
||||
CFLAGS += -DCONFIG_PFMLIB_ARCH_ARM64
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PFMLIB_ARCH_MIPS),y)
|
||||
|
||||
ifeq ($(SYS),Linux)
|
||||
SRCS += pfmlib_mips_perf_event.c
|
||||
endif
|
||||
|
||||
INCARCH = $(INC_MIPS)
|
||||
SRCS += pfmlib_mips.c pfmlib_mips_74k.c
|
||||
CFLAGS += -DCONFIG_PFMLIB_ARCH_MIPS
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_PFMLIB_CELL),y)
|
||||
INCARCH = $(INC_CELL)
|
||||
#SRCS += pfmlib_cell.c
|
||||
CFLAGS += -DCONFIG_PFMLIB_CELL
|
||||
endif
|
||||
|
||||
SRC_CC += $(addprefix $(LIBPFM4_DIR)/lib/,$(SRCS))
|
||||
vpath %.c $(LIBPFM4_DIR)/lib
|
||||
|
||||
CC_OPT += $(CFLAGS)
|
||||
|
||||
INC_DIR += $(LIBPFM4_DIR)/include $(LIBPFM4_DIR)/lib/events
|
||||
vpath %.h $(INC_DIR)
|
||||
|
||||
LIBS += base libm libc
|
||||
@@ -1,19 +1,27 @@
|
||||
MXTASKING_DIR := $(call select_from_ports,mxtasking)/src/lib/mxtasking
|
||||
GENODE_GCC_TOOLCHAIN_DIR := /usr/local/genode/tool/21.05
|
||||
|
||||
SRC_CC = $(shell find $(MXTASKING_DIR)/src/mx -name '*.cpp')
|
||||
vpath %.cpp $(MXTASKING_DIR)/src/mx
|
||||
|
||||
INC_DIR += $(MXTASKING_DIR)/src $(MXTASKING_DIR)/lib
|
||||
vpath %.h ${INC_DIR}
|
||||
INC_DIR += $(call select_from_repositories,src/lib/libc)
|
||||
INC_DIR += $(call select_from_repositories,src/lib/libc)/spec/x86_64
|
||||
|
||||
CC_OPT += -pedantic -Wall \
|
||||
CUSTOM_CXX = /usr/local/genode/tool/bin/clang++
|
||||
CUSTOM_CC = /usr/local/genode/tool/bin/clang
|
||||
|
||||
CC_OPT += --target=x86_64-genode --sysroot=/does/not/exist --gcc-toolchain=$(GENODE_GCC_TOOLCHAIN_DIR) -DCLANG_CXX11_ATOMICS
|
||||
CC_OPT += -std=c++20 -pedantic -Wall \
|
||||
-Wno-invalid-offsetof -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization \
|
||||
-Wformat=2 -Winit-self -Wmissing-declarations -Wmissing-include-dirs -Woverloaded-virtual \
|
||||
-Wredundant-decls -Wshadow -Wsign-promo -Wstrict-overflow=5 -Wswitch-default -Wundef \
|
||||
-Wno-unused -Wold-style-cast -Wno-uninitialized -O1 -g3 -fno-aligned-new
|
||||
-Wno-unused -Wold-style-cast -Wno-uninitialized -O2 -g
|
||||
|
||||
CC_OPT += $(addprefix -I ,$(INC_DIR))
|
||||
CC_OPT += $(addprefix -I ,$(INC_DIR))
|
||||
CC_CXX_WARN_STRICT =
|
||||
|
||||
LIBS += base libm libc stdcxx
|
||||
EXT_OBJECTS += /usr/local/genode/tool/lib/clang/14.0.5/lib/linux/libclang_rt.builtins-x86_64.a /usr/local/genode/tool/lib/libatomic.a
|
||||
#SHARED_LIB = yes
|
||||
|
||||
@@ -1183,8 +1183,12 @@ _ZTVSt8bad_cast D 40
|
||||
_ZTVSt9bad_alloc D 40
|
||||
_ZTVSt9exception D 40
|
||||
_ZTVSt9type_info D 64
|
||||
_ZdaPvSt11align_val_t W
|
||||
_ZdlPv W
|
||||
_ZdlPvm W
|
||||
_ZdlPvSt11align_val_t W
|
||||
_ZdlPvmSt11align_val_t W
|
||||
_ZnwmSt11align_val_t W
|
||||
__aeabi_atexit T
|
||||
__aeabi_unwind_cpp_pr0 T
|
||||
__aeabi_unwind_cpp_pr1 T
|
||||
|
||||
@@ -129,6 +129,7 @@ _ZNK11__gnu_debug16_Error_formatter8_M_errorEv T
|
||||
_ZNK11__gnu_debug19_Safe_iterator_base11_M_singularEv T
|
||||
_ZNK11__gnu_debug19_Safe_iterator_base14_M_can_compareERKS0_ T
|
||||
_ZNK11__gnu_debug25_Safe_local_iterator_base16_M_get_containerEv T
|
||||
_ZNSo6sentryD2Ev W
|
||||
_ZNKSt10bad_typeid4whatEv T
|
||||
_ZNKSt10error_code23default_error_conditionEv T
|
||||
_ZNKSt11logic_error4whatEv T
|
||||
@@ -136,6 +137,7 @@ _ZNKSt12bad_weak_ptr4whatEv T
|
||||
_ZNKSt12future_error4whatEv T
|
||||
_ZNKSt13random_device13_M_getentropyEv T
|
||||
_ZNKSt13runtime_error4whatEv T
|
||||
_ZNSt14basic_ofstreamIcSt11char_traitsIcEEC1ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode W
|
||||
_ZNKSt16bad_array_length4whatEv T
|
||||
_ZNKSt17bad_function_call4whatEv T
|
||||
_ZNKSt19__iosfail_type_info11__do_upcastEPKN10__cxxabiv117__class_type_infoEPPv T
|
||||
@@ -151,6 +153,7 @@ _ZNKSt6locale4nameEv T
|
||||
_ZNKSt6locale5facet11_M_cow_shimEPKNS_2idE T
|
||||
_ZNKSt6locale5facet11_M_sso_shimEPKNS_2idE T
|
||||
_ZNKSt6localeeqERKS_ T
|
||||
_ZNSt14basic_ifstreamIcSt11char_traitsIcEEC1ERKNSt7__cxx1112basic_stringIcS1_SaIcEEESt13_Ios_Openmode W
|
||||
_ZNKSt8__detail20_Prime_rehash_policy11_M_next_bktEm T
|
||||
_ZNKSt8__detail20_Prime_rehash_policy14_M_need_rehashEmmm T
|
||||
_ZNKSt8bad_cast4whatEv T
|
||||
@@ -320,6 +323,7 @@ _ZNSt13__future_base12_Result_baseD1Ev T
|
||||
_ZNSt13__future_base12_Result_baseD2Ev T
|
||||
_ZNSt13__future_base13_State_baseV211_Make_ready6_M_setEv T
|
||||
_ZNSt13__future_base13_State_baseV211_Make_ready6_S_runEPv T
|
||||
_ZNSt13basic_filebufIcSt11char_traitsIcEED2Ev W
|
||||
_ZNSt13basic_fstreamIcSt11char_traitsIcEE5closeEv T
|
||||
_ZNSt13random_device14_M_init_pretr1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE T
|
||||
_ZNSt13random_device14_M_init_pretr1ERKSs T
|
||||
|
||||
1
repos/libports/ports/libpfm4.hash
Normal file
1
repos/libports/ports/libpfm4.hash
Normal file
@@ -0,0 +1 @@
|
||||
b0ec09148c2be9f4a96203a3d2de4ebed6ce2da0
|
||||
13
repos/libports/ports/libpfm4.port
Normal file
13
repos/libports/ports/libpfm4.port
Normal file
@@ -0,0 +1,13 @@
|
||||
LICENSE := PD
|
||||
DOWNLOADS := libpfm4.git
|
||||
VERSION := git
|
||||
|
||||
URL(libpfm4) := https://github.com/wcohen/libpfm4.git
|
||||
REV(libpfm4) := 8aaaf1747e96031a47ed6bd9337ff61a21f8cc64
|
||||
DIR(libpfm4) := src/lib/libpfm4
|
||||
|
||||
DIRS += include
|
||||
DIRS += include/perfmon
|
||||
|
||||
DIR_CONTENT(include) += src/lib/libpfm4/include/perfmon
|
||||
DIR_CONTENT(include/perfmon) += src/lib/libpfm4/include/perfmon/*.h
|
||||
@@ -1 +1 @@
|
||||
dafcd5b6d7029c2626ead3b36f755a9fbd5acb13
|
||||
6074b9fabac4e9ad3df2ec7fb39bbae5b6ffa520
|
||||
|
||||
@@ -3,7 +3,7 @@ DOWNLOADS := mxtasking.git
|
||||
VERSION := git
|
||||
|
||||
URL(mxtasking) := https://github.com/mmueller41/mxtasking.git
|
||||
REV(mxtasking) := c81b9168104be5fceebf35674b867bb965e95d43
|
||||
REV(mxtasking) := yritys
|
||||
DIR(mxtasking) := src/lib/mxtasking
|
||||
|
||||
DIRS += include/mx/memory
|
||||
@@ -42,6 +42,12 @@ DIR_CONTENT(include/mx/util) += src/lib/mxtasking/src/mx/util/vector.h
|
||||
DIR_CONTENT(include/mx/util) += src/lib/mxtasking/src/mx/util/mpsc_queue.h
|
||||
DIR_CONTENT(include/mx/util) += src/lib/mxtasking/src/mx/util/queue.h
|
||||
DIR_CONTENT(include/mx/util) += src/lib/mxtasking/src/mx/util/random.h
|
||||
DIR_CONTENT(include/mx/util) += src/lib/mxtasking/src/mx/util/bits.h
|
||||
DIR_CONTENT(include/mx/util) += src/lib/mxtasking/src/mx/util/compiler.h
|
||||
DIR_CONTENT(include/mx/util) += src/lib/mxtasking/src/mx/util/atomic.h
|
||||
DIR_CONTENT(include/mx/util) += src/lib/mxtasking/src/mx/util/bit_alloc.h
|
||||
DIR_CONTENT(include/mx/util) += src/lib/mxtasking/src/mx/util/field_alloc.h
|
||||
DIR_CONTENT(include/mx/util) += src/lib/mxtasking/src/mx/util/util.h
|
||||
DIR_CONTENT(include/mx/system) += src/lib/mxtasking/src/mx/system/builtin.h
|
||||
DIR_CONTENT(include/mx/system) += src/lib/mxtasking/src/mx/system/cpuid.h
|
||||
DIR_CONTENT(include/mx/system) += src/lib/mxtasking/src/mx/system/cache.h
|
||||
|
||||
1
repos/libports/recipes/src/libpfm4/api
Normal file
1
repos/libports/recipes/src/libpfm4/api
Normal file
@@ -0,0 +1 @@
|
||||
libpfm4
|
||||
17
repos/libports/recipes/src/libpfm4/content.mk
Normal file
17
repos/libports/recipes/src/libpfm4/content.mk
Normal file
@@ -0,0 +1,17 @@
|
||||
MIRROR_FROM_REP_DIR := lib/mk/libpfm4.mk lib/import/import-libpfm4.mk
|
||||
|
||||
content: src/lib/libpfm4 COPYING $(MIRROR_FROM_REP_DIR)
|
||||
|
||||
PORT_DIR := $(call port_dir,$(REP_DIR)/ports/libpfm4)
|
||||
|
||||
src/lib/libpfm4:
|
||||
mkdir -p $@
|
||||
cp -r $(PORT_DIR)/src/lib/libpfm4/* $@
|
||||
rm -rf $@/.git
|
||||
echo "LIBS = libpfm4" > $@/target.mk
|
||||
|
||||
$(MIRROR_FROM_REP_DIR):
|
||||
$(mirror_from_rep_dir)
|
||||
|
||||
LICENSE:
|
||||
echo "libpfm license, see src/lib/libpfm4/COPYING" > $@
|
||||
3
repos/libports/recipes/src/libpfm4/used_api
Normal file
3
repos/libports/recipes/src/libpfm4/used_api
Normal file
@@ -0,0 +1,3 @@
|
||||
base
|
||||
libm
|
||||
libc
|
||||
@@ -39,13 +39,14 @@ set config {
|
||||
<service name="CPU"/>
|
||||
<service name="IO_MEM" />
|
||||
<service name="IO_PORT" />
|
||||
<service name="TOPO"/>
|
||||
</parent-provides>
|
||||
<default-route>
|
||||
<any-service> <parent/> <any-child/> </any-service>
|
||||
</default-route>
|
||||
|
||||
<start name="timer" caps="100">
|
||||
<resource name="RAM" quantum="2M"/>
|
||||
<resource name="RAM" quantum="16M"/>
|
||||
<provides><service name="Timer"/></provides>
|
||||
</start>
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ import_from_depot [depot_user]/src/[base_src] \
|
||||
[depot_user]/src/dynamic_rom \
|
||||
[depot_user]/src/init \
|
||||
[depot_user]/src/libc \
|
||||
[depot_user]/src/stdcxx \
|
||||
[depot_user]/src/nic_router \
|
||||
[depot_user]/src/vfs_audit \
|
||||
[depot_user]/src/vfs_[ipstack] \
|
||||
@@ -39,6 +40,7 @@ append config {
|
||||
<service name="RM"/>
|
||||
<service name="CPU"/>
|
||||
<service name="LOG"/>
|
||||
<service name="TOPO"/>
|
||||
</parent-provides>
|
||||
|
||||
<default-route>
|
||||
@@ -48,12 +50,12 @@ append config {
|
||||
<default caps="100"/>
|
||||
|
||||
<start name="timer">
|
||||
<resource name="RAM" quantum="1M"/>
|
||||
<resource name="RAM" quantum="16M"/>
|
||||
<provides> <service name="Timer"/> </provides>
|
||||
</start>
|
||||
|
||||
<start name="drivers" caps="1000" managing_system="yes">
|
||||
<resource name="RAM" quantum="32M"/>
|
||||
<resource name="RAM" quantum="512M"/>
|
||||
<binary name="init"/>
|
||||
<route>
|
||||
<service name="ROM" label="config"> <parent label="drivers.config"/> </service>
|
||||
@@ -64,7 +66,7 @@ append config {
|
||||
</start>
|
||||
|
||||
<start name="nic_router" caps="200">
|
||||
<resource name="RAM" quantum="10M"/>
|
||||
<resource name="RAM" quantum="20M"/>
|
||||
<provides>
|
||||
<service name="Nic"/>
|
||||
<service name="Uplink"/>
|
||||
@@ -73,7 +75,7 @@ append config {
|
||||
<policy label_prefix="socket_fs" domain="downlink"/>
|
||||
<policy label_prefix="drivers" domain="uplink"/>
|
||||
|
||||
<domain name="uplink" interface="10.0.2.55/24" gateway="10.0.2.1">
|
||||
<domain name="uplink" interface="10.0.2.55/24" gateway="10.0.2.1" verbose_packets="no">
|
||||
|
||||
<nat domain="downlink"
|
||||
tcp-ports="16384"
|
||||
@@ -88,7 +90,7 @@ append config {
|
||||
|
||||
</domain>
|
||||
|
||||
<domain name="downlink" interface="10.0.3.1/24">
|
||||
<domain name="downlink" interface="10.0.3.1/24" verbose_packets="no">
|
||||
|
||||
<dhcp-server ip_first="10.0.3.55" ip_last="10.0.3.55">
|
||||
<dns-server ip="1.1.1.1"/>
|
||||
@@ -106,14 +108,14 @@ append config {
|
||||
|
||||
append_if [use_dynamic_rom] config {
|
||||
<start name="dynamic_rom">
|
||||
<resource name="RAM" quantum="4M"/>
|
||||
<resource name="RAM" quantum="16M"/>
|
||||
<provides><service name="ROM"/> </provides>
|
||||
<config verbose="yes">
|
||||
<rom name="socket_fs.config"> <inline description="MTU default">
|
||||
<config ld_verbose="yes">
|
||||
<vfs>
|
||||
<dir name="socket">
|
||||
<} [ipstack] { ip_addr="10.0.3.55" netmask="255.255.255.0" gateway="10.0.3.1" nameserver="8.8.8.8"/>
|
||||
<lxip ip_addr="192.168.0.2" netmask="255.255.255.0" gateway="192.168.0.1" nameserver="8.8.8.8"/>
|
||||
</dir>
|
||||
</vfs>
|
||||
<default-policy root="/socket" writeable="yes" />
|
||||
@@ -268,4 +270,4 @@ append_qemu_nic_args "host=10.0.2.1,dhcpstart=10.0.2.55,hostfwd=tcp::10080-:80,h
|
||||
|
||||
run_genode_until forever
|
||||
|
||||
# vi: set ft=tcl :
|
||||
# vi: set ft=tcl
|
||||
|
||||
@@ -77,4 +77,4 @@ void Component::construct(Genode::Env &env)
|
||||
* Default stack size for libc-using components
|
||||
*/
|
||||
Genode::size_t Libc::Component::stack_size() __attribute__((weak));
|
||||
Genode::size_t Libc::Component::stack_size() { return 32UL*1024*sizeof(long); }
|
||||
Genode::size_t Libc::Component::stack_size() { return 96UL*1024*sizeof(long); }
|
||||
|
||||
@@ -100,6 +100,7 @@ class Libc::Env_implementation : public Libc::Env, public Config_accessor
|
||||
Region_map &rm() override { return _env.rm(); }
|
||||
Pd_session &pd() override { return _env.pd(); }
|
||||
Entrypoint &ep() override { return _env.ep(); }
|
||||
Topo_session &topo() override { return _env.topo(); }
|
||||
|
||||
Cpu_session_capability cpu_session_cap() override {
|
||||
return _env.cpu_session_cap(); }
|
||||
@@ -110,6 +111,10 @@ class Libc::Env_implementation : public Libc::Env, public Config_accessor
|
||||
Id_space<Parent::Client> &id_space() override {
|
||||
return _env.id_space(); }
|
||||
|
||||
Topo_session_capability topo_session_cap() override {
|
||||
return _env.topo_session_cap();
|
||||
}
|
||||
|
||||
Session_capability session(Parent::Service_name const &name,
|
||||
Parent::Client::Id id,
|
||||
Parent::Session_args const &args,
|
||||
|
||||
@@ -64,6 +64,18 @@ struct Libc::Malloc_ram_allocator : Ram_allocator
|
||||
[&] (Alloc_error error) {
|
||||
return error; });
|
||||
}
|
||||
|
||||
Alloc_result try_alloc(size_t size, Ram_allocator::Numa_id numa_id, Cache cache) override
|
||||
{
|
||||
return _ram.try_alloc(size, numa_id, cache).convert<Alloc_result>(
|
||||
|
||||
[&] (Ram_dataspace_capability cap) {
|
||||
new (_md_alloc) Registered<Dataspace>(_dataspaces, cap);
|
||||
return cap; },
|
||||
|
||||
[&] (Alloc_error error) {
|
||||
return error; });
|
||||
}
|
||||
|
||||
void free(Ram_dataspace_capability ds_cap) override
|
||||
{
|
||||
|
||||
@@ -86,7 +86,7 @@ class Libc::Malloc
|
||||
SLAB_START = 5, /* 32 bytes (log2) */
|
||||
SLAB_STOP = 11, /* 2048 bytes (log2) */
|
||||
NUM_SLABS = (SLAB_STOP - SLAB_START) + 1,
|
||||
DEFAULT_ALIGN = 16
|
||||
DEFAULT_ALIGN = 64
|
||||
};
|
||||
|
||||
struct Metadata
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
/* Local includes */
|
||||
#include <netty.h>
|
||||
|
||||
#include <thread>
|
||||
|
||||
namespace Netty { struct Tcp; }
|
||||
|
||||
@@ -59,56 +59,69 @@ void Netty::Tcp::server(int const sd, bool const nonblock, bool const read_write
|
||||
Genode::log("okay, accept will not block");
|
||||
}
|
||||
|
||||
Genode::log("test in ", nonblock ? "non-blocking" : "blocking", " mode");
|
||||
//Genode::log("test in ", nonblock ? "non-blocking" : "blocking", " mode");
|
||||
|
||||
int const cd = accept(sd, pcaddr, &scaddr);
|
||||
Genode::log("cd=", cd);
|
||||
//Genode::log("cd=", cd);
|
||||
if (cd == -1) DIE("accept");
|
||||
|
||||
getnames(cd);
|
||||
//getnames(cd);
|
||||
|
||||
size_t count = 0;
|
||||
static char data[64*1024];
|
||||
|
||||
if (nonblock) nonblocking(cd);
|
||||
|
||||
while (true) {
|
||||
int ret = read_write
|
||||
? read(cd, data, sizeof(data))
|
||||
: recv(cd, data, sizeof(data), 0);
|
||||
auto con_handler = std::thread{[cd, read_write, nonblock]()
|
||||
{
|
||||
size_t count = 0;
|
||||
static char data[64*1024];
|
||||
while (true)
|
||||
{
|
||||
//GENODE_LOG_TSC_NAMED(10, "netty_read");
|
||||
int ret = read_write
|
||||
? read(cd, data, sizeof(data))
|
||||
: recv(cd, data, sizeof(data), 0);
|
||||
|
||||
if (ret == 0) {
|
||||
Genode::log("experienced EOF");
|
||||
break;
|
||||
}
|
||||
if (ret == 0)
|
||||
{
|
||||
// Genode::log("experienced EOF");
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret > 0) {
|
||||
/* echo received data */
|
||||
ret = read_write
|
||||
? write(cd, data, ret)
|
||||
: send(cd, data, ret, 0);
|
||||
if (ret == -1) DIE(read_write ? "write" : "send");
|
||||
if (ret > 0)
|
||||
{
|
||||
//GENODE_LOG_TSC_NAMED(10, "netty_write");
|
||||
/* echo received data */
|
||||
ret = read_write
|
||||
? write(cd, data, ret)
|
||||
: send(cd, data, ret, 0);
|
||||
if (ret == -1)
|
||||
DIE(read_write ? "write" : "send");
|
||||
|
||||
count += ret;
|
||||
continue;
|
||||
}
|
||||
count += ret;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!nonblock || errno != EAGAIN)
|
||||
DIE(read_write ? "read" : "recv");
|
||||
if (!nonblock || errno != EAGAIN)
|
||||
DIE(read_write ? "read" : "recv");
|
||||
|
||||
Genode::log("block in select because of EAGAIN");
|
||||
fd_set read_fds; FD_ZERO(&read_fds); FD_SET(cd, &read_fds);
|
||||
ret = select(cd + 1, &read_fds, nullptr, nullptr, nullptr);
|
||||
if (ret == -1) DIE("select");
|
||||
}
|
||||
Genode::log("block in select because of EAGAIN");
|
||||
fd_set read_fds;
|
||||
FD_ZERO(&read_fds);
|
||||
FD_SET(cd, &read_fds);
|
||||
ret = select(cd + 1, &read_fds, nullptr, nullptr, nullptr);
|
||||
if (ret == -1)
|
||||
DIE("select");
|
||||
|
||||
Genode::log("echoed ", count, " bytes");
|
||||
ret = shutdown(cd, SHUT_RDWR);
|
||||
if (ret == -1) DIE("shutdown");
|
||||
|
||||
ret = shutdown(cd, SHUT_RDWR);
|
||||
if (ret == -1) DIE("shutdown");
|
||||
ret = close(cd);
|
||||
if (ret == -1) DIE("close");
|
||||
}
|
||||
}};
|
||||
con_handler.detach();
|
||||
|
||||
ret = close(cd);
|
||||
if (ret == -1) DIE("close");
|
||||
//Genode::log("echoed ", count, " bytes");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
TARGET = test-netty_tcp
|
||||
SRC_CC = main.cc netty.cc
|
||||
LIBS = base libc
|
||||
LIBS = base libc stdcxx
|
||||
|
||||
INC_DIR += $(PRG_DIR)/..
|
||||
|
||||
|
||||
66
repos/mml/include/mxip/arch/cc.h
Normal file
66
repos/mml/include/mxip/arch/cc.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* \brief Some size definitions and macros needed by LwIP.
|
||||
* \author Stefan Kalkowski
|
||||
* \author Emery Hemingway
|
||||
* \date 2009-11-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef __LWIP__ARCH__CC_H__
|
||||
#define __LWIP__ARCH__CC_H__
|
||||
|
||||
#ifdef LITTLE_ENDIAN
|
||||
#undef LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#ifdef BIG_ENDIAN
|
||||
#undef BIG_ENDIAN
|
||||
#endif
|
||||
|
||||
#ifndef LWIP_RAND
|
||||
genode_uint32_t genode_rand();
|
||||
#define LWIP_RAND() genode_rand()
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef LWIP_PLATFORM_DIAG
|
||||
void lwip_printf(const char *format, ...);
|
||||
#define LWIP_PLATFORM_DIAG(x) do { lwip_printf x; } while(0)
|
||||
#endif /* LWIP_PLATFORM_DIAG */
|
||||
|
||||
|
||||
#ifdef GENODE_RELEASE
|
||||
#define LWIP_PLATFORM_ASSERT(x)
|
||||
#else /* GENODE_RELEASE */
|
||||
void lwip_platform_assert(char const* msg, char const *file, int line);
|
||||
#define LWIP_PLATFORM_ASSERT(x) \
|
||||
do { \
|
||||
lwip_platform_assert(x, __FILE__, __LINE__); \
|
||||
} while (0)
|
||||
#endif /* GENODE_RELEASE */
|
||||
|
||||
|
||||
/*
|
||||
* XXX: Should these be inlined?
|
||||
*/
|
||||
void genode_memcpy( void *dst, const void *src, size_t len);
|
||||
void *genode_memmove(void *dst, const void *src, size_t len);
|
||||
|
||||
void genode_free(void *ptr);
|
||||
void *genode_malloc(unsigned long size);
|
||||
void *genode_calloc(unsigned long number, unsigned long size);
|
||||
|
||||
#define mem_clib_free genode_free
|
||||
#define mem_clib_malloc genode_malloc
|
||||
#define mem_clib_calloc genode_calloc
|
||||
|
||||
#endif /* __LWIP__ARCH__CC_H__ */
|
||||
20
repos/mml/include/mxip/arch/perf.h
Normal file
20
repos/mml/include/mxip/arch/perf.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* \brief Header file with macros needed by LwIP.
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2009-11-10
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef __LWIP__ARCH__PERF_H__
|
||||
#define __LWIP__ARCH__PERF_H__
|
||||
|
||||
#define PERF_START
|
||||
#define PERF_STOP(x)
|
||||
|
||||
#endif /* __LWIP__ARCH__PERF_H__ */
|
||||
26
repos/mml/include/mxip/genode_init.h
Normal file
26
repos/mml/include/mxip/genode_init.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* \brief Genode native lwIP initalization
|
||||
* \author Emery Hemingway
|
||||
* \date 2017-08-21
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__LWIP__GENODE_INIT_H_
|
||||
#define _INCLUDE__LWIP__GENODE_INIT_H_
|
||||
|
||||
#include <timer/timeout.h>
|
||||
#include <mx/memory/dynamic_size_allocator.h>
|
||||
|
||||
namespace Mxip {
|
||||
void mxip_init(mx::memory::dynamic::Allocator &heap, ::Timer::Connection &timer);
|
||||
|
||||
Genode::Mutex &mutex();
|
||||
}
|
||||
|
||||
#endif
|
||||
154
repos/mml/include/mxip/lwipopts.h
Normal file
154
repos/mml/include/mxip/lwipopts.h
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* \brief Configuration file for LwIP, adapt it to your needs.
|
||||
* \author Stefan Kalkowski
|
||||
* \author Emery Hemingway
|
||||
* \date 2009-11-10
|
||||
*
|
||||
* See lwip/src/include/lwip/opt.h for all options
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2009-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef __LWIP__LWIPOPTS_H__
|
||||
#define __LWIP__LWIPOPTS_H__
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/fixed_stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Use lwIP without OS-awareness
|
||||
*/
|
||||
#define NO_SYS 1
|
||||
#define SYS_LIGHTWEIGHT_PROT 0
|
||||
|
||||
#define LWIP_DNS 0 /* DNS support */
|
||||
#define LWIP_DHCP 0 /* DHCP support */
|
||||
#define LWIP_SOCKET 0 /* LwIP socket API */
|
||||
#define LWIP_NETIF_LOOPBACK 0 /* Looping back to same address? */
|
||||
#define LWIP_STATS 0 /* disable stating */
|
||||
#define LWIP_ICMP 0
|
||||
#define LWIP_SNMP 0
|
||||
#define LWIP_TCP_TIMESTAMPS 0
|
||||
#define TCP_LISTEN_BACKLOG 255
|
||||
#define TCP_MSS 1460
|
||||
#define TCP_WND (46 * TCP_MSS)
|
||||
#define TCP_SND_BUF (46 * TCP_MSS)
|
||||
#define LWIP_WND_SCALE 3
|
||||
#define TCP_RCV_SCALE 2
|
||||
#define TCP_SND_QUEUELEN ((512 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS))
|
||||
|
||||
#define LWIP_NETIF_STATUS_CALLBACK 1 /* callback function used for interface changes */
|
||||
#define LWIP_NETIF_LINK_CALLBACK 1 /* callback function used for link-state changes */
|
||||
#define LWIP_SUPPORT_CUSTOM_PBUF 1
|
||||
|
||||
#define LWIP_SINGLE_NETIF 1
|
||||
|
||||
#define TCP_QUEUE_OOSEQ 1
|
||||
#define LWIP_PCB_ARRAY 1
|
||||
/***********************************
|
||||
** Checksum calculation settings **
|
||||
***********************************/
|
||||
|
||||
/* checksum calculation for outgoing packets can be disabled if the hardware supports it */
|
||||
#define LWIP_CHECKSUM_ON_COPY 1 /* calculate checksum during memcpy */
|
||||
|
||||
/*********************
|
||||
** Memory settings **
|
||||
*********************/
|
||||
|
||||
#define MEM_LIBC_MALLOC 1
|
||||
#define MEMP_MEM_MALLOC 1
|
||||
#define MEMP_MEM_INIT 0
|
||||
#define MEMP_NUM_TCP_SEG (2*TCP_SND_QUEUELEN)
|
||||
/* MEM_ALIGNMENT > 4 e.g. for x86_64 are not supported, see Genode issue #817 */
|
||||
#define MEM_ALIGNMENT 4
|
||||
|
||||
#define DEFAULT_ACCEPTMBOX_SIZE 128
|
||||
#define TCPIP_MBOX_SIZE 128
|
||||
|
||||
#define RECV_BUFSIZE_DEFAULT (512*1024)
|
||||
|
||||
#define PBUF_POOL_SIZE 8192
|
||||
|
||||
#define MEMP_NUM_SYS_TIMEOUT 64
|
||||
#define MEMP_NUM_TCP_PCB 512
|
||||
#define MEMP_NUM_PBUF (128*4096)
|
||||
|
||||
#ifndef MEMCPY
|
||||
#define MEMCPY(dst,src,len) genode_memcpy(dst,src,len)
|
||||
#endif
|
||||
|
||||
#ifndef MEMMOVE
|
||||
#define MEMMOVE(dst,src,len) genode_memmove(dst,src,len)
|
||||
#endif
|
||||
|
||||
/********************
|
||||
** Debug settings **
|
||||
********************/
|
||||
#define LWIP_NOASSERT 1
|
||||
|
||||
/* #define LWIP_DEBUG */
|
||||
/* #define DHCP_DEBUG LWIP_DBG_ON */
|
||||
/* #define ETHARP_DEBUG LWIP_DBG_ON */
|
||||
/* #define NETIF_DEBUG LWIP_DBG_ON */
|
||||
/* #define PBUF_DEBUG LWIP_DBG_ON */
|
||||
/* #define API_LIB_DEBUG LWIP_DBG_ON */
|
||||
/* #define API_MSG_DEBUG LWIP_DBG_ON */
|
||||
/* #define SOCKETS_DEBUG LWIP_DBG_ON */
|
||||
/* #define ICMP_DEBUG LWIP_DBG_ON */
|
||||
/* #define INET_DEBUG LWIP_DBG_ON */
|
||||
/* #define IP_DEBUG LWIP_DBG_ON */
|
||||
/* #define IP_REASS_DEBUG LWIP_DBG_ON */
|
||||
/* #define RAW_DEBUG LWIP_DBG_ON */
|
||||
/* #define MEM_DEBUG LWIP_DBG_ON */
|
||||
/* #define MEMP_DEBUG LWIP_DBG_ON */
|
||||
/* #define SYS_DEBUG LWIP_DBG_ON */
|
||||
/* #define TCP_DEBUG LWIP_DBG_ON */
|
||||
|
||||
|
||||
/*
|
||||
----------------------------------
|
||||
---------- DHCP options ----------
|
||||
----------------------------------
|
||||
*/
|
||||
|
||||
#define LWIP_DHCP_CHECK_LINK_UP 1
|
||||
|
||||
|
||||
/*
|
||||
----------------------------------------------
|
||||
---------- Sequential layer options ----------
|
||||
----------------------------------------------
|
||||
*/
|
||||
/* no Netconn API */
|
||||
#define LWIP_NETCONN 0
|
||||
|
||||
|
||||
/*
|
||||
---------------------------------------
|
||||
---------- IPv6 options ---------------
|
||||
---------------------------------------
|
||||
*/
|
||||
|
||||
#define LWIP_IPV6 0
|
||||
#define IPV6_FRAG_COPYHEADER 1
|
||||
|
||||
#define LWIP_IPV4 1
|
||||
#define IPV4_FRAG_COPYHEADER 0
|
||||
#define IP_REASSEMBLY 0
|
||||
#define IP_FRAG 0
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __LWIP__LWIPOPTS_H__ */
|
||||
555
repos/mml/include/mxip/mxnic_netif.h
Normal file
555
repos/mml/include/mxip/mxnic_netif.h
Normal file
@@ -0,0 +1,555 @@
|
||||
/*
|
||||
* \brief LwIP netif for the Nic session
|
||||
* \author Emery Hemingway
|
||||
* \date 2016-09-28
|
||||
*
|
||||
* If you want to use the lwIP API in a native Genode
|
||||
* component then this is the Nic client to use.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016-2017 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef __LWIP__NIC_NETIF_H__
|
||||
#define __LWIP__NIC_NETIF_H__
|
||||
|
||||
#if ETH_PAD_SIZE
|
||||
#error ETH_PAD_SIZE defined but unsupported by lwip/nic_netif.h
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus
|
||||
#error lwip/nic_netif.h is a C++ only header
|
||||
#endif
|
||||
|
||||
/* Genode includes */
|
||||
#include <nic/packet_allocator.h>
|
||||
#include <nic_session/connection.h>
|
||||
#include <base/log.h>
|
||||
#include <base/sleep.h>
|
||||
#include <timer_session/connection.h>
|
||||
|
||||
/* MxTasking includes */
|
||||
#include <mx/tasking/runtime.h>
|
||||
#include <mx/tasking/task.h>
|
||||
#include <mx/memory/dynamic_size_allocator.h>
|
||||
|
||||
namespace Lwip {
|
||||
|
||||
extern "C" {
|
||||
/* LwIP includes */
|
||||
#include <lwip/netif.h>
|
||||
#include <netif/etharp.h>
|
||||
#if LWIP_IPV6
|
||||
#include <lwip/ethip6.h>
|
||||
#endif
|
||||
#include <lwip/init.h>
|
||||
#include <lwip/dhcp.h>
|
||||
#include <lwip/dns.h>
|
||||
#include <lwip/timeouts.h>
|
||||
#include <lwip/sys.h>
|
||||
}
|
||||
|
||||
class Nic_netif;
|
||||
class Receive_task;
|
||||
class Tx_ready_task;
|
||||
class Link_state_task;
|
||||
class Finished_rx_task;
|
||||
|
||||
extern "C" {
|
||||
|
||||
static void nic_netif_pbuf_free(pbuf *p);
|
||||
static err_t nic_netif_init(struct netif *netif);
|
||||
static err_t nic_netif_linkoutput(struct netif *netif, struct pbuf *p);
|
||||
static void nic_netif_status_callback(struct netif *netif);
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata for packet backed pbufs
|
||||
*/
|
||||
struct Nic_netif_pbuf
|
||||
{
|
||||
struct pbuf_custom p { };
|
||||
Nic_netif &netif;
|
||||
Nic::Packet_descriptor packet;
|
||||
|
||||
Nic_netif_pbuf(Nic_netif &nic, Nic::Packet_descriptor &pkt)
|
||||
: netif(nic), packet(pkt)
|
||||
{
|
||||
p.custom_free_function = nic_netif_pbuf_free;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class Lwip::Nic_netif
|
||||
{
|
||||
friend class Lwip::Receive_task;
|
||||
friend class Lwip::Tx_ready_task;
|
||||
friend class Lwip::Link_state_task;
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
PACKET_SIZE = Nic::Packet_allocator::DEFAULT_PACKET_SIZE,
|
||||
BUF_SIZE = 128*PACKET_SIZE,
|
||||
};
|
||||
|
||||
Genode::Tslab<Nic_netif_pbuf, 2048 * sizeof(Nic_netif_pbuf)> _pbuf_alloc;
|
||||
|
||||
Nic::Packet_allocator _nic_tx_alloc;
|
||||
Nic::Connection _nic;
|
||||
|
||||
Genode::Entrypoint &_ep;
|
||||
|
||||
struct netif _netif
|
||||
{ };
|
||||
|
||||
ip_addr_t ip { };
|
||||
ip_addr_t nm { };
|
||||
ip_addr_t gw { };
|
||||
|
||||
Genode::Io_signal_handler<Nic_netif> _link_state_handler;
|
||||
Genode::Io_signal_handler<Nic_netif> _rx_packet_handler;
|
||||
Genode::Io_signal_handler<Nic_netif> _tx_ready_handler;
|
||||
|
||||
bool _dhcp { false };
|
||||
|
||||
std::unique_ptr<mx::memory::dynamic::Allocator> _handler_allocator{nullptr};
|
||||
|
||||
public:
|
||||
|
||||
void free_pbuf(Nic_netif_pbuf &pbuf)
|
||||
{
|
||||
bool message_once = true;
|
||||
while (!_nic.rx()->ready_to_ack()) {
|
||||
if (message_once)
|
||||
Genode::error("Nic rx acknowledge queue congested.");
|
||||
message_once = false;
|
||||
_ep.wait_and_dispatch_one_io_signal();
|
||||
}
|
||||
|
||||
_nic.rx()->try_ack_packet(pbuf.packet);
|
||||
wake_up_nic_server();
|
||||
|
||||
destroy(_pbuf_alloc, &pbuf);
|
||||
}
|
||||
|
||||
Lwip::pbuf *alloc_pbuf(size_t len, const char *payload)
|
||||
{
|
||||
Lwip::pbuf_custom *pbuf = new (this->_pbuf_alloc) Lwip::pbuf_custom();
|
||||
|
||||
Lwip::pbuf *p = pbuf_alloced_custom(PBUF_TRANSPORT, len, PBUF_RAM, pbuf, static_cast<void*>(const_cast<char*>(payload)), len);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/*************************
|
||||
** Nic signal handlers **
|
||||
*************************/
|
||||
|
||||
void handle_link_state();
|
||||
void handle_rx_packets();
|
||||
|
||||
/**
|
||||
* Handle tx ack_avail and ready_to_submit signals
|
||||
*/
|
||||
void handle_tx_ready();
|
||||
|
||||
void configure(Genode::Xml_node const &config)
|
||||
{
|
||||
_dhcp = config.attribute_value("dhcp", false);
|
||||
|
||||
typedef Genode::String<IPADDR_STRLEN_MAX> Str;
|
||||
Str ip_str = config.attribute_value("ip_addr", Str());
|
||||
|
||||
Genode::log("Static IP: ", ip_str);
|
||||
|
||||
if (_dhcp && ip_str != "") {
|
||||
_dhcp = false;
|
||||
netif_set_down(&_netif);
|
||||
Genode::error("refusing to configure lwIP interface with both DHCP and a static IPv4 address");
|
||||
return;
|
||||
}
|
||||
|
||||
netif_set_up(&_netif);
|
||||
|
||||
if (ip_str != "") {
|
||||
ip_addr_t ipaddr;
|
||||
if (!ipaddr_aton(ip_str.string(), &ipaddr)) {
|
||||
Genode::error("lwIP configured with invalid IP address '",ip_str,"'");
|
||||
throw ip_str;
|
||||
}
|
||||
|
||||
netif_set_ipaddr(&_netif, ip_2_ip4(&ipaddr));
|
||||
|
||||
if (config.has_attribute("netmask")) {
|
||||
Str str = config.attribute_value("netmask", Str());
|
||||
ip_addr_t ip;
|
||||
ipaddr_aton(str.string(), &ip);
|
||||
netif_set_netmask(&_netif, ip_2_ip4(&ip));
|
||||
}
|
||||
|
||||
if (config.has_attribute("gateway")) {
|
||||
Str str = config.attribute_value("gateway", Str());
|
||||
ip_addr_t ip;
|
||||
ipaddr_aton(str.string(), &ip);
|
||||
netif_set_gw(&_netif, ip_2_ip4(&ip));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (config.has_attribute("nameserver")) {
|
||||
/*
|
||||
* LwIP does not use DNS internally, but the application
|
||||
* should expect "dns_getserver" to work regardless of
|
||||
* how the netif configures itself.
|
||||
*/
|
||||
Str str = config.attribute_value("nameserver", Str());
|
||||
ip_addr_t ip;
|
||||
ipaddr_aton(str.string(), &ip);
|
||||
//dns_setserver(0, &ip);
|
||||
}
|
||||
|
||||
handle_link_state();
|
||||
}
|
||||
|
||||
Nic_netif(Genode::Env &env,
|
||||
Genode::Allocator &alloc,
|
||||
Genode::Xml_node config)
|
||||
:
|
||||
_pbuf_alloc(alloc), _nic_tx_alloc(&alloc),
|
||||
_nic(env, &_nic_tx_alloc,
|
||||
BUF_SIZE, BUF_SIZE,
|
||||
config.attribute_value("label", Genode::String<160>("lwip")).string()), _ep(env.ep()),
|
||||
_link_state_handler(env.ep(), *this, &Nic_netif::handle_link_state),
|
||||
_rx_packet_handler( env.ep(), *this, &Nic_netif::handle_rx_packets),
|
||||
_tx_ready_handler( env.ep(), *this, &Nic_netif::handle_tx_ready)
|
||||
{
|
||||
Genode::memset(&_netif, 0x00, sizeof(_netif));
|
||||
|
||||
_handler_allocator.reset(new (mx::memory::GlobalHeap::allocate_cache_line_aligned(sizeof(mx::memory::dynamic::Allocator))) mx::memory::dynamic::Allocator());
|
||||
|
||||
{
|
||||
ip4_addr_t v4dummy;
|
||||
IP4_ADDR(&v4dummy, 0, 0, 0, 0);
|
||||
|
||||
netif* r = netif_add(&_netif, &v4dummy, &v4dummy, &v4dummy,
|
||||
this, nic_netif_init, ethernet_input);
|
||||
if (r == NULL) {
|
||||
Genode::error("failed to initialize Nic to lwIP interface");
|
||||
throw r;
|
||||
}
|
||||
}
|
||||
|
||||
netif_set_default(&_netif);
|
||||
netif_set_status_callback(
|
||||
&_netif, nic_netif_status_callback);
|
||||
nic_netif_status_callback(&_netif);
|
||||
|
||||
configure(config);
|
||||
}
|
||||
|
||||
virtual ~Nic_netif() { }
|
||||
|
||||
Lwip::netif& lwip_netif() { return _netif; }
|
||||
|
||||
/**
|
||||
* Status callback to override in subclass
|
||||
*/
|
||||
virtual void status_callback() { }
|
||||
|
||||
/**
|
||||
* Callback issued by lwIP to initialize netif struct
|
||||
*
|
||||
* \noapi
|
||||
*/
|
||||
err_t init()
|
||||
{
|
||||
/*
|
||||
* XXX: hostname and MTU could probably be
|
||||
* set in the Nic client constructor
|
||||
*/
|
||||
|
||||
#if LWIP_NETIF_HOSTNAME
|
||||
/* Initialize interface hostname */
|
||||
_netif.hostname = "";
|
||||
#endif /* LWIP_NETIF_HOSTNAME */
|
||||
|
||||
Genode::log("Setting name to en");
|
||||
_netif.name[0] = 'e';
|
||||
_netif.name[1] = 'n';
|
||||
|
||||
Genode::log("Setting callbacks");
|
||||
_netif.output = etharp_output;
|
||||
#if LWIP_IPV6
|
||||
_netif.output_ip6 = ethip6_output;
|
||||
#endif /* LWIP_IPV6 */
|
||||
|
||||
_netif.linkoutput = nic_netif_linkoutput;
|
||||
|
||||
/* Set physical MAC address */
|
||||
Genode::log("Setting MAC address");
|
||||
Nic::Mac_address const mac = _nic.mac_address();
|
||||
for(int i=0; i<6; ++i)
|
||||
_netif.hwaddr[i] = mac.addr[i];
|
||||
|
||||
Genode::log("Setting MTU and flags");
|
||||
_netif.mtu = 1500; /* XXX: just a guess */
|
||||
_netif.hwaddr_len = ETHARP_HWADDR_LEN;
|
||||
_netif.flags = NETIF_FLAG_BROADCAST |
|
||||
NETIF_FLAG_ETHARP |
|
||||
NETIF_FLAG_LINK_UP;
|
||||
|
||||
/* set Nic session signal handlers */
|
||||
Genode::log("Setting NIC handlers");
|
||||
_nic.link_state_sigh(_link_state_handler);
|
||||
_nic.rx_channel()->sigh_packet_avail(_rx_packet_handler);
|
||||
_nic.rx_channel()->sigh_ready_to_ack(_rx_packet_handler);
|
||||
_nic.tx_channel()->sigh_ready_to_submit(_tx_ready_handler);
|
||||
_nic.tx_channel()->sigh_ack_avail (_tx_ready_handler);
|
||||
|
||||
Genode::log("Finished init of netif");
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback issued by lwIP to write a Nic packet
|
||||
*
|
||||
* \noapi
|
||||
*/
|
||||
err_t linkoutput(struct pbuf *p)
|
||||
{
|
||||
auto &tx = *_nic.tx();
|
||||
//GENODE_LOG_TSC(1);
|
||||
|
||||
/* flush acknowledgements */
|
||||
while (tx.ack_avail())
|
||||
tx.release_packet(tx.get_acked_packet());
|
||||
|
||||
if (!tx.ready_to_submit()) {
|
||||
Genode::error("lwIP: Nic packet queue congested, cannot send packet");
|
||||
return ERR_WOULDBLOCK;
|
||||
}
|
||||
|
||||
Nic::Packet_descriptor packet;
|
||||
try { packet = tx.alloc_packet(p->tot_len); }
|
||||
catch (...) {
|
||||
Genode::error("lwIP: Nic packet allocation failed, cannot send packet");
|
||||
return ERR_WOULDBLOCK;
|
||||
}
|
||||
|
||||
/*
|
||||
* We iterate over the pbuf chain until we have read the entire
|
||||
* pbuf into the packet.
|
||||
*/
|
||||
char *dst = tx.packet_content(packet);
|
||||
for(struct pbuf *q = p; q != 0; q = q->next) {
|
||||
char const *src = (char*)q->payload;
|
||||
Genode::memcpy(dst, src, q->len);
|
||||
dst += q->len;
|
||||
}
|
||||
|
||||
tx.try_submit_packet(packet);
|
||||
wake_up_nic_server();
|
||||
LINK_STATS_INC(link.xmit);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
bool ready()
|
||||
{
|
||||
return netif_is_up(&_netif) &&
|
||||
!ip_addr_isany(&_netif.ip_addr);
|
||||
}
|
||||
|
||||
void wake_up_nic_server()
|
||||
{
|
||||
_nic.rx()->wakeup();
|
||||
_nic.tx()->wakeup();
|
||||
}
|
||||
};
|
||||
|
||||
class Lwip::Finished_rx_task : public mx::tasking::TaskInterface
|
||||
{
|
||||
public:
|
||||
Finished_rx_task(Lwip::Nic_netif &netif, Nic_netif_pbuf *pbuf) : _netif(netif), _pbuf(pbuf) {}
|
||||
|
||||
mx::tasking::TaskResult execute(std::uint16_t, std::uint16_t) override
|
||||
{
|
||||
//Genode::log("Executing finished rx task");
|
||||
_netif.free_pbuf(*_pbuf);
|
||||
|
||||
return mx::tasking::TaskResult::make_null();
|
||||
}
|
||||
|
||||
private:
|
||||
Lwip::Nic_netif &_netif;
|
||||
struct Lwip::Nic_netif_pbuf *_pbuf;
|
||||
};
|
||||
|
||||
class Lwip::Receive_task : public mx::tasking::TaskInterface
|
||||
{
|
||||
public:
|
||||
Receive_task(Lwip::pbuf *pbuf, struct netif &netif, Lwip::Nic_netif &net, Lwip::Nic_netif_pbuf *npbuf) : _netif(netif), _pbuf(pbuf), _npbuf(npbuf), _net(net) {}
|
||||
|
||||
mx::tasking::TaskResult execute(std::uint16_t, std::uint16_t) override
|
||||
{
|
||||
Lwip::err_t rc = _netif.input(_pbuf, &_netif);
|
||||
|
||||
|
||||
if (rc != Lwip::ERR_OK)
|
||||
{
|
||||
Genode::error("error forwarding Nic packet to lwIP: error=", static_cast<std::int16_t>(rc));
|
||||
pbuf_free(_pbuf);
|
||||
}
|
||||
|
||||
_net._handler_allocator->free(this);
|
||||
return mx::tasking::TaskResult::make_null();
|
||||
}
|
||||
|
||||
private:
|
||||
struct netif &_netif;
|
||||
struct Lwip::pbuf *_pbuf;
|
||||
Lwip::Nic_netif_pbuf *_npbuf;
|
||||
Lwip::Nic_netif &_net;
|
||||
};
|
||||
|
||||
class Lwip::Tx_ready_task : public mx::tasking::TaskInterface
|
||||
{
|
||||
public:
|
||||
Tx_ready_task(Nic::Connection &nic, Lwip::Nic_netif &netif) : _nic(nic), _netif(netif) {}
|
||||
mx::tasking::TaskResult execute(std::uint16_t, std::uint16_t) override
|
||||
{
|
||||
auto &tx = *_nic.tx();
|
||||
bool progress = false;
|
||||
|
||||
while (tx.ack_avail())
|
||||
{
|
||||
tx.release_packet(tx.try_get_acked_packet());
|
||||
progress = true;
|
||||
}
|
||||
|
||||
if (progress)
|
||||
_netif.wake_up_nic_server();
|
||||
|
||||
_netif._handler_allocator->free(this);
|
||||
return mx::tasking::TaskResult::make_null();
|
||||
|
||||
/* notify subclass to resume pending transmissions */
|
||||
//status_callback();
|
||||
}
|
||||
|
||||
private:
|
||||
Nic::Connection &_nic;
|
||||
Lwip::Nic_netif &_netif;
|
||||
};
|
||||
|
||||
class Lwip::Link_state_task : public mx::tasking::TaskInterface
|
||||
{
|
||||
public:
|
||||
Link_state_task(Nic::Connection &nic, Lwip::netif &netif, Lwip::Nic_netif &nic_netif, bool dhcp) : _nic(nic), _nic_netif(nic_netif), _netif(netif), _dhcp(dhcp) {}
|
||||
|
||||
mx::tasking::TaskResult execute(std::uint16_t, std::uint16_t) override
|
||||
{
|
||||
/*
|
||||
* if the application wants to be informed of the
|
||||
* link state then it should use 'set_link_callback'
|
||||
*/
|
||||
if (_nic.link_state()) {
|
||||
netif_set_link_up(&_netif);
|
||||
/*if (_dhcp) {
|
||||
err_t err = dhcp_start(&_netif);
|
||||
if (err != ERR_OK) {
|
||||
Genode::error("failed to configure lwIP interface with DHCP, error ", -err);
|
||||
}
|
||||
} else {
|
||||
//dhcp_inform(&_netif);
|
||||
}*/
|
||||
} else {
|
||||
netif_set_link_down(&_netif);
|
||||
if (_dhcp) {
|
||||
//dhcp_release_and_stop(&_netif);
|
||||
}
|
||||
}
|
||||
_nic_netif._handler_allocator->free(this);
|
||||
return mx::tasking::TaskResult::make_null();
|
||||
}
|
||||
private:
|
||||
Nic::Connection &_nic;
|
||||
Lwip::Nic_netif &_nic_netif;
|
||||
Lwip::netif &_netif;
|
||||
bool _dhcp;
|
||||
};
|
||||
|
||||
|
||||
/**************************
|
||||
** LwIP netif callbacks **
|
||||
**************************/
|
||||
|
||||
namespace Lwip
|
||||
{
|
||||
extern "C" {
|
||||
|
||||
/**
|
||||
* Free a packet buffer backed pbuf
|
||||
*/
|
||||
static void nic_netif_pbuf_free(pbuf *p)
|
||||
{
|
||||
Nic_netif_pbuf *nic_pbuf = reinterpret_cast<Nic_netif_pbuf*>(p);
|
||||
nic_pbuf->netif.free_pbuf(*nic_pbuf);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the netif
|
||||
*/
|
||||
static err_t nic_netif_init(struct netif *netif)
|
||||
{
|
||||
Lwip::Nic_netif *nic_netif = (Lwip::Nic_netif *)netif->state;
|
||||
return nic_netif->init();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send a raw packet to the Nic session
|
||||
*/
|
||||
static err_t nic_netif_linkoutput(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
Lwip::Nic_netif *nic_netif = (Lwip::Nic_netif *)netif->state;
|
||||
return nic_netif->linkoutput(p);
|
||||
}
|
||||
|
||||
|
||||
static void nic_netif_status_callback(struct netif *netif)
|
||||
{
|
||||
Lwip::Nic_netif *nic_netif = (Lwip::Nic_netif *)netif->state;
|
||||
|
||||
if (netif_is_up(netif)) {
|
||||
/*if (IP_IS_V6_VAL(netif->ip_addr)) {
|
||||
Genode::log("lwIP Nic interface up"
|
||||
", address=",(char const*)ip6addr_ntoa(netif_ip6_addr(netif, 0)));
|
||||
} else */if (!ip4_addr_isany(netif_ip4_addr(netif))) {
|
||||
typedef Genode::String<IPADDR_STRLEN_MAX> Str;
|
||||
Str address((char const*)ip4addr_ntoa(netif_ip4_addr(netif)));
|
||||
Str netmask((char const*)ip4addr_ntoa(netif_ip4_netmask(netif)));
|
||||
Str gateway((char const*)ip4addr_ntoa(netif_ip4_gw(netif)));
|
||||
|
||||
Genode::log("lwIP Nic interface up"
|
||||
" address=", address,
|
||||
" netmask=", netmask,
|
||||
" gateway=", gateway);
|
||||
}
|
||||
} else {
|
||||
Genode::log("lwIP Nic interface down");
|
||||
}
|
||||
|
||||
nic_netif->status_callback();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __LWIP__NIC_NETIF_H__ */
|
||||
2
repos/mml/lib/import/import-mxip.mk
Normal file
2
repos/mml/lib/import/import-mxip.mk
Normal file
@@ -0,0 +1,2 @@
|
||||
INC_DIR += $(call select_from_ports,lwip)/include/lwip
|
||||
INC_DIR += $(call select_from_repositories,include/mxip)
|
||||
49
repos/mml/lib/mk/mxip.mk
Normal file
49
repos/mml/lib/mk/mxip.mk
Normal file
@@ -0,0 +1,49 @@
|
||||
#
|
||||
# lwIP TCP/IP library
|
||||
#
|
||||
# The library implements TCP and UDP as well as DNS and DHCP.
|
||||
#
|
||||
|
||||
LWIP_PORT_DIR := $(call select_from_ports,mxip)
|
||||
LWIPDIR := $(LWIP_PORT_DIR)/src/lib/lwip/src
|
||||
|
||||
-include $(LWIPDIR)/Filelists.mk
|
||||
|
||||
# Genode platform files
|
||||
SRC_CC = printf.cc rand.cc sys_arch.cc mxnic_netif.cc
|
||||
|
||||
# Core files
|
||||
SRC_C += $(notdir $(COREFILES))
|
||||
|
||||
# IPv4 files
|
||||
SRC_C += $(notdir $(CORE4FILES))
|
||||
|
||||
# IPv6 files
|
||||
SRC_C += $(notdir $(CORE6FILES))
|
||||
|
||||
# Network interface files
|
||||
SRC_C += $(notdir $(NETIFFILES))
|
||||
|
||||
INC_DIR += $(REP_DIR)/include/mxip \
|
||||
$(LWIP_PORT_DIR)/include/lwip \
|
||||
$(LWIPDIR)/include \
|
||||
$(LWIPDIR)/include/ipv4 \
|
||||
$(LWIPDIR)/include/api \
|
||||
$(LWIPDIR)/include/netif \
|
||||
|
||||
vpath %.cc $(REP_DIR)/src/lib/mxip/platform
|
||||
vpath %.c $(sort $(dir \
|
||||
$(COREFILES) $(CORE4FILES) $(CORE6FILES) $(NETIFFILES)))
|
||||
|
||||
GENODE_GCC_TOOLCHAIN_DIR ?= /usr/local/genode/tool/21.05
|
||||
|
||||
CUSTOM_CXX = /usr/local/genode/tool/bin/clang++
|
||||
CUSTOM_CC = /usr/local/genode/tool/bin/clang
|
||||
|
||||
CC_OPT := --target=x86_64-genode --sysroot=/does/not/exist --gcc-toolchain=$(GENODE_GCC_TOOLCHAIN_DIR) -DCLANG_CXX11_ATOMICS -Wno-error=all -Wno-error=conversion -Wno-error=effc++ -Wno-error=unknown-attributes -g -DNDEBUG -I$(MXINC_DIR) -std=c++20 -mssse3 #-D_GLIBCXX_ATOMIC_BUILTINS_8 -D__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
|
||||
|
||||
CC_OLEVEL = -O3
|
||||
|
||||
LIBS += libm libc stdcxx mxtasking
|
||||
EXT_OBJECTS += /usr/local/genode/tool/lib/clang/14.0.5/lib/linux/libclang_rt.builtins-x86_64.a /usr/local/genode/tool/lib/libatomic.a
|
||||
|
||||
1
repos/mml/ports/ciao-ip.hash
Normal file
1
repos/mml/ports/ciao-ip.hash
Normal file
@@ -0,0 +1 @@
|
||||
9428aff1932ed69e452867f71012ee91412fc1fa
|
||||
146
repos/mml/ports/ciao-ip.port
Normal file
146
repos/mml/ports/ciao-ip.port
Normal file
@@ -0,0 +1,146 @@
|
||||
LICENSE := GPL
|
||||
DOWNLOADS := ciao-ip.git
|
||||
VERSION := git
|
||||
|
||||
URL(ciao-ip) := git@ess-git.inf.uos.de:software/ciao-ip.git
|
||||
REV(ciao-ip) := master
|
||||
DIR(ciao-ip) := src/lib/ciao-ip
|
||||
|
||||
CC_OPT += "--target x86_64-linux-gnu"
|
||||
#ifndef CIAO_IP_CONFIG
|
||||
# CIAO_IP_CONFIG = $(realpath $(dir $(PORT)))/.ciao-ip-config
|
||||
#endif
|
||||
|
||||
# Include the configuration file
|
||||
#include $(CIAO_IP_CONFIG)
|
||||
|
||||
#ACXX := $(which ag++)
|
||||
#ASPECTSRC = $(shell find -L ./src/lib/ciao-ip/src/ -name "*.ah" -not -name ".*"|cut -b 3-)
|
||||
|
||||
# Apply rules for conditional compilation, i.e., remove files if not selected
|
||||
#include $(realpath $(dir $(PORT)))/ciao-ip-config.mk
|
||||
|
||||
#ACXXFLAGS += $(foreach file,$(ASPECTSRC),-a $(file)) -p ./src/lib/ciao-ip/src/
|
||||
|
||||
DIRS += include/ciao-ip/hw/hal
|
||||
DIRS += include/ciao-ip/ipstack/router
|
||||
DIRS += include/ciao-ip/ipstack/api
|
||||
DIRS += include/ciao-ip/ipstack/arp
|
||||
DIRS += include/ciao-ip/ipstack/arp/ipv4
|
||||
DIRS += include/ciao-ip/ipstack/demux
|
||||
DIRS += include/ciao-ip/ipstack/icmp
|
||||
DIRS += include/ciao-ip/ipstack/ipv4/ipv4_icmp
|
||||
DIRS += include/ciao-ip/ipstack/ipv4/ipv4_tcp
|
||||
DIRS += include/ciao-ip/ipstack/ipv4/ipv4_udp
|
||||
DIRS += include/ciao-ip/ipstack/ipv4
|
||||
DIRS += include/ciao-ip/ipstack/router
|
||||
DIRS += include/ciao-ip/ipstack/tcp/tcp_history
|
||||
DIRS += include/ciao-ip/ipstack/tcp/tcp_receivebuffer
|
||||
DIRS += include/ciao-ip/ipstack/tcp/sws
|
||||
DIRS += include/ciao-ip/ipstack/tcp/statemachine
|
||||
DIRS += include/ciao-ip/ipstack/tcp/tcp_options
|
||||
DIRS += include/ciao-ip/ipstack/tcp
|
||||
DIRS += include/ciao-ip/ipstack/udp
|
||||
DIRS += include/ciao-ip/ipstack/util
|
||||
DIRS += include/ciao-ip/ipstack
|
||||
DIRS += include/ciao-ip/util
|
||||
|
||||
|
||||
|
||||
# for f in $(find build -name "*.ah"); do DST=$(dirname $f | sed -s 's/build\/header/include\/ciao-ip/' | sed -s "s/include/DIR_CONTENT(include/" | sed -s "s/$/) += /"); echo $DST $f; done
|
||||
DIR_CONTENT(include/ciao-ip/hw/hal) += src/lib/ciao-ip/build/header/hw/hal/NetworkDevice.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/icmp) += src/lib/ciao-ip/build/header/ipstack/icmp/ICMP.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/router) += src/lib/ciao-ip/build/header/ipstack/router/Interface.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/router) += src/lib/ciao-ip/build/header/ipstack/router/Router.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/util) += src/lib/ciao-ip/build/header/ipstack/util/MempoolBase.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/util) += src/lib/ciao-ip/build/header/ipstack/util/RingbufferBase.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/util) += src/lib/ciao-ip/build/header/ipstack/util/Mempool.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/util) += src/lib/ciao-ip/build/header/ipstack/util/Ringbuffer.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack) += src/lib/ciao-ip/build/header/ipstack/Eth_Frame.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/as) += src/lib/ciao-ip/build/header/ipstack/as/EventSupport.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack) += src/lib/ciao-ip/build/header/ipstack/Clock.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack) += src/lib/ciao-ip/build/header/ipstack/IPStack_Config_kconf.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/udp) += src/lib/ciao-ip/build/header/ipstack/udp/UDP.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/udp) += src/lib/ciao-ip/build/header/ipstack/udp/UDP_Socket.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp) += src/lib/ciao-ip/build/header/ipstack/tcp/TCP.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/tcp_receivebuffer) += src/lib/ciao-ip/build/header/ipstack/tcp/tcp_receivebuffer/TCP_ReceiveBuffer.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/tcp_receivebuffer) += src/lib/ciao-ip/build/header/ipstack/tcp/tcp_receivebuffer/TCP_RecvElement.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp) += src/lib/ciao-ip/build/header/ipstack/tcp/TCP_Socket.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp) += src/lib/ciao-ip/build/header/ipstack/tcp/TCP_Config.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/tcp_history) += src/lib/ciao-ip/build/header/ipstack/tcp/tcp_history/TCP_Record.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/tcp_history) += src/lib/ciao-ip/build/header/ipstack/tcp/tcp_history/TCP_History.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/api) += src/lib/ciao-ip/build/header/ipstack/api/Setup.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/api) += src/lib/ciao-ip/build/header/ipstack/api/IPv4_UDP_Socket.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/api) += src/lib/ciao-ip/build/header/ipstack/api/IPv4_TCP_Socket.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/demux) += src/lib/ciao-ip/build/header/ipstack/demux/Demux.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4/ipv4_tcp) += src/lib/ciao-ip/build/header/ipstack/ipv4/ipv4_tcp/IPv4_TCP_Socket.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4) += src/lib/ciao-ip/build/header/ipstack/ipv4/IPv4.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4) += src/lib/ciao-ip/build/header/ipstack/ipv4/IPv4_Socket.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4/ipv4_udp) += src/lib/ciao-ip/build/header/ipstack/ipv4/ipv4_udp/IPv4_UDP_Socket.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4) += src/lib/ciao-ip/build/header/ipstack/ipv4/InternetChecksum.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack) += src/lib/ciao-ip/build/header/ipstack/IPStack_Config.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/arp) += src/lib/ciao-ip/build/header/ipstack/arp/ARP_Cache.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/arp) += src/lib/ciao-ip/build/header/ipstack/arp/ARP.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/arp/ipv4) += src/lib/ciao-ip/build/header/ipstack/arp/ipv4/Eth_ARP_IPv4_Packet.h
|
||||
DIR_CONTENT(include/ciao-ip/util) += src/lib/ciao-ip/build/header/util/types.h
|
||||
DIR_CONTENT(include/ciao-ip/ipstack) += src/lib/ciao-ip/build/header/ipstack/Little_Endian.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/router) += src/lib/ciao-ip/build/header/ipstack/router/Interface_Delegation.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/router) += src/lib/ciao-ip/build/header/ipstack/router/Router.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/router) += src/lib/ciao-ip/build/header/ipstack/router/Interface.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/sws) += src/lib/ciao-ip/build/header/ipstack/tcp/sws/SWS_SenderAvoidance.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/sws) += src/lib/ciao-ip/build/header/ipstack/tcp/sws/SWS_ReceiverAvoidance.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/sws) += src/lib/ciao-ip/build/header/ipstack/tcp/sws/SWS_SenderAvoidance_Slice.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/statemachine) += src/lib/ciao-ip/build/header/ipstack/tcp/statemachine/synsent.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/statemachine) += src/lib/ciao-ip/build/header/ipstack/tcp/statemachine/synrcvd.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/statemachine) += src/lib/ciao-ip/build/header/ipstack/tcp/statemachine/listen.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/statemachine) += src/lib/ciao-ip/build/header/ipstack/tcp/statemachine/closed.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/statemachine) += src/lib/ciao-ip/build/header/ipstack/tcp/statemachine/closewait.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/statemachine) += src/lib/ciao-ip/build/header/ipstack/tcp/statemachine/finwait2.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/statemachine) += src/lib/ciao-ip/build/header/ipstack/tcp/statemachine/closing.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/statemachine) += src/lib/ciao-ip/build/header/ipstack/tcp/statemachine/established.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/statemachine) += src/lib/ciao-ip/build/header/ipstack/tcp/statemachine/finwait1.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/statemachine) += src/lib/ciao-ip/build/header/ipstack/tcp/statemachine/TCP_Statemachine.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/statemachine) += src/lib/ciao-ip/build/header/ipstack/tcp/statemachine/lastack.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/statemachine) += src/lib/ciao-ip/build/header/ipstack/tcp/statemachine/synsent_dummy.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/statemachine) += src/lib/ciao-ip/build/header/ipstack/tcp/statemachine/timewait.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/tcp_options) += src/lib/ciao-ip/build/header/ipstack/tcp/tcp_options/MSS.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/tcp_options) += src/lib/ciao-ip/build/header/ipstack/tcp/tcp_options/MSS_TCP_Segment_Slice.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/tcp_options) += src/lib/ciao-ip/build/header/ipstack/tcp/tcp_options/MSS_TCP_Socket_Slice.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/tcp_history) += src/lib/ciao-ip/build/header/ipstack/tcp/tcp_history/TCP_Record_RetransmissionCounter.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/tcp/tcp_history) += src/lib/ciao-ip/build/header/ipstack/tcp/tcp_history/TCP_Record_RetransmissionCounter_Slice.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/demux) += src/lib/ciao-ip/build/header/ipstack/demux/Demux.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4/ipv4_tcp) += src/lib/ciao-ip/build/header/ipstack/ipv4/ipv4_tcp/IPv4_TCP_Listen.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4/ipv4_tcp) += src/lib/ciao-ip/build/header/ipstack/ipv4/ipv4_tcp/IPv4_TCP_Tx_Checksumming.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4/ipv4_tcp) += src/lib/ciao-ip/build/header/ipstack/ipv4/ipv4_tcp/IPv4_TCP_Socket_Listen_Slice.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4/ipv4_tcp) += src/lib/ciao-ip/build/header/ipstack/ipv4/ipv4_tcp/Demux_IPv4_TCP_Slice.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4/ipv4_tcp) += src/lib/ciao-ip/build/header/ipstack/ipv4/ipv4_tcp/IPv4_TCP_Receive.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4/ipv4_tcp) += src/lib/ciao-ip/build/header/ipstack/ipv4/ipv4_tcp/Demux_IPv4_TCP_Listen_Slice.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4) += src/lib/ciao-ip/build/header/ipstack/ipv4/Demux_IPv4_Slice.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4) += src/lib/ciao-ip/build/header/ipstack/ipv4/IPv4_Receive_Ethernet.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4) += src/lib/ciao-ip/build/header/ipstack/ipv4/Router_IPv4_Slice.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4) += src/lib/ciao-ip/build/header/ipstack/ipv4/IPv4_Receive.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4) += src/lib/ciao-ip/build/header/ipstack/ipv4/IPv4_Socket_Ethernet.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4/ipv4_icmp) += src/lib/ciao-ip/build/header/ipstack/ipv4/ipv4_icmp/IPv4_ICMP_Ethernet.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4/ipv4_icmp) += src/lib/ciao-ip/build/header/ipstack/ipv4/ipv4_icmp/IPv4_ICMP_Receive.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4/ipv4_icmp) += src/lib/ciao-ip/build/header/ipstack/ipv4/ipv4_icmp/IPv4_ICMP_Echo_Reply.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4/ipv4_icmp) += src/lib/ciao-ip/build/header/ipstack/ipv4/ipv4_icmp/Demux_IPv4_ICMP_Slice.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4) += src/lib/ciao-ip/build/header/ipstack/ipv4/IPv4.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/ipv4) += src/lib/ciao-ip/build/header/ipstack/ipv4/Interface_IPv4_Slice.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack) += src/lib/ciao-ip/build/header/ipstack/Receive_Ethernet.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/arp) += src/lib/ciao-ip/build/header/ipstack/arp/ARP_Ethernet.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/arp) += src/lib/ciao-ip/build/header/ipstack/arp/ARP.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/arp) += src/lib/ciao-ip/build/header/ipstack/arp/Demux_ARP_Slice.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/arp/ipv4) += src/lib/ciao-ip/build/header/ipstack/arp/ipv4/ARP_Cache_IPv4_Slice.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/arp/ipv4) += src/lib/ciao-ip/build/header/ipstack/arp/ipv4/ARP_Cache_IPv4_Send_Receive_Slice.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/arp/ipv4) += src/lib/ciao-ip/build/header/ipstack/arp/ipv4/ARP_Cache_IPv4_Send_Slice.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/arp/ipv4) += src/lib/ciao-ip/build/header/ipstack/arp/ipv4/IPv4_ARP_Send.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/arp/ipv4) += src/lib/ciao-ip/build/header/ipstack/arp/ipv4/IPv4_Socket_Ethernet_ARP_Slice.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/arp/ipv4) += src/lib/ciao-ip/build/header/ipstack/arp/ipv4/IPv4_ARP.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/arp/ipv4) += src/lib/ciao-ip/build/header/ipstack/arp/ipv4/IPv4_Socket_Ethernet_ARP.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/arp/ipv4) += src/lib/ciao-ip/build/header/ipstack/arp/ipv4/IPv4_ARP_Receive.ah
|
||||
DIR_CONTENT(include/ciao-ip/ipstack/arp/ipv4) += src/lib/ciao-ip/build/header/ipstack/arp/ipv4/IPv4_ARP_Send_Receive.ah
|
||||
|
||||
headers:
|
||||
ACXXFLAGS=$(CC_OPT) make -C src/lib/ciao-ip header
|
||||
|
||||
_dirs: headers
|
||||
1
repos/mml/ports/mxip.hash
Normal file
1
repos/mml/ports/mxip.hash
Normal file
@@ -0,0 +1 @@
|
||||
e310a8d13995d4b3110cb727a298d781b4f03504
|
||||
23
repos/mml/ports/mxip.port
Normal file
23
repos/mml/ports/mxip.port
Normal file
@@ -0,0 +1,23 @@
|
||||
LICENSE := BSD
|
||||
VERSION := 2.1.2
|
||||
DOWNLOADS := lwip.archive
|
||||
|
||||
URL(lwip) := http://git.savannah.nongnu.org/cgit/lwip.git/snapshot/lwip-STABLE-2_1_2_RELEASE.tar.gz
|
||||
SHA(lwip) := da6a3e07944505e6add328f6efafea4ad670700731f36b1ba54bd43d4f35243e
|
||||
DIR(lwip) := src/lib/lwip
|
||||
|
||||
UNPACKED_DIR := src/lib/lwip
|
||||
|
||||
PATCHES := $(wildcard $(REP_DIR)/src/lib/lwip/*.patch)
|
||||
PATCH_OPT := -p1 -d src/lib/lwip
|
||||
|
||||
DIRS := \
|
||||
include/lwip/lwip \
|
||||
include/lwip/lwip/priv \
|
||||
include/lwip/lwip/prot \
|
||||
include/lwip/netif \
|
||||
|
||||
DIR_CONTENT(include/lwip/lwip/priv) := $(UNPACKED_DIR)/src/include/lwip/priv/*.h
|
||||
DIR_CONTENT(include/lwip/lwip/prot) := $(UNPACKED_DIR)/src/include/lwip/prot/*.h
|
||||
DIR_CONTENT(include/lwip/lwip) := $(UNPACKED_DIR)/src/include/lwip/*.h
|
||||
DIR_CONTENT(include/lwip/netif) := $(UNPACKED_DIR)/src/include/netif/*.h
|
||||
20
repos/mml/recipes/api/mxip/content.mk
Normal file
20
repos/mml/recipes/api/mxip/content.mk
Normal file
@@ -0,0 +1,20 @@
|
||||
MIRROR_FROM_REP_DIR := \
|
||||
$(shell cd $(REP_DIR); find include/mxip src/lib/mxip -type f) \
|
||||
lib/import/import-mxip.mk \
|
||||
lib/mk/mxip.mk \
|
||||
|
||||
PORT_DIR := $(call port_dir,$(REP_DIR)/ports/mxip)
|
||||
|
||||
MIRROR_FROM_PORT_DIR := $(shell cd $(PORT_DIR); find include src -type f)
|
||||
|
||||
content: $(MIRROR_FROM_REP_DIR) $(MIRROR_FROM_PORT_DIR) LICENSE
|
||||
|
||||
$(MIRROR_FROM_REP_DIR):
|
||||
$(mirror_from_rep_dir)
|
||||
|
||||
$(MIRROR_FROM_PORT_DIR):
|
||||
mkdir -p $(dir $@)
|
||||
cp -r $(PORT_DIR)/$@ $@
|
||||
|
||||
LICENSE:
|
||||
cp $(PORT_DIR)/src/lib/lwip/COPYING $@
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user