| /* SPDX-License-Identifier: GPL-2.0-only */ |
| |
| #ifndef ARCH_CPUID_H |
| #define ARCH_CPUID_H |
| |
| #include <types.h> |
| |
| struct cpuid_result { |
| uint32_t eax; |
| uint32_t ebx; |
| uint32_t ecx; |
| uint32_t edx; |
| }; |
| |
| /* |
| * Generic CPUID function |
| */ |
| static inline struct cpuid_result cpuid(const uint32_t eax) |
| { |
| struct cpuid_result result; |
| asm volatile( |
| "cpuid;" |
| : "=a" (result.eax), |
| "=b" (result.ebx), |
| "=c" (result.ecx), |
| "=d" (result.edx) |
| : "a" (eax)); |
| return result; |
| } |
| |
| /* |
| * Generic Extended CPUID function |
| */ |
| static inline struct cpuid_result cpuid_ext(const uint32_t eax, const uint32_t ecx) |
| { |
| struct cpuid_result result; |
| asm volatile( |
| "cpuid;" |
| : "=a" (result.eax), |
| "=b" (result.ebx), |
| "=c" (result.ecx), |
| "=d" (result.edx) |
| : "a" (eax), "c" (ecx)); |
| return result; |
| } |
| |
| /* |
| * CPUID functions returning a single datum |
| */ |
| static inline uint32_t cpuid_eax(uint32_t eax) |
| { |
| asm volatile( |
| "cpuid;" |
| : "+a" (eax) |
| :: "ebx", "ecx", "edx"); |
| return eax; |
| } |
| |
| static inline uint32_t cpuid_ebx(uint32_t eax) |
| { |
| uint32_t ebx; |
| |
| asm volatile( |
| "cpuid;" |
| : "=b" (ebx), "+a" (eax) |
| :: "ecx", "edx"); |
| return ebx; |
| } |
| |
| static inline uint32_t cpuid_ecx(uint32_t eax) |
| { |
| uint32_t ecx; |
| |
| asm volatile( |
| "cpuid;" |
| : "=c" (ecx), "+a" (eax) |
| :: "ebx", "edx"); |
| return ecx; |
| } |
| |
| static inline uint32_t cpuid_edx(uint32_t eax) |
| { |
| uint32_t edx; |
| |
| asm volatile( |
| "cpuid;" |
| : "=d" (edx), "+a" (eax) |
| :: "ebx", "ecx"); |
| return edx; |
| } |
| |
| #endif /* ARCH_CPUID_H */ |