github.com/f-secure-foundry/tamago@v0.0.0-20220307101044-d73fcdd7f11b/internal/reg/reg16.go (about) 1 // https://github.com/f-secure-foundry/tamago 2 // 3 // Copyright (c) F-Secure Corporation 4 // https://foundry.f-secure.com 5 // 6 // Use of this source code is governed by the license 7 // that can be found in the LICENSE file. 8 9 package reg 10 11 import ( 12 "runtime" 13 "time" 14 "unsafe" 15 ) 16 17 // As sync/atomic does not provide 16-bit support, note that these functions do 18 // not necessarily enforce memory ordering. 19 20 func Get16(addr uint32, pos int, mask int) uint16 { 21 reg := (*uint16)(unsafe.Pointer(uintptr(addr))) 22 return (*reg >> pos) & uint16(mask) 23 } 24 25 func Set16(addr uint32, pos int) { 26 reg := (*uint16)(unsafe.Pointer(uintptr(addr))) 27 *reg |= (1 << pos) 28 } 29 30 func Clear16(addr uint32, pos int) { 31 reg := (*uint16)(unsafe.Pointer(uintptr(addr))) 32 *reg &= ^(1 << pos) 33 } 34 35 func SetN16(addr uint32, pos int, mask int, val uint16) { 36 reg := (*uint16)(unsafe.Pointer(uintptr(addr))) 37 *reg = (*reg & (^(uint16(mask) << pos))) | (val << pos) 38 } 39 40 func ClearN16(addr uint32, pos int, mask int) { 41 reg := (*uint16)(unsafe.Pointer(uintptr(addr))) 42 *reg &= ^(uint16(mask) << pos) 43 } 44 45 func Read16(addr uint32) uint16 { 46 reg := (*uint16)(unsafe.Pointer(uintptr(addr))) 47 return *reg 48 } 49 50 func Write16(addr uint32, val uint16) { 51 reg := (*uint16)(unsafe.Pointer(uintptr(addr))) 52 *reg = val 53 } 54 55 func WriteBack16(addr uint32) { 56 reg := (*uint16)(unsafe.Pointer(uintptr(addr))) 57 *reg |= *reg 58 } 59 60 func Or16(addr uint32, val uint16) { 61 reg := (*uint16)(unsafe.Pointer(uintptr(addr))) 62 *reg |= val 63 } 64 65 // Wait16 waits for a specific register bit to match a value. This function 66 // cannot be used before runtime initialization with `GOOS=tamago`. 67 func Wait16(addr uint32, pos int, mask int, val uint16) { 68 for Get16(addr, pos, mask) != val { 69 // tamago is single-threaded, give other goroutines a chance 70 runtime.Gosched() 71 } 72 } 73 74 // WaitFor16 waits, until a timeout expires, for a specific register bit to match 75 // a value. The return boolean indicates whether the wait condition was checked 76 // (true) or if it timed out (false). This function cannot be used before 77 // runtime initialization with `GOOS=tamago`. 78 func WaitFor16(timeout time.Duration, addr uint32, pos int, mask int, val uint16) bool { 79 start := time.Now() 80 81 for Get16(addr, pos, mask) != val { 82 // tamago is single-threaded, give other goroutines a chance 83 runtime.Gosched() 84 85 if time.Since(start) >= timeout { 86 return false 87 } 88 } 89 90 return true 91 }