summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2018-06-09 09:38:53 +0200
committerGitHub <noreply@github.com>2018-06-09 09:38:53 +0200
commite00e7fec541220fcdd5c21c5a563a9bffe670b32 (patch)
tree864cd71d2213502c81b465e46a76753d158868c6
parentd4543500ee3be17f8c1738f271f2fe9fc23162c9 (diff)
parent5e54cd9fc9ce21311a4991f550e420f5bf1bd726 (diff)
downloadNim-e00e7fec541220fcdd5c21c5a563a9bffe670b32.tar.gz
Merge pull request #7873 from ehmry/GenodeEnv
Native access to Genode environment
-rw-r--r--compiler/cgen.nim10
-rw-r--r--lib/genode/alloc.nim (renamed from lib/system/genodealloc.nim)43
-rw-r--r--lib/genode/env.nim29
-rw-r--r--lib/genode_cpp/threads.h1
-rw-r--r--lib/nimbase.h5
-rw-r--r--lib/pure/concurrency/cpuinfo.nim8
-rw-r--r--lib/pure/os.nim2
-rw-r--r--lib/system.nim37
-rw-r--r--lib/system/osalloc.nim2
-rw-r--r--lib/system/threads.nim7
-rw-r--r--lib/wrappers/openssl.nim4
11 files changed, 111 insertions, 37 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim
index 6a16474c0..e749c78db 100644
--- a/compiler/cgen.nim
+++ b/compiler/cgen.nim
@@ -1035,14 +1035,19 @@ proc genMainProc(m: BModule) =
       "}$N$N"
 
     GenodeNimMain =
-      "Libc::Env *genodeEnv;$N" &
+      "extern Genode::Env *nim_runtime_env;$N" &
+      "extern void nim_component_construct(Genode::Env*);$N$N" &
       NimMainBody
 
     ComponentConstruct =
       "void Libc::Component::construct(Libc::Env &env) {$N" &
-      "\tgenodeEnv = &env;$N" &
+      "\t// Set Env used during runtime initialization$N" &
+      "\tnim_runtime_env = &env;$N" &
       "\tLibc::with_libc([&] () {$N\t" &
+      "\t// Initialize runtime and globals$N" &
       MainProcs &
+      "\t// Call application construct$N" &
+      "\t\tnim_component_construct(&env);$N" &
       "\t});$N" &
       "}$N$N"
 
@@ -1059,6 +1064,7 @@ proc genMainProc(m: BModule) =
   elif platform.targetOS == osGenode:
     nimMain = GenodeNimMain
     otherMain = ComponentConstruct
+    m.includeHeader("<libc/component.h>")
   elif optGenDynLib in m.config.globalOptions:
     nimMain = PosixNimDllMain
     otherMain = PosixCDllMain
diff --git a/lib/system/genodealloc.nim b/lib/genode/alloc.nim
index 3646a842d..52dc1c32c 100644
--- a/lib/system/genodealloc.nim
+++ b/lib/genode/alloc.nim
@@ -8,10 +8,15 @@
 #
 
 # Low level dataspace allocator for Genode.
+# For interacting with dataspaces outside of the
+# standard library see the Genode Nimble package.
 
 when not defined(genode):
   {.error: "Genode only module".}
 
+when not declared(GenodeEnv):
+  include genode/env
+
 type DataspaceCapability {.
   importcpp: "Genode::Dataspace_capability", pure.} = object
 
@@ -31,35 +36,35 @@ type
 
 const SlabBackendSize = 4096
 
-proc ramAvail(): int {.
-  importcpp: "genodeEnv->pd().avail_ram().value".}
+proc ramAvail(env: GenodeEnv): int {.
+  importcpp: "#->pd().avail_ram().value".}
   ## Return number of bytes available for allocation.
 
-proc capsAvail(): int {.
-  importcpp: "genodeEnv->pd().avail_caps().value".}
+proc capsAvail(env: GenodeEnv): int {.
+  importcpp: "#->pd().avail_caps().value".}
   ## Return the number of available capabilities.
   ## Each dataspace allocation consumes a capability.
 
