github.com/sagernet/gvisor@v0.0.0-20240428053021-e691de28565f/pkg/cpuid/cpuid_arm64.go (about)

     1  // Copyright 2020 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  //go:build arm64
    16  // +build arm64
    17  
    18  package cpuid
    19  
    20  import (
    21  	"fmt"
    22  	"io"
    23  )
    24  
    25  // FeatureSet for ARM64 is defined as a static set of bits.
    26  //
    27  // ARM64 doesn't have a CPUID equivalent, which means it has no architected
    28  // discovery mechanism for hardware features available to userspace code at
    29  // EL0. The kernel exposes the presence of these features to userspace through
    30  // a set of flags(HWCAP/HWCAP2) bits, exposed in the auxiliary vector. See
    31  // Documentation/arm64/elf_hwcaps.rst for more info.
    32  //
    33  // Currently, only the HWCAP bits are supported.
    34  //
    35  // +stateify savable
    36  type FeatureSet struct {
    37  	hwCap      hwCap
    38  	cpuFreqMHz float64
    39  	cpuImplHex uint64
    40  	cpuArchDec uint64
    41  	cpuVarHex  uint64
    42  	cpuPartHex uint64
    43  	cpuRevDec  uint64
    44  }
    45  
    46  // CPUImplementer is part of the processor signature.
    47  func (fs FeatureSet) CPUImplementer() uint8 {
    48  	return uint8(fs.cpuImplHex)
    49  }
    50  
    51  // CPUArchitecture is part of the processor signature.
    52  func (fs FeatureSet) CPUArchitecture() uint8 {
    53  	return uint8(fs.cpuArchDec)
    54  }
    55  
    56  // CPUVariant is part of the processor signature.
    57  func (fs FeatureSet) CPUVariant() uint8 {
    58  	return uint8(fs.cpuVarHex)
    59  }
    60  
    61  // CPUPartnum is part of the processor signature.
    62  func (fs FeatureSet) CPUPartnum() uint16 {
    63  	return uint16(fs.cpuPartHex)
    64  }
    65  
    66  // CPURevision is part of the processor signature.
    67  func (fs FeatureSet) CPURevision() uint8 {
    68  	return uint8(fs.cpuRevDec)
    69  }
    70  
    71  // ExtendedStateSize returns the number of bytes needed to save the "extended
    72  // state" for this processor and the boundary it must be aligned to. Extended
    73  // state includes floating point(NEON) registers, and other cpu state that's not
    74  // associated with the normal task context.
    75  func (fs FeatureSet) ExtendedStateSize() (size, align uint) {
    76  	// ARMv8 provide 32x128bits NEON registers.
    77  	//
    78  	// Ref arch/arm64/include/uapi/asm/ptrace.h
    79  	// struct user_fpsimd_state {
    80  	//        __uint128_t     vregs[32];
    81  	//        __u32           fpsr;
    82  	//        __u32           fpcr;
    83  	//        __u32           __reserved[2];
    84  	// };
    85  	return 528, 16
    86  }
    87  
    88  // HasFeature checks for the presence of a feature.
    89  func (fs FeatureSet) HasFeature(feature Feature) bool {
    90  	return fs.hwCap.hwCap1&(1<<feature) != 0
    91  }
    92  
    93  // WriteCPUInfoTo is to generate a section of one cpu in /proc/cpuinfo. This is
    94  // a minimal /proc/cpuinfo, and the bogomips field is simply made up.
    95  func (fs FeatureSet) WriteCPUInfoTo(cpu uint, w io.Writer) {
    96  	fmt.Fprintf(w, "processor\t: %d\n", cpu)
    97  	fmt.Fprintf(w, "BogoMIPS\t: %.02f\n", fs.cpuFreqMHz) // It's bogus anyway.
    98  	fmt.Fprintf(w, "Features\t\t: %s\n", fs.FlagString())
    99  	fmt.Fprintf(w, "CPU implementer\t: 0x%x\n", fs.cpuImplHex)
   100  	fmt.Fprintf(w, "CPU architecture\t: %d\n", fs.cpuArchDec)
   101  	fmt.Fprintf(w, "CPU variant\t: 0x%x\n", fs.cpuVarHex)
   102  	fmt.Fprintf(w, "CPU part\t: 0x%x\n", fs.cpuPartHex)
   103  	fmt.Fprintf(w, "CPU revision\t: %d\n", fs.cpuRevDec)
   104  	fmt.Fprintf(w, "\n") // The /proc/cpuinfo file ends with an extra newline.
   105  }
   106  
   107  // archCheckHostCompatible is a noop on arm64.
   108  func (FeatureSet) archCheckHostCompatible(FeatureSet) error {
   109  	return nil
   110  }