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
96a1ebd3
Commit
96a1ebd3
authored
Oct 28, 2013
by
Rusty Russell
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of ozlabs.org:ccan
parents
8700faf2
ef47a981
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
68 additions
and
40 deletions
+68
-40
ccan/cpuid/cpuid.c
ccan/cpuid/cpuid.c
+44
-8
ccan/cpuid/cpuid.h
ccan/cpuid/cpuid.h
+14
-6
ccan/cpuid/test/run.c
ccan/cpuid/test/run.c
+10
-26
No files found.
ccan/cpuid/cpuid.c
View file @
96a1ebd3
...
...
@@ -92,6 +92,8 @@ static struct {
bool
cpuid_is_supported
(
void
)
{
int
ret
=
0
;
#if defined(__GNUC__) || defined(__clang__)
/* The following assembly code uses EAX as the return value,
* but we store the value of EAX into ret since GCC uses EAX
* as the return register for every C function. That's a double
...
...
@@ -115,16 +117,15 @@ bool cpuid_is_supported(void)
#define ASM_POPF "popfq\n\t"
#define ASM_PUSHEAX "pushq %%rax\n\t"
#define ASM_POPEAX "popq %%rax\n\t"
#define ASM_PUSHECX "p
op
q %%rcx\n\t"
#define ASM_PUSHECX "p
ush
q %%rcx\n\t"
#elif UINTPTR_MAX == 0xffffffff
#define ASM_PUSHF "pushfl\n\t"
#define ASM_POPF "popfl\n\t"
#define ASM_PUSHEAX "pushl %%eax\n\t"
#define ASM_POPEAX "popl %%eax\n\t"
#define ASM_PUSHECX "p
op
l %%ecx\n\t"
#define ASM_PUSHECX "p
ush
l %%ecx\n\t"
#endif
int
ret
=
0
;
asm
volatile
(
ASM_PUSHF
ASM_POPEAX
...
...
@@ -147,7 +148,26 @@ bool cpuid_is_supported(void)
#undef ASM_PUSHEAX
#undef ASM_POPEAX
#undef ASM_PUSHECX
#elif defined _MSC_VER
__asm
{
pushfd
pop
eax
mov
ecx
,
eax
xor
eax
,
0x200000
push
eax
popfd
pushfd
pop
eax
xor
eax
,
ecx
shr
eax
,
0x21
and
eax
,
0x1
push
ecx
popfd
mov
eax
,
ret
};
#endif
return
!!
ret
;
}
...
...
@@ -220,9 +240,14 @@ cputype_t cpuid_get_cpu_type(void)
return
cputype
;
}
const
char
*
cpuid_get_cpu_type_string
(
const
cputype_t
cputype
)
bool
cpuid_sprintf_cputype
(
const
cputype_t
cputype
,
char
*
buf
)
{
return
cpuids
[(
int
)
cputype
];
if
(
cputype
==
CT_NONE
)
return
false
;
memcpy
(
buf
,
cpuids
[(
int
)
cputype
],
12
);
buf
[
12
]
=
'\0'
;
return
true
;
}
uint32_t
cpuid_highest_ext_func_supported
(
void
)
...
...
@@ -230,11 +255,19 @@ uint32_t cpuid_highest_ext_func_supported(void)
static
uint32_t
highest
;
if
(
!
highest
)
{
#if defined(__GNUC__) || defined(__clang__)
asm
volatile
(
"cpuid
\n\t
"
:
"=a"
(
highest
)
:
"a"
(
CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
)
);
#elif defined _MSC_VER
__asm
{
mov
eax
,
CPU_HIGHEST_EXTENDED_FUNCTION_SUPPORTED
cpuid
mov
highest
,
eax
};
#endif
}
return
highest
;
...
...
@@ -298,13 +331,16 @@ void cpuid(cpuid_t info, uint32_t *buf)
buf
[
3
]
=
edx
;
break
;
case
CPU_EXTENDED_L2_CACHE_FEATURES
:
*
buf
=
ecx
;
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
:
*
buf
=
edx
;
break
;
case
CPU_VIRT_PHYS_ADDR_SIZES
:
*
buf
=
eax
;
buf
[
0
]
=
eax
&
0xFF
;
/* physical. */
buf
[
1
]
=
(
eax
>>
8
)
&
0xFF
;
/* virtual. */
break
;
default:
*
buf
=
0xbaadf00d
;
...
...
ccan/cpuid/cpuid.h
View file @
96a1ebd3
...
...
@@ -26,7 +26,7 @@
#include <stdint.h>
/**
* enum cpuid - stuff to get information
on
from the CPU.
* enum cpuid - stuff to get information
about
from the CPU.
*
* This is used as a parameter in cpuid().
*
...
...
@@ -124,14 +124,17 @@ typedef enum cputype {
*
* See also: cpuid_get_cpu_type_string()
*/
#define is_intel_cpu() cpuid_get_cpu_type() == CT_INTEL
#define is_amd_cpu() cpuid_get_cpu_type() == CT_AMDK5 || cpuid_get_cpu_type() == CT_AMD
cputype_t
cpuid_get_cpu_type
(
void
);
/**
* cpuid_get_cpu_type_string - Get CPU Type string
* cpuid_sprintf_cputype - Get CPU Type string
* @cputype: a char of atleast 12 bytes in it.
*
* Returns t
he CPU type string based off cputype_t.
* Returns t
rue on success, false on failure
*/
const
char
*
cpuid_get_cpu_type_string
(
const
cputype_t
cputype
);
bool
cpuid_sprintf_cputype
(
const
cputype_t
cputype
,
char
*
buf
);
/**
* cpuid_is_supported - test if the CPUID instruction is supported
...
...
@@ -205,8 +208,14 @@ uint32_t cpuid_highest_ext_func_supported(void);
* For CPU_EXTENDED_PROC_INFO_FEATURE_BITS:
* Returns them in buf[0] and buf[1].
*
* For CPU_EXTENDED_L2_CACHE_FEATURES:
* buf[0]: Line size
* buf[1]: Associativity
* buf[2]: Cache size.
*
* For CPU_VIRT_PHYS_ADDR_SIZES:
* Returns it as an integer in *buf.
* buf[0]: Physical
* buf[1]: Virtual
*
* For CPU_PROC_BRAND_STRING:
* Have a char array with at least 48 bytes assigned to it.
...
...
@@ -269,4 +278,3 @@ bool cpuid_has_feature(int feature, bool extended);
#endif
#endif
ccan/cpuid/test/run.c
View file @
96a1ebd3
...
...
@@ -10,7 +10,9 @@ int main(void)
return
1
;
}
printf
(
"Vendor ID: %s
\n
"
,
cpuid_get_cpu_type_string
(
cpuid_get_cpu_type
()));
char
cputype
[
12
];
if
(
cpuid_sprintf_cputype
(
cpuid_get_cpu_type
(),
cputype
))
printf
(
"Vendor ID: %s
\n
"
,
cputype
);
char
buf
[
48
];
cpuid
(
CPU_PROC_BRAND_STRING
,
(
uint32_t
*
)
buf
);
...
...
@@ -18,39 +20,21 @@ int main(void)
printf
(
"Highest extended function supported: %#010x
\n
"
,
cpuid_highest_ext_func_supported
());
union
{
struct
{
uint32_t
phys_bits
:
8
;
uint32_t
virt_bits
:
8
;
uint32_t
reserved
:
16
;
};
uint32_t
w
;
}
s
;
cpuid
(
CPU_VIRT_PHYS_ADDR_SIZES
,
&
s
.
w
);
printf
(
"Physical address size: %d
\n
Virtual address size: %d
\n
"
,
s
.
phys_bits
,
s
.
virt_bits
);
uint32_t
phys_virt
[
2
];
cpuid
(
CPU_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
);
printf
(
"Extended processor info and feature bits: %d %d
\n
"
,
extfeatures
[
0
],
extfeatures
[
1
]);
union
{
struct
{
uint32_t
line_size
:
8
;
uint32_t
reserved
:
4
;
uint32_t
assoc
:
4
;
uint32_t
cache_size
:
16
;
};
uint32_t
w
;
}
l2c
;
cpuid
(
CPU_EXTENDED_L2_CACHE_FEATURES
,
&
l2c
.
w
);
printf
(
"L2 Cache Size: %u KB
\t
Line Size: %u bytes
\t
Associativity: %02xh
\n
"
,
l2c
.
cache_size
,
l2c
.
line_size
,
l2c
.
assoc
);
uint32_t
l2c
[
3
];
cpuid
(
CPU_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
]);
uint32_t
invalid
;
cpuid
(
0x0ffffffUL
,
&
invalid
);
printf
(
"Testing invalid: %#010x
\n
"
,
invalid
);
return
0
;
}
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