Genode platform fixes (#17521)

* Genode: move dyncall failures to runtime

Do not use the "error" pragma to warn that dynamic library loading is
not implemented, print a message at runtime and exit.

* Genode: use stricter dataspace type in page allocator

* Genode: remove compiler configuration from nim.cfg

Self-hosting Nim is not supported on Genode and defining the
cross-compilation environment can be done externally.

* Genode: use new mutex API

* Genode: call nim_component_construct as a C procedure

* Genode: implement echo for NimStringV2
This commit is contained in:
Emery Hemingway 2021-04-09 16:29:10 +02:00 • committed by GitHub
commit 8aa5991bea
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 60 additions and 53 deletions

View file

@ -1103,15 +1103,21 @@ proc genEcho(p: BProc, n: PNode) =
# echo directly to the Genode LOG session # echo directly to the Genode LOG session
var args: Rope = nil var args: Rope = nil
var a: TLoc var a: TLoc
for it in n.sons: for i, it in n.sons:
if it.skipConv.kind == nkNilLit: if it.skipConv.kind == nkNilLit:
args.add(", \"\"") args.add(", \"\"")
else: elif n.len != 0:
initLocExpr(p, it, a) initLocExpr(p, it, a)
args.add(ropecg(p.module, ", Genode::Cstring($1->data, $1->len)", [rdLoc(a)])) if i > 0:
args.add(", ")
case detectStrVersion(p.module)
of 2:
args.add(ropecg(p.module, "Genode::Cstring($1.p->data, $1.len)", [a.rdLoc]))
else:
args.add(ropecg(p.module, "Genode::Cstring($1->data, $1->len)", [a.rdLoc]))
p.module.includeHeader("<base/log.h>") p.module.includeHeader("<base/log.h>")
p.module.includeHeader("<util/string.h>") p.module.includeHeader("<util/string.h>")
linefmt(p, cpsStmts, """Genode::log(""$1);$n""", [args]) linefmt(p, cpsStmts, """Genode::log($1);$n""", [args])
else: else:
if n.len == 0: if n.len == 0:
linefmt(p, cpsStmts, "#echoBinSafe(NIM_NIL, $1);$n", [n.len]) linefmt(p, cpsStmts, "#echoBinSafe(NIM_NIL, $1);$n", [n.len])

View file

@ -1418,7 +1418,7 @@ proc genMainProc(m: BModule) =
GenodeNimMain = GenodeNimMain =
"extern Genode::Env *nim_runtime_env;$N" & "extern Genode::Env *nim_runtime_env;$N" &
"extern void nim_component_construct(Genode::Env*);$N$N" & "extern \"C\" void nim_component_construct(Genode::Env*);$N$N" &
NimMainBody NimMainBody
ComponentConstruct = ComponentConstruct =

View file

@ -114,7 +114,7 @@ nimblepath="$home/.nimble/pkgs/"
clang.options.linker = "-Wl,--as-needed -lnetwork" clang.options.linker = "-Wl,--as-needed -lnetwork"
clang.cpp.options.linker = "-Wl,--as-needed -lnetwork" clang.cpp.options.linker = "-Wl,--as-needed -lnetwork"
tcc.options.linker = "-Wl,--as-needed -lnetwork" tcc.options.linker = "-Wl,--as-needed -lnetwork"
@else: @elif not genode:
# -fopenmp # -fopenmp
gcc.options.linker = "-ldl" gcc.options.linker = "-ldl"
gcc.cpp.options.linker = "-ldl" gcc.cpp.options.linker = "-ldl"
@ -289,29 +289,6 @@ vcc.cpp.options.size = "/O1"
# Configuration for the Tiny C Compiler: # Configuration for the Tiny C Compiler:
tcc.options.always = "-w" tcc.options.always = "-w"
# Configuration for the Genode toolchain
@if genode:
noCppExceptions # avoid std C++
tlsEmulation:on # no TLS segment register magic
@if i386 or amd64:
gcc.exe = "genode-x86-gcc"
gcc.cpp.exe = "genode-x86-g++"
gcc.cpp.linkerexe = "genode-x86-ld"
@elif arm:
gcc.exe = "genode-arm-gcc"
gcc.cpp.exe = "genode-arm-g++"
gcc.cpp.linkerexe = "genode-arm-ld"
@elif arm64:
gcc.exe = "genode-aarch64-gcc"
gcc.cpp.exe = "genode-aarch64-g++"
gcc.cpp.linkerexe = "genode-aarch64-ld"
@elif riscv64:
gcc.exe = "genode-riscv-gcc"
gcc.cpp.exe = "genode-riscv-g++"
gcc.cpp.linkerexe = "genode-riscv-ld"
@end
@end
@if arm or arm64: @if arm or arm64:
--define:nimEmulateOverflowChecks --define:nimEmulateOverflowChecks
@end @end

View file

@ -17,18 +17,18 @@ when not defined(genode):
when not declared(GenodeEnv): when not declared(GenodeEnv):
include genode/env include genode/env
type DataspaceCapability {. type RamDataspaceCapability {.
importcpp: "Genode::Dataspace_capability", pure.} = object importcpp: "Genode::Ram_dataspace_capability", pure.} = object
type type
Map = object Map = object
attachment: pointer attachment: pointer
size: int size: int
ds: DataspaceCapability ds: RamDataspaceCapability
SlabMeta = object SlabMeta = object
next: ptr MapSlab next: ptr MapSlab
ds: DataspaceCapability ds: RamDataspaceCapability
MapSlab = object MapSlab = object
meta: SlabMeta meta: SlabMeta
@ -45,11 +45,11 @@ proc capsAvail(env: GenodeEnv): int {.
## Return the number of available capabilities. ## Return the number of available capabilities.
## Each dataspace allocation consumes a capability. ## Each dataspace allocation consumes a capability.
proc allocDataspace(env: GenodeEnv; size: int): DataspaceCapability {. proc allocDataspace(env: GenodeEnv; size: int): RamDataspaceCapability {.
importcpp: "#->pd().alloc(@)".} importcpp: "#->pd().alloc(@)".}
## Allocate a dataspace and its capability. ## Allocate a dataspace and its capability.
proc attachDataspace(env: GenodeEnv; ds: DataspaceCapability): pointer {. proc attachDataspace(env: GenodeEnv; ds: RamDataspaceCapability): pointer {.
importcpp: "#->rm().attach(@)".} importcpp: "#->rm().attach(@)".}
## Attach a dataspace into the component address-space. ## Attach a dataspace into the component address-space.
@ -57,7 +57,7 @@ proc detachAddress(env: GenodeEnv; p: pointer) {.
importcpp: "#->rm().detach(@)".} importcpp: "#->rm().detach(@)".}
## Detach a dataspace from the component address-space. ## Detach a dataspace from the component address-space.
proc freeDataspace(env: GenodeEnv; ds: DataspaceCapability) {. proc freeDataspace(env: GenodeEnv; ds: RamDataspaceCapability) {.
importcpp: "#->pd().free(@)".} importcpp: "#->pd().free(@)".}
## Free a dataspace. ## Free a dataspace.

View file

@ -13,7 +13,7 @@
/* Genode includes */ /* Genode includes */
#include <base/semaphore.h> #include <base/semaphore.h>
#include <base/lock.h> #include <base/mutex.h>
namespace Nim { namespace Nim {
struct SysLock; struct SysLock;
@ -22,15 +22,14 @@ namespace Nim {
struct Nim::SysLock struct Nim::SysLock
{ {
Genode::Lock _lock_a, _lock_b; Genode::Mutex _mutex_a, _mutex_b;
bool _locked; bool _locked;
void acquireSys() void acquireSys()
{ {
_lock_a.lock(); Genode::Mutex::Guard guard(_mutex_a);
_locked = true; _locked = true;
_lock_a.unlock(); _mutex_b.acquire();
_lock_b.lock();
} }
bool tryAcquireSys() bool tryAcquireSys()
@ -38,23 +37,22 @@ struct Nim::SysLock
if (_locked) if (_locked)
return false; return false;
_lock_a.lock(); Genode::Mutex::Guard guard(_mutex_a);
if (_locked) { if (_locked) {
_lock_a.unlock();
return false; return false;
} else { } else {
_locked = true; _locked = true;
_lock_b.lock(); _mutex_b.acquire();
_lock_a.unlock();
return true; return true;
} }
} }
void releaseSys() void releaseSys()
{ {
Genode::Mutex::Guard guard(_mutex_a);
_locked = false; _locked = false;
_lock_a.unlock(); _mutex_b.release();
_lock_b.unlock();
} }
}; };

View file

@ -150,6 +150,32 @@ elif defined(nintendoswitch):
proc symAddr(lib: LibHandle, name: cstring): pointer = proc symAddr(lib: LibHandle, name: cstring): pointer =
raise newException(OSError, "symAddr not implemented on Nintendo Switch!") raise newException(OSError, "symAddr not implemented on Nintendo Switch!")
elif defined(genode):
#
# =========================================================================
# Not implemented for Genode without POSIX. Raise an error if called.
# =========================================================================
#
template raiseErr(prc: string) =
raise newException(OSError, prc & " not implemented, compile with POSIX suport")
proc dlclose(lib: LibHandle) =
raiseErr(OSError, "dlclose")
proc dlopen(path: cstring, mode: int): LibHandle =
raiseErr(OSError, "dlopen")
proc dlsym(lib: LibHandle, name: cstring): pointer =
raiseErr(OSError, "dlsym")
proc loadLib(path: string, global_symbols = false): LibHandle =
raiseErr(OSError, "loadLib")
proc loadLib(): LibHandle =
raiseErr(OSError, "loadLib")
proc unloadLib(lib: LibHandle) =
raiseErr(OSError, "unloadLib")
proc symAddr(lib: LibHandle, name: cstring): pointer =
raiseErr(OSError, "symAddr")
elif defined(windows) or defined(dos): elif defined(windows) or defined(dos):
# #
# ======================================================================= # =======================================================================

View file

@ -167,14 +167,14 @@ elif defined(windows) or defined(dos):
elif defined(genode): elif defined(genode):
proc nimUnloadLibrary(lib: LibHandle) {. proc nimUnloadLibrary(lib: LibHandle) =
error: "nimUnloadLibrary not implemented".} raiseAssert("nimUnloadLibrary not implemented")
proc nimLoadLibrary(path: string): LibHandle {. proc nimLoadLibrary(path: string): LibHandle =
error: "nimLoadLibrary not implemented".} raiseAssert("nimLoadLibrary not implemented")
proc nimGetProcAddr(lib: LibHandle, name: cstring): ProcAddr {. proc nimGetProcAddr(lib: LibHandle, name: cstring): ProcAddr =
error: "nimGetProcAddr not implemented".} raiseAssert("nimGetProcAddr not implemented")
elif defined(nintendoswitch) or defined(freertos): elif defined(nintendoswitch) or defined(freertos):
proc nimUnloadLibrary(lib: LibHandle) = proc nimUnloadLibrary(lib: LibHandle) =