FFmpeg
cpu.c
Go to the documentation of this file.
1 /*
2  * Copyright © 2018, VideoLAN and dav1d authors
3  * Copyright © 2018, Two Orioles, LLC
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  *
12  * 2. Redistributions in binary form must reproduce the above copyright notice,
13  * this list of conditions and the following disclaimer in the documentation
14  * and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #include "checkasm_config.h"
29 
30 #if HAVE_GETAUXVAL || HAVE_ELF_AUX_INFO
31  #include <sys/auxv.h>
32 #endif
33 #ifdef __APPLE__
34  #include <sys/sysctl.h>
35 #endif
36 
37 #include <inttypes.h>
38 
39 #include "cpu.h"
40 #include "internal.h"
41 
43 {
44 #if ARCH_X86
45  checkasm_init_x86();
46 #elif ARCH_ARM
47  checkasm_init_arm();
48 #endif
49 }
50 
51 COLD unsigned long checkasm_getauxval(unsigned long type)
52 {
53 #if HAVE_GETAUXVAL
54  return getauxval(type);
55 #elif HAVE_ELF_AUX_INFO
56  unsigned long aux = 0;
57  elf_aux_info(type, &aux, sizeof(aux));
58  return aux;
59 #else
60  (void) type;
61  return 0;
62 #endif
63 }
64 
65 static COLD const char *get_brand_string(char *buf, size_t buflen, int affinity)
66 {
67 #if ARCH_X86
68  return checkasm_get_x86_cpuid(buf, buflen);
69 #elif defined(__APPLE__)
70  if (sysctlbyname("machdep.cpu.brand_string", buf, &buflen, NULL, 0) != 0) {
71  return NULL;
72  }
73  return buf;
74 #elif (ARCH_ARM || ARCH_AARCH64) && defined(__linux__)
75  return checkasm_get_arm_cpuinfo(buf, buflen, affinity);
76 #elif (ARCH_ARM || ARCH_AARCH64) && defined(_WIN32)
77  return checkasm_get_arm_win32_reg(buf, buflen, affinity);
78 #else
79  return NULL;
80 #endif
81 }
82 
83 COLD void checkasm_cpu_info(void (*info_cb)(void *priv, const char *fmt, ...), void *priv,
84  const CheckasmConfig *config)
85 {
86  char buf[128];
87 
88  const int affinity = config->cpu_affinity_set ? (int) config->cpu_affinity : -1;
89  const char *name = get_brand_string(buf, sizeof(buf), affinity);
90  if (name)
91  info_cb(priv, "%s", name);
92 
93 #if ARCH_RISCV
94  uint32_t vendorid;
95  uintptr_t archid, impid;
96 
97  if (checkasm_get_cpuids(&vendorid, &archid, &impid) == 0) {
98  const char *vendor = checkasm_get_riscv_vendor_name(vendorid);
99  const char *arch
100  = checkasm_get_riscv_arch_name(buf, sizeof(buf), vendorid, archid);
101 
102  info_cb(priv, "%s, %s, imp 0x%" PRIXPTR, vendor, arch, impid);
103  }
104 
105  if (checkasm_has_vector()) {
106  const unsigned long vlen = checkasm_get_vlen();
107  info_cb(priv, "VLEN = %lu bits", vlen);
108  }
109 #endif
110 #if ARCH_AARCH64
111  #if HAVE_SVE
112  if (checkasm_has_sve()) {
113  const unsigned sve_len = checkasm_sve_length();
114  info_cb(priv, "SVE = %d bits", sve_len);
115  }
116  #endif
117  #if HAVE_SME
118  if (checkasm_has_sme()) {
119  const unsigned sme_len = checkasm_sme_length();
120  info_cb(priv, "SME = %d bits", sme_len);
121  }
122  #endif
123 #endif
124 }
125 
126 struct jedec_vendor {
127  unsigned char bank;
128  unsigned char offset;
129  char name[14];
130 };
131 
132 static const struct jedec_vendor vendors[] = {
133  /* From JEDEC JEP106 (see OpenOCD's `jep106.inc` for a free equivalent). */
134  /* /!\ Must be sorted by bank then offset /!\ */
135  { 0, 0x01, "AMD" },
136  { 0, 0x09, "Intel" },
137  { 0, 0x29, "Microchip" },
138  { 0, 0x48, "Apple" },
139  { 2, 0x27, "MIPS" },
140  { 3, 0x6B, "NVIDIA" },
141  { 4, 0x3B, "ARM" },
142  { 6, 0x1E, "Andes Tech" },
143  { 9, 0x09, "SiFive Inc" },
144  { 10, 0x03, "Codasip GmbH" },
145  { 11, 0x37, "T-Head" }, // formerly C-Sky
146  { 14, 0x10, "SpacemiT" },
147  { 15, 0x21, "Tenstorrent" },
148 };
149 
150 static COLD int jvcmp(const void *pa, const void *pb)
151 {
152  const struct jedec_vendor *va = pa, *vb = pb;
153  int a = (va->bank << 7) | va->offset;
154  int b = (vb->bank << 7) | vb->offset;
155 
156  return a - b;
157 }
158 
159 COLD const char *checkasm_get_jedec_vendor_name(unsigned bank, unsigned offset)
160 {
161  const struct jedec_vendor key = { bank, offset, "" };
162  const struct jedec_vendor *v = bsearch(&key, vendors, ARRAY_SIZE(vendors),
163  sizeof (*v), jvcmp);
164 
165  return (v != NULL) ? v->name : "unknown";
166 }
COLD
#define COLD
Definition: internal.h:45
checkasm_cpu_info
COLD void checkasm_cpu_info(void(*info_cb)(void *priv, const char *fmt,...), void *priv, const CheckasmConfig *config)
Definition: cpu.c:83
checkasm_config.h
name
const char * name
Definition: cpu.c:41
b
#define b
Definition: input.c:43
vendors
static const struct jedec_vendor vendors[]
Definition: cpu.c:132
checkasm_getauxval
COLD unsigned long checkasm_getauxval(unsigned long type)
Definition: cpu.c:51
tf_sess_config.config
config
Definition: tf_sess_config.py:33
jedec_vendor::offset
unsigned char offset
Definition: cpu.c:128
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
key
const char * key
Definition: hwcontext_opencl.c:189
NULL
#define NULL
Definition: coverity.c:32
ARRAY_SIZE
#define ARRAY_SIZE(a)
Definition: internal.h:81
CheckasmConfig
Configuration structure for the checkasm test suite.
Definition: checkasm.h:158
checkasm_init_cpu
COLD void checkasm_init_cpu(void)
Definition: cpu.c:42
cpu.h
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
checkasm_get_jedec_vendor_name
const COLD char * checkasm_get_jedec_vendor_name(unsigned bank, unsigned offset)
Definition: cpu.c:159
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
jedec_vendor::bank
unsigned char bank
Definition: cpu.c:127
jedec_vendor::name
char name[14]
Definition: cpu.c:129
jvcmp
static COLD int jvcmp(const void *pa, const void *pb)
Definition: cpu.c:150
get_brand_string
static const COLD char * get_brand_string(char *buf, size_t buflen, int affinity)
Definition: cpu.c:65
internal.h
jedec_vendor
Definition: cpu.c:126