github.com/x04/go/src@v0.0.0-20200202162449-3d481ceb3525/runtime/os_freebsd_arm64.go (about)

     1  // Copyright 2019 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package runtime
     6  
     7  import "github.com/x04/go/src/internal/cpu"
     8  
     9  const (
    10  	hwcap_FP	= 1 << 0
    11  	hwcap_ASIMD	= 1 << 1
    12  	hwcap_EVTSTRM	= 1 << 2
    13  	hwcap_AES	= 1 << 3
    14  	hwcap_PMULL	= 1 << 4
    15  	hwcap_SHA1	= 1 << 5
    16  	hwcap_SHA2	= 1 << 6
    17  	hwcap_CRC32	= 1 << 7
    18  	hwcap_ATOMICS	= 1 << 8
    19  	hwcap_FPHP	= 1 << 9
    20  	hwcap_ASIMDHP	= 1 << 10
    21  	hwcap_CPUID	= 1 << 11
    22  	hwcap_ASIMDRDM	= 1 << 12
    23  	hwcap_JSCVT	= 1 << 13
    24  	hwcap_FCMA	= 1 << 14
    25  	hwcap_LRCPC	= 1 << 15
    26  	hwcap_DCPOP	= 1 << 16
    27  	hwcap_SHA3	= 1 << 17
    28  	hwcap_SM3	= 1 << 18
    29  	hwcap_SM4	= 1 << 19
    30  	hwcap_ASIMDDP	= 1 << 20
    31  	hwcap_SHA512	= 1 << 21
    32  	hwcap_SVE	= 1 << 22
    33  	hwcap_ASIMDFHM	= 1 << 23
    34  )
    35  
    36  func getisar0() uint64
    37  func getisar1() uint64
    38  func getpfr0() uint64
    39  
    40  // no hwcap support on FreeBSD aarch64, we need to retrieve the info from
    41  // ID_AA64ISAR0_EL1, ID_AA64ISAR1_EL1 and ID_AA64PFR0_EL1
    42  func archauxv(tag, val uintptr) {
    43  	var isar0, isar1, pfr0 uint64
    44  
    45  	isar0 = getisar0()
    46  	isar1 = getisar1()
    47  	pfr0 = getpfr0()
    48  
    49  	// ID_AA64ISAR0_EL1
    50  	switch extractBits(isar0, 4, 7) {
    51  	case 1:
    52  		cpu.HWCap |= hwcap_AES
    53  	case 2:
    54  		cpu.HWCap |= hwcap_PMULL | hwcap_AES
    55  	}
    56  
    57  	switch extractBits(isar0, 8, 11) {
    58  	case 1:
    59  		cpu.HWCap |= hwcap_SHA1
    60  	}
    61  
    62  	switch extractBits(isar0, 12, 15) {
    63  	case 1:
    64  		cpu.HWCap |= hwcap_SHA2
    65  	case 2:
    66  		cpu.HWCap |= hwcap_SHA2 | hwcap_SHA512
    67  	}
    68  
    69  	switch extractBits(isar0, 16, 19) {
    70  	case 1:
    71  		cpu.HWCap |= hwcap_CRC32
    72  	}
    73  
    74  	switch extractBits(isar0, 20, 23) {
    75  	case 2:
    76  		cpu.HWCap |= hwcap_ATOMICS
    77  	}
    78  
    79  	switch extractBits(isar0, 28, 31) {
    80  	case 1:
    81  		cpu.HWCap |= hwcap_ASIMDRDM
    82  	}
    83  
    84  	switch extractBits(isar0, 32, 35) {
    85  	case 1:
    86  		cpu.HWCap |= hwcap_SHA3
    87  	}
    88  
    89  	switch extractBits(isar0, 36, 39) {
    90  	case 1:
    91  		cpu.HWCap |= hwcap_SM3
    92  	}
    93  
    94  	switch extractBits(isar0, 40, 43) {
    95  	case 1:
    96  		cpu.HWCap |= hwcap_SM4
    97  	}
    98  
    99  	switch extractBits(isar0, 44, 47) {
   100  	case 1:
   101  		cpu.HWCap |= hwcap_ASIMDDP
   102  	}
   103  
   104  	// ID_AA64ISAR1_EL1
   105  	switch extractBits(isar1, 0, 3) {
   106  	case 1:
   107  		cpu.HWCap |= hwcap_DCPOP
   108  	}
   109  
   110  	switch extractBits(isar1, 12, 15) {
   111  	case 1:
   112  		cpu.HWCap |= hwcap_JSCVT
   113  	}
   114  
   115  	switch extractBits(isar1, 16, 19) {
   116  	case 1:
   117  		cpu.HWCap |= hwcap_FCMA
   118  	}
   119  
   120  	switch extractBits(isar1, 20, 23) {
   121  	case 1:
   122  		cpu.HWCap |= hwcap_LRCPC
   123  	}
   124  
   125  	// ID_AA64PFR0_EL1
   126  	switch extractBits(pfr0, 16, 19) {
   127  	case 0:
   128  		cpu.HWCap |= hwcap_FP
   129  	case 1:
   130  		cpu.HWCap |= hwcap_FP | hwcap_FPHP
   131  	}
   132  
   133  	switch extractBits(pfr0, 20, 23) {
   134  	case 0:
   135  		cpu.HWCap |= hwcap_ASIMD
   136  	case 1:
   137  		cpu.HWCap |= hwcap_ASIMD | hwcap_ASIMDHP
   138  	}
   139  
   140  	switch extractBits(pfr0, 32, 35) {
   141  	case 1:
   142  		cpu.HWCap |= hwcap_SVE
   143  	}
   144  }
   145  
   146  func extractBits(data uint64, start, end uint) uint {
   147  	return (uint)(data>>start) & ((1 << (end - start + 1)) - 1)
   148  }
   149  
   150  //go:nosplit
   151  func cputicks() int64 {
   152  	// Currently cputicks() is used in blocking profiler and to seed fastrand().
   153  	// nanotime() is a poor approximation of CPU ticks that is enough for the profiler.
   154  	return nanotime()
   155  }