Skip to content
This repository was archived by the owner on Jan 4, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ add_custom_target(run
-cdrom ${CMAKE_CURRENT_BINARY_DIR}/VoidFrame.iso
-no-reboot -no-shutdown
-m 4G
-smp 4
-boot d
# Debug console and serial output
-debugcon file:bootstrap.log
Expand Down
3 changes: 2 additions & 1 deletion arch/x86_64/features/x64.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,13 @@ typedef struct {
__asm__ volatile("mfence; sfence; lfence" ::: "memory");\
__sync_synchronize();\
}
#ifdef VF_CONFIG_INTEL
#define _full_mem_prot_end_intel() {\
__asm__ volatile("mfence; sfence; lfence" ::: "memory");\
__sync_synchronize();\
__builtin_ia32_serialize();\
}

#endif
void CpuInit(void);
CpuFeatures* GetCpuFeatures(void);

Expand Down
3 changes: 3 additions & 0 deletions cmake/cache.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@
# ============================================================================
set(VF_SCHEDULER "EEVDF" CACHE STRING "Scheduler type: MLFQ or EEVDF")
set_property(CACHE VF_SCHEDULER PROPERTY STRINGS MLFQ EEVDF)

set(CLANG_TARGET_TRIPLE "x86_64-unknown-none-elf" CACHE STRING "Clang target triple for cross-compilation")
set_property(CACHE CLANG_TARGET_TRIPLE PROPERTY STRINGS x86_64-unknown-none-elf x86_64-pc-none-elf x86_64-pc-linux-gnu) # Why would anyone use linux-gnu for a kernel? Who knows.
2 changes: 1 addition & 1 deletion cmake/ccache.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ if(VF_ENABLE_CCACHE)

# Set ccache options for kernel development
set(ENV{CCACHE_SLOPPINESS} "file_macro,locale,time_macros")
set(ENV{CCACHE_MAXSIZE} "2G")
set(ENV{CCACHE_MAXSIZE} "12G")
set(ENV{CCACHE_COMPRESS} "true")
set(ENV{CCACHE_COMPRESSLEVEL} "6")

Expand Down
5 changes: 3 additions & 2 deletions cmake/configuration.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
# ============================================================================
option(EXCLUDE_EXTRA_OBJECTS "Exclude extra objects from the build" OFF)
option(AUTOMATIC_POST "Run POST automatically on boot" OFF)
option(DEBUG_SYMBOLS "Enable debug symbols" ON)
option(DEBUG_SYMBOLS "Enable debug symbols" OFF)
option(STACK_PROTECTION "Enable stack protection" ON)
option(SILENT_BUILD "Enable silent build (suppress warnings)" OFF)
option(SILENT_BUILD "Enable silent build (suppress warnings)" ON)
option(SANITIZER "Enable sanitizers" OFF)

option(VF_CONFIG_ENABLE_VMWARE_SVGA_II "Enable VMware SVGA II support" OFF)
option(VF_CONFIG_PANIC_OVERRIDE "Enable panic override" OFF)
Expand Down
6 changes: 5 additions & 1 deletion cmake/flags.cmake
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# ============================================================================
# Compiler Flags
# ============================================================================
set(C_FLAGS " -m64 -target x86_64-unknown-none-elf -O2 -fno-omit-frame-pointer -finline-functions -foptimize-sibling-calls -nostdinc -nostdlib -fno-builtin -ffreestanding -mno-red-zone -mserialize -fPIE -fPIC -mcmodel=kernel -fcf-protection=full -fvisibility=hidden")
set(C_FLAGS " -m64 -target ${CLANG_TARGET_TRIPLE} -O2 -fno-omit-frame-pointer -finline-functions -foptimize-sibling-calls -nostdinc -nostdlib -fno-builtin -ffreestanding -mno-red-zone -mserialize -fPIE -fPIC -mcmodel=kernel -fcf-protection=full -fvisibility=hidden")

if(SILENT_BUILD)
string(APPEND C_FLAGS " -w")
Expand All @@ -15,6 +15,10 @@ if(STACK_PROTECTION)
string(APPEND C_FLAGS " -fstack-protector-all -D_FORTIFY_SOURCE=2")
endif()

if(SANITIZER)
string(APPEND C_FLAGS " -fsanitize=bounds,null,return,vla-bound")
endif()

if(DEBUG_SYMBOLS)
string(APPEND C_FLAGS " -g3 -DDEBUG")
string(APPEND CMAKE_ASM_NASM_FLAGS " -g -O0")
Expand Down
7 changes: 7 additions & 0 deletions cmake/source.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ set(KERNEL_ETC_SOURCES
kernel/etc/POST.c
)

set(UBSAN_SOURCES
kernel/ubsan/Sanitizer.c
)

