| // Copyright 2016 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package runtime |
| |
| import ( |
| "unsafe" |
| ) |
| |
| const ( |
| permRead = 1 << 0 |
| permWrite = 1 << 1 |
| |
| propName = 3 |
| ) |
| |
| //go:linkname sys_vmar_unmap syscall/zx.Sys_vmar_unmap |
| func sys_vmar_unmap(h uint32, addr unsafe.Pointer, l uint64) int32 |
| |
| //go:linkname sys_vmo_create syscall/zx.Sys_vmo_create |
| //go:noescape |
| func sys_vmo_create(size uint64, options uint32, out *uint32) int32 |
| |
| //go:linkname sys_object_set_property syscall/zx.Sys_object_set_property |
| //go:noescape |
| func sys_object_set_property(handle uint32, property uint32, value unsafe.Pointer, value_size uint) int32 |
| |
| //go:linkname sys_vmar_map syscall/zx.Sys_vmar_map |
| //go:noescape |
| func sys_vmar_map(handle uint32, options uint32, vmar_offset uint64, vmo uint32, vmo_offset uint64, len uint64, mapped_addr *unsafe.Pointer) int32 |
| |
| //go:linkname sys_handle_close syscall/zx.Sys_handle_close |
| //go:noescape |
| func sys_handle_close(handle uint32) int32 |
| |
| //go:linkname sys_vmar_protect syscall/zx.Sys_vmar_protect |
| func sys_vmar_protect(handle uint32, options uint32, addr unsafe.Pointer, len uint64) int32 |
| |
| //go:nosplit |
| func sysAlloc(n uintptr, sysStat *uint64) unsafe.Pointer { |
| var p unsafe.Pointer |
| sysMmap(unsafe.Pointer(&p), n, permRead|permWrite) |
| if uintptr(p) < 4096 { |
| println("runtime: sysMmap failed n=", n) |
| exit(2) |
| } |
| mSysStatInc(sysStat, n) |
| return p |
| } |
| |
| func sysUnused(v unsafe.Pointer, n uintptr) { |
| // TODO(dho): Implement this based on ZX_VMO_OP_DECOMMIT |
| } |
| |
| func sysUsed(v unsafe.Pointer, n uintptr) { |
| // TODO(dho): Maybe implement this based on ZX_VMO_OP_COMMIT |
| } |
| |
| //go:nosplit |
| func sysFree(v unsafe.Pointer, n uintptr, sysStat *uint64) { |
| mSysStatDec(sysStat, n) |
| if status := sys_vmar_unmap(fdioHandles.vmarRootSelf, v, uint64(n)); status != 0 { |
| println("runtime: sys_vmar_unmap failed: ", status) |
| } |
| } |
| |
| func sysMmap(ptr unsafe.Pointer, sz uintptr, flags uint32) { |
| var h uint32 |
| if status := sys_vmo_create(uint64(sz), 0, &h); status != 0 { |
| println("runtime: sys_vmo_create failed: ", status) |
| exit(2) |
| } |
| |
| prop := []byte("go-sys-mmap") |
| if status := sys_object_set_property(h, propName, unsafe.Pointer(&prop[0]), uint(len(prop))); status != 0 { |
| println("runtime: sys_object_set_property failed: ", status) |
| exit(2) |
| } |
| |
| if status := sys_vmar_map(fdioHandles.vmarRootSelf, flags, 0, h, 0, uint64(sz), (*unsafe.Pointer)(ptr)); status != 0 { |
| println("runtime: sys_vmar_map failed: ", status) |
| exit(2) |
| } |
| |
| if status := sys_handle_close(h); status != 0 { |
| println("runtime: sys_handle_close failed: ", status) |
| exit(2) |
| } |
| } |
| |
| func sysReserve(v unsafe.Pointer, n uintptr) unsafe.Pointer { |
| p := v |
| sysMmap(unsafe.Pointer(&p), n, 0) |
| return p |
| } |
| |
| func sysFault(v unsafe.Pointer, n uintptr) { |
| println("TODO sysFault") |
| } |
| |
| func sysMap(v unsafe.Pointer, n uintptr, sysStat *uint64) { |
| mSysStatInc(sysStat, n) |
| |
| if status := sys_vmar_protect(fdioHandles.vmarRootSelf, permRead|permWrite, v, uint64(n)); status != 0 { |
| println("runtime: sys_vmar_protect failed: ", status) |
| exit(2) |
| } |
| } |