Compare commits

...

6 Commits

Author SHA1 Message Date
1824c99ca0
userspace/libc: flush stdout & stderr on exit
Some checks failed
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 9m48s
Build OS / Build Cross-Compiler & Toolchain (push) Successful in 1h57m16s
Build OS / Analyze (${{ matrix.language }}) (manual, c-cpp) (push) Failing after 6m20s
Build OS / Build amd64 (push) Failing after 6m19s
Build OS / Build aarch64 (push) Failing after 6m20s
Build OS / Build arm (push) Failing after 6m17s
Build OS / Build i386 (push) Failing after 19m15s
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-25 00:16:58 +02:00
e8b61e6d7f
userspace/libc: fix stack alignment
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-25 00:08:46 +02:00
69bc044b09
userspace: include crt1.c to streamline startup code
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-25 00:07:09 +02:00
c86d24030e
kernel: refactor FPU state structure for improved clarity and consistency
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-24 23:57:49 +02:00
4ced264c3c
userspace: simplify SIMD test application assembly code
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-24 23:57:15 +02:00
a25c5f4a96
userspace: add SIMD test application
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
2025-01-24 22:40:38 +02:00
9 changed files with 170 additions and 139 deletions

View File

@ -308,9 +308,9 @@ namespace CPU
cr4.OSXMMEXCPT = true;
CPUData *CoreData = GetCPU(Core);
CoreData->Data.FPU.mxcsr = 0b0001111110000000;
CoreData->Data.FPU.mxcsrmask = 0b1111111110111111;
CoreData->Data.FPU.fcw = 0b0000001100111111;
CoreData->Data.FPU.MXCSR.raw = 0b0001111110000000;
CoreData->Data.FPU.MXCSR_MASK = 0b1111111110111111;
CoreData->Data.FPU.FCW.raw = 0b0000001100111111;
CPU::x86::fxrstor(&CoreData->Data.FPU);
SSEEnableAfter = true;

View File