-proc allocDataspace(size: int): DataspaceCapability {.
-  importcpp: "genodeEnv->pd().alloc(@)".}
+proc allocDataspace(env: GenodeEnv; size: int): DataspaceCapability {.
+  importcpp: "#->pd().alloc(@)".}
   ## Allocate a dataspace and its capability.
 
-proc attachDataspace(ds: DataspaceCapability): pointer {.
-  importcpp: "genodeEnv->rm().attach(@)".}
+proc attachDataspace(env: GenodeEnv; ds: DataspaceCapability): pointer {.
+  importcpp: "#->rm().attach(@)".}
   ## Attach a dataspace into the component address-space.
 
-proc detachAddress(p: pointer) {.
-  importcpp: "genodeEnv->rm().detach(@)".}
+proc detachAddress(env: GenodeEnv; p: pointer) {.
+  importcpp: "#->rm().detach(@)".}
   ## Detach a dataspace from the component address-space.
 
-proc freeDataspace(ds: DataspaceCapability) {.
-  importcpp: "genodeEnv->pd().free(@)".}
+proc freeDataspace(env: GenodeEnv; ds: DataspaceCapability) {.
+  importcpp: "#->pd().free(@)".}
   ## Free a dataspace.
 
 proc newMapSlab(): ptr MapSlab =
   let
-    ds = allocDataspace SlabBackendSize
-    p = attachDataspace ds
+    ds = runtimeEnv.allocDataspace SlabBackendSize
+    p = runtimeEnv.attachDataspace ds
   result = cast[ptr MapSlab](p)
   result.meta.ds = ds
 
@@ -89,13 +94,13 @@ proc osAllocPages(size: int): pointer =
           # tack a new slab on the tail
       slab = slab.meta.next
         # move to next slab in linked list
-  map.ds = allocDataspace size
+  map.ds = runtimeEnv.allocDataspace size
   map.size = size
-  map.attachment = attachDataspace map.ds
+  map.attachment = runtimeEnv.attachDataspace map.ds
   result = map.attachment
 
 proc osTryAllocPages(size: int): pointer =
-  if ramAvail() >= size and capsAvail() > 1:
+  if runtimeEnv.ramAvail() >= size and runtimeEnv.capsAvail() > 4:
     result = osAllocPages size
 
 proc osDeallocPages(p: pointer; size: int) =
@@ -107,8 +112,8 @@ proc osDeallocPages(p: pointer; size: int) =
         if m.size != size:
           echo "cannot partially detach dataspace"
           quit -1
-        detachAddress m.attachment
-        freeDataspace m.ds
+        runtimeEnv.detachAddress m.attachment
+        runtimeEnv.freeDataspace m.ds
         m[] = Map()
         return
     slab = slab.meta.next
diff --git a/lib/genode/env.nim b/lib/genode/env.nim
new file mode 100644
index 000000000..2b180d1b3
--- /dev/null
+++ b/lib/genode/env.nim
@@ -0,0 +1,29 @@
+#
+#
+#            Nim's Runtime Library
+#        (c) Copyright 2018 Emery Hemingway
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+#
+# This file contains the minimum required definitions
+# for interacting with the initial Genode environment.
+# It is reserved for use only within the standard
+# library. See ``componentConstructHook`` in the system
+# module for accessing the Genode environment after the
+# standard library has finished initializating.
+#
+
+when not defined(genode):
+  {.error: "Genode only include".}
+
+type
+  GenodeEnvObj {.importcpp: "Genode::Env", header: "<base/env.h>", pure.} = object
+  GenodeEnvPtr = ptr GenodeEnvObj
+
+const runtimeEnvSym = "nim_runtime_env"
+
+when not defined(nimscript):
+  var runtimeEnv {.importcpp: runtimeEnvSym.}: GenodeEnvPtr
diff --git a/lib/genode_cpp/threads.h b/lib/genode_cpp/threads.h
index a7cb2f17b..c901efb45 100644
--- a/lib/genode_cpp/threads.h
+++ b/lib/genode_cpp/threads.h
@@ -13,6 +13,7 @@
 #define _GENODE_CPP__THREAD_H_
 
 #include <base/thread.h>