set(ATOMIC_IPC_SOURCES
kernel/atomic/Atomics.c
kernel/atomic/cpp/Spinlock.cpp
Expand Down Expand Up @@ -93,6 +97,7 @@ set(DRIVER_SOURCES
drivers/Serial.c
drivers/Random.c
drivers/PS2.c
drivers/PS2Keymap.c
drivers/storage/Ide.c
drivers/Vesa.c
drivers/PCI/PCI.c
Expand Down Expand Up @@ -195,6 +200,7 @@ include_directories(
kernel/execf/macho
kernel/ipc
kernel/sched
kernel/ubsan
mm
mm/asm
mm/dynamic
Expand Down Expand Up @@ -236,4 +242,5 @@ set(C_SOURCES
${INCLUDE_SOURCES}
${VFC_SOURCES}
${CRYPTO_SOURCES}
${UBSAN_SOURCES}
)
23 changes: 5 additions & 18 deletions drivers/PS2.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <Compositor.h>
#include <PS2.h>
#include <PS2Keymap.h>

#include <APIC/APIC.h>
#include <Console.h>
Expand Down Expand Up @@ -27,22 +28,7 @@ typedef struct {

static MouseState mouse = {0};

static char scancode_to_ascii[] = {
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',
'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',
0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0,
'*', 0, ' '
};

static char scancode_to_ascii_shift[] = {
0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b',
'\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n',
0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',
0, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 0,

'*', 0, ' '
};

// Compute result of a modifier combo with a base character.
char PS2_CalcCombo(uint8_t mods, char base) {
Expand Down Expand Up @@ -83,6 +69,8 @@ void send_mouse_command(uint8_t cmd) {
}

void PS2Init(void) {
PS2_InitKeymaps();

uint8_t status = inb(KEYBOARD_STATUS_PORT);
if (status & 0xC0) { // Bits 6-7: timeout/parity errors
PrintKernelWarning("PS2: Controller errors detected, performing reset\n");
Expand Down Expand Up @@ -173,10 +161,9 @@ static void ProcessKeyboardData(uint8_t scancode) {
}

if (key_released) return;
if (scancode >= sizeof(scancode_to_ascii)) return;

char base = shift_pressed ? scancode_to_ascii_shift[scancode]
: scancode_to_ascii[scancode];
char base = PS2_TranslateKey(scancode, shift_pressed);
if (!base) return;

uint8_t mods = (shift_pressed ? K_SHIFT : 0) |
(ctrl_pressed ? K_CTRL : 0) |
Expand Down
69 changes: 33 additions & 36 deletions drivers/PS2.h
Original file line number Diff line number Diff line change
@@ -1,47 +1,38 @@
#include <stdint.h>
#include <Compositor.h>
#ifndef VOIDFRAME_PS2_H
#define VOIDFRAME_PS2_H

#ifndef PS2_H
#define PS2_H
#include <stdint.h>

#define KEYBOARD_DATA_PORT 0x60
#define KEYBOARD_STATUS_PORT 0x64
// PS/2 Controller ports
#define KEYBOARD_DATA_PORT 0x60
#define KEYBOARD_STATUS_PORT 0x64

// PS2 Controller Commands
#define PS2_CMD_READ_CONFIG 0x20
#define PS2_CMD_WRITE_CONFIG 0x60
#define PS2_CMD_DISABLE_AUX 0xA7
#define PS2_CMD_ENABLE_AUX 0xA8
#define PS2_CMD_TEST_AUX 0xA9
#define PS2_CMD_WRITE_AUX 0xD4
// PS/2 Commands
#define PS2_CMD_READ_CONFIG 0x20
#define PS2_CMD_WRITE_CONFIG 0x60
#define PS2_CMD_DISABLE_AUX 0xA7
#define PS2_CMD_ENABLE_AUX 0xA8
#define PS2_CMD_WRITE_AUX 0xD4

// Mouse Commands
#define MOUSE_CMD_RESET 0xFF
#define MOUSE_CMD_ENABLE 0xF4
#define MOUSE_CMD_SET_DEFAULTS 0xF6
#define MOUSE_CMD_SET_SAMPLE 0xF3
// Mouse commands
#define MOUSE_CMD_SET_DEFAULTS 0xF6
#define MOUSE_CMD_ENABLE 0xF4

// Modifier flags for combos
// Modifier key flags
#define K_SHIFT 0x01
#define K_CTRL 0x02
#define K_ALT 0x04
#define K_SUPER 0x08

// Compute the resulting character for a given modifier combo and base char
char PS2_CalcCombo(uint8_t mods, char base);

// Fast helper for control-key combos: returns ASCII control code for letters
static inline char PS2_Ctrl(char c) {
if (c >= 'a' && c <= 'z') return (char)(c - 'a' + 1);
if (c >= 'A' && c <= 'Z') return (char)(c - 'A' + 1);
return c;
}


//keyboard
// PS/2 functions
void PS2Init(void);
// Unified PS/2 interrupt handler
void PS2Handler(void);

// Keyboard functions
char PS2_GetChar(void);
int PS2_HasInput(void);
char PS2_CalcCombo(uint8_t mods, char base);

// Mouse functions
int GetMouseX(void);
int GetMouseY(void);
int GetMouseDeltaX(void);
Expand All @@ -50,6 +41,12 @@ uint8_t GetMouseButtons(void);
int IsLeftButtonPressed(void);
int IsRightButtonPressed(void);
int IsMiddleButtonPressed(void);
char PS2_GetChar(void);
int PS2_HasInput(void);
#endif

// Helper function for control characters
static inline char PS2_Ctrl(char c) {
if (c >= 'a' && c <= 'z') return c - 'a' + 1;
if (c >= 'A' && c <= 'Z') return c - 'A' + 1;
return c;
}

#endif // VOIDFRAME_PS2_H
118 changes: 118 additions & 0 deletions drivers/PS2Keymap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#include <PS2Keymap.h>
#include <Console.h>
#include <MemOps.h>
#include <StringOps.h>

#define MAX_KEYMAPS 8

static Keymap keymaps[MAX_KEYMAPS];
static int keymap_count = 0;
static int current_keymap = 0;

// US QWERTY layout
static const Keymap us_qwerty = {
.name = "us_qwerty",
.normal = {
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',
'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',
0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0,
'*', 0, ' '
},
.shift = {
0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b',
'\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n',
0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',
0, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 0,
'*', 0, ' '
}
};

static const Keymap us_qwertz = {
.name = "us_qwertz",
.normal = {
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',
'\t', 'q', 'w', 'e', 'r', 't', 'z', 'u', 'i', 'o', 'p', '[', ']', '\n',
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',
0, '\\', 'y', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0,
'*', 0, ' '
},
.shift = {
0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b',
'\t', 'Q', 'W', 'E', 'R', 'T', 'Z', 'U', 'I', 'O', 'P', '{', '}', '\n',
0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',
0, '|', 'Y', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 0,
'*', 0, ' '
}
};

// Dvorak layout
static const Keymap dvorak = {
.name = "dvorak",
.normal = {
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '[', ']', '\b',
'\t', '\'', ',', '.', 'p', 'y', 'f', 'g', 'c', 'r', 'l', '/', '=', '\n',
0, 'a', 'o', 'e', 'u', 'i', 'd', 'h', 't', 'n', 's', '-', '`',
0, '\\', ';', 'q', 'j', 'k', 'x', 'b', 'm', 'w', 'v', 'z', 0,
'*', 0, ' '
},
.shift = {
0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '{', '}', '\b',
'\t', '"', '<', '>', 'P', 'Y', 'F', 'G', 'C', 'R', 'L', '?', '+', '\n',
0, 'A', 'O', 'E', 'U', 'I', 'D', 'H', 'T', 'N', 'S', '_', '~',
0, '|', ':', 'Q', 'J', 'K', 'X', 'B', 'M', 'W', 'V', 'Z', 0,
'*', 0, ' '
}
};

void PS2_InitKeymaps(void) {
keymap_count = 0;
PS2_RegisterKeymap(&us_qwerty);
PS2_RegisterKeymap(&dvorak);
PS2_RegisterKeymap(&us_qwertz);
current_keymap = 0;
PrintKernelSuccess("PS2: Initialized keymaps (default: us)\n");
}

int PS2_RegisterKeymap(const Keymap* keymap) {
if (keymap_count >= MAX_KEYMAPS) return -1;

FastMemcpy(&keymaps[keymap_count], keymap, sizeof(Keymap));
keymap_count++;
return 0;
}

int PS2_SetKeymap(const char* name) {
for (int i = 0; i < keymap_count; i++) {
if (FastStrCmp(keymaps[i].name, name) == 0) {
current_keymap = i;
PrintKernelF("PS2: Switched to keymap: %s\n", name);
return 0;
}
}
return -1;
}

const char* PS2_GetCurrentKeymapName(void) {
if (current_keymap < keymap_count) {
return keymaps[current_keymap].name;
}
return "unknown";
}

void PS2_ListKeymaps(void) {
PrintKernel("Available keymaps:\n");
for (int i = 0; i < keymap_count; i++) {
PrintKernelF(" %s%s\n", keymaps[i].name,
(i == current_keymap) ? " (current)" : "");
}
}

char PS2_TranslateKey(uint8_t scancode, int shift_pressed) {
if (current_keymap >= keymap_count || scancode >= MAX_SCANCODE) {
return 0;
}

return shift_pressed ? keymaps[current_keymap].shift[scancode]
: keymaps[current_keymap].normal[scancode];
}
25 changes: 25 additions & 0 deletions drivers/PS2Keymap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef VOIDFRAME_PS2_KEYMAP_H
#define VOIDFRAME_PS2_KEYMAP_H

#include <stdint.h>

#define MAX_SCANCODE 128
#define MAX_KEYMAP_NAME 32

typedef struct {
char name[MAX_KEYMAP_NAME];
char normal[MAX_SCANCODE];
char shift[MAX_SCANCODE];
} Keymap;

// Keymap management
void PS2_InitKeymaps(void);
int PS2_SetKeymap(const char* name);
const char* PS2_GetCurrentKeymapName(void);
void PS2_ListKeymaps(void);
int PS2_RegisterKeymap(const Keymap* keymap);

// Internal functions
char PS2_TranslateKey(uint8_t scancode, int shift_pressed);

#endif // VOIDFRAME_PS2_KEYMAP_H
Loading