MOS Source Code
Loading...
Searching...
No Matches
cpu.cpp
Go to the documentation of this file.
1
// SPDX-License-Identifier: GPL-3.0-or-later
2
3
#include "
mos/x86/cpu/cpu.hpp
"
4
5
#include "
mos/assert.hpp
"
6
#include "
mos/platform/platform.hpp
"
7
#include "mos/platform/platform_defs.hpp"
8
#include "
mos/syslog/printk.hpp
"
9
#include "
mos/x86/cpu/cpuid.hpp
"
10
#include "
mos/x86/tasks/fpu_context.hpp
"
11
12
#include <
mos_string.hpp
>
13
14
// clang-format off
15
#define do_static_assert(feat) MOS_STATIC_ASSERT(X86_CPUID_LEAF_ENUM(feat) >= 0);
16
#define test_ensure_all_leaves_are_supported(feature) do_static_assert(CPU_FEATURE_##feature)
17
FOR_ALL_CPU_FEATURES
(
test_ensure_all_leaves_are_supported
)
18
#undef test_ensure_all_leaves_are_supported
19
#undef do_static_assert
20
// clang-format on
21
22
void
x86_cpu_initialise_caps
(
void
)
23
{
24
platform_cpuinfo_t
*cpuinfo = &
per_cpu
(
platform_info
->cpu)->cpuinfo;
25
memzero
(cpuinfo,
sizeof
(
platform_cpuinfo_t
));
26
27
#define impl_fill_leaf(_l, _sl, _r) cpuinfo->cpuid[X86_CPUID_LEAF_ENUM(_l, _sl, _r, _)] = x86_cpuid(_r, _l, _sl);
28
FOR_ALL_SUPPORTED_CPUID_LEAF
(
impl_fill_leaf
);
29
#undef impl_fill_leaf
30
31
MOS_ASSERT_X
(
cpu_has_feature
(
CPU_FEATURE_FSGSBASE
),
"FSGSBASE is required"
);
32
MOS_ASSERT_X
(
cpu_has_feature
(
CPU_FEATURE_FXSR
),
"FXSR is required"
);
33
MOS_ASSERT_X
(
cpu_has_feature
(
CPU_FEATURE_SSE
),
"SSE is required"
);
34
MOS_ASSERT_X
(
cpu_has_feature
(
CPU_FEATURE_XSAVE
),
"XSAVE is required"
);
35
36
x86_cpu_set_cr4
(
x86_cpu_get_cr4
() |
BIT
(7) |
BIT
(11) |
BIT
(16));
// set CR4.PGE, CR4.FSGSBASE, CR4.UMIP
37
}
38
39
void
x86_cpu_setup_xsave_area
(
void
)
40
{
41
pr_dinfo2
(x86_startup,
"setting up xsave area..."
);
42
43
reg_t
cr0 =
x86_cpu_get_cr0
();
44
cr0 &=
~BIT
(2);
// clear coprocessor emulation CR0.EM
45
cr0 |=
BIT
(1);
46
x86_cpu_set_cr0
(cr0);
47
48
reg_t
cr4 =
x86_cpu_get_cr4
();
49
cr4 |=
BIT
(9) |
BIT
(10) |
BIT
(18);
// set CR4.OSFXSR, CR4.OSXMMEXCPT and CR4.OSXSAVE
50
x86_cpu_set_cr4
(cr4);
51
52
reg_t
xcr0 =
XCR0_X87
|
XCR0_SSE
;
// bit 0, 1
53
size_t
xsave_size = 512;
// X87 + SSE
54
55
// SSE
56
xcr0 |=
XCR0_SSE
;
// bit 1
57
xsave_size += 64;
// XSAVE header
58
59
// AVX
60
if
(
cpu_has_feature
(
CPU_FEATURE_AVX
))
61
xcr0 |=
XCR0_AVX
;
62
63
static
const
char
*
const
xcr0_names[] = {
64
/*0*/
"x87"
,
//
65
/*1*/
"SSE"
,
//
66
/*2*/
"AVX"
,
//
67
/*3*/
"MPX BNDREGS"
,
//
68
/*4*/
"MPX BNDCSR"
,
//
69
/*5*/
"AVX-512 OPMASK"
,
//
70
/*6*/
"AVX-512 ZMM0-15"
,
//
71
/*7*/
"AVX-512 ZMM16-31"
,
//
72
/*8*/
"PT"
,
//
73
/*9*/
"PKRU"
,
//
74
};
75
76
for
(
size_t
state_component = 2; state_component < 64; state_component++)
77
{
78
reg32_t
size
, offset, ecx, edx;
79
__cpuid_count(0xd, state_component,
size
, offset, ecx, edx);
80
if
(
size
&& offset && ((ecx &
BIT
(0)) == 0))
81
{
82
const
char
*
const
name
= state_component <
MOS_ARRAY_SIZE
(xcr0_names) ? xcr0_names[state_component] :
"<unknown>"
;
83
pr_dinfo2
(x86_startup,
"XSAVE state component '%s': size=%d, offset=%d"
,
name
,
size
, offset);
84
85
if
(xcr0 &
BIT
(state_component))
86
{
87
pr_dcont
(x86_startup,
" (enabled)"
);
88
xsave_size +=
size
;
89
}
90
}
91
}
92
93
pr_dinfo2
(x86_startup,
"XSAVE area size: %zu"
, xsave_size);
94
95
__asm__
volatile
(
"xsetbv"
: :
"c"
(0),
"a"
(xcr0),
"d"
(xcr0 >> 32));
96
xsave_area_slab
.ent_size = xsave_size;
97
}
assert.hpp
MOS_ASSERT_X
#define MOS_ASSERT_X(cond, msg,...)
Definition
assert.hpp:15
x86_cpu_initialise_caps
void x86_cpu_initialise_caps(void)
Definition
cpu.cpp:22
test_ensure_all_leaves_are_supported
#define test_ensure_all_leaves_are_supported(feature)
Definition
cpu.cpp:16
x86_cpu_setup_xsave_area
void x86_cpu_setup_xsave_area(void)
Definition
cpu.cpp:39
impl_fill_leaf
#define impl_fill_leaf(_l, _sl, _r)
cpuid.hpp
XCR0_SSE
#define XCR0_SSE
Definition
cpuid.hpp:105
CPU_FEATURE_SSE
#define CPU_FEATURE_SSE
Definition
cpuid.hpp:32
FOR_ALL_CPU_FEATURES
#define FOR_ALL_CPU_FEATURES(M)
Definition
cpuid.hpp:64
CPU_FEATURE_XSAVE
#define CPU_FEATURE_XSAVE
Definition
cpuid.hpp:50
CPU_FEATURE_AVX
#define CPU_FEATURE_AVX
Definition
cpuid.hpp:52
XCR0_AVX
#define XCR0_AVX
Definition
cpuid.hpp:106
CPU_FEATURE_FXSR
#define CPU_FEATURE_FXSR
Definition
cpuid.hpp:31
cpu_has_feature
#define cpu_has_feature(feat)
Definition
cpuid.hpp:82
CPU_FEATURE_FSGSBASE
#define CPU_FEATURE_FSGSBASE
Definition
cpuid.hpp:57
XCR0_X87
#define XCR0_X87
Definition
cpuid.hpp:104
FOR_ALL_SUPPORTED_CPUID_LEAF
#define FOR_ALL_SUPPORTED_CPUID_LEAF(M)
Definition
cpuid.hpp:84
fpu_context.hpp
xsave_area_slab
mos::Slab< u8 > xsave_area_slab
MOS_ARRAY_SIZE
#define MOS_ARRAY_SIZE(x)
Definition
mos_global.h:84
BIT
#define BIT(x)
Definition
mos_global.h:107
mos_string.hpp
platform.hpp
per_cpu
#define per_cpu(var)
Definition
platform.hpp:27
printk.hpp
pr_dcont
#define pr_dcont(feat, fmt,...)
Definition
printk.hpp:33
pr_dinfo2
#define pr_dinfo2(feat, fmt,...)
Definition
printk.hpp:27
platform_info
mos_platform_info_t *const platform_info
Definition
riscv64_platform.cpp:65
memzero
#define memzero(ptr, size)
Definition
rpc_server.cpp:48
size
size_t size
Definition
slab.cpp:34
name
const char * name
Definition
slab.cpp:35
platform_cpuinfo_t
Definition
platform_defs.hpp:63
reg_t
uintn reg_t
Definition
types.h:47
reg32_t
u32 reg32_t
Definition
types.h:49
cpu.hpp
x86_cpu_get_cr4
#define x86_cpu_get_cr4()
Definition
cpu.hpp:43
x86_cpu_get_cr0
#define x86_cpu_get_cr0()
Definition
cpu.hpp:40
x86_cpu_set_cr4
#define x86_cpu_set_cr4(val)
Definition
cpu.hpp:47
x86_cpu_set_cr0
#define x86_cpu_set_cr0(val)
Definition
cpu.hpp:45
kernel
arch
x86_64
cpu
cpu.cpp
Generated on Tue Feb 18 2025 16:41:40 for MOS Source Code by
1.13.2