+#include <base/env.h>
 #include <util/reconstructible.h>
 
 namespace Nim { struct SysThread; }
diff --git a/lib/nimbase.h b/lib/nimbase.h
index 20ac9979b..6dc742910 100644
--- a/lib/nimbase.h
+++ b/lib/nimbase.h
@@ -502,11 +502,6 @@ typedef int Nim_and_C_compiler_disagree_on_target_architecture[sizeof(NI) == siz
 #  include <sys/types.h>
 #endif
 
-#if defined(__GENODE__)
-#include <libc/component.h>
-extern Libc::Env *genodeEnv;
-#endif
-
 /* Compile with -d:checkAbi and a sufficiently C11:ish compiler to enable */
 #define NIM_CHECK_SIZE(typ, sz) \
   _Static_assert(sizeof(typ) == sz, "Nim & C disagree on type size")
diff --git a/lib/pure/concurrency/cpuinfo.nim b/lib/pure/concurrency/cpuinfo.nim
index f01488811..6d41aa1b2 100644
--- a/lib/pure/concurrency/cpuinfo.nim
+++ b/lib/pure/concurrency/cpuinfo.nim
@@ -38,8 +38,10 @@ when defined(macosx) or defined(bsd):
               importc: "sysctl", nodecl.}
 
 when defined(genode):
-  proc affinitySpaceTotal(): cuint {.
-    importcpp: "genodeEnv->cpu().affinity_space().total()".}
+  include genode/env
+
+  proc affinitySpaceTotal(env: GenodeEnvPtr): cuint {.
+    importcpp: "@->cpu().affinity_space().total()".}
 
 proc countProcessors*(): int {.rtl, extern: "ncpi$1".} =
   ## returns the numer of the processors/cores the machine has.
@@ -83,7 +85,7 @@ proc countProcessors*(): int {.rtl, extern: "ncpi$1".} =
     var SC_NPROC_ONLN {.importc: "_SC_NPROC_ONLN", header: "<unistd.h>".}: cint
     result = sysconf(SC_NPROC_ONLN)
   elif defined(genode):
-    result = affinitySpaceTotal().int
+    result = runtimeEnv.affinitySpaceTotal().int
   else:
     result = sysconf(SC_NPROCESSORS_ONLN)
   if result <= 0: result = 0
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index 04afb1eff..5008b904c 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -1440,7 +1440,7 @@ proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [ReadIOEffect].} =
     elif defined(solaris):
       result = getApplAux("/proc/" & $getpid() & "/path/a.out")
     elif defined(genode):
-      raiseOSError("POSIX command line not supported")
+      raiseOSError(OSErrorCode(-1), "POSIX command line not supported")
     elif defined(freebsd) or defined(dragonfly):
       result = getApplFreebsd()
     # little heuristic that may work on other POSIX-like systems:
diff --git a/lib/system.nim b/lib/system.nim
index fee9dc314..fb02fde23 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -1498,11 +1498,21 @@ when defined(nimdoc):
     ## macro, use the `error <manual.html#error-pragma>`_ or `fatal
     ## <manual.html#fatal-pragma>`_ pragmas.
 
-
 elif defined(genode):
