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  }