PatchworkOS  19e446b
A non-POSIX operating system.
Loading...
Searching...
No Matches
simd.c
Go to the documentation of this file.
1#include <kernel/cpu/cpu.h>
2#include <kernel/cpu/percpu.h>
3#include <kernel/cpu/regs.h>
4#include <kernel/cpu/simd.h>
5#include <kernel/log/log.h>
6#include <kernel/mem/pmm.h>
7
8#include <sys/defs.h>
9
10#include <stdint.h>
11#include <string.h>
12#include <sys/cpuid.h>
13
14static uint8_t initCtx[PAGE_SIZE] ALIGNED(64);
15
16static void simd_xsave_init(void)
17{
19
20 uint64_t xcr0 = 0;
21
23
25 cpuid_feature_info(&info);
26
29
30 if (info.featuresEcx & CPUID_ECX_AVX)
31 {
32 xcr0 = xcr0 | XCR0_AVX_ENABLE;
33
34 if (extInfo.featuresEbx & CPUID_EBX_AVX512F)
35 {
37 }
38 }
39
40 xcr0_write(0, xcr0);
41}
42
43PERCPU_DEFINE_CTOR(static void, pcpu_simd)
44{
47
49
51 cpuid_feature_info(&info);
52
55
57 {
59 }
60
61 ASM("fninit");
63 {
64 ASM("xsave %0" : : "m"(*initCtx), "a"(UINT64_MAX), "d"(UINT64_MAX) : "memory");
65 }
66 else
67 {
68 ASM("fxsave (%0)" : : "r"(initCtx));
69 }
70
71 if (SELF->id != CPU_ID_BOOTSTRAP) // Only log for bootstrap CPU
72 {
73 return;
74 }
75
76 LOG_INFO("simd ");
78 {
79 LOG_INFO("xsave ");
80 }
81
84 {
85 LOG_INFO("sse ");
86 }
88 {
89 LOG_INFO("sse2 ");
90 }
92 {
93 LOG_INFO("sse3 ");
94 }
96 {
97 LOG_INFO("ssse3 ");
98 }
100 {
101 LOG_INFO("sse4.1 ");
102 }
104 {
105 LOG_INFO("sse4.2 ");
106 }
107 if (sets & CPUID_INSTRUCTION_SET_AVX)
108 {
109 LOG_INFO("avx ");
110 }
112 {
113 LOG_INFO("avx2 ");
114 }
116 {
117 LOG_INFO("avx512 ");
118 }
119
120 LOG_INFO("enabled\n");
121}
122
124{
125 pfn_t pfn = pmm_alloc();
126 if (pfn == ERR)
127 {
128 return ERR;
129 }
130 ctx->buffer = PFN_TO_VIRT(pfn);
131 memcpy(ctx->buffer, initCtx, PAGE_SIZE);
132
133 return 0;
134}
135
137{
138 pfn_t pfn = VIRT_TO_PFN(ctx->buffer);
139 pmm_free(pfn);
140}
141
143{
145 cpuid_feature_info(&info);
146
148 {
149 ASM("xsave %0" : : "m"(*ctx->buffer), "a"(UINT64_MAX), "d"(UINT64_MAX) : "memory");
150 }
151 else
152 {
153 ASM("fxsave (%0)" : : "r"(ctx->buffer));
154 }
155}
156
158{
160 cpuid_feature_info(&info);
161
163 {
164 ASM("xrstor %0" : : "m"(*ctx->buffer), "a"(UINT64_MAX), "d"(UINT64_MAX) : "memory");
165 }
166 else
167 {
168 ASM("fxrstor (%0)" : : "r"(ctx->buffer));
169 }
170}
#define SELF
Macro to access data in the current cpu.
Definition percpu.h:85
#define PERCPU_DEFINE_CTOR(type, name)
Macro to define a percpu variable with a constructor.
Definition percpu.h:130
void simd_ctx_save(simd_ctx_t *ctx)
Definition simd.c:142
void simd_ctx_load(simd_ctx_t *ctx)
Definition simd.c:157
uint64_t simd_ctx_init(simd_ctx_t *ctx)
Definition simd.c:123
void simd_ctx_deinit(simd_ctx_t *ctx)
Definition simd.c:136
#define CPU_ID_BOOTSTRAP
ID of the bootstrap CPU.
Definition cpu.h:55
#define LOG_INFO(format,...)
Definition log.h:91
#define VIRT_TO_PFN(_addr)
Convert a identity mapped higher half virtual address to its PFN.
#define PFN_TO_VIRT(_pfn)
Convert a PFN to its identity mapped higher half virtual address.
size_t pfn_t
Page Frame Number type.
void pmm_free(pfn_t pfn)
Free a single page of physical memory.
Definition pmm.c:341
pfn_t pmm_alloc(void)
Allocate a single page of physical memory.
Definition pmm.c:249
static cpuid_instruction_sets_t cpuid_detect_instruction_sets(void)
Helper to detect supported instruction sets.
Definition cpuid.h:259
static void cpuid_feature_info(cpuid_feature_info_t *info)
Wrapper to get CPU feature information.
Definition cpuid.h:205
cpuid_instruction_sets_t
Supported CPU instruction sets.
Definition cpuid.h:241
static void cpuid_extended_feature_info(cpuid_extended_feature_info_t *info)
Wrapper to get CPU extended feature information.
Definition cpuid.h:229
@ CPUID_ECX_AVX
Definition cpuid.h:75
@ CPUID_ECX_OSXSAVE
Definition cpuid.h:74
@ CPUID_INSTRUCTION_SET_SSSE3
Definition cpuid.h:246
@ CPUID_INSTRUCTION_SET_SSE2
Definition cpuid.h:244
@ CPUID_INSTRUCTION_SET_SSE4_2
Definition cpuid.h:248
@ CPUID_INSTRUCTION_SET_SSE3
Definition cpuid.h:245
@ CPUID_INSTRUCTION_SET_AVX512
Definition cpuid.h:251
@ CPUID_INSTRUCTION_SET_AVX
Definition cpuid.h:249
@ CPUID_INSTRUCTION_SET_SSE4_1
Definition cpuid.h:247
@ CPUID_INSTRUCTION_SET_SSE
Definition cpuid.h:243
@ CPUID_INSTRUCTION_SET_AVX2
Definition cpuid.h:250
@ CPUID_EBX_AVX512F
Definition cpuid.h:146
#define ASM(...)
Inline assembly macro.
Definition defs.h:160
#define ALIGNED(alignment)
GCC aligned attribute.
Definition defs.h:23
#define ERR
Integer error value.
Definition ERR.h:17
#define PAGE_SIZE
The size of a memory page in bytes.
Definition PAGE_SIZE.h:8
#define CR4_XSAVE_ENABLE
Definition regs.h:56
#define XCR0_AVX512_ENABLE
Definition regs.h:9
static uint64_t cr0_read(void)
Definition regs.h:128
#define CR0_NUMERIC_ERROR_ENABLE
Definition regs.h:46
#define XCR0_ZMM16_32_ENABLE
Definition regs.h:11
#define XCR0_AVX_ENABLE
Definition regs.h:8
#define XCR0_XSAVE_SAVE_SSE
Definition regs.h:7
#define CR4_FXSR_ENABLE
Definition regs.h:54
#define CR0_EMULATION
Definition regs.h:43
static uint64_t cr4_read(void)
Definition regs.h:92
#define XCR0_ZMM0_15_ENABLE
Definition regs.h:10
#define CR4_SIMD_EXCEPTION
Definition regs.h:55
static void cr4_write(uint64_t value)
Definition regs.h:99
#define CR0_MONITOR_CO_PROCESSOR
Definition regs.h:42
static void cr0_write(uint64_t value)
Definition regs.h:135
static void xcr0_write(uint32_t xcr, uint64_t value)
Definition regs.h:58
#define XCR0_XSAVE_SAVE_X87
Definition regs.h:6
static void simd_xsave_init(void)
Definition simd.c:16
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
#define UINT64_MAX
Definition stdint.h:74
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
_PUBLIC void * memcpy(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
Definition memcpy.c:61
CPU extended feature information structure.
Definition cpuid.h:220
cpuid_ebx_features_t featuresEbx
Definition cpuid.h:221
CPU feature information structure.
Definition cpuid.h:193
cpuid_ecx_features_t featuresEcx
Definition cpuid.h:196
uint8_t * buffer
Definition simd.h:23