@ -978,27 +978,118 @@ namespace CPU
struct FXState
{
/** @brief FPU control word */
uint16_t fcw;
/** @brief FPU status word */
uint16_t fsw;
/** @brief FPU tag words */
uint8_t ftw;
/** @brief Reserved (zero) */
uint8_t Reserved;
/** @brief FPU opcode */
uint16_t fop;
/** @brief PFU instruction pointer */
uint64_t rip;
/** @brief FPU data pointer */
uint64_t rdp;
/** @brief SSE control register */
uint32_t mxcsr;
/** @brief SSE control register mask */
uint32_t mxcsrmask;
/** @brief FPU registers (last 6 bytes reserved) */
union
{
struct
{
/* #MF Exception Masks */
uint16_t IM : 1; /** Invalid-Operation Exception Mask */
uint16_t DM : 1; /** Denormalized-Operand Exception Mask */
uint16_t ZM : 1; /** Zero-Divide Exception Mask */
uint16_t OM : 1; /** Overflow Exception Mask */
uint16_t UM : 1; /** Underflow Exception Mask */
uint16_t PM : 1; /** Precision Exception Mask */
uint16_t __reserved0 : 2; /** Reserved */
/**
* 00 Single precision
* 01 reserved
* 10 Double precision
* 11 Double-extended precision (default)
*/
uint16_t PC : 2; /** Precision Control */
/**
* 00 Round to nearest (default)
* 01 Round down
* 10 Round up
* 11 Round towards zero
*/
uint16_t RC : 2; /** Rounding Control */
uint16_t Infinity : 1; /** Infinity Bit (80287 compatibility) */
uint16_t Reserved2 : 3; /** Reserved */
};
uint16_t raw;
} FCW; /** FPU Control Word */
union
{
struct
{
uint16_t IE : 1; /** Invalid-Operation Exception */
uint16_t DE : 1; /** Denormalized-Operand Exception */
uint16_t ZE : 1; /** Zero-Divide Exception */
uint16_t OE : 1; /** Overflow Exception */
uint16_t UE : 1; /** Underflow Exception */
uint16_t PE : 1; /** Precision Exception */
uint16_t SF : 1; /** Stack Fault */
uint16_t ES : 1; /** Exception Status */
uint16_t C0 : 1; /** Condition Code 0 */
uint16_t C1 : 1; /** Condition Code 1 */
uint16_t C2 : 1; /** Condition Code 2 */
uint16_t TOP : 3; /** Top of Stack Pointer */
uint16_t C3 : 1; /** Condition Code 3 */
uint16_t B : 1; /** x87 Floating-Point Unit Busy */
};
uint16_t raw;
} FSW; /** FPU Status Word */
/**
* Tag Values
*
* 00 = Valid
* 01 = Zero
* 10 = Special
* 11 = Empty
*/
uint8_t FTW; /** x87 Tag Word */
uint8_t __reserved0;
uint16_t FOP; /** FPU Op Code */
uint64_t RIP; /** PFU Instruction Pointer */
uint64_t RDP; /** PFU Data Pointer */
union
{
struct
{
/* Exception Flags */
uint32_t IE : 1; /** Invalid-Operation Exception */
uint32_t DE : 1; /** Denormalized-Operand Exception */
uint32_t ZE : 1; /** Zero-Divide Exception */
uint32_t OE : 1; /** Overflow Exception */
uint32_t UE : 1; /** Underflow Exception */
uint32_t PE : 1; /** Precision Exception */
uint32_t DAZ : 1; /** Denormals Are Zeros */
/* Exception Masks */
uint32_t IM : 1; /** Invalid-Operation Mask */
uint32_t DM : 1; /** Denormalized-Operand Mask */
uint32_t ZM : 1; /** Zero-Divide Mask */
uint32_t OM : 1; /** Overflow Mask */
uint32_t UM : 1; /** Underflow Mask */
uint32_t PM : 1; /** Precision Mask */
/**
* 00 = round to nearest (default)
* 01 = round down
* 10 = round up
* 11 = round toward zero
*/
uint32_t RC : 2; /** Floating-Point Rounding Control */
uint32_t FZ : 1; /** Flush-to-Zero for Masked Underflow */
uint32_t __reserved3 : 1;
uint32_t MM : 1; /** Misaligned Exception Mask */
uint32_t __reserved4 : 14;
};
uint32_t raw;
} MXCSR; /** SSE Control Register */
uint32_t MXCSR_MASK; /** SSE Control Register Mask */
/** FPU registers (last 6 bytes reserved) */
uint8_t st[8][16];
/** @brief XMM registers */
/** XMM registers */
uint8_t xmm[16][16];
} __packed __aligned(16);

View File

@ -612,9 +612,9 @@ namespace Tasking
// TODO: Is really a good idea to use the FPU in kernel mode?
#if defined(__amd64__) || defined(__i386__)
this->FPU.mxcsr = 0b0001111110000000;
this->FPU.mxcsrmask = 0b1111111110111111;
this->FPU.fcw = 0b0000001100111111;
this->FPU.MXCSR.raw = 0b0001111110000000;
this->FPU.MXCSR_MASK = 0b1111111110111111;
this->FPU.FCW.raw = 0b0000001100111111;
#endif
#ifdef DEBUG

View File

@ -0,0 +1 @@
simd_test

View File

@ -0,0 +1,36 @@
default:
$(error Do not run this Makefile directly!)
S_SOURCES = $(shell find ./ -type f -name '*.S')
C_SOURCES = $(shell find ./ -type f -name '*.c')
CXX_SOURCES = $(shell find ./ -type f -name '*.cpp')
OBJ = $(S_SOURCES:.S=.o) $(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o)
FILENAME = $(notdir $(shell pwd))
WARNCFLAG = -Wall -Wextra
build: $(FILENAME)
cp $(FILENAME) $(WORKSPACE_DIR)/out/bin/$(FILENAME)
# Use static linking
LDFLAGS += -static -fno-pic -fno-pie -Wl,-static
$(FILENAME): $(OBJ)
$(info Linking $@)
$(CC) $(LDFLAGS) $(SYSROOT) $(OBJ) -o $@
%.o: %.c $(HEADERS)
$(info Compiling $<)
$(CC) $(CFLAGS) $(WARNCFLAG) -std=c17 -c $< -o $@
%.o: %.cpp $(HEADERS)
$(info Compiling $<)
$(CXX) $(CFLAGS) $(WARNCFLAG) -std=c++20 -fexceptions -c $< -o $@ -fno-rtti
%.o: %.S
$(info Compiling $<)
$(AS) -o $@ $<
clean:
rm -f $(OBJ) $(FILENAME)