-  proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit", noreturn,
-    importcpp: "genodeEnv->parent().exit(@); Genode::sleep_forever()",
-    header: "<base/sleep.h>".}
+  include genode/env
+
+  var systemEnv {.exportc: runtimeEnvSym.}: GenodeEnvPtr
+
+  type GenodeEnv* = GenodeEnvPtr
+    ## Opaque type representing Genode environment.
+
+  proc quit*(env: GenodeEnv; errorcode: int) {.magic: "Exit", noreturn,
+    importcpp: "#->parent().exit(@); Genode::sleep_forever()", header: "<base/sleep.h>".}
+
+  proc quit*(errorcode: int = QuitSuccess) =
+    systemEnv.quit(errorCode)
+
+
 
 elif defined(nodejs):
   proc quit*(errorcode: int = QuitSuccess) {.magic: "Exit",
@@ -4215,3 +4225,22 @@ when not defined(js):
 type
   ForLoopStmt* {.compilerProc.} = object ## special type that marks a macro
                                          ## as a `for-loop macro`:idx:
+
+when defined(genode):
+  var componentConstructHook*: proc (env: GenodeEnv) {.nimcall.}
+      ## Hook into the Genode component bootstrap process.
+      ## This hook is called after all globals are initialized.
+      ## When this hook is set the component will not automatically exit,
+      ## call ``quit`` explicitly to do so. This is the only available method
+      ## of accessing the initial Genode environment.
+
+  proc nim_component_construct(env: GenodeEnv) {.exportc.} =
+    ## Procedure called during ``Component::construct`` by the loader.
+    if componentConstructHook.isNil:
+      env.quit(programResult)
+        # No native Genode application initialization,
+        # exit as would POSIX.
+    else:
+      componentConstructHook(env)
+        # Perform application initialization
+        # and return to thread entrypoint.
diff --git a/lib/system/osalloc.nim b/lib/system/osalloc.nim
index 9609b6d39..a63eadf8e 100644
--- a/lib/system/osalloc.nim
+++ b/lib/system/osalloc.nim
@@ -78,7 +78,7 @@ when defined(emscripten):
     munmap(mmapDescr.realPointer, mmapDescr.realSize)
 
 elif defined(genode):
-  include genodealloc # osAllocPages, osTryAllocPages, osDeallocPages
+  include genode/alloc # osAllocPages, osTryAllocPages, osDeallocPages
 
 elif defined(posix):
   const
diff --git a/lib/system/threads.nim b/lib/system/threads.nim
index 861bde13f..c8ea03f92 100644
--- a/lib/system/threads.nim
+++ b/lib/system/threads.nim
@@ -116,6 +116,7 @@ when defined(windows):
     importc: "SetThreadAffinityMask", stdcall, header: "<windows.h>".}
 
 elif defined(genode):
+  import genode/env
   const
     GenodeHeader = "genode_cpp/threads.h"
   type
@@ -125,11 +126,12 @@ elif defined(genode):
     ThreadVarSlot = int
 
   proc initThread(s: var SysThread,
+                  env: GenodeEnv,
                   stackSize: culonglong,
                   entry: GenodeThreadProc,
                   arg: pointer,
                   affinity: cuint) {.
-    importcpp: "#.initThread(genodeEnv, @)".}
+    importcpp: "#.initThread(@)".}
 
   proc threadVarAlloc(): ThreadVarSlot = 0
 
@@ -569,7 +571,7 @@ when hostOS == "windows":
 
 elif defined(genode):
   var affinityOffset: cuint = 1
-  # CPU affinity offset for next thread, safe to roll-over
+    ## CPU affinity offset for next thread, safe to roll-over
 
   proc createThread*[TArg](t: var Thread[TArg],
                            tp: proc (arg: TArg) {.thread, nimcall.},
@@ -580,6 +582,7 @@ elif defined(genode):
     t.dataFn = tp
     when hasSharedHeap: t.stackSize = ThreadStackSize
     t.sys.initThread(
+      runtimeEnv,
       ThreadStackSize.culonglong,
       threadProcWrapper[TArg], addr(t), affinityOffset)
     inc affinityOffset
diff --git a/lib/wrappers/openssl.nim b/lib/wrappers/openssl.nim
index a24575d11..de3bfa616 100644
--- a/lib/wrappers/openssl.nim
+++ b/lib/wrappers/openssl.nim
@@ -44,6 +44,10 @@ else:
     const
       DLLSSLName* = "libssl" & versions & ".dylib"
       DLLUtilName* = "libcrypto" & versions & ".dylib"
+  elif defined(genode):
+    const
+      DLLSSLName* = "libssl.lib.so"
+      DLLUtilName* = "libcrypto.lib.so"
   else:
     const
       DLLSSLName* = "libssl.so" & versions