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
Show 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 @@
...
@@ -31,8 +31,8 @@
#include <string.h>
#include <string.h>
enum
{
enum
{
CPU_PROC_BRAND_STRING_INTERNAL0
=
0x80000003
,
CPU
ID
_PROC_BRAND_STRING_INTERNAL0
=
0x80000003
,
CPU_PROC_BRAND_STRING_INTERNAL1
=
0x80000004
CPU
ID
_PROC_BRAND_STRING_INTERNAL1
=
0x80000004
};
};
#ifndef _MSC_VER
#ifndef _MSC_VER
...
@@ -61,35 +61,6 @@ static void ___cpuid(cpuid_t info, uint32_t *eax, uint32_t *ebx, uint32_t *ecx,
...
@@ -61,35 +61,6 @@ static void ___cpuid(cpuid_t info, uint32_t *eax, uint32_t *ebx, uint32_t *ecx,
}
}
#endif
#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
)
bool
cpuid_is_supported
(
void
)
{
{
int
ret
=
0
;
int
ret
=
0
;
...
@@ -160,8 +131,8 @@ bool cpuid_is_supported(void)
...
@@ -160,8 +131,8 @@ bool cpuid_is_supported(void)
pushfd
pushfd
pop
eax
pop
eax
xor
eax
,
ecx
xor
eax
,
ecx
shr
eax
,
0x
21
shr
eax
,
21
and
eax
,
0x
1
and
eax
,
1
push
ecx
push
ecx
popfd
popfd
...
@@ -173,30 +144,54 @@ bool cpuid_is_supported(void)
...
@@ -173,30 +144,54 @@ bool cpuid_is_supported(void)
bool
cpuid_test_feature
(
cpuid_t
feature
)
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
false
;
return
(
feature
<=
cpuid_highest_ext_func_supported
());
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
;
static
uint32_t
_ecx
;
if
(
_ecx
==
0
)
{
if
(
!
extended
)
#if defined(__GNUC__) || defined(__clang__)
___cpuid
(
CPU_PROCINFO_AND_FEATUREBITS
,
&
eax
,
&
ebx
,
&
ecx
,
&
edx
);
asm
volatile
(
else
"cpuid
\n\t
"
___cpuid
(
CPU_EXTENDED_PROC_INFO_FEATURE_BITS
,
&
eax
,
&
ebx
,
&
ecx
,
&
edx
);
:
"=c"
(
_ecx
)
:
"a"
(
CPUID_PROCINFO_AND_FEATUREBITS
)
for
(
i
=
0
;
i
<
sizeof
(
features
)
/
sizeof
(
features
[
0
]);
++
i
)
{
);
if
(
features
[
i
].
feature
==
feature
)
{
#elif defined _MSC_VER
if
(
features
[
i
].
use_edx
)
__asm
{
return
(
edx
&
features
[
i
].
mask
);
mov
eax
,
CPUID_PROCINFO_AND_FEATUREBITS
else
cpuid
return
(
ecx
&
features
[
i
].
mask
);
mov
_ecx
,
ecx
};
#endif
}
}
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
false
;
return
(
_edx
&
feature
)
==
feature
;
}
}
static
const
char
*
const
cpuids
[]
=
{
static
const
char
*
const
cpuids
[]
=
{
...
@@ -228,7 +223,7 @@ cputype_t cpuid_get_cpu_type(void)
...
@@ -228,7 +223,7 @@ cputype_t cpuid_get_cpu_type(void)
}
u
;
}
u
;
uint32_t
i
;
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
)
{
for
(
i
=
0
;
i
<
sizeof
(
cpuids
)
/
sizeof
(
cpuids
[
0
]);
++
i
)
{
if
(
strncmp
(
cpuids
[
i
],
u
.
buf
,
12
)
==
0
)
{
if
(
strncmp
(
cpuids
[
i
],
u
.
buf
,
12
)
==
0
)
{
cputype
=
(
cputype_t
)
i
;
cputype
=
(
cputype_t
)
i
;
...
@@ -259,11 +254,11 @@ uint32_t cpuid_highest_ext_func_supported(void)
...
@@ -259,11 +254,11 @@ uint32_t cpuid_highest_ext_func_supported(void)
asm
volatile
(
asm
volatile
(
"cpuid
\n\t
"
"cpuid
\n\t
"
:
"=a"
(
highest
)
:
"=a"
(
highest
)
:
"a"
(
CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
)
:
"a"
(
CPU
ID
_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
)
);
);
#elif defined _MSC_VER
#elif defined _MSC_VER
__asm
{
__asm
{
mov
eax
,
CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
mov
eax
,
CPU
ID
_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
cpuid
cpuid
mov
highest
,
eax
mov
highest
,
eax
};
};
...
@@ -278,23 +273,23 @@ void cpuid(cpuid_t info, uint32_t *buf)
...
@@ -278,23 +273,23 @@ void cpuid(cpuid_t info, uint32_t *buf)
/* Sanity checks, make sure we're not trying to do something
/* Sanity checks, make sure we're not trying to do something
* invalid or we are trying to get information that isn't supported
* invalid or we are trying to get information that isn't supported
* by the CPU. */
* 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
)))
&&
!
cpuid_test_feature
(
info
)))
return
;
return
;
if
(
info
==
CPU_PROC_BRAND_STRING
)
{
if
(
info
==
CPU
ID
_PROC_BRAND_STRING
)
{
static
char
cached
[
48
]
=
{
0
};
static
char
cached
[
48
]
=
{
0
};
if
(
cached
[
0
]
==
'\0'
)
{
if
(
cached
[
0
]
==
'\0'
)
{
___cpuid
(
CPU_PROC_BRAND_STRING
,
&
buf
[
0
],
&
buf
[
1
],
&
buf
[
2
],
&
buf
[
3
]);
___cpuid
(
CPU
ID
_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
ID
_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_INTERNAL1
,
&
buf
[
8
],
&
buf
[
9
],
&
buf
[
10
],
&
buf
[
11
]);
memcpy
(
cached
,
buf
,
sizeof
cached
);
memcpy
(
cached
,
buf
,
sizeof
cached
);
}
else
}
else
buf
=
(
uint32_t
*
)
cached
;
buf
=
(
uint32_t
*
)
cached
;
return
;
return
;
}
else
if
(
info
==
CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
)
{
}
else
if
(
info
==
CPU
ID
_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
)
{
*
buf
=
cpuid_highest_ext_func_supported
();
*
buf
=
cpuid_highest_ext_func_supported
();
return
;
return
;
}
}
...
@@ -303,42 +298,52 @@ void cpuid(cpuid_t info, uint32_t *buf)
...
@@ -303,42 +298,52 @@ void cpuid(cpuid_t info, uint32_t *buf)
___cpuid
(
info
,
&
eax
,
&
ebx
,
&
ecx
,
&
edx
);
___cpuid
(
info
,
&
eax
,
&
ebx
,
&
ecx
,
&
edx
);
switch
(
info
)
{
switch
(
info
)
{
case
CPU_VENDORID
:
case
CPU
ID
_VENDORID
:
buf
[
0
]
=
ebx
;
buf
[
0
]
=
ebx
;
buf
[
1
]
=
edx
;
buf
[
1
]
=
edx
;
buf
[
2
]
=
ecx
;
buf
[
2
]
=
ecx
;
break
;
break
;
case
CPU_PROCINFO_AND_FEATUREBITS
:
case
CPUID_PROCINFO_AND_FEATUREBITS
:
buf
[
0
]
=
eax
;
/* The so called "signature" of the CPU. */
buf
[
0
]
=
(
eax
&
0x0F
);
/* Stepping */
buf
[
1
]
=
edx
;
/* Feature flags #1. */
buf
[
1
]
=
(
eax
>>
4
)
&
0x0F
;
/* Model */
buf
[
2
]
=
ecx
;
/* Feature flags #2. */
buf
[
2
]
=
(
eax
>>
8
)
&
0x0F
;
/* Family */
buf
[
3
]
=
ebx
;
/* Additional feature information. */
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
;
break
;
case
CPU_CACHE_AND_TLBD_INFO
:
case
CPU
ID
_CACHE_AND_TLBD_INFO
:
buf
[
0
]
=
eax
;
buf
[
0
]
=
eax
;
buf
[
1
]
=
ebx
;
buf
[
1
]
=
ebx
;
buf
[
2
]
=
ecx
;
buf
[
2
]
=
ecx
;
buf
[
3
]
=
edx
;
buf
[
3
]
=
edx
;
break
;
break
;
case
CPU_EXTENDED_PROC_INFO_FEATURE_BITS
:
case
CPU
ID
_EXTENDED_PROC_INFO_FEATURE_BITS
:
buf
[
0
]
=
edx
;
buf
[
0
]
=
edx
;
buf
[
1
]
=
ecx
;
buf
[
1
]
=
ecx
;
break
;
break
;
case
CPU_L1_CACHE_AND_TLB_IDS
:
case
CPU
ID
_L1_CACHE_AND_TLB_IDS
:
buf
[
0
]
=
eax
;
buf
[
0
]
=
eax
;
buf
[
1
]
=
ebx
;
buf
[
1
]
=
ebx
;
buf
[
2
]
=
ecx
;
buf
[
2
]
=
ecx
;
buf
[
3
]
=
edx
;
buf
[
3
]
=
edx
;
break
;
break
;
case
CPU_EXTENDED_L2_CACHE_FEATURES
:
case
CPU
ID
_EXTENDED_L2_CACHE_FEATURES
:
buf
[
0
]
=
ecx
&
0xFF
;
/* Line size. */
buf
[
0
]
=
ecx
&
0xFF
;
/* Line size. */
buf
[
1
]
=
(
ecx
>>
12
)
&
0xFF
;
/* Associativity. */
buf
[
1
]
=
(
ecx
>>
12
)
&
0xFF
;
/* Associativity. */
buf
[
2
]
=
ecx
>>
16
;
/* Cache size. */
buf
[
2
]
=
ecx
>>
16
;
/* Cache size. */
break
;
break
;
case
CPU_ADV_POWER_MGT_INFO
:
case
CPU
ID
_ADV_POWER_MGT_INFO
:
*
buf
=
edx
;
*
buf
=
edx
;
break
;
break
;
case
CPU_VIRT_PHYS_ADDR_SIZES
:
case
CPU
ID
_VIRT_PHYS_ADDR_SIZES
:
buf
[
0
]
=
eax
&
0xFF
;
/* physical. */
buf
[
0
]
=
eax
&
0xFF
;
/* physical. */
buf
[
1
]
=
(
eax
>>
8
)
&
0xFF
;
/* virtual. */
buf
[
1
]
=
(
eax
>>
8
)
&
0xFF
;
/* virtual. */
break
;
break
;
...
...
ccan/cpuid/cpuid.h
View file @
004098ab
...
@@ -30,71 +30,110 @@
...
@@ -30,71 +30,110 @@
*
*
* This is used as a parameter in cpuid().
* This is used as a parameter in cpuid().
*
*
* CPU_VENDORID:
* CPU
ID
_VENDORID:
* The CPU's Vendor ID.
* The CPU's Vendor ID.
*
*
* CPU_PROCINFO_AND_FEATUREBITS:
* CPU
ID
_PROCINFO_AND_FEATUREBITS:
* Processor information and feature bits (SSE, etc.).
* Processor information and feature bits (SSE, etc.).
*
*
* CPU_CACHE_AND_TLBD_INFO
* CPU
ID
_CACHE_AND_TLBD_INFO
* Cache and TLBD Information.
* Cache and TLBD Information.
*
*
* CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED:
* CPU
ID
_HIGHEST_EXTENDED_FUNCTION_SUPPORTED:
* Highest extended function supported address.
* Highest extended function supported address.
* Can be like 0x80000008.
* 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.)
* Extended processor information and feature bits (64bit etc.)
*
*
* CPU_PROC_BRAND_STRING:
* CPU
ID
_PROC_BRAND_STRING:
* The Processor's 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.
* L1 Cache and TLB Identifications.
*
*
* CPU_EXTENDED_L2_CACHE_FEATURES:
* CPU
ID
_EXTENDED_L2_CACHE_FEATURES:
* Extended L2 Cache features.
* Extended L2 Cache features.
*
*
* CPU_ADV_POWER_MGT_INFO:
* CPU
ID
_ADV_POWER_MGT_INFO:
* Advaned power management information.
* Advaned power management information.
*
*
* CPU_VIRT_PHYS_ADDR_SIZES:
* CPU
ID
_VIRT_PHYS_ADDR_SIZES:
* Virtual and physical address sizes.
* Virtual and physical address sizes.
*/
*/
typedef
enum
cpuid
{
typedef
enum
cpuid
{
CPU_VENDORID
=
0
,
CPU
ID
_VENDORID
=
0
,
CPU_PROCINFO_AND_FEATUREBITS
=
1
,
CPU
ID
_PROCINFO_AND_FEATUREBITS
=
1
,
CPU_CACHE_AND_TLBD_INFO
=
2
,
CPU
ID
_CACHE_AND_TLBD_INFO
=
2
,
CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
=
0x80000000
,
CPU
ID
_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
=
0x80000000
,
CPU_EXTENDED_PROC_INFO_FEATURE_BITS
=
0x80000001
,
CPU
ID
_EXTENDED_PROC_INFO_FEATURE_BITS
=
0x80000001
,
CPU_PROC_BRAND_STRING
=
0x80000002
,
CPU
ID
_PROC_BRAND_STRING
=
0x80000002
,
CPU_L1_CACHE_AND_TLB_IDS
=
0x80000005
,
CPU
ID
_L1_CACHE_AND_TLB_IDS
=
0x80000005
,
CPU_EXTENDED_L2_CACHE_FEATURES
=
0x80000006
,
CPU
ID
_EXTENDED_L2_CACHE_FEATURES
=
0x80000006
,
CPU_ADV_POWER_MGT_INFO
=
0x80000007
,
CPU
ID
_ADV_POWER_MGT_INFO
=
0x80000007
,
CPU_VIRT_PHYS_ADDR_SIZES
=
0x80000008
CPU
ID
_VIRT_PHYS_ADDR_SIZES
=
0x80000008
}
cpuid_t
;
}
cpuid_t
;
#define CF_MMX 0
enum
{
#define CF_SSE 1
CPUID_FEAT_ECX_SSE3
=
1
<<
0
,
#define CF_SSE2 2
CPUID_FEAT_ECX_PCLMUL
=
1
<<
1
,
#define CF_SSE3 3
CPUID_FEAT_ECX_DTES64
=
1
<<
2
,
#define CF_FPU 4
CPUID_FEAT_ECX_MONITOR
=
1
<<
3
,
#define CF_TSC 5
CPUID_FEAT_ECX_DS_CPL
=
1
<<
4
,
#define CF_MSR 6
CPUID_FEAT_ECX_VMX
=
1
<<
5
,
#define CF_SSSE3 7
CPUID_FEAT_ECX_SMX
=
1
<<
6
,
#define CF_AVX 8
CPUID_FEAT_ECX_EST
=
1
<<
7
,
#define CF_FMA 9
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
CPUID_FEAT_EDX_FPU
=
1
<<
0
,
#define CEF_FPU 11
CPUID_FEAT_EDX_VME
=
1
<<
1
,
#define CEF_DE 12
CPUID_FEAT_EDX_DE
=
1
<<
2
,
#define CEF_SYSCALLRET 13
CPUID_FEAT_EDX_PSE
=
1
<<
3
,
#define CEF_CMOV 14
CPUID_FEAT_EDX_TSC
=
1
<<
4
,
#define CEF_SSE4a 15
CPUID_FEAT_EDX_MSR
=
1
<<
5
,
#define CEF_FMA4 16
CPUID_FEAT_EDX_PAE
=
1
<<
6
,
#define CEF_XOP 17
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
{
typedef
enum
cputype
{
CT_NONE
,
CT_NONE
,
...
@@ -154,7 +193,7 @@ bool cpuid_is_supported(void);
...
@@ -154,7 +193,7 @@ bool cpuid_is_supported(void);
* Returns the highest extended function supported.
* Returns the highest extended function supported.
*
*
* This is the same as calling:
* 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
* 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.
* instead of calling cpuid with less type-checking. cpuid calls this.
...
@@ -169,23 +208,23 @@ uint32_t cpuid_highest_ext_func_supported(void);
...
@@ -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/...
* This function expects buf to be a valid pointer to a string/int/...
* depending on the requested information.
* depending on the requested information.
*
*
* For CPU_VENDOR_ID:
* For CPU
ID
_VENDOR_ID:
* Returns a string into buf.
* Returns a string into buf.
*
*
* For CPU_PROCINFO_AND_FEATUREBITS:
* For CPUID_PROCINFO_AND_FEATUREBITS:
* buf[0]:
* buf[0]: Stepping
* - 3:0 - Stepping
* buf[1]: Model
* - 7:4 - Model
* buf[2]: Family
* - 11:8 - Family
* buf[3]: Extended Model
* - 13:12 - Processor Type
* buf[4]: Extended Family
* - 19:16 - Extended Model
* buf[5] and buf[6]:
* - 27:20 - Extended family
* buf[1] and buf[2]:
* Feature flags
* Feature flags
* buf[3]:
* buf[7]: Brand Index
* Additional feature information.
* 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):
* buf[0]: (eax):
* - 7..0 Number of times to exec cpuid to get all descriptors.
* - 7..0 Number of times to exec cpuid to get all descriptors.
* - 15..8 Instruction TLB: 4K Pages, 4-way set associtive, 128 entries.
* - 15..8 Instruction TLB: 4K Pages, 4-way set associtive, 128 entries.
...
@@ -202,22 +241,22 @@ uint32_t cpuid_highest_ext_func_supported(void);
...
@@ -202,22 +241,22 @@ uint32_t cpuid_highest_ext_func_supported(void);
* - 16..23 Data TLB: 4M Pages, 4-way set associtive, 8 entires.
* - 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
* - 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)
* 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].
* 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[0]: Line size
* buf[1]: Associativity
* buf[1]: Associativity
* buf[2]: Cache size.
* buf[2]: Cache size.
*
*
* For CPU_VIRT_PHYS_ADDR_SIZES:
* For CPU
ID
_VIRT_PHYS_ADDR_SIZES:
* buf[0]: Physical
* buf[0]: Physical
* buf[1]: Virtual
* 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.
* 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.
* 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);
...
@@ -232,8 +271,8 @@ void cpuid(cpuid_t info, uint32_t *buf);
*
*
* Returns true if feature is supported, false otherwise.
* Returns true if feature is supported, false otherwise.
*
*
* The feature parameter must be >= CPU_EXTENDED_PROC_INFO_FEATURE_BITS
* The feature parameter must be >= CPU
ID
_EXTENDED_PROC_INFO_FEATURE_BITS
* and <= CPU_VIRT_PHYS_ADDR_SIZES.
* and <= CPU
ID
_VIRT_PHYS_ADDR_SIZES.
*/
*/
bool
cpuid_test_feature
(
cpuid_t
feature
);
bool
cpuid_test_feature
(
cpuid_t
feature
);
...
@@ -241,27 +280,13 @@ 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
* cpuid_has_feature - Test if @feature is supported
*
*
* Test if the CPU supports MMX/SSE* etc.
* Test if the CPU supports MMX/SSE* etc.
* For the extended parameter, usually you want to pass it as
* Use cpuid_has_ecxfeature() for *_ECX* features and
* false if you're not passing CEF_*.
* cpuid_has_edxfeature() for *_EDX* features.
*
* For more information about the CPU extended features, have a look
* at:
* http://en.wikipedia.org/wiki/CPUID
*
*
* Returns true if the feature is available, false otherwise.
* Returns true if the feature is available, false otherwise.
*/
*/
#define cpuid_has_mmx() cpuid_has_feature(CF_MMX, false)
bool
cpuid_has_ecxfeature
(
int
feature
);
#define cpuid_has_sse() cpuid_has_feature(CF_SSE, false)
bool
cpuid_has_edxfeature
(
int
feature
);
#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
);
#else
#else
#include <ccan/build_assert/build_assert.h>
#include <ccan/build_assert/build_assert.h>
...
...
ccan/cpuid/test/run.c
View file @
004098ab
...
@@ -15,21 +15,28 @@ int main(void)
...
@@ -15,21 +15,28 @@ int main(void)
printf
(
"Vendor ID: %s
\n
"
,
cputype
);
printf
(
"Vendor ID: %s
\n
"
,
cputype
);
char
buf
[
48
];
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
);
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
());
printf
(
"Highest extended function supported: %#010x
\n
"
,
cpuid_highest_ext_func_supported
());
uint32_t
phys_virt
[
2
];
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
]);
printf
(
"Physical address size: %d
\n
Virtual address size: %d
\n
"
,
phys_virt
[
0
],
phys_virt
[
1
]);
uint32_t
extfeatures
[
2
];
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
]);
printf
(
"Extended processor info and feature bits: %d %d
\n
"
,
extfeatures
[
0
],
extfeatures
[
1
]);
uint32_t
l2c
[
3
];
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
"
,
printf
(
"L2 Line size: %u bytes
\t
Associativity: %02xh
\t
Cache Size: %u KB
\n
"
,
l2c
[
0
],
l2c
[
1
],
l2c
[
2
]);
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