View File

@ -0,0 +1,9 @@
int main(int, char *[], char *[])
{
#if defined(__amd64__) || defined(__i386__)
__asm__ __volatile__("movaps %%xmm1, %%xmm0\n" : : : "memory");
#else
#warning "Unimplemented"
#endif
return 0;
}

View File

@ -1,110 +1 @@
/*
This file is part of Fennix Userspace.
Fennix Userspace is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.
Fennix Userspace is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Fennix Userspace. If not, see <https://www.gnu.org/licenses/>.
*/
typedef void (*fct)(void);
#define asm __asm__ __volatile__
extern void (*__preinit_array_start[])(void) __attribute__((weak));
extern void (*__preinit_array_end[])(void) __attribute__((weak));
extern void (*__init_array_start[])(void) __attribute__((weak));
extern void (*__init_array_end[])(void) __attribute__((weak));
extern void (*__fini_array_start[])(void) __attribute__((weak));
extern void (*__fini_array_end[])(void) __attribute__((weak));
void __crt_init_array(void)
{
for (fct *func = __init_array_start; func != __init_array_end; func++)
(*func)();
}
void __crt_fini_array(void)
{
for (fct *func = __fini_array_start; func != __fini_array_end; func++)
(*func)();
}
__attribute__((naked, used, no_stack_protector, section(".text"))) void _start()
{
#if defined(__amd64__)
asm("movq $0, %rbp\n"
"pushq %rbp\n"
"pushq %rbp\n"
"movq %rsp, %rbp\n"
"pushq %rcx\n"
"pushq %rdx\n"
"pushq %rsi\n"
"pushq %rdi\n"
"call __libc_init\n"
"call __crt_init_array\n"
"popq %rdi\n"
"popq %rsi\n"
"popq %rdx\n"
"popq %rcx\n"
"call main\n"
"pushq %rax\n"
"call __crt_fini_array\n"
"popq %rax\n"
"movl %eax, %edi\n"
"call _exit\n");
#elif defined(__i386__)
#warning "i386 _start not implemented"
#elif defined(__arm__)
#warning "arm _start not implemented"
#elif defined(__aarch64__)
#warning "aarch64 _start not implemented"
#else
#error "Unsupported architecture"
#endif
}
/* These are declared in GNU ld */
enum
{
NT_FNX_ABI_TAG = 1,
NT_FNX_VERSION = 2,
NT_FNX_BUILD_ID = 3,
NT_FNX_ARCH = 4
};
typedef struct Elf_Nhdr
{
__UINT32_TYPE__ n_namesz;
__UINT32_TYPE__ n_descsz;
__UINT32_TYPE__ n_type;
char n_name[];
} __attribute__((packed)) Elf_Nhdr;
const struct
{
Elf_Nhdr header;
char name[4];
__UINT32_TYPE__ desc[4];
} __abi_tag __attribute__((aligned(4), section(".note.ABI-tag"))) = {
.header = {
.n_namesz = 4, /* "FNX" + '\0' */
.n_descsz = sizeof(__UINT32_TYPE__) * 4, /* Description Size */
.n_type = NT_FNX_ABI_TAG, /* Type */
},
.name = "FNX",
.desc = {0, 0, 0, 0},
};
#include "crt1.c"

View File

@ -40,9 +40,8 @@ void __crt_fini_array(void)
__attribute__((naked, used, no_stack_protector, section(".text"))) void _start()
{
#if defined(__amd64__)
asm("movq $0, %rbp\n"
"pushq %rbp\n"
"pushq %rbp\n"
asm("xor %rbp, %rbp\n"
"andq $-16, %rsp\n"
"movq %rsp, %rbp\n"
"pushq %rcx\n"

View File

@ -17,6 +17,8 @@
#include <fennix/syscalls.h>
#include <stdio.h>
int __init_pthread(void);
void __init_stdio(void);
@ -28,6 +30,8 @@ __attribute__((visibility("default"))) void __libc_init(void)
__attribute__((visibility("default"))) void _exit(int Code)
{
fflush(stdout);
fflush(stderr);
call_exit(Code);
while (1)
;