111 lines
3.5 KiB
Go
111 lines
3.5 KiB
Go
// Copyright 2020 The gVisor Authors.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
//go:build arm64
|
|
// +build arm64
|
|
|
|
package cpuid
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
)
|
|
|
|
// FeatureSet for ARM64 is defined as a static set of bits.
|
|
//
|
|
// ARM64 doesn't have a CPUID equivalent, which means it has no architected
|
|
// discovery mechanism for hardware features available to userspace code at
|
|
// EL0. The kernel exposes the presence of these features to userspace through
|
|
// a set of flags(HWCAP/HWCAP2) bits, exposed in the auxiliary vector. See
|
|
// Documentation/arm64/elf_hwcaps.rst for more info.
|
|
//
|
|
// Currently, only the HWCAP bits are supported.
|
|
//
|
|
// +stateify savable
|
|
type FeatureSet struct {
|
|
hwCap uint
|
|
cpuFreqMHz float64
|
|
cpuImplHex uint64
|
|
cpuArchDec uint64
|
|
cpuVarHex uint64
|
|
cpuPartHex uint64
|
|
cpuRevDec uint64
|
|
}
|
|
|
|
// CPUImplementer is part of the processor signature.
|
|
func (fs FeatureSet) CPUImplementer() uint8 {
|
|
return uint8(fs.cpuImplHex)
|
|
}
|
|
|
|
// CPUArchitecture is part of the processor signature.
|
|
func (fs FeatureSet) CPUArchitecture() uint8 {
|
|
return uint8(fs.cpuArchDec)
|
|
}
|
|
|
|
// CPUVariant is part of the processor signature.
|
|
func (fs FeatureSet) CPUVariant() uint8 {
|
|
return uint8(fs.cpuVarHex)
|
|
}
|
|
|
|
// CPUPartnum is part of the processor signature.
|
|
func (fs FeatureSet) CPUPartnum() uint16 {
|
|
return uint16(fs.cpuPartHex)
|
|
}
|
|
|
|
// CPURevision is part of the processor signature.
|
|
func (fs FeatureSet) CPURevision() uint8 {
|
|
return uint8(fs.cpuRevDec)
|
|
}
|
|
|
|
// ExtendedStateSize returns the number of bytes needed to save the "extended
|
|
// state" for this processor and the boundary it must be aligned to. Extended
|
|
// state includes floating point(NEON) registers, and other cpu state that's not
|
|
// associated with the normal task context.
|
|
func (fs FeatureSet) ExtendedStateSize() (size, align uint) {
|
|
// ARMv8 provide 32x128bits NEON registers.
|
|
//
|
|
// Ref arch/arm64/include/uapi/asm/ptrace.h
|
|
// struct user_fpsimd_state {
|
|
// __uint128_t vregs[32];
|
|
// __u32 fpsr;
|
|
// __u32 fpcr;
|
|
// __u32 __reserved[2];
|
|
// };
|
|
return 528, 16
|
|
}
|
|
|
|
// HasFeature checks for the presence of a feature.
|
|
func (fs FeatureSet) HasFeature(feature Feature) bool {
|
|
return fs.hwCap&(1<<feature) != 0
|
|
}
|
|
|
|
// WriteCPUInfoTo is to generate a section of one cpu in /proc/cpuinfo. This is
|
|
// a minimal /proc/cpuinfo, and the bogomips field is simply made up.
|
|
func (fs FeatureSet) WriteCPUInfoTo(cpu uint, w io.Writer) {
|
|
fmt.Fprintf(w, "processor\t: %d\n", cpu)
|
|
fmt.Fprintf(w, "BogoMIPS\t: %.02f\n", fs.cpuFreqMHz) // It's bogus anyway.
|
|
fmt.Fprintf(w, "Features\t\t: %s\n", fs.FlagString())
|
|
fmt.Fprintf(w, "CPU implementer\t: 0x%x\n", fs.cpuImplHex)
|
|
fmt.Fprintf(w, "CPU architecture\t: %d\n", fs.cpuArchDec)
|
|
fmt.Fprintf(w, "CPU variant\t: 0x%x\n", fs.cpuVarHex)
|
|
fmt.Fprintf(w, "CPU part\t: 0x%x\n", fs.cpuPartHex)
|
|
fmt.Fprintf(w, "CPU revision\t: %d\n", fs.cpuRevDec)
|
|
fmt.Fprintf(w, "\n") // The /proc/cpuinfo file ends with an extra newline.
|
|
}
|
|
|
|
// archCheckHostCompatible is a noop on arm64.
|
|
func (FeatureSet) archCheckHostCompatible(FeatureSet) error {
|
|
return nil
|
|
}
|