Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
ccan
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
mirror
ccan
Commits
004098ab
Commit
004098ab
authored
Nov 09, 2013
by
Rusty Russell
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of ozlabs.org:ccan
parents
447cfb71
7cc24627
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
189 additions
and
152 deletions
+189
-152
ccan/cpuid/cpuid.c
ccan/cpuid/cpuid.c
+76
-71
ccan/cpuid/cpuid.h
ccan/cpuid/cpuid.h
+102
-77
ccan/cpuid/test/run.c
ccan/cpuid/test/run.c
+11
-4
No files found.
ccan/cpuid/cpuid.c
View file @
004098ab
...
...
@@ -31,8 +31,8 @@
#include <string.h>
enum
{
CPU_PROC_BRAND_STRING_INTERNAL0
=
0x80000003
,
CPU_PROC_BRAND_STRING_INTERNAL1
=
0x80000004
CPU
ID
_PROC_BRAND_STRING_INTERNAL0
=
0x80000003
,
CPU
ID
_PROC_BRAND_STRING_INTERNAL1
=
0x80000004
};
#ifndef _MSC_VER
...
...
@@ -61,35 +61,6 @@ static void ___cpuid(cpuid_t info, uint32_t *eax, uint32_t *ebx, uint32_t *ecx,
}
#endif
static
struct
{
uint32_t
feature
;
uint32_t
mask
;
bool
use_edx
;
/* ecx will be used if false. */
}
features
[]
=
{
{
CF_MMX
,
1
<<
23
,
true
},
{
CF_SSE
,
1
<<
25
,
true
},
{
CF_SSE2
,
1
<<
26
,
true
},
{
CF_SSE3
,
1
<<
9
,
false
},
{
CF_FPU
,
1
<<
0
,
true
},
{
CF_TSC
,
1
<<
4
,
true
},
{
CF_MSR
,
1
<<
5
,
true
},
{
CF_SSSE3
,
1
<<
9
,
false
},
{
CF_AVX
,
1
<<
28
,
false
},
/* Extended ones. */
{
CEF_x64
,
1
<<
30
,
true
},
{
CEF_FPU
,
1
<<
0
,
true
},
{
CEF_DE
,
1
<<
2
,
true
},
{
CEF_SYSCALLRET
,
1
<<
11
,
true
},
{
CEF_CMOV
,
1
<<
15
,
true
},
{
CEF_SSE4a
,
1
<<
6
,
false
},
{
CEF_FMA4
,
1
<<
16
,
false
},
{
CEF_XOP
,
1
<<
11
,
false
}
};
bool
cpuid_is_supported
(
void
)
{
int
ret
=
0
;
...
...
@@ -160,8 +131,8 @@ bool cpuid_is_supported(void)
pushfd
pop
eax
xor
eax
,
ecx
shr
eax
,
0x
21
and
eax
,
0x
1
shr
eax
,
21
and
eax
,
1
push
ecx
popfd
...
...
@@ -173,30 +144,54 @@ bool cpuid_is_supported(void)
bool
cpuid_test_feature
(
cpuid_t
feature
)
{
if
(
feature
>
CPU
_VIRT_PHYS_ADDR_SIZES
||
feature
<
CPU
_EXTENDED_PROC_INFO_FEATURE_BITS
)
if
(
feature
>
CPU
ID_VIRT_PHYS_ADDR_SIZES
||
feature
<
CPUID
_EXTENDED_PROC_INFO_FEATURE_BITS
)
return
false
;
return
(
feature
<=
cpuid_highest_ext_func_supported
());
}
bool
cpuid_has_
feature
(
int
feature
,
bool
extended
)
bool
cpuid_has_
ecxfeature
(
int
feature
)
{
uint32_t
eax
,
ebx
,
ecx
,
edx
,
i
;
if
(
!
extended
)
___cpuid
(
CPU_PROCINFO_AND_FEATUREBITS
,
&
eax
,
&
ebx
,
&
ecx
,
&
edx
);
else
___cpuid
(
CPU_EXTENDED_PROC_INFO_FEATURE_BITS
,
&
eax
,
&
ebx
,
&
ecx
,
&
edx
);
for
(
i
=
0
;
i
<
sizeof
(
features
)
/
sizeof
(
features
[
0
]);
++
i
)
{
if
(
features
[
i
].
feature
==
feature
)
{
if
(
features
[
i
].
use_edx
)
return
(
edx
&
features
[
i
].
mask
);
else
return
(
ecx
&
features
[
i
].
mask
);
}
static
uint32_t
_ecx
;
if
(
_ecx
==
0
)
{
#if defined(__GNUC__) || defined(__clang__)
asm
volatile
(
"cpuid
\n\t
"
:
"=c"
(
_ecx
)
:
"a"
(
CPUID_PROCINFO_AND_FEATUREBITS
)
);
#elif defined _MSC_VER
__asm
{
mov
eax
,
CPUID_PROCINFO_AND_FEATUREBITS
cpuid
mov
_ecx
,
ecx
};
#endif
}
return
false
;
return
(
_ecx
&
feature
)
==
feature
;
}
bool
cpuid_has_edxfeature
(
int
feature
)
{
static
uint32_t
_edx
;
if
(
_edx
==
0
)
{
#if defined(__GNUC__) || defined(__clang__)
asm
volatile
(
"cpuid
\n\t
"
:
"=d"
(
_edx
)
:
"a"
(
CPUID_PROCINFO_AND_FEATUREBITS
)
);
#elif defined _MSC_VER
__asm
{
mov
eax
,
CPUID_PROCINFO_AND_FEATUREBITS
cpuid
mov
_edx
,
edx
};
#endif
}
return
(
_edx
&
feature
)
==
feature
;
}
static
const
char
*
const
cpuids
[]
=
{
...
...
@@ -228,7 +223,7 @@ cputype_t cpuid_get_cpu_type(void)
}
u
;
uint32_t
i
;
___cpuid
(
CPU_VENDORID
,
&
i
,
&
u
.
bufu32
[
0
],
&
u
.
bufu32
[
2
],
&
u
.
bufu32
[
1
]);
___cpuid
(
CPU
ID
_VENDORID
,
&
i
,
&
u
.
bufu32
[
0
],
&
u
.
bufu32
[
2
],
&
u
.
bufu32
[
1
]);
for
(
i
=
0
;
i
<
sizeof
(
cpuids
)
/
sizeof
(
cpuids
[
0
]);
++
i
)
{
if
(
strncmp
(
cpuids
[
i
],
u
.
buf
,
12
)
==
0
)
{
cputype
=
(
cputype_t
)
i
;
...
...
@@ -259,11 +254,11 @@ uint32_t cpuid_highest_ext_func_supported(void)
asm
volatile
(
"cpuid
\n\t
"
:
"=a"
(
highest
)
:
"a"
(
CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
)
:
"a"
(
CPU
ID
_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
)
);
#elif defined _MSC_VER
__asm
{
mov
eax
,
CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
mov
eax
,
CPU
ID
_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
cpuid
mov
highest
,
eax
};
...
...
@@ -278,23 +273,23 @@ void cpuid(cpuid_t info, uint32_t *buf)
/* Sanity checks, make sure we're not trying to do something
* invalid or we are trying to get information that isn't supported
* by the CPU. */
if
(
info
>
CPU
_VIRT_PHYS_ADDR_SIZES
||
(
info
>
CPU
_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
if
(
info
>
CPU
ID_VIRT_PHYS_ADDR_SIZES
||
(
info
>
CPUID
_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
&&
!
cpuid_test_feature
(
info
)))
return
;
if
(
info
==
CPU_PROC_BRAND_STRING
)
{
if
(
info
==
CPU
ID
_PROC_BRAND_STRING
)
{
static
char
cached
[
48
]
=
{
0
};
if
(
cached
[
0
]
==
'\0'
)
{
___cpuid
(
CPU_PROC_BRAND_STRING
,
&
buf
[
0
],
&
buf
[
1
],
&
buf
[
2
],
&
buf
[
3
]);
___cpuid
(
CPU_PROC_BRAND_STRING_INTERNAL0
,
&
buf
[
4
],
&
buf
[
5
],
&
buf
[
6
],
&
buf
[
7
]);
___cpuid
(
CPU_PROC_BRAND_STRING_INTERNAL1
,
&
buf
[
8
],
&
buf
[
9
],
&
buf
[
10
],
&
buf
[
11
]);
___cpuid
(
CPU
ID
_PROC_BRAND_STRING
,
&
buf
[
0
],
&
buf
[
1
],
&
buf
[
2
],
&
buf
[
3
]);
___cpuid
(
CPU
ID
_PROC_BRAND_STRING_INTERNAL0
,
&
buf
[
4
],
&
buf
[
5
],
&
buf
[
6
],
&
buf
[
7
]);
___cpuid
(
CPU
ID
_PROC_BRAND_STRING_INTERNAL1
,
&
buf
[
8
],
&
buf
[
9
],
&
buf
[
10
],
&
buf
[
11
]);
memcpy
(
cached
,
buf
,
sizeof
cached
);
}
else
buf
=
(
uint32_t
*
)
cached
;
return
;
}
else
if
(
info
==
CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
)
{
}
else
if
(
info
==
CPU
ID
_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
)
{
*
buf
=
cpuid_highest_ext_func_supported
();
return
;
}
...
...
@@ -303,42 +298,52 @@ void cpuid(cpuid_t info, uint32_t *buf)
___cpuid
(
info
,
&
eax
,
&
ebx
,
&
ecx
,
&
edx
);
switch
(
info
)
{
case
CPU_VENDORID
:
case
CPU
ID
_VENDORID
:
buf
[
0
]
=
ebx
;
buf
[
1
]
=
edx
;
buf
[
2
]
=
ecx
;
break
;
case
CPU_PROCINFO_AND_FEATUREBITS
:
buf
[
0
]
=
eax
;
/* The so called "signature" of the CPU. */
buf
[
1
]
=
edx
;
/* Feature flags #1. */
buf
[
2
]
=
ecx
;
/* Feature flags #2. */
buf
[
3
]
=
ebx
;
/* Additional feature information. */
case
CPUID_PROCINFO_AND_FEATUREBITS
:
buf
[
0
]
=
(
eax
&
0x0F
);
/* Stepping */
buf
[
1
]
=
(
eax
>>
4
)
&
0x0F
;
/* Model */
buf
[
2
]
=
(
eax
>>
8
)
&
0x0F
;
/* Family */
buf
[
3
]
=
(
eax
>>
16
)
&
0x0F
;
/* Extended Model. */
buf
[
4
]
=
(
eax
>>
24
)
&
0x0F
;
/* Extended Family. */
buf
[
5
]
=
edx
;
/* Feature flags #1. */
buf
[
6
]
=
ecx
;
/* Feature flags #2. */
/* Additional Feature information. */
buf
[
7
]
=
ebx
&
0xFF
;
buf
[
8
]
=
(
ebx
>>
8
)
&
0xFF
;
buf
[
9
]
=
(
ebx
>>
16
)
&
0xFF
;
buf
[
10
]
=
(
ebx
>>
24
)
&
0xFF
;
break
;
case
CPU_CACHE_AND_TLBD_INFO
:
case
CPU
ID
_CACHE_AND_TLBD_INFO
:
buf
[
0
]
=
eax
;
buf
[
1
]
=
ebx
;
buf
[
2
]
=
ecx
;
buf
[
3
]
=
edx
;
break
;
case
CPU_EXTENDED_PROC_INFO_FEATURE_BITS
:
case
CPU
ID
_EXTENDED_PROC_INFO_FEATURE_BITS
:
buf
[
0
]
=
edx
;
buf
[
1
]
=
ecx
;
break
;
case
CPU_L1_CACHE_AND_TLB_IDS
:
case
CPU
ID
_L1_CACHE_AND_TLB_IDS
:
buf
[
0
]
=
eax
;
buf
[
1
]
=
ebx
;
buf
[
2
]
=
ecx
;
buf
[
3
]
=
edx
;
break
;
case
CPU_EXTENDED_L2_CACHE_FEATURES
:
case
CPU
ID
_EXTENDED_L2_CACHE_FEATURES
:
buf
[
0
]
=
ecx
&
0xFF
;
/* Line size. */
buf
[
1
]
=
(
ecx
>>
12
)
&
0xFF
;
/* Associativity. */
buf
[
2
]
=
ecx
>>
16
;
/* Cache size. */
break
;
case
CPU_ADV_POWER_MGT_INFO
:
case
CPU
ID
_ADV_POWER_MGT_INFO
:
*
buf
=
edx
;
break
;
case
CPU_VIRT_PHYS_ADDR_SIZES
:
case
CPU
ID
_VIRT_PHYS_ADDR_SIZES
:
buf
[
0
]
=
eax
&
0xFF
;
/* physical. */
buf
[
1
]
=
(
eax
>>
8
)
&
0xFF
;
/* virtual. */
break
;
...
...
ccan/cpuid/cpuid.h
View file @
004098ab
...
...
@@ -30,71 +30,110 @@
*
* This is used as a parameter in cpuid().
*
* CPU_VENDORID:
* CPU
ID
_VENDORID:
* The CPU's Vendor ID.
*
* CPU_PROCINFO_AND_FEATUREBITS:
* CPU
ID
_PROCINFO_AND_FEATUREBITS:
* Processor information and feature bits (SSE, etc.).
*
* CPU_CACHE_AND_TLBD_INFO
* CPU
ID
_CACHE_AND_TLBD_INFO
* Cache and TLBD Information.
*
* CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED:
* CPU
ID
_HIGHEST_EXTENDED_FUNCTION_SUPPORTED:
* Highest extended function supported address.
* Can be like 0x80000008.
*
* CPU_EXTENDED_PROC_INFO_FEATURE_BITS:
* CPU
ID
_EXTENDED_PROC_INFO_FEATURE_BITS:
* Extended processor information and feature bits (64bit etc.)
*
* CPU_PROC_BRAND_STRING:
* CPU
ID
_PROC_BRAND_STRING:
* The Processor's brand string.
*
* CPU_L1_CACHE_AND_TLB_IDS:
* CPU
ID
_L1_CACHE_AND_TLB_IDS:
* L1 Cache and TLB Identifications.
*
* CPU_EXTENDED_L2_CACHE_FEATURES:
* CPU
ID
_EXTENDED_L2_CACHE_FEATURES:
* Extended L2 Cache features.
*
* CPU_ADV_POWER_MGT_INFO:
* CPU
ID
_ADV_POWER_MGT_INFO:
* Advaned power management information.
*
* CPU_VIRT_PHYS_ADDR_SIZES:
* CPU
ID
_VIRT_PHYS_ADDR_SIZES:
* Virtual and physical address sizes.
*/
typedef
enum
cpuid
{
CPU_VENDORID
=
0
,
CPU_PROCINFO_AND_FEATUREBITS
=
1
,
CPU_CACHE_AND_TLBD_INFO
=
2
,
CPU
ID
_VENDORID
=
0
,
CPU
ID
_PROCINFO_AND_FEATUREBITS
=
1
,
CPU
ID
_CACHE_AND_TLBD_INFO
=
2
,
CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
=
0x80000000
,
CPU_EXTENDED_PROC_INFO_FEATURE_BITS
=
0x80000001
,
CPU_PROC_BRAND_STRING
=
0x80000002
,
CPU_L1_CACHE_AND_TLB_IDS
=
0x80000005
,
CPU_EXTENDED_L2_CACHE_FEATURES
=
0x80000006
,
CPU_ADV_POWER_MGT_INFO
=
0x80000007
,
CPU_VIRT_PHYS_ADDR_SIZES
=
0x80000008
CPU
ID
_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
=
0x80000000
,
CPU
ID
_EXTENDED_PROC_INFO_FEATURE_BITS
=
0x80000001
,
CPU
ID
_PROC_BRAND_STRING
=
0x80000002
,
CPU
ID
_L1_CACHE_AND_TLB_IDS
=
0x80000005
,
CPU
ID
_EXTENDED_L2_CACHE_FEATURES
=
0x80000006
,
CPU
ID
_ADV_POWER_MGT_INFO
=
0x80000007
,
CPU
ID
_VIRT_PHYS_ADDR_SIZES
=
0x80000008
}
cpuid_t
;
#define CF_MMX 0
#define CF_SSE 1
#define CF_SSE2 2
#define CF_SSE3 3
#define CF_FPU 4
#define CF_TSC 5
#define CF_MSR 6
#define CF_SSSE3 7
#define CF_AVX 8
#define CF_FMA 9
enum
{
CPUID_FEAT_ECX_SSE3
=
1
<<
0
,
CPUID_FEAT_ECX_PCLMUL
=
1
<<
1
,
CPUID_FEAT_ECX_DTES64
=
1
<<
2
,
CPUID_FEAT_ECX_MONITOR
=
1
<<
3
,
CPUID_FEAT_ECX_DS_CPL
=
1
<<
4
,
CPUID_FEAT_ECX_VMX
=
1
<<
5
,
CPUID_FEAT_ECX_SMX
=
1
<<
6
,
CPUID_FEAT_ECX_EST
=
1
<<
7
,
CPUID_FEAT_ECX_TM2
=
1
<<
8
,
CPUID_FEAT_ECX_SSSE3
=
1
<<
9
,
CPUID_FEAT_ECX_CID
=
1
<<
10
,
CPUID_FEAT_ECX_FMA
=
1
<<
12
,
CPUID_FEAT_ECX_CX16
=
1
<<
13
,
CPUID_FEAT_ECX_ETPRD
=
1
<<
14
,
CPUID_FEAT_ECX_PDCM
=
1
<<
15
,
CPUID_FEAT_ECX_DCA
=
1
<<
18
,
CPUID_FEAT_ECX_SSE4_1
=
1
<<
19
,
CPUID_FEAT_ECX_SSE4_2
=
1
<<
20
,
CPUID_FEAT_ECX_x2APIC
=
1
<<
21
,
CPUID_FEAT_ECX_MOVBE
=
1
<<
22
,
CPUID_FEAT_ECX_POPCNT
=
1
<<
23
,
CPUID_FEAT_ECX_AES
=
1
<<
25
,
CPUID_FEAT_ECX_XSAVE
=
1
<<
26
,
CPUID_FEAT_ECX_OSXSAVE
=
1
<<
27
,
CPUID_FEAT_ECX_AVX
=
1
<<
28
,
#define CEF_x64 10
#define CEF_FPU 11
#define CEF_DE 12
#define CEF_SYSCALLRET 13
#define CEF_CMOV 14
#define CEF_SSE4a 15
#define CEF_FMA4 16
#define CEF_XOP 17
CPUID_FEAT_EDX_FPU
=
1
<<
0
,
CPUID_FEAT_EDX_VME
=
1
<<
1
,
CPUID_FEAT_EDX_DE
=
1
<<
2
,
CPUID_FEAT_EDX_PSE
=
1
<<
3
,
CPUID_FEAT_EDX_TSC
=
1
<<
4
,
CPUID_FEAT_EDX_MSR
=
1
<<
5
,
CPUID_FEAT_EDX_PAE
=
1
<<
6
,
CPUID_FEAT_EDX_MCE
=
1
<<
7
,
CPUID_FEAT_EDX_CX8
=
1
<<
8
,
CPUID_FEAT_EDX_APIC
=
1
<<
9
,
CPUID_FEAT_EDX_SEP
=
1
<<
11
,
CPUID_FEAT_EDX_MTRR
=
1
<<
12
,
CPUID_FEAT_EDX_PGE
=
1
<<
13
,
CPUID_FEAT_EDX_MCA
=
1
<<
14
,
CPUID_FEAT_EDX_CMOV
=
1
<<
15
,
CPUID_FEAT_EDX_PAT
=
1
<<
16
,
CPUID_FEAT_EDX_PSE36
=
1
<<
17
,
CPUID_FEAT_EDX_PSN
=
1
<<
18
,
CPUID_FEAT_EDX_CLF
=
1
<<
19
,
CPUID_FEAT_EDX_DTES
=
1
<<
21
,
CPUID_FEAT_EDX_ACPI
=
1
<<
22
,
CPUID_FEAT_EDX_MMX
=
1
<<
23
,
CPUID_FEAT_EDX_FXSR
=
1
<<
24
,
CPUID_FEAT_EDX_SSE
=
1
<<
25
,
CPUID_FEAT_EDX_SSE2
=
1
<<
26
,
CPUID_FEAT_EDX_SS
=
1
<<
27
,
CPUID_FEAT_EDX_HTT
=
1
<<
28
,
CPUID_FEAT_EDX_TM1
=
1
<<
29
,
CPUID_FEAT_EDX_IA64
=
1
<<
30
,
CPUID_FEAT_EDX_PBE
=
1
<<
31
};
typedef
enum
cputype
{
CT_NONE
,
...
...
@@ -154,7 +193,7 @@ bool cpuid_is_supported(void);
* Returns the highest extended function supported.
*
* This is the same as calling:
* cpuid(CPU_HIGHEST_EEXTENDED_FUNCTION_SUPPORTED, &highest);
* cpuid(CPU
ID
_HIGHEST_EEXTENDED_FUNCTION_SUPPORTED, &highest);
*
* This is made visible to the linker because it's easier to call it
* instead of calling cpuid with less type-checking. cpuid calls this.
...
...
@@ -169,23 +208,23 @@ uint32_t cpuid_highest_ext_func_supported(void);
* This function expects buf to be a valid pointer to a string/int/...
* depending on the requested information.
*
* For CPU_VENDOR_ID:
* For CPU
ID
_VENDOR_ID:
* Returns a string into buf.
*
* For CPU_PROCINFO_AND_FEATUREBITS:
* buf[0]:
* - 3:0 - Stepping
* - 7:4 - Model
* - 11:8 - Family
* - 13:12 - Processor Type
* - 19:16 - Extended Model
* - 27:20 - Extended family
* buf[1] and buf[2]:
* For CPUID_PROCINFO_AND_FEATUREBITS:
* buf[0]: Stepping
* buf[1]: Model
* buf[2]: Family
* buf[3]: Extended Model
* buf[4]: Extended Family
* buf[5] and buf[6]:
* Feature flags
* buf[3]:
* Additional feature information.
* buf[7]: Brand Index
* buf[8]: CL Flush Line Size
* buf[9]: Logical Processors
* buf[10]: Initial APICID
*
* For CPU_L1_CACHE_AND_TLB_IDS:
* For CPU
ID
_L1_CACHE_AND_TLB_IDS:
* buf[0]: (eax):
* - 7..0 Number of times to exec cpuid to get all descriptors.
* - 15..8 Instruction TLB: 4K Pages, 4-way set associtive, 128 entries.
...
...
@@ -202,22 +241,22 @@ uint32_t cpuid_highest_ext_func_supported(void);
* - 16..23 Data TLB: 4M Pages, 4-way set associtive, 8 entires.
* - 24..31 1st-level data cache: 32K, 8-way set associtive, 64 byte line size
*
* For CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED:
* For CPU
ID
_HIGHEST_EXTENDED_FUNCTION_SUPPORTED:
* Returns the highest supported function in *buf (expects an integer ofc)
*
* For CPU_EXTENDED_PROC_INFO_FEATURE_BITS:
* For CPU
ID
_EXTENDED_PROC_INFO_FEATURE_BITS:
* Returns them in buf[0] and buf[1].
*
* For CPU_EXTENDED_L2_CACHE_FEATURES:
* For CPU
ID
_EXTENDED_L2_CACHE_FEATURES:
* buf[0]: Line size
* buf[1]: Associativity
* buf[2]: Cache size.
*
* For CPU_VIRT_PHYS_ADDR_SIZES:
* For CPU
ID
_VIRT_PHYS_ADDR_SIZES:
* buf[0]: Physical
* buf[1]: Virtual
*
* For CPU_PROC_BRAND_STRING:
* For CPU
ID
_PROC_BRAND_STRING:
* Have a char array with at least 48 bytes assigned to it.
*
* Here's a page which will help you parse the data provided by this function.
...
...
@@ -232,8 +271,8 @@ void cpuid(cpuid_t info, uint32_t *buf);
*
* Returns true if feature is supported, false otherwise.
*
* The feature parameter must be >= CPU_EXTENDED_PROC_INFO_FEATURE_BITS
* and <= CPU_VIRT_PHYS_ADDR_SIZES.
* The feature parameter must be >= CPU
ID
_EXTENDED_PROC_INFO_FEATURE_BITS
* and <= CPU
ID
_VIRT_PHYS_ADDR_SIZES.
*/
bool
cpuid_test_feature
(
cpuid_t
feature
);
...
...
@@ -241,27 +280,13 @@ bool cpuid_test_feature(cpuid_t feature);
* cpuid_has_feature - Test if @feature is supported
*
* Test if the CPU supports MMX/SSE* etc.
* For the extended parameter, usually you want to pass it as
* false if you're not passing CEF_*.
*
* For more information about the CPU extended features, have a look
* at:
* http://en.wikipedia.org/wiki/CPUID
* Use cpuid_has_ecxfeature() for *_ECX* features and
* cpuid_has_edxfeature() for *_EDX* features.
*
* Returns true if the feature is available, false otherwise.
*/
#define cpuid_has_mmx() cpuid_has_feature(CF_MMX, false)
#define cpuid_has_sse() cpuid_has_feature(CF_SSE, false)
#define cpuid_has_sse2() cpuid_has_feature(CF_SSE2, false)
#define cpuid_has_sse3() cpuid_has_feature(CF_SSE3, false)
#define cpuid_has_ssse3() cpuid_has_feature(CF_SSSE3, false)
#define cpuid_has_avx() cpuid_has_feature(CF_AVX, false)
#define cpuid_has_fma() cpuid_has_feature(CF_FMA, false)
#define cpuid_has_x64() cpuid_has_feature(CEF_x64, true)
#define cpuid_has_sse4a() cpuid_has_feature(CEF_SSE4a, true)
#define cpuid_has_fma4() cpuid_has_feature(CEF_FMA4, true)
#define cpuid_has_xop() cpuid_has_feature(CEF_XOP, true)
bool
cpuid_has_feature
(
int
feature
,
bool
extended
);
bool
cpuid_has_ecxfeature
(
int
feature
);
bool
cpuid_has_edxfeature
(
int
feature
);
#else
#include <ccan/build_assert/build_assert.h>
...
...
ccan/cpuid/test/run.c
View file @
004098ab
...
...
@@ -15,21 +15,28 @@ int main(void)
printf
(
"Vendor ID: %s
\n
"
,
cputype
);
char
buf
[
48
];
cpuid
(
CPU_PROC_BRAND_STRING
,
(
uint32_t
*
)
buf
);
cpuid
(
CPU
ID
_PROC_BRAND_STRING
,
(
uint32_t
*
)
buf
);
printf
(
"Processor Brand: %s
\n
"
,
buf
);
uint32_t
procinfo
[
11
];
cpuid
(
CPUID_PROCINFO_AND_FEATUREBITS
,
procinfo
);
printf
(
"Stepping: %d Model: 0x%X Family: %d extended model: %d extended family: %d
\n
"
,
procinfo
[
0
],
procinfo
[
1
],
procinfo
[
2
],
procinfo
[
3
],
procinfo
[
4
]);
printf
(
"Brand Index: %d CL Flush Line Size: %d Logical Processors: %d Initial APICID: %d
\n
"
,
procinfo
[
7
],
procinfo
[
8
],
procinfo
[
9
],
procinfo
[
10
]);
printf
(
"Highest extended function supported: %#010x
\n
"
,
cpuid_highest_ext_func_supported
());
uint32_t
phys_virt
[
2
];
cpuid
(
CPU_VIRT_PHYS_ADDR_SIZES
,
phys_virt
);
cpuid
(
CPU
ID
_VIRT_PHYS_ADDR_SIZES
,
phys_virt
);
printf
(
"Physical address size: %d
\n
Virtual address size: %d
\n
"
,
phys_virt
[
0
],
phys_virt
[
1
]);
uint32_t
extfeatures
[
2
];
cpuid
(
CPU_EXTENDED_PROC_INFO_FEATURE_BITS
,
extfeatures
);
cpuid
(
CPU
ID
_EXTENDED_PROC_INFO_FEATURE_BITS
,
extfeatures
);
printf
(
"Extended processor info and feature bits: %d %d
\n
"
,
extfeatures
[
0
],
extfeatures
[
1
]);
uint32_t
l2c
[
3
];
cpuid
(
CPU_EXTENDED_L2_CACHE_FEATURES
,
l2c
);
cpuid
(
CPU
ID
_EXTENDED_L2_CACHE_FEATURES
,
l2c
);
printf
(
"L2 Line size: %u bytes
\t
Associativity: %02xh
\t
Cache Size: %u KB
\n
"
,
l2c
[
0
],
l2c
[
1
],
l2c
[
2
]);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment