blob: b2780bec472c79c85e7f8c2d24c344f9b56abddf [file] [log] [blame]
Martin Roth568670f92022-09-17 15:52:36 -06001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#ifndef ARCH_CPUID_H
4#define ARCH_CPUID_H
5
6#include <types.h>
7
8struct cpuid_result {
9 uint32_t eax;
10 uint32_t ebx;
11 uint32_t ecx;
12 uint32_t edx;
13};
14
15/*
16 * Generic CPUID function
17 */
Matei Dibu516eff02022-08-02 00:48:59 +030018static inline struct cpuid_result cpuid(const uint32_t eax)
Martin Roth568670f92022-09-17 15:52:36 -060019{
20 struct cpuid_result result;
21 asm volatile(
Martin Roth568670f92022-09-17 15:52:36 -060022 "cpuid;"
Martin Roth568670f92022-09-17 15:52:36 -060023 : "=a" (result.eax),
Matei Dibu516eff02022-08-02 00:48:59 +030024 "=b" (result.ebx),
Martin Roth568670f92022-09-17 15:52:36 -060025 "=c" (result.ecx),
26 "=d" (result.edx)
Matei Dibu516eff02022-08-02 00:48:59 +030027 : "a" (eax));
Martin Roth568670f92022-09-17 15:52:36 -060028 return result;
29}
30
31/*
32 * Generic Extended CPUID function
33 */
Matei Dibu516eff02022-08-02 00:48:59 +030034static inline struct cpuid_result cpuid_ext(const uint32_t eax, const uint32_t ecx)
Martin Roth568670f92022-09-17 15:52:36 -060035{
36 struct cpuid_result result;
37 asm volatile(
Martin Roth568670f92022-09-17 15:52:36 -060038 "cpuid;"
Martin Roth568670f92022-09-17 15:52:36 -060039 : "=a" (result.eax),
Matei Dibu516eff02022-08-02 00:48:59 +030040 "=b" (result.ebx),
Martin Roth568670f92022-09-17 15:52:36 -060041 "=c" (result.ecx),
42 "=d" (result.edx)
Matei Dibu516eff02022-08-02 00:48:59 +030043 : "a" (eax), "c" (ecx));
Martin Roth568670f92022-09-17 15:52:36 -060044 return result;
45}
46
47/*
48 * CPUID functions returning a single datum
49 */
Matei Dibu516eff02022-08-02 00:48:59 +030050static inline uint32_t cpuid_eax(uint32_t eax)
Martin Roth568670f92022-09-17 15:52:36 -060051{
Matei Dibu516eff02022-08-02 00:48:59 +030052 asm volatile(
Martin Roth568670f92022-09-17 15:52:36 -060053 "cpuid;"
Matei Dibu516eff02022-08-02 00:48:59 +030054 : "+a" (eax)
55 :: "ebx", "ecx", "edx");
Martin Roth568670f92022-09-17 15:52:36 -060056 return eax;
57}
58
Patrick Rudolph699b1c42023-09-30 15:12:17 +020059static inline uint32_t cpuid_ebx(uint32_t eax)
Martin Roth568670f92022-09-17 15:52:36 -060060{
Matei Dibu516eff02022-08-02 00:48:59 +030061 uint32_t ebx;
Martin Roth568670f92022-09-17 15:52:36 -060062
Matei Dibu516eff02022-08-02 00:48:59 +030063 asm volatile(
Martin Roth568670f92022-09-17 15:52:36 -060064 "cpuid;"
Patrick Rudolph699b1c42023-09-30 15:12:17 +020065 : "=b" (ebx), "+a" (eax)
66 :: "ecx", "edx");
Martin Roth568670f92022-09-17 15:52:36 -060067 return ebx;
68}
69
Patrick Rudolph699b1c42023-09-30 15:12:17 +020070static inline uint32_t cpuid_ecx(uint32_t eax)
Martin Roth568670f92022-09-17 15:52:36 -060071{
Matei Dibu516eff02022-08-02 00:48:59 +030072 uint32_t ecx;
Martin Roth568670f92022-09-17 15:52:36 -060073
Matei Dibu516eff02022-08-02 00:48:59 +030074 asm volatile(
Martin Roth568670f92022-09-17 15:52:36 -060075 "cpuid;"
Patrick Rudolph699b1c42023-09-30 15:12:17 +020076 : "=c" (ecx), "+a" (eax)
77 :: "ebx", "edx");
Martin Roth568670f92022-09-17 15:52:36 -060078 return ecx;
79}
80
Patrick Rudolph699b1c42023-09-30 15:12:17 +020081static inline uint32_t cpuid_edx(uint32_t eax)
Martin Roth568670f92022-09-17 15:52:36 -060082{
Matei Dibu516eff02022-08-02 00:48:59 +030083 uint32_t edx;
Martin Roth568670f92022-09-17 15:52:36 -060084
Matei Dibu516eff02022-08-02 00:48:59 +030085 asm volatile(
Martin Roth568670f92022-09-17 15:52:36 -060086 "cpuid;"
Patrick Rudolph699b1c42023-09-30 15:12:17 +020087 : "=d" (edx), "+a" (eax)
88 :: "ebx", "ecx");
Martin Roth568670f92022-09-17 15:52:36 -060089 return edx;
90}
91
92#endif /* ARCH_CPUID_H */