summaryrefslogtreecommitdiffstats
path: root/sys/arm64/include/cpu.h
diff options
context:
space:
mode:
authorzbb <zbb@FreeBSD.org>2015-07-09 11:32:29 +0000
committerzbb <zbb@FreeBSD.org>2015-07-09 11:32:29 +0000
commit99ff382570a14b26be5e95ed8886d0936ca03502 (patch)
tree62da4bc6a8ad154f56ea07d47a54d6fadc13432b /sys/arm64/include/cpu.h
parent58e696649e35af551042cee351aacf02aefae047 (diff)
downloadFreeBSD-src-99ff382570a14b26be5e95ed8886d0936ca03502.zip
FreeBSD-src-99ff382570a14b26be5e95ed8886d0936ca03502.tar.gz
Rework CPU identification on ARM64
This commit reworks the code responsible for identification of the CPUs during runtime. It is necessary to provide a way for workarounds and erratums to be applied only for certain HW versions. The copy of MIDR is now stored in pcpu to provide a fast and convenient way for assambly code to read it (pcpu is used quite often so there is a chance it's inside the cache). The MIDR is also better way of identification than using user-friendly cpu_desc structure, because it can be compiled into comparision of single u32 with only one access to the memory - this is crucial for some erratums which are called from performance-critical places. Changes in cpu_identify makes this function safe to be called on non-boot CPUs. New function CPU_MATCH was implemented which returns boolean value based on mathing masked MIDR with chip identification. Example of usage: printf("is thunder: %d\n", CPU_MATCH(CPU_IMPL_MASK | CPU_PART_MASK, CPU_IMPL_CAVIUM, CPU_PART_THUNDER, 0, 0)); printf("is generic: %d\n", CPU_MATCH(CPU_IMPL_MASK | CPU_PART_MASK, CPU_IMPL_ARM, CPU_PART_FOUNDATION, 0, 0)); Reviewed by: andrew Obtained from: Semihalf Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D3030
Diffstat (limited to 'sys/arm64/include/cpu.h')
-rw-r--r--sys/arm64/include/cpu.h37
1 files changed, 37 insertions, 0 deletions
diff --git a/sys/arm64/include/cpu.h b/sys/arm64/include/cpu.h
index e2438de..b805ddd 100644
--- a/sys/arm64/include/cpu.h
+++ b/sys/arm64/include/cpu.h
@@ -60,6 +60,43 @@
#ifdef _KERNEL
+#define CPU_IMPL_ARM 0x41
+#define CPU_IMPL_BROADCOM 0x42
+#define CPU_IMPL_CAVIUM 0x43
+#define CPU_IMPL_DEC 0x44
+#define CPU_IMPL_INFINEON 0x49
+#define CPU_IMPL_FREESCALE 0x4D
+#define CPU_IMPL_NVIDIA 0x4E
+#define CPU_IMPL_APM 0x50
+#define CPU_IMPL_QUALCOMM 0x51
+#define CPU_IMPL_MARVELL 0x56
+#define CPU_IMPL_INTEL 0x69
+
+#define CPU_PART_THUNDER 0x0A1
+#define CPU_PART_FOUNDATION 0xD00
+#define CPU_PART_CORTEX_A53 0xD03
+#define CPU_PART_CORTEX_A57 0xD07
+
+#define CPU_IMPL(midr) (((midr) >> 24) & 0xff)
+#define CPU_PART(midr) (((midr) >> 4) & 0xfff)
+#define CPU_VAR(midr) (((midr) >> 20) & 0xf)
+#define CPU_REV(midr) (((midr) >> 0) & 0xf)
+
+#define CPU_IMPL_TO_MIDR(val) (((val) & 0xff) << 24)
+#define CPU_PART_TO_MIDR(val) (((val) & 0xfff) << 4)
+#define CPU_VAR_TO_MIDR(val) (((val) & 0xf) << 20)
+#define CPU_REV_TO_MIDR(val) (((val) & 0xf) << 0)
+
+#define CPU_IMPL_MASK (0xff << 24)
+#define CPU_PART_MASK (0xfff << 4)
+#define CPU_VAR_MASK (0xf << 20)
+#define CPU_REV_MASK (0xf << 0)
+
+#define CPU_MATCH(mask, impl, part, var, rev) \
+ (((mask) & PCPU_GET(midr)) == (CPU_IMPL_TO_MIDR((impl)) | \
+ CPU_PART_TO_MIDR((part)) | CPU_VAR_TO_MIDR((var)) | \
+ CPU_REV_TO_MIDR((rev))))
+
extern char btext[];
extern char etext[];
OpenPOWER on IntegriCloud