From c3490830e4e36d9e4201250c673428b866e75b06 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Tue, 19 Jun 2018 17:12:07 +0900 Subject: [PATCH] Add GC support for Nintendo Switch --- lib/nintendoswitch/switch_memory.nim | 24 +++++++++++++++++++++++ lib/system/osalloc.nim | 29 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 lib/nintendoswitch/switch_memory.nim diff --git a/lib/nintendoswitch/switch_memory.nim b/lib/nintendoswitch/switch_memory.nim new file mode 100644 index 000000000..fd0a215de --- /dev/null +++ b/lib/nintendoswitch/switch_memory.nim @@ -0,0 +1,24 @@ +const virtMemHeader = "" +const svcHeader = "" +const mallocHeader = "" + +type + Result* = uint32 + +proc memalign*(bytes: csize, size: csize): pointer {.importc: "memalign", + header: mallocHeader.} + +proc free*(address: pointer) {.importc: "free", + header: mallocHeader.} + +proc svcMapMemory*(dst_addr: pointer; src_addr: pointer; size: uint64): Result {. + importc: "svcMapMemory", header: svcHeader.} + +proc svcUnmapMemory*(dst_addr: pointer; src_addr: pointer; size: uint64): Result {. + importc: "svcUnmapMemory", header: svcHeader.} + +proc virtmemReserveMap*(size: csize): pointer {.importc: "virtmemReserveMap", + header: virtMemHeader.} + +proc virtmemFreeMap*(address: pointer; size: csize) {.importc: "virtmemFreeMap", + header: virtMemHeader.} diff --git a/lib/system/osalloc.nim b/lib/system/osalloc.nim index a63eadf8e..9b517cf49 100644 --- a/lib/system/osalloc.nim +++ b/lib/system/osalloc.nim @@ -80,6 +80,35 @@ when defined(emscripten): elif defined(genode): include genode/alloc # osAllocPages, osTryAllocPages, osDeallocPages +elif defined(nintendoswitch): + import nintendoswitch/switch_memory + + var + stack: pointer + + proc osAllocPages(size: int): pointer {.inline.} = + stack = memalign(0x1000, size) + result = virtmemReserveMap(size.csize) + let rc = svcMapMemory(result, stack, size.uint64) + if rc.uint32 != 0: + #discard svcUnmapMemory(result, stack, size.csize) + raiseOutOfMem() + + proc osTryAllocPages(size: int): pointer {.inline.} = + stack = memalign(0x1000, size) + result = virtmemReserveMap(size.csize) + let rc = svcMapMemory(result, stack, size.uint64) + if rc.uint32 != 0: + #discard svcUnmapMemory(result, stack, size.csize) + result = nil + + proc osDeallocPages(p: pointer, size: int) {.inline.} = + when reallyOsDealloc: + discard svcUnmapMemory(p, stack, size.uint64) + virtmemFreeMap(p, size.csize) + free(stack) + + elif defined(posix): const PROT_READ = 1 # page can be read