PatchworkOS  c9fea19
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/simd.h>
3#include <kernel/log/log.h>
4#include <kernel/mem/pmm.h>
5
6#include <kernel/defs.h>
7
8#include <stdint.h>
9#include <string.h>
10#include <sys/cpuid.h>
11
12static uint8_t initCtx[PAGE_SIZE] ALIGNED(64);
13
14static void simd_xsave_init(void)
15{
17
18 uint64_t xcr0 = 0;
19
21
24
27
28 if (info.featuresEcx & CPUID_ECX_AVX)
29 {
30 xcr0 = xcr0 | XCR0_AVX_ENABLE;
31
32 if (extInfo.featuresEbx & CPUID_EBX_AVX512F)
33 {
35 }
36 }
37
38 xcr0_write(0, xcr0);
39}
40
41void simd_cpu_init(void)
42{
45
47
50
53
54 if (info.featuresEcx & CPUID_ECX_OSXSAVE)
55 {
57 }
58
59 asm volatile("fninit");
60 if (info.featuresEcx & CPUID_ECX_OSXSAVE)
61 {
62 asm volatile("xsave %0" : : "m"(*initCtx), "a"(UINT64_MAX), "d"(UINT64_MAX) : "memory");
63 }
64 else
65 {
66 asm volatile("fxsave (%0)" : : "r"(initCtx));
67 }
68
69 if (cpu_get_unsafe()->id != CPU_ID_BOOTSTRAP) // Only log for bootstrap CPU
70 {
71 return;
72 }
73
74 LOG_INFO("simd ");
75 if (info.featuresEcx & CPUID_ECX_OSXSAVE)
76 {
77 LOG_INFO("xsave ");
78 }
79
82 {
83 LOG_INFO("sse ");
84 }
86 {
87 LOG_INFO("sse2 ");
88 }
90 {
91 LOG_INFO("sse3 ");
92 }
94 {
95 LOG_INFO("ssse3 ");
96 }
98 {
99 LOG_INFO("sse4.1 ");
100 }
102 {
103 LOG_INFO("sse4.2 ");
104 }
105 if (sets & CPUID_INSTRUCTION_SET_AVX)
106 {
107 LOG_INFO("avx ");
108 }
110 {
111 LOG_INFO("avx2 ");
112 }
114 {
115 LOG_INFO("avx512 ");
116 }
117
118 LOG_INFO("enabled\n");
119}
120
122{
123 ctx->buffer = pmm_alloc();
124 if (ctx->buffer == NULL)
125 {
126 return ERR;
127 }
128
129 memcpy(ctx->buffer, initCtx, PAGE_SIZE);
130
131 return 0;
132}
133
135{
136 pmm_free(ctx->buffer);
137}
138
140{
143
144 if (info.featuresEcx & CPUID_ECX_OSXSAVE)
145 {
146 asm volatile("xsave %0" : : "m"(*ctx->buffer), "a"(UINT64_MAX), "d"(UINT64_MAX) : "memory");
147 }
148 else
149 {
150 asm volatile("fxsave (%0)" : : "r"(ctx->buffer));
151 }
152}
153
155{
158
159 if (info.featuresEcx & CPUID_ECX_OSXSAVE)
160 {
161 asm volatile("xrstor %0" : : "m"(*ctx->buffer), "a"(UINT64_MAX), "d"(UINT64_MAX) : "memory");
162 }
163 else
164 {
165 asm volatile("fxrstor (%0)" : : "r"(ctx->buffer));
166 }
167}
void simd_ctx_save(simd_ctx_t *ctx)
Definition simd.c:139
void simd_ctx_load(simd_ctx_t *ctx)
Definition simd.c:154
uint64_t simd_ctx_init(simd_ctx_t *ctx)
Definition simd.c:121
void simd_cpu_init(void)
Definition simd.c:41
void simd_ctx_deinit(simd_ctx_t *ctx)
Definition simd.c:134
static cpu_t * cpu_get_unsafe(void)
Gets the current CPU structure without disabling interrupts.
Definition cpu.h:299
#define CPU_ID_BOOTSTRAP
ID of the bootstrap CPU.
Definition cpu.h:56
#define ALIGNED(alignment)
GCC aligned attribute.
Definition defs.h:22
#define LOG_INFO(format,...)
Definition log.h:106
void pmm_free(void *address)
Frees a single physical page.
Definition pmm.c:220
void * pmm_alloc(void)
Allocates a single physical page.
Definition pmm.c:171
static cpuid_instruction_sets_t cpuid_detect_instruction_sets(void)
Helper to detect supported instruction sets.
Definition cpuid.h:258
static void cpuid_feature_info(cpuid_feature_info_t *info)
Wrapper to get CPU feature information.
Definition cpuid.h:204
cpuid_instruction_sets_t
Supported CPU instruction sets.
Definition cpuid.h:240
static void cpuid_extended_feature_info(cpuid_extended_feature_info_t *info)
Wrapper to get CPU extended feature information.
Definition cpuid.h:228
@ CPUID_ECX_AVX
Definition cpuid.h:74
@ CPUID_ECX_OSXSAVE
Definition cpuid.h:73
@ CPUID_INSTRUCTION_SET_SSSE3
Definition cpuid.h:245
@ CPUID_INSTRUCTION_SET_SSE2
Definition cpuid.h:243
@ CPUID_INSTRUCTION_SET_SSE4_2
Definition cpuid.h:247
@ CPUID_INSTRUCTION_SET_SSE3
Definition cpuid.h:244
@ CPUID_INSTRUCTION_SET_AVX512
Definition cpuid.h:250
@ CPUID_INSTRUCTION_SET_AVX
Definition cpuid.h:248
@ CPUID_INSTRUCTION_SET_SSE4_1
Definition cpuid.h:246
@ CPUID_INSTRUCTION_SET_SSE
Definition cpuid.h:242
@ CPUID_INSTRUCTION_SET_AVX2
Definition cpuid.h:249
@ CPUID_EBX_AVX512F
Definition cpuid.h:145
#define PAGE_SIZE
The size of a memory page in bytes.
Definition proc.h:106
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
static fb_info_t info
Definition gop.c:51
#define CR4_XSAVE_ENABLE
Definition regs.h:54
#define XCR0_AVX512_ENABLE
Definition regs.h:8
#define CR0_NUMERIC_ERROR_ENABLE
Definition regs.h:44
#define XCR0_ZMM16_32_ENABLE
Definition regs.h:10
#define XCR0_AVX_ENABLE
Definition regs.h:7
#define XCR0_XSAVE_SAVE_SSE
Definition regs.h:6
#define CR4_FXSR_ENABLE
Definition regs.h:52
#define CR0_EMULATION
Definition regs.h:41
#define XCR0_ZMM0_15_ENABLE
Definition regs.h:9
#define CR4_SIMD_EXCEPTION
Definition regs.h:53
static void cr4_write(uint64_t value)
Definition regs.h:97
#define CR0_MONITOR_CO_PROCESSOR
Definition regs.h:40
static void cr0_write(uint64_t value)
Definition regs.h:133
static void xcr0_write(uint32_t xcr, uint64_t value)
Definition regs.h:56
static uint64_t cr0_read()
Definition regs.h:126
static uint64_t cr4_read()
Definition regs.h:90
#define XCR0_XSAVE_SAVE_X87
Definition regs.h:5
static void simd_xsave_init(void)
Definition simd.c:14
__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
cpuid_t id
Definition cpu.h:123
CPU extended feature information structure.
Definition cpuid.h:219
cpuid_ebx_features_t featuresEbx
Definition cpuid.h:220
CPU feature information structure.
Definition cpuid.h:192
uint8_t * buffer
Definition simd.h:23