WIP
This commit is contained in:
35
Makefile
35
Makefile
@@ -1,14 +1,13 @@
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
.PHONY: all clean
|
||||
.PHONY: all clean test tests
|
||||
|
||||
all: myos.iso
|
||||
|
||||
SOURCE_DIR := src
|
||||
BUILD_DIR := build
|
||||
|
||||
|
||||
CONTAINER_CMD := podman run -v "$(shell pwd)":"/scratch" \
|
||||
--workdir="/scratch" \
|
||||
--network=none \
|
||||
@@ -16,17 +15,23 @@ CONTAINER_CMD := podman run -v "$(shell pwd)":"/scratch" \
|
||||
-t \
|
||||
cc-i686:latest
|
||||
|
||||
QEMU := qemu-system-i386
|
||||
QEMU_FLAGS := -d int -no-reboot
|
||||
|
||||
CC := $(CONTAINER_CMD) i686-elf-gcc
|
||||
LD := $(CONTAINER_CMD) i686-elf-ld
|
||||
AS := $(CONTAINER_CMD) i686-elf-as
|
||||
AR := $(CONTAINER_CMD) i686-elf-ar
|
||||
|
||||
C_SOURCES := $(shell find $(SOURCE_DIR) ! -name 'test_*' -name '*.c')
|
||||
C_SOURCES := $(shell find $(SOURCE_DIR) ! -name '*_test*' -name '*.c')
|
||||
ASM_SOURCES := $(shell find $(SOURCE_DIR) -name '*.S')
|
||||
OBJECTS := $(patsubst $(SOURCE_DIR)/%, $(BUILD_DIR)/%, $(C_SOURCES:.c=.o) $(ASM_SOURCES:.S=.o))
|
||||
DEPENDS := $(patsubst $(SOURCE_DIR)/%, $(BUILD_DIR)/%, $(C_SOURCES:.c=.d))
|
||||
|
||||
CFLAGS := -MMD -ffreestanding -nostdlib -O1 -Wall -Wextra -Werror -std=c2x -I$(SOURCE_DIR)/include -no-pie -fstack-protector-strong -g3
|
||||
CFLAGS := -ffreestanding -nostdlib -std=c2x -MMD -I$(SOURCE_DIR)/lib/include -I$(SOURCE_DIR) -no-pie
|
||||
CFLAGS += -O1 -g3
|
||||
CFLAGS += -Wall -Wextra -Werror
|
||||
CFLAGS += -fstack-protector-strong -g3
|
||||
CFLAGS += -Wno-unused-function
|
||||
CFLAGS += -Wno-unused-variable
|
||||
ASFLAGS :=
|
||||
@@ -37,7 +42,7 @@ ASFLAGS :=
|
||||
#$(info DEPENDS is $(DEPENDS))
|
||||
|
||||
run: myos.iso
|
||||
qemu-system-i386 -d int -no-reboot -cdrom myos.iso
|
||||
$(QEMU) $(QEMU_FLAGS) -cdrom myos.iso
|
||||
|
||||
cross-compiler: cross-compiler-image/Dockerfile
|
||||
podman build cross-compiler-image -t cc-i686
|
||||
@@ -74,21 +79,23 @@ $(BUILD_DIR)/%.o: $(SOURCE_DIR)/%.S Makefile
|
||||
# TESTS #
|
||||
###################
|
||||
|
||||
TEST_SOURCE_DIR := $(SOURCE_DIR)/test
|
||||
TEST_BUILD_DIR := $(BUILD_DIR)/test
|
||||
TEST_BUILD_DIR := $(BUILD_DIR)/tests
|
||||
|
||||
TEST_SOURCES := $(shell find $(TEST_SOURCE_DIR) -name 'test_*.c')
|
||||
TEST_DEPENDS := $(patsubst $(TEST_SOURCE_DIR)/%, $(TEST_BUILD_DIR)/%, $(TEST_SOURCES:.c=.d))
|
||||
TEST_OUTPUT := $(patsubst $(TEST_SOURCE_DIR)/%, $(TEST_BUILD_DIR)/%, $(TEST_SOURCES:.c=))
|
||||
#TEST_SOURCES := $(shell find $(SOURCE_DIR) -name '*_test.c')
|
||||
#TEST_DEPENDS := $(patsubst $(SOURCE_DIR)/%, $(TEST_BUILD_DIR)/%, $(TEST_SOURCES:.c=.d))
|
||||
#TEST_OUTPUT := $(patsubst $(SOURCE_DIR)/%, $(TEST_BUILD_DIR)/%, $(TEST_SOURCES:.c=))
|
||||
|
||||
$(info TEST_SOURCES is $(TEST_SOURCES))
|
||||
$(info TEST_OUTPUT is $(TEST_OUTPUT))
|
||||
|
||||
tests: $(TEST_OUTPUT)
|
||||
$(info TEST_SOURCES is $(TEST_SOURCES))
|
||||
$(info TEST_DEPENDS is $(TEST_DEPENDS))
|
||||
$(info TEST_OUTPUT is $(TEST_OUTPUT))
|
||||
test: tests
|
||||
|
||||
-include $(TEST_DEPENDS)
|
||||
|
||||
$(TEST_BUILD_DIR)/test_%: $(TEST_SOURCE_DIR)/test_%.c $(SOURCE_DIR)/lib/%.c | Makefile
|
||||
$(TEST_BUILD_DIR)/%_test: $(SOURCE_DIR)/%.c $(SOURCE_DIR)/%_test.c | Makefile
|
||||
@mkdir -p $(@D)
|
||||
gcc -O1 -fsanitize=address,undefined -Wall -Wextra -Werror -g3 -std=c2x -D_FORTIFY_SOURCE=2 -I$(SOURCE_DIR)/include -o $@ $^
|
||||
gcc -O1 -fsanitize=address,undefined -Wall -Wextra -Werror -g3 -std=c2x -D_FORTIFY_SOURCE=2 -I$(SOURCE_DIR)/lib/include -o $@ $^
|
||||
./$@
|
||||
|
||||
|
||||
4
kernel.d
Normal file
4
kernel.d
Normal file
@@ -0,0 +1,4 @@
|
||||
kernel.o: src/kernel/kernel.c src/kernel/gdt.h src/kernel/types.h \
|
||||
src/kernel/tss.h src/kernel/idt.h src/kernel/interrupts.h \
|
||||
src/kernel/kernel_state.h src/lib/include/str.h src/kernel/pic.h \
|
||||
src/kernel/page.h src/lib/include/libc.h src/kernel/tty.h
|
||||
@@ -50,6 +50,7 @@ SECTIONS
|
||||
.data BLOCK(4K) : ALIGN(4K)
|
||||
{
|
||||
*(.data)
|
||||
kernel_data_end = .;
|
||||
}
|
||||
|
||||
/* Read-write data (uninitialized) and stack */
|
||||
@@ -57,6 +58,8 @@ SECTIONS
|
||||
{
|
||||
*(COMMON)
|
||||
*(.bss)
|
||||
|
||||
kernel_memory_end = .;
|
||||
}
|
||||
|
||||
/* The compiler may produce other sections, by default it will put them in
|
||||
|
||||
@@ -32,178 +32,3 @@ const struct str ps2_response_str[] = {
|
||||
[PS2RESPONSE_RESEND ] = str_attach("PS2RESPONSE_RESEND"),
|
||||
};
|
||||
|
||||
const struct str ps2_key_str[] = {
|
||||
[KEY_EXTENDED ] = str_attach("KEY_EXTENDED (PRESSED)"),
|
||||
[KEY_ESCAPE ] = str_attach("KEY_ESCAPE (PRESSED)"),
|
||||
[KEY_1 ] = str_attach("KEY_1 (PRESSED)"),
|
||||
[KEY_2 ] = str_attach("KEY_2 (PRESSED)"),
|
||||
[KEY_3 ] = str_attach("KEY_3 (PRESSED)"),
|
||||
[KEY_4 ] = str_attach("KEY_4 (PRESSED)"),
|
||||
[KEY_5 ] = str_attach("KEY_5 (PRESSED)"),
|
||||
[KEY_6 ] = str_attach("KEY_6 (PRESSED)"),
|
||||
[KEY_7 ] = str_attach("KEY_7 (PRESSED)"),
|
||||
[KEY_8 ] = str_attach("KEY_8 (PRESSED)"),
|
||||
[KEY_9 ] = str_attach("KEY_9 (PRESSED)"),
|
||||
[KEY_0 ] = str_attach("KEY_0 (PRESSED)"),
|
||||
[KEY_MINUS ] = str_attach("KEY_MINUS (PRESSED)"),
|
||||
[KEY_EQUALS ] = str_attach("KEY_EQUALS (PRESSED)"),
|
||||
[KEY_BACKSPACE ] = str_attach("KEY_BACKSPACE (PRESSED)"),
|
||||
[KEY_TAB ] = str_attach("KEY_TAB (PRESSED)"),
|
||||
[KEY_Q ] = str_attach("KEY_Q (PRESSED)"),
|
||||
[KEY_W ] = str_attach("KEY_W (PRESSED)"),
|
||||
[KEY_E ] = str_attach("KEY_E (PRESSED)"),
|
||||
[KEY_R ] = str_attach("KEY_R (PRESSED)"),
|
||||
[KEY_T ] = str_attach("KEY_T (PRESSED)"),
|
||||
[KEY_Y ] = str_attach("KEY_Y (PRESSED)"),
|
||||
[KEY_U ] = str_attach("KEY_U (PRESSED)"),
|
||||
[KEY_I ] = str_attach("KEY_I (PRESSED)"),
|
||||
[KEY_O ] = str_attach("KEY_O (PRESSED)"),
|
||||
[KEY_P ] = str_attach("KEY_P (PRESSED)"),
|
||||
[KEY_SQUARE_BRACKET_LEFT ] = str_attach("KEY_SQUARE_BRACKET_LEFT (PRESSED)"),
|
||||
[KEY_SQUARE_BRACKET_RIGHT] = str_attach("KEY_SQUARE_BRACKET_RIGHT (PRESSED)"),
|
||||
[KEY_ENTER ] = str_attach("KEY_ENTER (PRESSED)"),
|
||||
[KEY_LEFT_CONTROL ] = str_attach("KEY_LEFT_CONTROL (PRESSED)"),
|
||||
[KEY_A ] = str_attach("KEY_A (PRESSED)"),
|
||||
[KEY_S ] = str_attach("KEY_S (PRESSED)"),
|
||||
[KEY_D ] = str_attach("KEY_D (PRESSED)"),
|
||||
[KEY_F ] = str_attach("KEY_F (PRESSED)"),
|
||||
[KEY_G ] = str_attach("KEY_G (PRESSED)"),
|
||||
[KEY_H ] = str_attach("KEY_H (PRESSED)"),
|
||||
[KEY_J ] = str_attach("KEY_J (PRESSED)"),
|
||||
[KEY_K ] = str_attach("KEY_K (PRESSED)"),
|
||||
[KEY_L ] = str_attach("KEY_L (PRESSED)"),
|
||||
[KEY_SEMICOLON ] = str_attach("KEY_SEMICOLON (PRESSED)"),
|
||||
[KEY_SINGLE_QUOTE ] = str_attach("KEY_SINGLE_QUOTE (PRESSED)"),
|
||||
[KEY_BACKTICK ] = str_attach("KEY_BACKTICK (PRESSED)"),
|
||||
[KEY_LEFT_SHIFT ] = str_attach("KEY_LEFT_SHIFT (PRESSED)"),
|
||||
[KEY_BACKSLASH ] = str_attach("KEY_BACKSLASH (PRESSED)"),
|
||||
[KEY_Z ] = str_attach("KEY_Z (PRESSED)"),
|
||||
[KEY_X ] = str_attach("KEY_X (PRESSED)"),
|
||||
[KEY_C ] = str_attach("KEY_C (PRESSED)"),
|
||||
[KEY_V ] = str_attach("KEY_V (PRESSED)"),
|
||||
[KEY_B ] = str_attach("KEY_B (PRESSED)"),
|
||||
[KEY_N ] = str_attach("KEY_N (PRESSED)"),
|
||||
[KEY_M ] = str_attach("KEY_M (PRESSED)"),
|
||||
[KEY_COMMA ] = str_attach("KEY_COMMA (PRESSED)"),
|
||||
[KEY_DOT ] = str_attach("KEY_DOT (PRESSED)"),
|
||||
[KEY_FORWARD_SLASH ] = str_attach("KEY_FORWARD_SLASH (PRESSED)"),
|
||||
[KEY_RIGHT_SHIFT ] = str_attach("KEY_RIGHT_SHIFT (PRESSED)"),
|
||||
[KEY_KEYPAD_ASTERISK ] = str_attach("KEY_KEYPAD_ASTERISK (PRESSED)"),
|
||||
[KEY_LEFT_ALT ] = str_attach("KEY_LEFT_ALT (PRESSED)"),
|
||||
[KEY_SPACE ] = str_attach("KEY_SPACE (PRESSED)"),
|
||||
[KEY_CAPSLOCK ] = str_attach("KEY_CAPSLOCK (PRESSED)"),
|
||||
[KEY_F1 ] = str_attach("KEY_F1 (PRESSED)"),
|
||||
[KEY_F2 ] = str_attach("KEY_F2 (PRESSED)"),
|
||||
[KEY_F3 ] = str_attach("KEY_F3 (PRESSED)"),
|
||||
[KEY_F4 ] = str_attach("KEY_F4 (PRESSED)"),
|
||||
[KEY_F5 ] = str_attach("KEY_F5 (PRESSED)"),
|
||||
[KEY_F6 ] = str_attach("KEY_F6 (PRESSED)"),
|
||||
[KEY_F7 ] = str_attach("KEY_F7 (PRESSED)"),
|
||||
[KEY_F8 ] = str_attach("KEY_F8 (PRESSED)"),
|
||||
[KEY_F9 ] = str_attach("KEY_F9 (PRESSED)"),
|
||||
[KEY_F10 ] = str_attach("KEY_F10 (PRESSED)"),
|
||||
[KEY_NUMBERLOCK ] = str_attach("KEY_NUMBERLOCK (PRESSED)"),
|
||||
[KEY_SCROLLLOCK ] = str_attach("KEY_SCROLLLOCK (PRESSED)"),
|
||||
[KEY_KEYPAD_7 ] = str_attach("KEY_KEYPAD_7 (PRESSED)"),
|
||||
[KEY_KEYPAD_8 ] = str_attach("KEY_KEYPAD_8 (PRESSED)"),
|
||||
[KEY_KEYPAD_9 ] = str_attach("KEY_KEYPAD_9 (PRESSED)"),
|
||||
[KEY_KEYPAD_MINUS ] = str_attach("KEY_KEYPAD_MINUS (PRESSED)"),
|
||||
[KEY_KEYPAD_4 ] = str_attach("KEY_KEYPAD_4 (PRESSED)"),
|
||||
[KEY_KEYPAD_5 ] = str_attach("KEY_KEYPAD_5 (PRESSED)"),
|
||||
[KEY_KEYPAD_6 ] = str_attach("KEY_KEYPAD_6 (PRESSED)"),
|
||||
[KEY_KEYPAD_PLUS ] = str_attach("KEY_KEYPAD_PLUS (PRESSED)"),
|
||||
[KEY_KEYPAD_1 ] = str_attach("KEY_KEYPAD_1 (PRESSED)"),
|
||||
[KEY_KEYPAD_2 ] = str_attach("KEY_KEYPAD_2 (PRESSED)"),
|
||||
[KEY_KEYPAD_3 ] = str_attach("KEY_KEYPAD_3 (PRESSED)"),
|
||||
[KEY_KEYPAD_0 ] = str_attach("KEY_KEYPAD_0 (PRESSED)"),
|
||||
[KEY_KEYPAD_DOT ] = str_attach("KEY_KEYPAD_DOT (PRESSED)"),
|
||||
[KEY_F11 ] = str_attach("KEY_F11 (PRESSED)"),
|
||||
[KEY_F12 ] = str_attach("KEY_F12 (PRESSED)"),
|
||||
|
||||
[KEY_RELEASED | KEY_ESCAPE ] = str_attach("KEY_ESCAPE (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_1 ] = str_attach("KEY_1 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_2 ] = str_attach("KEY_2 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_3 ] = str_attach("KEY_3 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_4 ] = str_attach("KEY_4 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_5 ] = str_attach("KEY_5 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_6 ] = str_attach("KEY_6 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_7 ] = str_attach("KEY_7 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_8 ] = str_attach("KEY_8 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_9 ] = str_attach("KEY_9 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_0 ] = str_attach("KEY_0 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_MINUS ] = str_attach("KEY_MINUS (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_EQUALS ] = str_attach("KEY_EQUALS (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_BACKSPACE ] = str_attach("KEY_BACKSPACE (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_TAB ] = str_attach("KEY_TAB (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_Q ] = str_attach("KEY_Q (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_W ] = str_attach("KEY_W (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_E ] = str_attach("KEY_E (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_R ] = str_attach("KEY_R (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_T ] = str_attach("KEY_T (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_Y ] = str_attach("KEY_Y (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_U ] = str_attach("KEY_U (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_I ] = str_attach("KEY_I (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_O ] = str_attach("KEY_O (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_P ] = str_attach("KEY_P (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_SQUARE_BRACKET_LEFT ] = str_attach("KEY_SQUARE_BRACKET_LEFT (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_SQUARE_BRACKET_RIGHT] = str_attach("KEY_SQUARE_BRACKET_RIGHT (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_ENTER ] = str_attach("KEY_ENTER (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_LEFT_CONTROL ] = str_attach("KEY_LEFT_CONTROL (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_A ] = str_attach("KEY_A (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_S ] = str_attach("KEY_S (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_D ] = str_attach("KEY_D (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F ] = str_attach("KEY_F (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_G ] = str_attach("KEY_G (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_H ] = str_attach("KEY_H (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_J ] = str_attach("KEY_J (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_K ] = str_attach("KEY_K (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_L ] = str_attach("KEY_L (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_SEMICOLON ] = str_attach("KEY_SEMICOLON (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_SINGLE_QUOTE ] = str_attach("KEY_SINGLE_QUOTE (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_BACKTICK ] = str_attach("KEY_BACKTICK (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_LEFT_SHIFT ] = str_attach("KEY_LEFT_SHIFT (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_BACKSLASH ] = str_attach("KEY_BACKSLASH (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_Z ] = str_attach("KEY_Z (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_X ] = str_attach("KEY_X (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_C ] = str_attach("KEY_C (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_V ] = str_attach("KEY_V (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_B ] = str_attach("KEY_B (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_N ] = str_attach("KEY_N (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_M ] = str_attach("KEY_M (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_COMMA ] = str_attach("KEY_COMMA (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_DOT ] = str_attach("KEY_DOT (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_FORWARD_SLASH ] = str_attach("KEY_FORWARD_SLASH (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_RIGHT_SHIFT ] = str_attach("KEY_RIGHT_SHIFT (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_ASTERISK ] = str_attach("KEY_KEYPAD_ASTERISK (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_LEFT_ALT ] = str_attach("KEY_LEFT_ALT (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_SPACE ] = str_attach("KEY_SPACE (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_CAPSLOCK ] = str_attach("KEY_CAPSLOCK (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F1 ] = str_attach("KEY_F1 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F2 ] = str_attach("KEY_F2 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F3 ] = str_attach("KEY_F3 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F4 ] = str_attach("KEY_F4 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F5 ] = str_attach("KEY_F5 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F6 ] = str_attach("KEY_F6 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F7 ] = str_attach("KEY_F7 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F8 ] = str_attach("KEY_F8 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F9 ] = str_attach("KEY_F9 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F10 ] = str_attach("KEY_F10 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_NUMBERLOCK ] = str_attach("KEY_NUMBERLOCK (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_SCROLLLOCK ] = str_attach("KEY_SCROLLLOCK (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_7 ] = str_attach("KEY_KEYPAD_7 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_8 ] = str_attach("KEY_KEYPAD_8 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_9 ] = str_attach("KEY_KEYPAD_9 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_MINUS ] = str_attach("KEY_KEYPAD_MINUS (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_4 ] = str_attach("KEY_KEYPAD_4 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_5 ] = str_attach("KEY_KEYPAD_5 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_6 ] = str_attach("KEY_KEYPAD_6 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_PLUS ] = str_attach("KEY_KEYPAD_PLUS (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_1 ] = str_attach("KEY_KEYPAD_1 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_2 ] = str_attach("KEY_KEYPAD_2 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_3 ] = str_attach("KEY_KEYPAD_3 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_0 ] = str_attach("KEY_KEYPAD_0 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_DOT ] = str_attach("KEY_KEYPAD_DOT (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F11 ] = str_attach("KEY_F11 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F12 ] = str_attach("KEY_F12 (RELEASED)"),
|
||||
};
|
||||
|
||||
|
||||
@@ -176,6 +176,9 @@ enum ps2_keys {
|
||||
};
|
||||
extern const struct str ps2_key_str[];
|
||||
|
||||
constexpr size_t KEY_MODIFIER_SHIFT = 0x80; /* used by ps2_key_char[] */
|
||||
extern const char ps2_key_char[];
|
||||
|
||||
enum ps2_extended_key : uint8_t {
|
||||
KEY_E_MULTIMEDIA_PREV_TRACK = 0x10,
|
||||
KEY_E_MULTIMEDIA_NEXT_TRACK = 0x19,
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "libc.h"
|
||||
#include "tty.h"
|
||||
#include "interrupts.h"
|
||||
@@ -22,7 +23,7 @@ static void print_interrupt_frame(struct interrupt_frame* f)
|
||||
"Interrupt frame:\n"
|
||||
"================\n"
|
||||
"ip: {x32}\n"
|
||||
"cs: {x32}\n"
|
||||
"cs: {x32} == {cs}\n"
|
||||
"flags: {x32}\n"
|
||||
"sp: {x32}\n"
|
||||
"ss: {x32}\n"),
|
||||
@@ -35,14 +36,15 @@ static void print_interrupt_frame(struct interrupt_frame* f)
|
||||
|
||||
/* not an interrupt/exception, but called by exception stubs */
|
||||
__attribute__((noreturn))
|
||||
static void panic_exception_not_implemented(struct interrupt_frame* frame, int exception_no)
|
||||
static void panic_exception_not_implemented(struct interrupt_frame* frame, int exception_no, uint32_t err)
|
||||
{
|
||||
terminal_set_color(VGA_COLOR_WHITE, VGA_COLOR_RED);
|
||||
printf(str_attach("non-implemented exception {i32} occurred\n"), exception_no);
|
||||
struct str name = idt_desc_index_str[exception_no];
|
||||
if (name.len != 0) {
|
||||
printf(str_attach("exception name: {str})\n"), name);
|
||||
printf(str_attach("exception name: {str}\n"), name, err);
|
||||
}
|
||||
printf(str_attach("error: {x32}\n"), err);
|
||||
if (frame != NULL) {
|
||||
print_interrupt_frame(frame);
|
||||
} else {
|
||||
@@ -94,6 +96,7 @@ void exception_handler_div_by_zero(struct interrupt_frame* frame)
|
||||
panic(str_attach("div by zero occured :("));
|
||||
}
|
||||
|
||||
#include "page.h"
|
||||
__attribute__((interrupt, noreturn))
|
||||
void exception_handler_page_fault(struct interrupt_frame* frame, int err)
|
||||
{
|
||||
@@ -103,9 +106,41 @@ void exception_handler_page_fault(struct interrupt_frame* frame, int err)
|
||||
}
|
||||
terminal_set_color(VGA_COLOR_WHITE, VGA_COLOR_RED);
|
||||
printf(str_attach(
|
||||
"page fault :(, err: 0x{x32}\n"),
|
||||
err,
|
||||
gdt_segment_index_str[err/8]);
|
||||
"page fault :(, err: 0x{x32}: ["),
|
||||
err);
|
||||
|
||||
/* page fault error bits */
|
||||
enum {
|
||||
present = 1<<0,
|
||||
write = 1<<1,
|
||||
user = 1<<2,
|
||||
reserved_write = 1<<3,
|
||||
instruction_fetch = 1<<4,
|
||||
protection_key = 1<<5,
|
||||
shadow_stack = 1<<6,
|
||||
software_guard_ex = 1<<15,
|
||||
};
|
||||
|
||||
const struct str error_names[] = {
|
||||
[0] = str_attach("present"),
|
||||
[1] = str_attach("write"),
|
||||
[2] = str_attach("user"),
|
||||
[3] = str_attach("reserved_write"),
|
||||
[4] = str_attach("instruction_fetch"),
|
||||
[5] = str_attach("protection_key"),
|
||||
[6] = str_attach("shadow_stack"),
|
||||
[15] = str_attach("software_guard_ex"),
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof error_names / sizeof *error_names; i++) {
|
||||
if ((err & (1<<i)) && error_names[i].data) {
|
||||
printf(str_attach("{str} | "), error_names[i]);
|
||||
}
|
||||
}
|
||||
printf(str_attach("0]\n"));
|
||||
|
||||
print_interrupt_frame(frame);
|
||||
|
||||
__asm__ volatile("cli; hlt");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
@@ -158,16 +193,54 @@ static void irq_stub(struct interrupt_frame* frame, int line)
|
||||
__attribute__((interrupt)) void irq_handler_0(struct interrupt_frame* frame) { irq_stub(frame, 0); }
|
||||
|
||||
/* IRQ1 - keyboard controller */
|
||||
#include "ps2-keyboard.h"
|
||||
__attribute__((interrupt)) void irq_handler_1(struct interrupt_frame* frame)
|
||||
#include "keys.h"
|
||||
|
||||
__attribute__((interrupt))
|
||||
void irq_handler_1(struct interrupt_frame* frame)
|
||||
{
|
||||
/* TODO: move keyboard logic to a separate compilation unit */
|
||||
(void)frame;
|
||||
|
||||
for (struct kernel_hook* p = kernel.keypress_hooks;
|
||||
p != NULL;
|
||||
p = p->next)
|
||||
{
|
||||
// TODO
|
||||
//proc_send(p->);
|
||||
}
|
||||
|
||||
#if 0
|
||||
uint8_t key = inb(PIC_KEYBOARD);
|
||||
|
||||
bool released = key & KEY_RELEASED;
|
||||
key &= ~KEY_RELEASED;
|
||||
|
||||
if (key == KEY_RIGHT_SHIFT || key == KEY_LEFT_SHIFT) {
|
||||
shift = !released;
|
||||
outb(PIC1_COMMAND, OCW2_EOI);
|
||||
return;
|
||||
}
|
||||
|
||||
if (key == KEY_E_RIGHT_CONTROL || key == KEY_LEFT_CONTROL) {
|
||||
ctrl = !released;
|
||||
(void)ctrl;
|
||||
outb(PIC1_COMMAND, OCW2_EOI);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!released) {
|
||||
if (shift) {
|
||||
key |= KEY_MODIFIER_SHIFT;
|
||||
}
|
||||
const char ch = ps2_key_char[key];
|
||||
if (ch) {
|
||||
terminal_putchar(ch);
|
||||
kernel_input_buffer_push(ch);
|
||||
} else {
|
||||
printf(str_attach("[{str}]"), ps2_key_str[key]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
printf(str_attach("key {str}\n"), ps2_key_str[key]);
|
||||
outb(PIC1_COMMAND, OCW2_EOI);
|
||||
}
|
||||
|
||||
@@ -191,12 +264,13 @@ __attribute__((interrupt)) void irq_handler_15(struct interrupt_frame* frame) {
|
||||
* Exception Stubs
|
||||
* ===============
|
||||
*/
|
||||
#define EXCEPTION_STUB(n) exception_stub_##n
|
||||
|
||||
#define DEFINE_EXCEPTION_STUB(n) \
|
||||
__attribute__((interrupt, noreturn)) \
|
||||
void EXCEPTION_STUB(n)(struct interrupt_frame* frame) \
|
||||
void EXCEPTION_STUB(n)(struct interrupt_frame* frame, uint32_t err) \
|
||||
{ \
|
||||
panic_exception_not_implemented(frame, n); \
|
||||
panic_exception_not_implemented(frame, n, err); \
|
||||
}
|
||||
|
||||
DEFINE_EXCEPTION_STUB(0)
|
||||
|
||||
@@ -2,14 +2,6 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
struct __attribute__((packed)) interrupt_frame {
|
||||
uword_t ip;
|
||||
uword_t cs;
|
||||
uword_t flags;
|
||||
uword_t sp;
|
||||
uword_t ss;
|
||||
};
|
||||
|
||||
/*
|
||||
* Exceptions
|
||||
* ==========*/
|
||||
@@ -22,6 +14,9 @@ void exception_handler_general_protection_fault(struct interrupt_frame* frame, i
|
||||
__attribute__((interrupt, noreturn))
|
||||
void exception_handler_double_fault(struct interrupt_frame* frame);
|
||||
|
||||
__attribute__((interrupt, noreturn))
|
||||
void exception_handler_page_fault(struct interrupt_frame* frame, int err);
|
||||
|
||||
__attribute__((interrupt, noreturn))
|
||||
void exception_default(struct interrupt_frame* frame);
|
||||
|
||||
@@ -78,265 +73,266 @@ static void idt_init_stubs(struct idt_gate_descriptor idt[]) {
|
||||
IDT_DPL_3, \
|
||||
IDT_GATE_TYPE_TRAP32)
|
||||
|
||||
#define DECLARE_EXCEPTION_STUB(n) \
|
||||
__attribute__((interrupt)) void EXCEPTION_STUB(n)(struct interrupt_frame*); \
|
||||
#define SET_EXCEPTION_STUB(n) \
|
||||
__attribute__((interrupt)) void EXCEPTION_STUB(n)(struct interrupt_frame*, uint32_t err); \
|
||||
idt[n] = DESC(EXCEPTION_STUB(n))
|
||||
DECLARE_EXCEPTION_STUB(0);
|
||||
DECLARE_EXCEPTION_STUB(1);
|
||||
DECLARE_EXCEPTION_STUB(2);
|
||||
DECLARE_EXCEPTION_STUB(3);
|
||||
DECLARE_EXCEPTION_STUB(4);
|
||||
DECLARE_EXCEPTION_STUB(5);
|
||||
DECLARE_EXCEPTION_STUB(6);
|
||||
DECLARE_EXCEPTION_STUB(7);
|
||||
DECLARE_EXCEPTION_STUB(8);
|
||||
DECLARE_EXCEPTION_STUB(9);
|
||||
DECLARE_EXCEPTION_STUB(10);
|
||||
DECLARE_EXCEPTION_STUB(11);
|
||||
DECLARE_EXCEPTION_STUB(12);
|
||||
DECLARE_EXCEPTION_STUB(13);
|
||||
DECLARE_EXCEPTION_STUB(14);
|
||||
DECLARE_EXCEPTION_STUB(15);
|
||||
DECLARE_EXCEPTION_STUB(16);
|
||||
DECLARE_EXCEPTION_STUB(17);
|
||||
DECLARE_EXCEPTION_STUB(18);
|
||||
DECLARE_EXCEPTION_STUB(19);
|
||||
DECLARE_EXCEPTION_STUB(20);
|
||||
DECLARE_EXCEPTION_STUB(21);
|
||||
DECLARE_EXCEPTION_STUB(22);
|
||||
DECLARE_EXCEPTION_STUB(23);
|
||||
DECLARE_EXCEPTION_STUB(24);
|
||||
DECLARE_EXCEPTION_STUB(25);
|
||||
DECLARE_EXCEPTION_STUB(26);
|
||||
DECLARE_EXCEPTION_STUB(27);
|
||||
DECLARE_EXCEPTION_STUB(28);
|
||||
DECLARE_EXCEPTION_STUB(29);
|
||||
DECLARE_EXCEPTION_STUB(30);
|
||||
DECLARE_EXCEPTION_STUB(31);
|
||||
DECLARE_EXCEPTION_STUB(32);
|
||||
DECLARE_EXCEPTION_STUB(33);
|
||||
DECLARE_EXCEPTION_STUB(34);
|
||||
DECLARE_EXCEPTION_STUB(35);
|
||||
DECLARE_EXCEPTION_STUB(36);
|
||||
DECLARE_EXCEPTION_STUB(37);
|
||||
DECLARE_EXCEPTION_STUB(38);
|
||||
DECLARE_EXCEPTION_STUB(39);
|
||||
DECLARE_EXCEPTION_STUB(40);
|
||||
DECLARE_EXCEPTION_STUB(41);
|
||||
DECLARE_EXCEPTION_STUB(42);
|
||||
DECLARE_EXCEPTION_STUB(43);
|
||||
DECLARE_EXCEPTION_STUB(44);
|
||||
DECLARE_EXCEPTION_STUB(45);
|
||||
DECLARE_EXCEPTION_STUB(46);
|
||||
DECLARE_EXCEPTION_STUB(47);
|
||||
DECLARE_EXCEPTION_STUB(48);
|
||||
DECLARE_EXCEPTION_STUB(49);
|
||||
DECLARE_EXCEPTION_STUB(50);
|
||||
DECLARE_EXCEPTION_STUB(51);
|
||||
DECLARE_EXCEPTION_STUB(52);
|
||||
DECLARE_EXCEPTION_STUB(53);
|
||||
DECLARE_EXCEPTION_STUB(54);
|
||||
DECLARE_EXCEPTION_STUB(55);
|
||||
DECLARE_EXCEPTION_STUB(56);
|
||||
DECLARE_EXCEPTION_STUB(57);
|
||||
DECLARE_EXCEPTION_STUB(58);
|
||||
DECLARE_EXCEPTION_STUB(59);
|
||||
DECLARE_EXCEPTION_STUB(60);
|
||||
DECLARE_EXCEPTION_STUB(61);
|
||||
DECLARE_EXCEPTION_STUB(62);
|
||||
DECLARE_EXCEPTION_STUB(63);
|
||||
DECLARE_EXCEPTION_STUB(64);
|
||||
DECLARE_EXCEPTION_STUB(65);
|
||||
DECLARE_EXCEPTION_STUB(66);
|
||||
DECLARE_EXCEPTION_STUB(67);
|
||||
DECLARE_EXCEPTION_STUB(68);
|
||||
DECLARE_EXCEPTION_STUB(69);
|
||||
DECLARE_EXCEPTION_STUB(70);
|
||||
DECLARE_EXCEPTION_STUB(71);
|
||||
DECLARE_EXCEPTION_STUB(72);
|
||||
DECLARE_EXCEPTION_STUB(73);
|
||||
DECLARE_EXCEPTION_STUB(74);
|
||||
DECLARE_EXCEPTION_STUB(75);
|
||||
DECLARE_EXCEPTION_STUB(76);
|
||||
DECLARE_EXCEPTION_STUB(77);
|
||||
DECLARE_EXCEPTION_STUB(78);
|
||||
DECLARE_EXCEPTION_STUB(79);
|
||||
DECLARE_EXCEPTION_STUB(80);
|
||||
DECLARE_EXCEPTION_STUB(81);
|
||||
DECLARE_EXCEPTION_STUB(82);
|
||||
DECLARE_EXCEPTION_STUB(83);
|
||||
DECLARE_EXCEPTION_STUB(84);
|
||||
DECLARE_EXCEPTION_STUB(85);
|
||||
DECLARE_EXCEPTION_STUB(86);
|
||||
DECLARE_EXCEPTION_STUB(87);
|
||||
DECLARE_EXCEPTION_STUB(88);
|
||||
DECLARE_EXCEPTION_STUB(89);
|
||||
DECLARE_EXCEPTION_STUB(90);
|
||||
DECLARE_EXCEPTION_STUB(91);
|
||||
DECLARE_EXCEPTION_STUB(92);
|
||||
DECLARE_EXCEPTION_STUB(93);
|
||||
DECLARE_EXCEPTION_STUB(94);
|
||||
DECLARE_EXCEPTION_STUB(95);
|
||||
DECLARE_EXCEPTION_STUB(96);
|
||||
DECLARE_EXCEPTION_STUB(97);
|
||||
DECLARE_EXCEPTION_STUB(98);
|
||||
DECLARE_EXCEPTION_STUB(99);
|
||||
DECLARE_EXCEPTION_STUB(100);
|
||||
DECLARE_EXCEPTION_STUB(101);
|
||||
DECLARE_EXCEPTION_STUB(102);
|
||||
DECLARE_EXCEPTION_STUB(103);
|
||||
DECLARE_EXCEPTION_STUB(104);
|
||||
DECLARE_EXCEPTION_STUB(105);
|
||||
DECLARE_EXCEPTION_STUB(106);
|
||||
DECLARE_EXCEPTION_STUB(107);
|
||||
DECLARE_EXCEPTION_STUB(108);
|
||||
DECLARE_EXCEPTION_STUB(109);
|
||||
DECLARE_EXCEPTION_STUB(110);
|
||||
DECLARE_EXCEPTION_STUB(111);
|
||||
DECLARE_EXCEPTION_STUB(112);
|
||||
DECLARE_EXCEPTION_STUB(113);
|
||||
DECLARE_EXCEPTION_STUB(114);
|
||||
DECLARE_EXCEPTION_STUB(115);
|
||||
DECLARE_EXCEPTION_STUB(116);
|
||||
DECLARE_EXCEPTION_STUB(117);
|
||||
DECLARE_EXCEPTION_STUB(118);
|
||||
DECLARE_EXCEPTION_STUB(119);
|
||||
DECLARE_EXCEPTION_STUB(120);
|
||||
DECLARE_EXCEPTION_STUB(121);
|
||||
DECLARE_EXCEPTION_STUB(122);
|
||||
DECLARE_EXCEPTION_STUB(123);
|
||||
DECLARE_EXCEPTION_STUB(124);
|
||||
DECLARE_EXCEPTION_STUB(125);
|
||||
DECLARE_EXCEPTION_STUB(126);
|
||||
DECLARE_EXCEPTION_STUB(127);
|
||||
DECLARE_EXCEPTION_STUB(128);
|
||||
DECLARE_EXCEPTION_STUB(129);
|
||||
DECLARE_EXCEPTION_STUB(130);
|
||||
DECLARE_EXCEPTION_STUB(131);
|
||||
DECLARE_EXCEPTION_STUB(132);
|
||||
DECLARE_EXCEPTION_STUB(133);
|
||||
DECLARE_EXCEPTION_STUB(134);
|
||||
DECLARE_EXCEPTION_STUB(135);
|
||||
DECLARE_EXCEPTION_STUB(136);
|
||||
DECLARE_EXCEPTION_STUB(137);
|
||||
DECLARE_EXCEPTION_STUB(138);
|
||||
DECLARE_EXCEPTION_STUB(139);
|
||||
DECLARE_EXCEPTION_STUB(140);
|
||||
DECLARE_EXCEPTION_STUB(141);
|
||||
DECLARE_EXCEPTION_STUB(142);
|
||||
DECLARE_EXCEPTION_STUB(143);
|
||||
DECLARE_EXCEPTION_STUB(144);
|
||||
DECLARE_EXCEPTION_STUB(145);
|
||||
DECLARE_EXCEPTION_STUB(146);
|
||||
DECLARE_EXCEPTION_STUB(147);
|
||||
DECLARE_EXCEPTION_STUB(148);
|
||||
DECLARE_EXCEPTION_STUB(149);
|
||||
DECLARE_EXCEPTION_STUB(150);
|
||||
DECLARE_EXCEPTION_STUB(151);
|
||||
DECLARE_EXCEPTION_STUB(152);
|
||||
DECLARE_EXCEPTION_STUB(153);
|
||||
DECLARE_EXCEPTION_STUB(154);
|
||||
DECLARE_EXCEPTION_STUB(155);
|
||||
DECLARE_EXCEPTION_STUB(156);
|
||||
DECLARE_EXCEPTION_STUB(157);
|
||||
DECLARE_EXCEPTION_STUB(158);
|
||||
DECLARE_EXCEPTION_STUB(159);
|
||||
DECLARE_EXCEPTION_STUB(160);
|
||||
DECLARE_EXCEPTION_STUB(161);
|
||||
DECLARE_EXCEPTION_STUB(162);
|
||||
DECLARE_EXCEPTION_STUB(163);
|
||||
DECLARE_EXCEPTION_STUB(164);
|
||||
DECLARE_EXCEPTION_STUB(165);
|
||||
DECLARE_EXCEPTION_STUB(166);
|
||||
DECLARE_EXCEPTION_STUB(167);
|
||||
DECLARE_EXCEPTION_STUB(168);
|
||||
DECLARE_EXCEPTION_STUB(169);
|
||||
DECLARE_EXCEPTION_STUB(170);
|
||||
DECLARE_EXCEPTION_STUB(171);
|
||||
DECLARE_EXCEPTION_STUB(172);
|
||||
DECLARE_EXCEPTION_STUB(173);
|
||||
DECLARE_EXCEPTION_STUB(174);
|
||||
DECLARE_EXCEPTION_STUB(175);
|
||||
DECLARE_EXCEPTION_STUB(176);
|
||||
DECLARE_EXCEPTION_STUB(177);
|
||||
DECLARE_EXCEPTION_STUB(178);
|
||||
DECLARE_EXCEPTION_STUB(179);
|
||||
DECLARE_EXCEPTION_STUB(180);
|
||||
DECLARE_EXCEPTION_STUB(181);
|
||||
DECLARE_EXCEPTION_STUB(182);
|
||||
DECLARE_EXCEPTION_STUB(183);
|
||||
DECLARE_EXCEPTION_STUB(184);
|
||||
DECLARE_EXCEPTION_STUB(185);
|
||||
DECLARE_EXCEPTION_STUB(186);
|
||||
DECLARE_EXCEPTION_STUB(187);
|
||||
DECLARE_EXCEPTION_STUB(188);
|
||||
DECLARE_EXCEPTION_STUB(189);
|
||||
DECLARE_EXCEPTION_STUB(190);
|
||||
DECLARE_EXCEPTION_STUB(191);
|
||||
DECLARE_EXCEPTION_STUB(192);
|
||||
DECLARE_EXCEPTION_STUB(193);
|
||||
DECLARE_EXCEPTION_STUB(194);
|
||||
DECLARE_EXCEPTION_STUB(195);
|
||||
DECLARE_EXCEPTION_STUB(196);
|
||||
DECLARE_EXCEPTION_STUB(197);
|
||||
DECLARE_EXCEPTION_STUB(198);
|
||||
DECLARE_EXCEPTION_STUB(199);
|
||||
DECLARE_EXCEPTION_STUB(200);
|
||||
DECLARE_EXCEPTION_STUB(201);
|
||||
DECLARE_EXCEPTION_STUB(202);
|
||||
DECLARE_EXCEPTION_STUB(203);
|
||||
DECLARE_EXCEPTION_STUB(204);
|
||||
DECLARE_EXCEPTION_STUB(205);
|
||||
DECLARE_EXCEPTION_STUB(206);
|
||||
DECLARE_EXCEPTION_STUB(207);
|
||||
DECLARE_EXCEPTION_STUB(208);
|
||||
DECLARE_EXCEPTION_STUB(209);
|
||||
DECLARE_EXCEPTION_STUB(210);
|
||||
DECLARE_EXCEPTION_STUB(211);
|
||||
DECLARE_EXCEPTION_STUB(212);
|
||||
DECLARE_EXCEPTION_STUB(213);
|
||||
DECLARE_EXCEPTION_STUB(214);
|
||||
DECLARE_EXCEPTION_STUB(215);
|
||||
DECLARE_EXCEPTION_STUB(216);
|
||||
DECLARE_EXCEPTION_STUB(217);
|
||||
DECLARE_EXCEPTION_STUB(218);
|
||||
DECLARE_EXCEPTION_STUB(219);
|
||||
DECLARE_EXCEPTION_STUB(220);
|
||||
DECLARE_EXCEPTION_STUB(221);
|
||||
DECLARE_EXCEPTION_STUB(222);
|
||||
DECLARE_EXCEPTION_STUB(223);
|
||||
DECLARE_EXCEPTION_STUB(224);
|
||||
DECLARE_EXCEPTION_STUB(225);
|
||||
DECLARE_EXCEPTION_STUB(226);
|
||||
DECLARE_EXCEPTION_STUB(227);
|
||||
DECLARE_EXCEPTION_STUB(228);
|
||||
DECLARE_EXCEPTION_STUB(229);
|
||||
DECLARE_EXCEPTION_STUB(230);
|
||||
DECLARE_EXCEPTION_STUB(231);
|
||||
DECLARE_EXCEPTION_STUB(232);
|
||||
DECLARE_EXCEPTION_STUB(233);
|
||||
DECLARE_EXCEPTION_STUB(234);
|
||||
DECLARE_EXCEPTION_STUB(235);
|
||||
DECLARE_EXCEPTION_STUB(236);
|
||||
DECLARE_EXCEPTION_STUB(237);
|
||||
DECLARE_EXCEPTION_STUB(238);
|
||||
DECLARE_EXCEPTION_STUB(239);
|
||||
DECLARE_EXCEPTION_STUB(240);
|
||||
DECLARE_EXCEPTION_STUB(241);
|
||||
DECLARE_EXCEPTION_STUB(242);
|
||||
DECLARE_EXCEPTION_STUB(243);
|
||||
DECLARE_EXCEPTION_STUB(244);
|
||||
DECLARE_EXCEPTION_STUB(245);
|
||||
DECLARE_EXCEPTION_STUB(246);
|
||||
DECLARE_EXCEPTION_STUB(247);
|
||||
DECLARE_EXCEPTION_STUB(248);
|
||||
DECLARE_EXCEPTION_STUB(249);
|
||||
DECLARE_EXCEPTION_STUB(250);
|
||||
DECLARE_EXCEPTION_STUB(251);
|
||||
DECLARE_EXCEPTION_STUB(252);
|
||||
DECLARE_EXCEPTION_STUB(253);
|
||||
DECLARE_EXCEPTION_STUB(254);
|
||||
DECLARE_EXCEPTION_STUB(255);
|
||||
SET_EXCEPTION_STUB(0);
|
||||
SET_EXCEPTION_STUB(1);
|
||||
SET_EXCEPTION_STUB(2);
|
||||
SET_EXCEPTION_STUB(3);
|
||||
SET_EXCEPTION_STUB(4);
|
||||
SET_EXCEPTION_STUB(5);
|
||||
SET_EXCEPTION_STUB(6);
|
||||
SET_EXCEPTION_STUB(7);
|
||||
SET_EXCEPTION_STUB(8);
|
||||
SET_EXCEPTION_STUB(9);
|
||||
SET_EXCEPTION_STUB(10);
|
||||
SET_EXCEPTION_STUB(11);
|
||||
SET_EXCEPTION_STUB(12);
|
||||
SET_EXCEPTION_STUB(13);
|
||||
SET_EXCEPTION_STUB(14);
|
||||
SET_EXCEPTION_STUB(15);
|
||||
SET_EXCEPTION_STUB(16);
|
||||
SET_EXCEPTION_STUB(17);
|
||||
SET_EXCEPTION_STUB(18);
|
||||
SET_EXCEPTION_STUB(19);
|
||||
SET_EXCEPTION_STUB(20);
|
||||
SET_EXCEPTION_STUB(21);
|
||||
SET_EXCEPTION_STUB(22);
|
||||
SET_EXCEPTION_STUB(23);
|
||||
SET_EXCEPTION_STUB(24);
|
||||
SET_EXCEPTION_STUB(25);
|
||||
SET_EXCEPTION_STUB(26);
|
||||
SET_EXCEPTION_STUB(27);
|
||||
SET_EXCEPTION_STUB(28);
|
||||
SET_EXCEPTION_STUB(29);
|
||||
SET_EXCEPTION_STUB(30);
|
||||
SET_EXCEPTION_STUB(31);
|
||||
SET_EXCEPTION_STUB(32);
|
||||
SET_EXCEPTION_STUB(33);
|
||||
SET_EXCEPTION_STUB(34);
|
||||
SET_EXCEPTION_STUB(35);
|
||||
SET_EXCEPTION_STUB(36);
|
||||
SET_EXCEPTION_STUB(37);
|
||||
SET_EXCEPTION_STUB(38);
|
||||
SET_EXCEPTION_STUB(39);
|
||||
SET_EXCEPTION_STUB(40);
|
||||
SET_EXCEPTION_STUB(41);
|
||||
SET_EXCEPTION_STUB(42);
|
||||
SET_EXCEPTION_STUB(43);
|
||||
SET_EXCEPTION_STUB(44);
|
||||
SET_EXCEPTION_STUB(45);
|
||||
SET_EXCEPTION_STUB(46);
|
||||
SET_EXCEPTION_STUB(47);
|
||||
SET_EXCEPTION_STUB(48);
|
||||
SET_EXCEPTION_STUB(49);
|
||||
SET_EXCEPTION_STUB(50);
|
||||
SET_EXCEPTION_STUB(51);
|
||||
SET_EXCEPTION_STUB(52);
|
||||
SET_EXCEPTION_STUB(53);
|
||||
SET_EXCEPTION_STUB(54);
|
||||
SET_EXCEPTION_STUB(55);
|
||||
SET_EXCEPTION_STUB(56);
|
||||
SET_EXCEPTION_STUB(57);
|
||||
SET_EXCEPTION_STUB(58);
|
||||
SET_EXCEPTION_STUB(59);
|
||||
SET_EXCEPTION_STUB(60);
|
||||
SET_EXCEPTION_STUB(61);
|
||||
SET_EXCEPTION_STUB(62);
|
||||
SET_EXCEPTION_STUB(63);
|
||||
SET_EXCEPTION_STUB(64);
|
||||
SET_EXCEPTION_STUB(65);
|
||||
SET_EXCEPTION_STUB(66);
|
||||
SET_EXCEPTION_STUB(67);
|
||||
SET_EXCEPTION_STUB(68);
|
||||
SET_EXCEPTION_STUB(69);
|
||||
SET_EXCEPTION_STUB(70);
|
||||
SET_EXCEPTION_STUB(71);
|
||||
SET_EXCEPTION_STUB(72);
|
||||
SET_EXCEPTION_STUB(73);
|
||||
SET_EXCEPTION_STUB(74);
|
||||
SET_EXCEPTION_STUB(75);
|
||||
SET_EXCEPTION_STUB(76);
|
||||
SET_EXCEPTION_STUB(77);
|
||||
SET_EXCEPTION_STUB(78);
|
||||
SET_EXCEPTION_STUB(79);
|
||||
SET_EXCEPTION_STUB(80);
|
||||
SET_EXCEPTION_STUB(81);
|
||||
SET_EXCEPTION_STUB(82);
|
||||
SET_EXCEPTION_STUB(83);
|
||||
SET_EXCEPTION_STUB(84);
|
||||
SET_EXCEPTION_STUB(85);
|
||||
SET_EXCEPTION_STUB(86);
|
||||
SET_EXCEPTION_STUB(87);
|
||||
SET_EXCEPTION_STUB(88);
|
||||
SET_EXCEPTION_STUB(89);
|
||||
SET_EXCEPTION_STUB(90);
|
||||
SET_EXCEPTION_STUB(91);
|
||||
SET_EXCEPTION_STUB(92);
|
||||
SET_EXCEPTION_STUB(93);
|
||||
SET_EXCEPTION_STUB(94);
|
||||
SET_EXCEPTION_STUB(95);
|
||||
SET_EXCEPTION_STUB(96);
|
||||
SET_EXCEPTION_STUB(97);
|
||||
SET_EXCEPTION_STUB(98);
|
||||
SET_EXCEPTION_STUB(99);
|
||||
SET_EXCEPTION_STUB(100);
|
||||
SET_EXCEPTION_STUB(101);
|
||||
SET_EXCEPTION_STUB(102);
|
||||
SET_EXCEPTION_STUB(103);
|
||||
SET_EXCEPTION_STUB(104);
|
||||
SET_EXCEPTION_STUB(105);
|
||||
SET_EXCEPTION_STUB(106);
|
||||
SET_EXCEPTION_STUB(107);
|
||||
SET_EXCEPTION_STUB(108);
|
||||
SET_EXCEPTION_STUB(109);
|
||||
SET_EXCEPTION_STUB(110);
|
||||
SET_EXCEPTION_STUB(111);
|
||||
SET_EXCEPTION_STUB(112);
|
||||
SET_EXCEPTION_STUB(113);
|
||||
SET_EXCEPTION_STUB(114);
|
||||
SET_EXCEPTION_STUB(115);
|
||||
SET_EXCEPTION_STUB(116);
|
||||
SET_EXCEPTION_STUB(117);
|
||||
SET_EXCEPTION_STUB(118);
|
||||
SET_EXCEPTION_STUB(119);
|
||||
SET_EXCEPTION_STUB(120);
|
||||
SET_EXCEPTION_STUB(121);
|
||||
SET_EXCEPTION_STUB(122);
|
||||
SET_EXCEPTION_STUB(123);
|
||||
SET_EXCEPTION_STUB(124);
|
||||
SET_EXCEPTION_STUB(125);
|
||||
SET_EXCEPTION_STUB(126);
|
||||
SET_EXCEPTION_STUB(127);
|
||||
SET_EXCEPTION_STUB(128);
|
||||
SET_EXCEPTION_STUB(129);
|
||||
SET_EXCEPTION_STUB(130);
|
||||
SET_EXCEPTION_STUB(131);
|
||||
SET_EXCEPTION_STUB(132);
|
||||
SET_EXCEPTION_STUB(133);
|
||||
SET_EXCEPTION_STUB(134);
|
||||
SET_EXCEPTION_STUB(135);
|
||||
SET_EXCEPTION_STUB(136);
|
||||
SET_EXCEPTION_STUB(137);
|
||||
SET_EXCEPTION_STUB(138);
|
||||
SET_EXCEPTION_STUB(139);
|
||||
SET_EXCEPTION_STUB(140);
|
||||
SET_EXCEPTION_STUB(141);
|
||||
SET_EXCEPTION_STUB(142);
|
||||
SET_EXCEPTION_STUB(143);
|
||||
SET_EXCEPTION_STUB(144);
|
||||
SET_EXCEPTION_STUB(145);
|
||||
SET_EXCEPTION_STUB(146);
|
||||
SET_EXCEPTION_STUB(147);
|
||||
SET_EXCEPTION_STUB(148);
|
||||
SET_EXCEPTION_STUB(149);
|
||||
SET_EXCEPTION_STUB(150);
|
||||
SET_EXCEPTION_STUB(151);
|
||||
SET_EXCEPTION_STUB(152);
|
||||
SET_EXCEPTION_STUB(153);
|
||||
SET_EXCEPTION_STUB(154);
|
||||
SET_EXCEPTION_STUB(155);
|
||||
SET_EXCEPTION_STUB(156);
|
||||
SET_EXCEPTION_STUB(157);
|
||||
SET_EXCEPTION_STUB(158);
|
||||
SET_EXCEPTION_STUB(159);
|
||||
SET_EXCEPTION_STUB(160);
|
||||
SET_EXCEPTION_STUB(161);
|
||||
SET_EXCEPTION_STUB(162);
|
||||
SET_EXCEPTION_STUB(163);
|
||||
SET_EXCEPTION_STUB(164);
|
||||
SET_EXCEPTION_STUB(165);
|
||||
SET_EXCEPTION_STUB(166);
|
||||
SET_EXCEPTION_STUB(167);
|
||||
SET_EXCEPTION_STUB(168);
|
||||
SET_EXCEPTION_STUB(169);
|
||||
SET_EXCEPTION_STUB(170);
|
||||
SET_EXCEPTION_STUB(171);
|
||||
SET_EXCEPTION_STUB(172);
|
||||
SET_EXCEPTION_STUB(173);
|
||||
SET_EXCEPTION_STUB(174);
|
||||
SET_EXCEPTION_STUB(175);
|
||||
SET_EXCEPTION_STUB(176);
|
||||
SET_EXCEPTION_STUB(177);
|
||||
SET_EXCEPTION_STUB(178);
|
||||
SET_EXCEPTION_STUB(179);
|
||||
SET_EXCEPTION_STUB(180);
|
||||
SET_EXCEPTION_STUB(181);
|
||||
SET_EXCEPTION_STUB(182);
|
||||
SET_EXCEPTION_STUB(183);
|
||||
SET_EXCEPTION_STUB(184);
|
||||
SET_EXCEPTION_STUB(185);
|
||||
SET_EXCEPTION_STUB(186);
|
||||
SET_EXCEPTION_STUB(187);
|
||||
SET_EXCEPTION_STUB(188);
|
||||
SET_EXCEPTION_STUB(189);
|
||||
SET_EXCEPTION_STUB(190);
|
||||
SET_EXCEPTION_STUB(191);
|
||||
SET_EXCEPTION_STUB(192);
|
||||
SET_EXCEPTION_STUB(193);
|
||||
SET_EXCEPTION_STUB(194);
|
||||
SET_EXCEPTION_STUB(195);
|
||||
SET_EXCEPTION_STUB(196);
|
||||
SET_EXCEPTION_STUB(197);
|
||||
SET_EXCEPTION_STUB(198);
|
||||
SET_EXCEPTION_STUB(199);
|
||||
SET_EXCEPTION_STUB(200);
|
||||
SET_EXCEPTION_STUB(201);
|
||||
SET_EXCEPTION_STUB(202);
|
||||
SET_EXCEPTION_STUB(203);
|
||||
SET_EXCEPTION_STUB(204);
|
||||
SET_EXCEPTION_STUB(205);
|
||||
SET_EXCEPTION_STUB(206);
|
||||
SET_EXCEPTION_STUB(207);
|
||||
SET_EXCEPTION_STUB(208);
|
||||
SET_EXCEPTION_STUB(209);
|
||||
SET_EXCEPTION_STUB(210);
|
||||
SET_EXCEPTION_STUB(211);
|
||||
SET_EXCEPTION_STUB(212);
|
||||
SET_EXCEPTION_STUB(213);
|
||||
SET_EXCEPTION_STUB(214);
|
||||
SET_EXCEPTION_STUB(215);
|
||||
SET_EXCEPTION_STUB(216);
|
||||
SET_EXCEPTION_STUB(217);
|
||||
SET_EXCEPTION_STUB(218);
|
||||
SET_EXCEPTION_STUB(219);
|
||||
SET_EXCEPTION_STUB(220);
|
||||
SET_EXCEPTION_STUB(221);
|
||||
SET_EXCEPTION_STUB(222);
|
||||
SET_EXCEPTION_STUB(223);
|
||||
SET_EXCEPTION_STUB(224);
|
||||
SET_EXCEPTION_STUB(225);
|
||||
SET_EXCEPTION_STUB(226);
|
||||
SET_EXCEPTION_STUB(227);
|
||||
SET_EXCEPTION_STUB(228);
|
||||
SET_EXCEPTION_STUB(229);
|
||||
SET_EXCEPTION_STUB(230);
|
||||
SET_EXCEPTION_STUB(231);
|
||||
SET_EXCEPTION_STUB(232);
|
||||
SET_EXCEPTION_STUB(233);
|
||||
SET_EXCEPTION_STUB(234);
|
||||
SET_EXCEPTION_STUB(235);
|
||||
SET_EXCEPTION_STUB(236);
|
||||
SET_EXCEPTION_STUB(237);
|
||||
SET_EXCEPTION_STUB(238);
|
||||
SET_EXCEPTION_STUB(239);
|
||||
SET_EXCEPTION_STUB(240);
|
||||
SET_EXCEPTION_STUB(241);
|
||||
SET_EXCEPTION_STUB(242);
|
||||
SET_EXCEPTION_STUB(243);
|
||||
SET_EXCEPTION_STUB(244);
|
||||
SET_EXCEPTION_STUB(245);
|
||||
SET_EXCEPTION_STUB(246);
|
||||
SET_EXCEPTION_STUB(247);
|
||||
SET_EXCEPTION_STUB(248);
|
||||
SET_EXCEPTION_STUB(249);
|
||||
SET_EXCEPTION_STUB(250);
|
||||
SET_EXCEPTION_STUB(251);
|
||||
SET_EXCEPTION_STUB(252);
|
||||
SET_EXCEPTION_STUB(253);
|
||||
SET_EXCEPTION_STUB(254);
|
||||
SET_EXCEPTION_STUB(255);
|
||||
#undef DESC
|
||||
#undef DECLARE_EXCEPTION_STUB
|
||||
#undef SET_EXCEPTION_STUB
|
||||
#undef EXCEPTION_STUB
|
||||
}
|
||||
|
||||
@@ -10,16 +10,23 @@
|
||||
#include "kernel_state.h"
|
||||
#include "pic.h"
|
||||
|
||||
#include "page.h"
|
||||
|
||||
// Future user-space
|
||||
#include "libc.h"
|
||||
#include "tty.h"
|
||||
#include "str.h"
|
||||
#include "bitmap.h"
|
||||
|
||||
uint32_t page_directory[1024] __attribute__((aligned(4096)));
|
||||
uint32_t page_table[1024] __attribute__((aligned(4096)));
|
||||
_Static_assert(((uint32_t)page_table & 0xfff) == 0);
|
||||
_Static_assert(((uint32_t)page_directory & 0xfff) == 0);
|
||||
|
||||
static void user_mode_code(void*)
|
||||
{
|
||||
printf(str_attach("hello from user-space before interrupt :)\n"));
|
||||
//__asm__ volatile ("int $0x80");
|
||||
//while (1) /* busy loop */;
|
||||
__asm__ volatile ("int $0x80");
|
||||
|
||||
#if 0
|
||||
printf(str_attach("hello from user-space before exception :)\n"));
|
||||
@@ -47,10 +54,10 @@ static void ring3_mode(segment_t udata_segment, segment_t ucode_segment, func_t
|
||||
"push %%ax\n"
|
||||
|
||||
"mov %%esp, %%eax\n"
|
||||
"push %%eax\n" // esp
|
||||
"pushf\n" // eflags
|
||||
"push %%eax\n"
|
||||
"pushf\n"
|
||||
"push %[ucode]\n"
|
||||
"push %[callback]\n" // instruction address to return to
|
||||
"push %[callback]\n"
|
||||
"iret"
|
||||
:
|
||||
: [udata] "i"(udata_segment),
|
||||
@@ -161,6 +168,7 @@ void kernel_main(void)
|
||||
kernel.idt[IDT_DESC_EXCEPTION_DIVISION_ERROR] = mtrap(exception_handler_div_by_zero);
|
||||
kernel.idt[IDT_DESC_EXCEPTION_DOUBLE_FAULT] = mtrap(exception_handler_double_fault);
|
||||
kernel.idt[IDT_DESC_EXCEPTION_GENERAL_PROTECTION_FAULT] = mtrap(exception_handler_general_protection_fault);
|
||||
kernel.idt[IDT_DESC_EXCEPTION_PAGE_FAULT] = mtrap(exception_handler_page_fault);
|
||||
|
||||
/* IRQs */
|
||||
kernel.idt[IDT_DESC_PIC1 + 0] = mint(irq_handler_0);
|
||||
@@ -200,11 +208,42 @@ void kernel_main(void)
|
||||
/* enable interrupts */
|
||||
__asm__ volatile("sti");
|
||||
|
||||
printf(str_attach("hello from kernel space!\n"));
|
||||
printf(str_attach("setting up paging...\n"));
|
||||
|
||||
/**
|
||||
* Paging setup
|
||||
* ============
|
||||
* We align by 1<<12 because page directory and page table entries store
|
||||
* addresses from bit 12-31
|
||||
*
|
||||
* For now give user access to pages to avoid a page fault
|
||||
*/
|
||||
for (size_t i = 0; i < sizeof page_table / sizeof *page_table; i++) {
|
||||
page_directory[i] = PDE_WRITE;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sizeof page_table / sizeof *page_table; i++) {
|
||||
page_table[i] = PTE_ADDRESS(i) | PTE_WRITE | PTE_PRESENT | PTE_USER;
|
||||
}
|
||||
|
||||
page_directory[0] = ((uint32_t)page_table) | PDE_WRITE | PDE_PRESENT | PDE_USER_ACCESS;
|
||||
|
||||
cr3_set((uint32_t)page_directory);
|
||||
cr0_flags_set(CR0_PAGING);
|
||||
|
||||
printf(str_attach("done!\n"));
|
||||
|
||||
printf(str_attach("starting code in ring 3...\n"));
|
||||
/* Finally go to ring 3 */
|
||||
ring3_mode(segment(SEGMENT_USER_DATA, SEGMENT_GDT, 3),
|
||||
segment(SEGMENT_USER_CODE, SEGMENT_GDT, 3),
|
||||
user_mode_code);
|
||||
|
||||
printf(str_attach("back to kernel mode...\n"));
|
||||
|
||||
while (1)
|
||||
/* busy loop */;
|
||||
|
||||
__asm__ volatile ("hlt");
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "kernel_state.h"
|
||||
|
||||
struct kernel_state kernel = { 0 };
|
||||
|
||||
const struct str gdt_segment_index_str[SEGMENT_COUNT] = {
|
||||
[SEGMENT_NULL ] = str_attach("SEGMENT_NULL"),
|
||||
[SEGMENT_KERNEL_CODE] = str_attach("SEGMENT_KERNEL_CODE"),
|
||||
@@ -42,4 +44,3 @@ const struct str idt_desc_index_str[IDT_DESC_COUNT] = {
|
||||
[IDT_DESC_INTERRUPT_SYSCALL ] = str_attach("IDT_DESC_INTERRUPT_SYSCALL"),
|
||||
};
|
||||
|
||||
struct kernel_state kernel = { 0 };
|
||||
|
||||
@@ -6,8 +6,12 @@
|
||||
#include "idt.h"
|
||||
#include "gdt.h"
|
||||
|
||||
/* defined in linker.ld */
|
||||
extern char kernel_memory_end[];
|
||||
|
||||
/*
|
||||
* Constants for the GDT
|
||||
* =====================
|
||||
* */
|
||||
enum gdt_segment_index : size_t {
|
||||
SEGMENT_NULL,
|
||||
@@ -22,11 +26,13 @@ extern const struct str gdt_segment_index_str[SEGMENT_COUNT]; // reverse lookup
|
||||
|
||||
/**
|
||||
* Constants for the TSS
|
||||
* =====================
|
||||
*/
|
||||
constexpr size_t KERNEL_STACK_SIZE = 1024;
|
||||
|
||||
/*
|
||||
* Constants for IDT descriptors
|
||||
* =============================
|
||||
* */
|
||||
static constexpr size_t IDT_EXCEPTION_COUNT = 32;
|
||||
static constexpr size_t IDT_IRQ_MASTER_COUNT = 8;
|
||||
@@ -66,19 +72,51 @@ enum idt_desc_index : size_t {
|
||||
IDT_DESC_PIC1 = 32,
|
||||
IDT_DESC_PIC2 = IDT_DESC_PIC1 + 8,
|
||||
|
||||
/* Software Interrupts */
|
||||
IDT_DESC_INTERRUPT_SYSCALL = 128,
|
||||
|
||||
IDT_DESC_COUNT = 256,
|
||||
};
|
||||
extern const struct str idt_desc_index_str[IDT_DESC_COUNT]; // reverse lookup enum -> str
|
||||
|
||||
/**
|
||||
* hook objects (placeholder for files I guess)
|
||||
* ====================
|
||||
* Processes can subscribe to objects and will be signaled when the object is
|
||||
* ready.
|
||||
*/
|
||||
struct kernel_hook {
|
||||
struct kernel_hook* next;
|
||||
size_t process;
|
||||
};
|
||||
|
||||
/**
|
||||
* The process object
|
||||
* ==================
|
||||
*/
|
||||
constexpr size_t PROC_MAX = 1024;
|
||||
|
||||
struct kernel_process {
|
||||
struct interrupt_frame frame;
|
||||
};
|
||||
|
||||
/**
|
||||
* The global kernel state object
|
||||
* ==============================
|
||||
*/
|
||||
struct kernel_state {
|
||||
struct tss tss;
|
||||
|
||||
struct gdt_table_entry gdt[SEGMENT_COUNT];
|
||||
|
||||
struct idt_gate_descriptor idt[IDT_DESC_COUNT];
|
||||
|
||||
struct kernel_process processes[PROC_MAX];
|
||||
size_t process_count;
|
||||
|
||||
int nested_exception_counter;
|
||||
|
||||
struct kernel_hook* keypress_hooks;
|
||||
};
|
||||
extern struct kernel_state kernel;
|
||||
|
||||
|
||||
58
src/kernel/malloc.c
Normal file
58
src/kernel/malloc.c
Normal file
@@ -0,0 +1,58 @@
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "kernel_state.h"
|
||||
#include "libc.h"
|
||||
|
||||
static constexpr size_t HEAP_SIZE = 1024*1024;
|
||||
static constexpr size_t HEAP_ALIGN = 16;
|
||||
|
||||
static uint8_t heap[HEAP_SIZE] = {0};
|
||||
|
||||
#if 0
|
||||
static uint8_t bitmap[HEAP_SIZE / CHAR_BIT] = {0};
|
||||
|
||||
static inline void bitmap_set(size_t i)
|
||||
{
|
||||
bitmap[i / CHAR_BIT] |= 1<<(i%CHAR_BIT);
|
||||
}
|
||||
|
||||
static inline void bitmap_clear(size_t i)
|
||||
{
|
||||
bitmap[i / CHAR_BIT] &= ~(1<<(i%CHAR_BIT));
|
||||
}
|
||||
|
||||
static inline bool bitmap_get(size_t i)
|
||||
{
|
||||
return bitmap[i / CHAR_BIT] & (1<<(i%CHAR_BIT));
|
||||
}
|
||||
#endif
|
||||
|
||||
void* kalloc(size_t size)
|
||||
{
|
||||
static int n = 0;
|
||||
|
||||
if (n + size > HEAP_SIZE) {
|
||||
panic(str_attach("no more heap space!\n"));
|
||||
}
|
||||
|
||||
void* ptr = &(heap[n]);
|
||||
n += size;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void kfree(void* ptr)
|
||||
{
|
||||
/* do nothing, lol */
|
||||
(void)ptr;
|
||||
}
|
||||
|
||||
void* krealloc(void* ptr, size_t size)
|
||||
{
|
||||
void* new = kalloc(size);
|
||||
if (new == NULL)
|
||||
return NULL;
|
||||
memmove(new, ptr, size); // this overflows but it's ok
|
||||
kfree(ptr);
|
||||
return new;
|
||||
}
|
||||
134
src/kernel/page.h
Normal file
134
src/kernel/page.h
Normal file
@@ -0,0 +1,134 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "kernel_state.h" /* kernel_memory_end */
|
||||
#include "bitmap.h"
|
||||
|
||||
constexpr uint32_t PAGE_SIZE = 4 * 1024;
|
||||
|
||||
typedef uint32_t pageframe_t;
|
||||
|
||||
typedef uint32_t cr0_flags_t;
|
||||
enum cr0_flags : cr0_flags_t {
|
||||
CR0_PROTECTED_MODE = 1U<<0,
|
||||
CR0_MONITOR_COPROCESSOR = 1U<<1,
|
||||
CR0_EMULATION = 1U<<2,
|
||||
CR0_TASK_SWITCHED = 1U<<3,
|
||||
CR0_EXTENSION_TYPE = 1U<<4,
|
||||
CR0_NUMERIC_ERROR = 1U<<5,
|
||||
CR0_WRITE_PROTECT = 1U<<16,
|
||||
CR0_ALIGNMENT_MASK = 1U<<18,
|
||||
CR0_NOT_WRITETHROUGH = 1U<<29,
|
||||
CR0_CACHE_DISABLE = 1U<<30,
|
||||
CR0_PAGING = 1U<<31,
|
||||
};
|
||||
|
||||
typedef uint32_t cr4_flags_t;
|
||||
enum cr4_flags : cr4_flags_t {
|
||||
CR4_VME = 1U<<0,
|
||||
CR4_PVI = 1U<<1,
|
||||
CR4_TSD = 1U<<2,
|
||||
CR4_DE = 1U<<3,
|
||||
CR4_PSE = 1U<<4,
|
||||
CR4_PAE = 1U<<5,
|
||||
CR4_MCE = 1U<<6,
|
||||
CR4_PGE = 1U<<7,
|
||||
CR4_PCE = 1U<<8,
|
||||
CR4_OSFXSR = 1U<<9,
|
||||
CR4_OSXMMEXCPT = 1U<<10,
|
||||
CR4_UMIP = 1U<<11,
|
||||
CR4_LA57 = 1U<<12,
|
||||
CR4_VMXE = 1U<<13,
|
||||
CR4_SMXE = 1U<<14,
|
||||
CR4_RESERVED_0 = 1U<<15,
|
||||
CR4_FSGSBASE = 1U<<16,
|
||||
CR4_PCIDE = 1U<<17,
|
||||
CR4_OSXSAVE = 1U<<18,
|
||||
CR4_KL = 1U<<19,
|
||||
CR4_SMEP = 1U<<20,
|
||||
CR4_SMAP = 1U<<21,
|
||||
CR4_PKE = 1U<<22,
|
||||
CR4_CET = 1U<<23,
|
||||
CR4_PKS = 1U<<24,
|
||||
CR4_UINTR = 1U<<25,
|
||||
};
|
||||
|
||||
enum page_directory_entry_flags : pageframe_t {
|
||||
PDE_PRESENT = 1<<0,
|
||||
PDE_WRITE = 1<<1,
|
||||
PDE_USER_ACCESS = 1<<2,
|
||||
PDE_WRITE_THROUGH = 1<<3,
|
||||
PDE_DISABLE_CACHE = 1<<4,
|
||||
PDE_ACCESSED = 1<<5,
|
||||
PDE_DIRTY = 1<<6,
|
||||
PDE_AVAILABLE = 1<<6,
|
||||
PDE_4MB = 1<<7,
|
||||
PDE_GLOBAL = 1<<8,
|
||||
PDE_PAT = 1<<12,
|
||||
};
|
||||
#define PDE_ADDRESS_4KB(x) ((x)<<12)
|
||||
|
||||
#define PDE_ADDRESS_4MB(x) (((x)<<13) & ~(1<<21))
|
||||
|
||||
enum page_table_entry_flags : pageframe_t {
|
||||
PTE_PRESENT = 1<<0,
|
||||
PTE_WRITE = 1<<1,
|
||||
PTE_USER = 1<<2,
|
||||
PTE_WRITE_THROUGH = 1<<3,
|
||||
PTE_DISABLE_CACHE = 1<<4,
|
||||
PTE_ACCESSED = 1<<5,
|
||||
PTE_DIRTY = 1<<6,
|
||||
PTE_PAGE_ATTRIBUTE_TABLE = 1<<7,
|
||||
PTE_GLOBAL = 1<<8,
|
||||
};
|
||||
#define PTE_ADDRESS(x) ((x)<<12)
|
||||
|
||||
static inline void cr3_set(uint32_t page_directory)
|
||||
{
|
||||
__asm__ volatile (
|
||||
"mov %[page_directory], %%eax\n\t"
|
||||
"mov %%eax, %%cr3\n\t"
|
||||
: /* no output */
|
||||
: /* inputs: */ [page_directory] "m" (page_directory)
|
||||
: /* clobber: */ "eax"
|
||||
);
|
||||
}
|
||||
|
||||
/* these are macros so that they can compile on O0 due to the "i" constraint */
|
||||
#define cr0_flags_set(flags) \
|
||||
__asm__ volatile ( \
|
||||
"mov %%cr0, %%eax\n\t" \
|
||||
"or %0, %%eax\n\t" \
|
||||
"mov %%eax, %%cr0\n\t" \
|
||||
: /* no outputs */ \
|
||||
: /* inputs: */ "i"((flags)) \
|
||||
: /* clobbers: */ "eax" \
|
||||
)
|
||||
|
||||
#define cr0_flags_unset(flags) \
|
||||
__asm__ volatile ( \
|
||||
"mov %%cr0, %%eax\n\t" \
|
||||
"and %0, %%eax\n\t" \
|
||||
"mov %%eax, %%cr0\n\t" \
|
||||
: /* no outputs */ \
|
||||
: /* inputs: */ "i"(~(flags)) \
|
||||
: /* clobbers: */ "eax" \
|
||||
)
|
||||
|
||||
static pageframe_t kalloc_frame(struct bitmap* frame_map, uint32_t startframe)
|
||||
{
|
||||
for (size_t i = 0; i < frame_map->bit_count; i++) {
|
||||
if (bitmap_get(frame_map, i) == 0) {
|
||||
bitmap_set(frame_map, i);
|
||||
return (startframe + PTE_ADDRESS(i));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static pageframe_t kfree_frame(uint32_t frame)
|
||||
{
|
||||
/* TODO */
|
||||
(void)frame;
|
||||
return 0;
|
||||
}
|
||||
@@ -62,6 +62,9 @@ void terminal_scroll(int n)
|
||||
|
||||
void terminal_putchar(int c)
|
||||
{
|
||||
/* clear the cursor marker */
|
||||
terminal_putentryat(' ', t.color, t.column, t.row);
|
||||
|
||||
// TODO: implement other control characters
|
||||
switch (c) {
|
||||
|
||||
@@ -83,6 +86,9 @@ void terminal_putchar(int c)
|
||||
if (t.row == VGA_HEIGHT) {
|
||||
terminal_scroll(1);
|
||||
}
|
||||
|
||||
/* set the cursor marker */
|
||||
terminal_putentryat(' ', vga_color(VGA_COLOR_BLACK, VGA_COLOR_LIGHT_GREY), t.column, t.row);
|
||||
}
|
||||
|
||||
void terminal_write(struct str str)
|
||||
@@ -11,6 +11,14 @@ typedef unsigned long long int uword_t;
|
||||
typedef unsigned int uword_t;
|
||||
#endif
|
||||
|
||||
struct __attribute__((packed)) interrupt_frame {
|
||||
uword_t ip;
|
||||
uword_t cs;
|
||||
uword_t flags;
|
||||
uword_t sp;
|
||||
uword_t ss;
|
||||
};
|
||||
|
||||
/* segment selectors identifies segments either in the gdt or the ldt */
|
||||
typedef uint16_t segment_t;
|
||||
|
||||
@@ -23,5 +31,3 @@ static inline segment_t segment(uint16_t index, enum segment_ti ti, uint16_t rpl
|
||||
{
|
||||
return (index << 3) | ((ti & 0xF) << 1) | (rpl & 0xFF);
|
||||
}
|
||||
|
||||
|
||||
|
||||
145
src/lib/bitmap.c
Normal file
145
src/lib/bitmap.c
Normal file
@@ -0,0 +1,145 @@
|
||||
|
||||
#include "bitmap.h"
|
||||
#include <limits.h>
|
||||
|
||||
static constexpr struct bitmap B = {0};
|
||||
static constexpr size_t bits_per_index = sizeof (B.data[0]) * CHAR_BIT;
|
||||
|
||||
#define mask(n) ((1<<(n))-1)
|
||||
_Static_assert(mask(0) == 0b0000);
|
||||
_Static_assert(mask(1) == 0b0001);
|
||||
_Static_assert(mask(2) == 0b0011);
|
||||
_Static_assert(mask(3) == 0b0111);
|
||||
|
||||
static inline int trailing_zeroes(int n)
|
||||
{
|
||||
return __builtin_ctz(n);
|
||||
}
|
||||
|
||||
int bitmap_set_range(struct bitmap* bitmap, size_t begin, size_t end)
|
||||
{
|
||||
if (end < begin) {
|
||||
return bitmap_set_range(bitmap, end, begin);
|
||||
}
|
||||
|
||||
if (unlikely(begin > bitmap->bit_count)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (unlikely(end > bitmap->bit_count)) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* begin and end are within the same index: */
|
||||
if ((begin / bits_per_index) == (end / bits_per_index)) {
|
||||
#define expr(begin, end) (~mask((begin) % bits_per_index) & mask((end) % bits_per_index))
|
||||
_Static_assert(expr(1,6) == 0b0000111110, "bitmap range logic invalid!");
|
||||
bitmap->data[begin / bits_per_index] |= expr(begin, end);
|
||||
#undef expr
|
||||
} else {
|
||||
bitmap->data[begin / bits_per_index] |= ~mask(begin % bits_per_index);
|
||||
for (size_t i = 1 + begin/bits_per_index;
|
||||
i < end/bits_per_index;
|
||||
i++)
|
||||
{
|
||||
bitmap->data[i] |= ~0;
|
||||
}
|
||||
bitmap->data[end / bits_per_index] |= mask(end % bits_per_index);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bitmap_clear_range(struct bitmap* bitmap, size_t begin, size_t end)
|
||||
{
|
||||
if (end < begin) {
|
||||
return bitmap_set_range(bitmap, end, begin);
|
||||
}
|
||||
|
||||
if (unlikely(begin > bitmap->bit_count)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (unlikely(end > bitmap->bit_count)) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* begin and end are within the same index: */
|
||||
if ((begin / bits_per_index) == (end / bits_per_index)) {
|
||||
#define expr(begin, end) (~mask((begin) % bits_per_index) & mask((end) % bits_per_index))
|
||||
_Static_assert(expr(1,6) == 0b0000111110, "bitmap range logic invalid!");
|
||||
bitmap->data[begin / bits_per_index] &= ~expr(begin, end);
|
||||
#undef expr
|
||||
} else {
|
||||
bitmap->data[begin / bits_per_index] &= mask(begin % bits_per_index);
|
||||
for (size_t i = 1 + begin/bits_per_index;
|
||||
i < end/bits_per_index;
|
||||
i++)
|
||||
{
|
||||
bitmap->data[i] = 0;
|
||||
}
|
||||
bitmap->data[end / bits_per_index] &= ~mask(end % bits_per_index);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This 4 am code is almost certainly wrong. No tests have been written yet.
|
||||
*
|
||||
* Returns 0 if range is empty.
|
||||
* If range is not emtpy, it returns the offset of the first non-zero bit
|
||||
* from `begin`
|
||||
*
|
||||
* TODO: write tests */
|
||||
int bitmap_range_empty(struct bitmap* bitmap, size_t begin, size_t end)
|
||||
{
|
||||
if (end < begin) {
|
||||
return bitmap_set_range(bitmap, end, begin);
|
||||
}
|
||||
|
||||
if (unlikely(begin > bitmap->bit_count)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (unlikely(end > bitmap->bit_count)) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* begin and end are within the same index: */
|
||||
if ((begin / bits_per_index) == (end / bits_per_index)) {
|
||||
#define expr(begin, end) (~mask((begin) % bits_per_index) & mask((end) % bits_per_index))
|
||||
_Static_assert(expr(1,6) == 0b0000111110, "bitmap range logic invalid!");
|
||||
const typeof(bitmap->data[0]) n = bitmap->data[begin / bits_per_index];
|
||||
if (n & expr(begin, end)) {
|
||||
return trailing_zeroes(n) - (begin % bits_per_index) ;
|
||||
};
|
||||
#undef expr
|
||||
} else {
|
||||
{
|
||||
const typeof(bitmap->data[0]) n = bitmap->data[begin / bits_per_index];
|
||||
if (n & ~mask(begin % bits_per_index)) {
|
||||
return trailing_zeroes(n) - (begin % bits_per_index);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 1 + begin/bits_per_index;
|
||||
i < end/bits_per_index;
|
||||
i++)
|
||||
{
|
||||
const typeof(bitmap->data[0]) n = bitmap->data[i];
|
||||
if (n != 0) {
|
||||
return i*bits_per_index + trailing_zeroes(n);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
const typeof(bitmap->data[0]) n = bitmap->data[end / bits_per_index];
|
||||
if (n & mask(end % bits_per_index)) {
|
||||
return (end % bits_per_index) - trailing_zeroes(n);
|
||||
}
|
||||
bitmap->data[end / bits_per_index] &= ~mask(end % bits_per_index);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
296
src/lib/bitmap_test.c
Normal file
296
src/lib/bitmap_test.c
Normal file
@@ -0,0 +1,296 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "bitmap.h"
|
||||
|
||||
static int g_status = EXIT_SUCCESS;
|
||||
static int test_no = 0;
|
||||
static bool test_ongoing = false;
|
||||
|
||||
static void bitmap_print(struct bitmap* bitmap)
|
||||
{
|
||||
static constexpr size_t bits_per_index = sizeof (bitmap->data[0]) * CHAR_BIT;
|
||||
fprintf(stderr, "printing bitmap... (bit_count: %zu, indices: %zu)\n", bitmap->bit_count, bitmap->bit_count / bits_per_index);
|
||||
for (size_t i = 0; i < bitmap->bit_count / bits_per_index; i++) {
|
||||
typeof(bitmap->data[0]) n = bitmap->data[i];
|
||||
for (size_t i = 0; i < bits_per_index; i++) {
|
||||
fprintf(stderr, "%d", n & 1);
|
||||
n >>= 1;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
#define test_begin(name) _test_begin(name, __LINE__)
|
||||
static void _test_begin(const char* name, int line)
|
||||
{
|
||||
(void)line; // unused for now
|
||||
assert(!test_ongoing);
|
||||
test_ongoing = true;
|
||||
printf("\n#%i - %s:\n", test_no, name);
|
||||
test_no += 1;
|
||||
}
|
||||
|
||||
static void test_ok(const char* format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
printf("OK: ");
|
||||
vprintf(format, ap);
|
||||
printf("\n");
|
||||
va_end(ap);
|
||||
test_ongoing = false;
|
||||
}
|
||||
|
||||
static void test_fail(const char* format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
printf("FAIL: ");
|
||||
vprintf(format, ap);
|
||||
printf("\n");
|
||||
va_end(ap);
|
||||
g_status = EXIT_FAILURE;
|
||||
test_ongoing = false;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
|
||||
test_begin("test bitmap_set()");
|
||||
do {
|
||||
static uint32_t data[4] = {0};
|
||||
struct bitmap b = BITMAP_ATTACH(data, sizeof data);
|
||||
constexpr size_t index = 3;
|
||||
int ok = bitmap_set(&b, index);
|
||||
if (ok != 0) {
|
||||
test_fail("bitmap_set(%zu) returned non-zero value", index);
|
||||
break;
|
||||
}
|
||||
bitmap_print(&b);
|
||||
if (b.data[0] != 0b1000) {
|
||||
test_fail("bitmap_set(%zu) failed", index);
|
||||
break;
|
||||
}
|
||||
|
||||
test_ok("bitmap_set(%zu) ok", index);
|
||||
} while (0);
|
||||
|
||||
test_begin("test bitmap_get()");
|
||||
do {
|
||||
static uint32_t data[4] = {0};
|
||||
struct bitmap b = BITMAP_ATTACH(data, sizeof data);
|
||||
constexpr size_t index = 3;
|
||||
int ok = bitmap_set(&b, index);
|
||||
if (ok != 0) {
|
||||
test_fail("bitmap_set(%zu) failed when testing bitmap_get(%zu)", index, index);
|
||||
break;
|
||||
}
|
||||
bitmap_print(&b);
|
||||
int v = bitmap_get(&b, 3);
|
||||
if (v < 0) {
|
||||
test_fail("bitmap_get(%zu) returned negative value", index);
|
||||
break;
|
||||
}
|
||||
if (v != 1) {
|
||||
test_fail("expected 1, got 0");
|
||||
break;
|
||||
}
|
||||
test_ok("bitmap_get(%zu) ok", index);
|
||||
} while (0);
|
||||
|
||||
test_begin("test bitmap_set_range() within one cell");
|
||||
{
|
||||
static uint32_t data[4] = {0};
|
||||
struct bitmap b = BITMAP_ATTACH(data, sizeof data);
|
||||
|
||||
constexpr size_t begin = 3;
|
||||
constexpr size_t end = 6;
|
||||
int ok = bitmap_set_range(&b, begin, end);
|
||||
if (ok < 0) {
|
||||
test_fail("bitmap_set_range returned negative value");
|
||||
goto end_set_range;
|
||||
}
|
||||
bitmap_print(&b);
|
||||
for (size_t i = 0; i < begin; i++) {
|
||||
if (bitmap_get(&b, i) == 1) {
|
||||
test_fail("bitmap_set_range setting bad values");
|
||||
goto end_set_range;
|
||||
}
|
||||
}
|
||||
for (size_t i = begin; i < end; i++) {
|
||||
if (bitmap_get(&b, i) == 0) {
|
||||
test_fail("bitmap_set_range setting bad values");
|
||||
goto end_set_range;
|
||||
}
|
||||
}
|
||||
for (size_t i = end; i < b.bit_count; i++) {
|
||||
if (bitmap_get(&b, i) == 1) {
|
||||
test_fail("bitmap_set_range setting bad values");
|
||||
goto end_set_range;
|
||||
}
|
||||
}
|
||||
test_ok("bitmap_set_range(..., 3, 6) ok!");
|
||||
end_set_range:
|
||||
};
|
||||
|
||||
test_begin("test bitmap_set_range() across two cells");
|
||||
{
|
||||
static uint32_t data[4] = {0};
|
||||
struct bitmap b = BITMAP_ATTACH(data, sizeof data);
|
||||
|
||||
constexpr size_t begin = 14;
|
||||
constexpr size_t end = 14 + 2 * sizeof (b.data[0]) * CHAR_BIT;
|
||||
int ok = bitmap_set_range(&b, begin, end);
|
||||
|
||||
if (ok < 0) {
|
||||
test_fail("bitmap_set_range returned negative value");
|
||||
goto multi_cell_set_range_fail;
|
||||
}
|
||||
bitmap_print(&b);
|
||||
|
||||
for (size_t i = 0; i < begin; i++) {
|
||||
if (bitmap_get(&b, i) != 0) {
|
||||
test_fail("bitmap_set_range(..., %zu, %zu) setting bad values", begin, end);
|
||||
goto multi_cell_set_range_fail;
|
||||
}
|
||||
}
|
||||
for (size_t i = begin; i < end; i++) {
|
||||
if (bitmap_get(&b, i) != 1) {
|
||||
test_fail("bitmap_set_range(..., %zu, %zu) setting bad values", begin, end);
|
||||
goto multi_cell_set_range_fail;
|
||||
}
|
||||
}
|
||||
for (size_t i = end; i < b.bit_count; i++) {
|
||||
if (bitmap_get(&b, i) != 0) {
|
||||
test_fail("bitmap_set_range(..., %zu, %zu) setting bad values", begin, end);
|
||||
goto multi_cell_set_range_fail;
|
||||
}
|
||||
}
|
||||
|
||||
test_ok("bitmap_set_range(..., %zu, %zu) ok!", begin, end);
|
||||
|
||||
multi_cell_set_range_fail:
|
||||
};
|
||||
|
||||
test_begin("test bitmap_clear_range() within one cell");
|
||||
{
|
||||
static uint32_t data[4] = {0};
|
||||
struct bitmap b = BITMAP_ATTACH(data, sizeof data);
|
||||
|
||||
memset(data, 0xff, sizeof data);
|
||||
|
||||
constexpr size_t begin = 3;
|
||||
constexpr size_t end = 7;
|
||||
int ok = bitmap_clear_range(&b, begin, end);
|
||||
if (ok < 0) {
|
||||
test_fail("bitmap_clear_range(..., %zu, %zu) returned negative value", begin, end);
|
||||
goto single_cell_clear_fail;
|
||||
}
|
||||
bitmap_print(&b);
|
||||
|
||||
for (size_t i = 0; i < begin; i++) {
|
||||
if (bitmap_get(&b, i) != 1) {
|
||||
test_fail("bitmap_clear_range(..., %zu, %zu) setting bad values", begin, end);
|
||||
goto single_cell_clear_fail;
|
||||
}
|
||||
}
|
||||
for (size_t i = begin; i < end; i++) {
|
||||
if (bitmap_get(&b, i) != 0) {
|
||||
test_fail("bitmap_clear_range(..., %zu, %zu) setting bad values", begin, end);
|
||||
goto single_cell_clear_fail;
|
||||
}
|
||||
}
|
||||
for (size_t i = end; i < b.bit_count; i++) {
|
||||
if (bitmap_get(&b, i) != 1) {
|
||||
test_fail("bitmap_clear_range(..., %zu, %zu) setting bad values", begin, end);
|
||||
goto single_cell_clear_fail;
|
||||
}
|
||||
}
|
||||
|
||||
test_ok("bitmap_clear_range(..., %zu, %zu) ok!", begin, end);
|
||||
single_cell_clear_fail:
|
||||
}
|
||||
|
||||
test_begin("test bitmap_clear_range() within multiple cells");
|
||||
{
|
||||
static uint32_t data[4] = {0};
|
||||
struct bitmap b = BITMAP_ATTACH(data, sizeof data);
|
||||
|
||||
memset(data, 0xff, sizeof data);
|
||||
|
||||
constexpr size_t begin = 3;
|
||||
constexpr size_t end = begin + 2 * sizeof(b.data[0]) * CHAR_BIT;
|
||||
int ok = bitmap_clear_range(&b, begin, end);
|
||||
if (ok < 0) {
|
||||
test_fail("bitmap_clear_range(..., %zu, %zu) returned negative value", begin, end);
|
||||
goto multi_cell_clear_fail;
|
||||
}
|
||||
bitmap_print(&b);
|
||||
|
||||
for (size_t i = 0; i < begin; i++) {
|
||||
if (bitmap_get(&b, i) != 1) {
|
||||
test_fail("bitmap_clear_range(..., %zu, %zu) setting bad values", begin, end);
|
||||
goto multi_cell_clear_fail;
|
||||
}
|
||||
}
|
||||
for (size_t i = begin; i < end; i++) {
|
||||
if (bitmap_get(&b, i) != 0) {
|
||||
test_fail("bitmap_clear_range(..., %zu, %zu) setting bad values", begin, end);
|
||||
goto multi_cell_clear_fail;
|
||||
}
|
||||
}
|
||||
for (size_t i = end; i < b.bit_count; i++) {
|
||||
if (bitmap_get(&b, i) != 1) {
|
||||
test_fail("bitmap_clear_range(..., %zu, %zu) setting bad values", begin, end);
|
||||
goto multi_cell_clear_fail;
|
||||
}
|
||||
}
|
||||
|
||||
test_ok("bitmap_clear_range(..., %zu, %zu) ok!", begin, end);
|
||||
multi_cell_clear_fail:
|
||||
}
|
||||
|
||||
test_begin("test bitmap_empty()");
|
||||
do {
|
||||
static uint32_t data[4] = {0};
|
||||
struct bitmap b = BITMAP_ATTACH(data, sizeof data);
|
||||
|
||||
constexpr size_t roadblock = 14;
|
||||
int ok = bitmap_set(&b, roadblock);
|
||||
if (ok != 0) {
|
||||
test_fail("bitmap_set(..., %zu) failed when testing bitmap_empty", roadblock);
|
||||
break;
|
||||
}
|
||||
bitmap_print(&b);
|
||||
|
||||
{
|
||||
constexpr size_t begin = 0;
|
||||
constexpr size_t end = roadblock - 1;
|
||||
size_t v = bitmap_range_empty(&b, begin, end);
|
||||
if (v != 0) {
|
||||
test_fail("bitmap_range_empty(..., %zu, %zu) returned %d when it should return %d", begin, end, v, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
constexpr size_t begin = 4;
|
||||
constexpr size_t end = 32;
|
||||
int v = bitmap_range_empty(&b, begin, end);
|
||||
if (v != roadblock - begin) {
|
||||
test_fail("expected bitmap_range_empty(..., %zu, %zu) to return %d, got %d", begin, end, roadblock - begin, v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
test_ok("bitmap_range_empty() ok!");
|
||||
|
||||
} while (0);
|
||||
|
||||
return g_status;
|
||||
}
|
||||
49
src/lib/include/bitmap.h
Normal file
49
src/lib/include/bitmap.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
#include "macros.h"
|
||||
|
||||
struct bitmap {
|
||||
size_t bit_count;
|
||||
uint32_t* data;
|
||||
};
|
||||
|
||||
/* buf: buffer to use for bitmap
|
||||
* buf_size: size of buffer in bytes */
|
||||
#define BITMAP_ATTACH(buf, buf_size) (struct bitmap){.bit_count = buf_size * CHAR_BIT, .data = buf}
|
||||
|
||||
static inline int bitmap_set(struct bitmap* bitmap, size_t index)
|
||||
{
|
||||
constexpr size_t bits_per_index = sizeof (bitmap->data[0]) * CHAR_BIT;
|
||||
_Static_assert(bits_per_index == 32);
|
||||
if (unlikely(index > bitmap->bit_count)) {
|
||||
return -1;
|
||||
}
|
||||
bitmap->data[index / bits_per_index] |= (1 << (index % bits_per_index));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int bitmap_unset(struct bitmap* bitmap, size_t index)
|
||||
{
|
||||
constexpr size_t bits_per_index = sizeof (bitmap->data[0]) * CHAR_BIT;
|
||||
if (unlikely(index > bitmap->bit_count)) {
|
||||
return -1;
|
||||
}
|
||||
bitmap->data[index / bits_per_index] &= ~(1 << (index % bits_per_index));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int bitmap_get(struct bitmap* bitmap, size_t index)
|
||||
{
|
||||
constexpr size_t bits_per_index = sizeof (bitmap->data[0]) * CHAR_BIT;
|
||||
if (unlikely(index > bitmap->bit_count)) {
|
||||
return -1;
|
||||
}
|
||||
return !!(bitmap->data[index / bits_per_index] & (1ULL << (index % bits_per_index)));
|
||||
}
|
||||
|
||||
int bitmap_set_range(struct bitmap* bitmap, size_t begin, size_t end);
|
||||
int bitmap_clear_range(struct bitmap* bitmap, size_t begin, size_t end);
|
||||
int bitmap_range_empty(struct bitmap* bitmap, size_t begin, size_t end);
|
||||
146
src/lib/include/keys.h
Normal file
146
src/lib/include/keys.h
Normal file
@@ -0,0 +1,146 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "str.h"
|
||||
|
||||
enum key {
|
||||
KEY_RELEASED = 0x80,
|
||||
KEY_EXTENDED = 0xE0,
|
||||
|
||||
KEY_ESCAPE = 0x01,
|
||||
KEY_1 = 0x02,
|
||||
KEY_2 = 0x03,
|
||||
KEY_3 = 0x04,
|
||||
KEY_4 = 0x05,
|
||||
KEY_5 = 0x06,
|
||||
KEY_6 = 0x07,
|
||||
KEY_7 = 0x08,
|
||||
KEY_8 = 0x09,
|
||||
KEY_9 = 0x0A,
|
||||
KEY_0 = 0x0B,
|
||||
KEY_MINUS = 0x0C,
|
||||
KEY_EQUALS = 0x0D,
|
||||
KEY_BACKSPACE = 0x0E,
|
||||
KEY_TAB = 0x0F,
|
||||
KEY_Q = 0x10,
|
||||
KEY_W = 0x11,
|
||||
KEY_E = 0x12,
|
||||
KEY_R = 0x13,
|
||||
KEY_T = 0x14,
|
||||
KEY_Y = 0x15,
|
||||
KEY_U = 0x16,
|
||||
KEY_I = 0x17,
|
||||
KEY_O = 0x18,
|
||||
KEY_P = 0x19,
|
||||
KEY_SQUARE_BRACKET_LEFT = 0x1A,
|
||||
KEY_SQUARE_BRACKET_RIGHT = 0x1B,
|
||||
KEY_ENTER = 0x1C,
|
||||
KEY_LEFT_CONTROL = 0x1D,
|
||||
KEY_A = 0x1E,
|
||||
KEY_S = 0x1F,
|
||||
KEY_D = 0x20,
|
||||
KEY_F = 0x21,
|
||||
KEY_G = 0x22,
|
||||
KEY_H = 0x23,
|
||||
KEY_J = 0x24,
|
||||
KEY_K = 0x25,
|
||||
KEY_L = 0x26,
|
||||
KEY_SEMICOLON = 0x27,
|
||||
KEY_SINGLE_QUOTE = 0x28,
|
||||
KEY_BACKTICK = 0x29,
|
||||
KEY_LEFT_SHIFT = 0x2A,
|
||||
KEY_BACKSLASH = 0x2B,
|
||||
KEY_Z = 0x2C,
|
||||
KEY_X = 0x2D,
|
||||
KEY_C = 0x2E,
|
||||
KEY_V = 0x2F,
|
||||
KEY_B = 0x30,
|
||||
KEY_N = 0x31,
|
||||
KEY_M = 0x32,
|
||||
KEY_COMMA = 0x33,
|
||||
KEY_DOT = 0x34,
|
||||
KEY_FORWARD_SLASH = 0x35,
|
||||
KEY_RIGHT_SHIFT = 0x36,
|
||||
KEY_KEYPAD_ASTERISK = 0x37,
|
||||
KEY_LEFT_ALT = 0x38,
|
||||
KEY_SPACE = 0x39,
|
||||
KEY_CAPSLOCK = 0x3A,
|
||||
KEY_F1 = 0x3B,
|
||||
KEY_F2 = 0x3C,
|
||||
KEY_F3 = 0x3D,
|
||||
KEY_F4 = 0x3E,
|
||||
KEY_F5 = 0x3F,
|
||||
KEY_F6 = 0x40,
|
||||
KEY_F7 = 0x41,
|
||||
KEY_F8 = 0x42,
|
||||
KEY_F9 = 0x43,
|
||||
KEY_F10 = 0x44,
|
||||
KEY_NUMBERLOCK = 0x45,
|
||||
KEY_SCROLLLOCK = 0x46,
|
||||
KEY_KEYPAD_7 = 0x47,
|
||||
KEY_KEYPAD_8 = 0x48,
|
||||
KEY_KEYPAD_9 = 0x49,
|
||||
KEY_KEYPAD_MINUS = 0x4A,
|
||||
KEY_KEYPAD_4 = 0x4B,
|
||||
KEY_KEYPAD_5 = 0x4C,
|
||||
KEY_KEYPAD_6 = 0x4D,
|
||||
KEY_KEYPAD_PLUS = 0x4E,
|
||||
KEY_KEYPAD_1 = 0x4F,
|
||||
KEY_KEYPAD_2 = 0x50,
|
||||
KEY_KEYPAD_3 = 0x51,
|
||||
KEY_KEYPAD_0 = 0x52,
|
||||
KEY_KEYPAD_DOT = 0x53,
|
||||
KEY_F11 = 0x57,
|
||||
KEY_F12 = 0x58,
|
||||
};
|
||||
extern const struct str key_str[];
|
||||
|
||||
/* keys_default_keymap[k | KEY_MODIFIER_SHIFT] --> shift key value of key `k` */
|
||||
constexpr size_t KEY_MODIFIER_SHIFT = 0x80;
|
||||
|
||||
extern const char keys_default_keymap[];
|
||||
|
||||
/* Not supported at the moment */
|
||||
enum extended_keys : uint8_t {
|
||||
KEY_E_MULTIMEDIA_PREV_TRACK = 0x10,
|
||||
KEY_E_MULTIMEDIA_NEXT_TRACK = 0x19,
|
||||
KEY_E_KEYPAD_ENTER = 0x1C,
|
||||
KEY_E_RIGHT_CONTROL = 0x1D,
|
||||
KEY_E_MULTIMEDIA_MUTE = 0x20,
|
||||
KEY_E_MULTIMEDIA_CALCULATOR = 0x21,
|
||||
KEY_E_MULTIMEDIA_PLAY = 0x22,
|
||||
KEY_E_MULTIMEDIA_STOP = 0x24,
|
||||
KEY_E_MULTIMEDIA_VOLUME_DOWN = 0x2E,
|
||||
KEY_E_MULTIMEDIA_VOLUME_UP = 0x30,
|
||||
KEY_E_MULTIMEDIA_WWW_HOME = 0x32,
|
||||
KEY_E_KEYPAD_FORWARD_SLASH = 0x35,
|
||||
KEY_E_RIGHT_ALT = 0x38,
|
||||
KEY_E_HOME = 0x47,
|
||||
KEY_E_CURSOR_UP = 0x48,
|
||||
KEY_E_PAGE_UP = 0x49,
|
||||
KEY_E_CURSOR_LEFT = 0x4B,
|
||||
KEY_E_CURSOR_RIGHT = 0x4D,
|
||||
KEY_E_END = 0x4F,
|
||||
KEY_E_CURSOR_DOWN = 0x50,
|
||||
KEY_E_PAGE_DOWN = 0x51,
|
||||
KEY_E_DELETE = 0x53,
|
||||
KEY_E_LEFT_GUI = 0x5B,
|
||||
KEY_E_RIGHT_GUI = 0x5C,
|
||||
KEY_E_APPS = 0x5D,
|
||||
KEY_E_ACPI_SLEEP = 0x5F,
|
||||
KEY_E_ACPI_WAKE = 0x63,
|
||||
KEY_E_MULTIMEDIA_WWW_SEARCH = 0x65,
|
||||
KEY_E_MULTIMEDIA_WWW_REFRESH = 0x67,
|
||||
KEY_E_MULTIMEDIA_WWW_STOP = 0x68,
|
||||
KEY_E_MULTIMEDIA_WWW_FORWARD = 0x69,
|
||||
KEY_E_MULTIMEDIA_MY_COMPUTER = 0x6B,
|
||||
KEY_E_MULTIMEDIA_EMAIL = 0x6C,
|
||||
KEY_E_MULTIMEDIA_MEDIA_SELECT = 0x6D,
|
||||
/* TODO: implement these:
|
||||
0xE1, 0x1D, 0x45, 0xE1, 0x9D, 0xC5 pause pressed
|
||||
0x2A, 0xE0, 0x37 print screen pressed
|
||||
0xB7, 0xE0, 0xAA print screen released
|
||||
*/
|
||||
};
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include "str.h"
|
||||
#include "tty.h"
|
||||
|
||||
__attribute__((noreturn))
|
||||
void panic(struct str s);
|
||||
6
src/lib/include/macros.h
Normal file
6
src/lib/include/macros.h
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define likely(x) __builtin_expect(!!(x), 1)
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
|
||||
303
src/lib/keys.c
Normal file
303
src/lib/keys.c
Normal file
@@ -0,0 +1,303 @@
|
||||
|
||||
#include "keys.h"
|
||||
|
||||
const struct str ps2_key_str[] = {
|
||||
[KEY_EXTENDED ] = str_attach("KEY_EXTENDED (PRESSED)"),
|
||||
[KEY_ESCAPE ] = str_attach("KEY_ESCAPE (PRESSED)"),
|
||||
[KEY_1 ] = str_attach("KEY_1 (PRESSED)"),
|
||||
[KEY_2 ] = str_attach("KEY_2 (PRESSED)"),
|
||||
[KEY_3 ] = str_attach("KEY_3 (PRESSED)"),
|
||||
[KEY_4 ] = str_attach("KEY_4 (PRESSED)"),
|
||||
[KEY_5 ] = str_attach("KEY_5 (PRESSED)"),
|
||||
[KEY_6 ] = str_attach("KEY_6 (PRESSED)"),
|
||||
[KEY_7 ] = str_attach("KEY_7 (PRESSED)"),
|
||||
[KEY_8 ] = str_attach("KEY_8 (PRESSED)"),
|
||||
[KEY_9 ] = str_attach("KEY_9 (PRESSED)"),
|
||||
[KEY_0 ] = str_attach("KEY_0 (PRESSED)"),
|
||||
[KEY_MINUS ] = str_attach("KEY_MINUS (PRESSED)"),
|
||||
[KEY_EQUALS ] = str_attach("KEY_EQUALS (PRESSED)"),
|
||||
[KEY_BACKSPACE ] = str_attach("KEY_BACKSPACE (PRESSED)"),
|
||||
[KEY_TAB ] = str_attach("KEY_TAB (PRESSED)"),
|
||||
[KEY_Q ] = str_attach("KEY_Q (PRESSED)"),
|
||||
[KEY_W ] = str_attach("KEY_W (PRESSED)"),
|
||||
[KEY_E ] = str_attach("KEY_E (PRESSED)"),
|
||||
[KEY_R ] = str_attach("KEY_R (PRESSED)"),
|
||||
[KEY_T ] = str_attach("KEY_T (PRESSED)"),
|
||||
[KEY_Y ] = str_attach("KEY_Y (PRESSED)"),
|
||||
[KEY_U ] = str_attach("KEY_U (PRESSED)"),
|
||||
[KEY_I ] = str_attach("KEY_I (PRESSED)"),
|
||||
[KEY_O ] = str_attach("KEY_O (PRESSED)"),
|
||||
[KEY_P ] = str_attach("KEY_P (PRESSED)"),
|
||||
[KEY_SQUARE_BRACKET_LEFT ] = str_attach("KEY_SQUARE_BRACKET_LEFT (PRESSED)"),
|
||||
[KEY_SQUARE_BRACKET_RIGHT] = str_attach("KEY_SQUARE_BRACKET_RIGHT (PRESSED)"),
|
||||
[KEY_ENTER ] = str_attach("KEY_ENTER (PRESSED)"),
|
||||
[KEY_LEFT_CONTROL ] = str_attach("KEY_LEFT_CONTROL (PRESSED)"),
|
||||
[KEY_A ] = str_attach("KEY_A (PRESSED)"),
|
||||
[KEY_S ] = str_attach("KEY_S (PRESSED)"),
|
||||
[KEY_D ] = str_attach("KEY_D (PRESSED)"),
|
||||
[KEY_F ] = str_attach("KEY_F (PRESSED)"),
|
||||
[KEY_G ] = str_attach("KEY_G (PRESSED)"),
|
||||
[KEY_H ] = str_attach("KEY_H (PRESSED)"),
|
||||
[KEY_J ] = str_attach("KEY_J (PRESSED)"),
|
||||
[KEY_K ] = str_attach("KEY_K (PRESSED)"),
|
||||
[KEY_L ] = str_attach("KEY_L (PRESSED)"),
|
||||
[KEY_SEMICOLON ] = str_attach("KEY_SEMICOLON (PRESSED)"),
|
||||
[KEY_SINGLE_QUOTE ] = str_attach("KEY_SINGLE_QUOTE (PRESSED)"),
|
||||
[KEY_BACKTICK ] = str_attach("KEY_BACKTICK (PRESSED)"),
|
||||
[KEY_LEFT_SHIFT ] = str_attach("KEY_LEFT_SHIFT (PRESSED)"),
|
||||
[KEY_BACKSLASH ] = str_attach("KEY_BACKSLASH (PRESSED)"),
|
||||
[KEY_Z ] = str_attach("KEY_Z (PRESSED)"),
|
||||
[KEY_X ] = str_attach("KEY_X (PRESSED)"),
|
||||
[KEY_C ] = str_attach("KEY_C (PRESSED)"),
|
||||
[KEY_V ] = str_attach("KEY_V (PRESSED)"),
|
||||
[KEY_B ] = str_attach("KEY_B (PRESSED)"),
|
||||
[KEY_N ] = str_attach("KEY_N (PRESSED)"),
|
||||
[KEY_M ] = str_attach("KEY_M (PRESSED)"),
|
||||
[KEY_COMMA ] = str_attach("KEY_COMMA (PRESSED)"),
|
||||
[KEY_DOT ] = str_attach("KEY_DOT (PRESSED)"),
|
||||
[KEY_FORWARD_SLASH ] = str_attach("KEY_FORWARD_SLASH (PRESSED)"),
|
||||
[KEY_RIGHT_SHIFT ] = str_attach("KEY_RIGHT_SHIFT (PRESSED)"),
|
||||
[KEY_KEYPAD_ASTERISK ] = str_attach("KEY_KEYPAD_ASTERISK (PRESSED)"),
|
||||
[KEY_LEFT_ALT ] = str_attach("KEY_LEFT_ALT (PRESSED)"),
|
||||
[KEY_SPACE ] = str_attach("KEY_SPACE (PRESSED)"),
|
||||
[KEY_CAPSLOCK ] = str_attach("KEY_CAPSLOCK (PRESSED)"),
|
||||
[KEY_F1 ] = str_attach("KEY_F1 (PRESSED)"),
|
||||
[KEY_F2 ] = str_attach("KEY_F2 (PRESSED)"),
|
||||
[KEY_F3 ] = str_attach("KEY_F3 (PRESSED)"),
|
||||
[KEY_F4 ] = str_attach("KEY_F4 (PRESSED)"),
|
||||
[KEY_F5 ] = str_attach("KEY_F5 (PRESSED)"),
|
||||
[KEY_F6 ] = str_attach("KEY_F6 (PRESSED)"),
|
||||
[KEY_F7 ] = str_attach("KEY_F7 (PRESSED)"),
|
||||
[KEY_F8 ] = str_attach("KEY_F8 (PRESSED)"),
|
||||
[KEY_F9 ] = str_attach("KEY_F9 (PRESSED)"),
|
||||
[KEY_F10 ] = str_attach("KEY_F10 (PRESSED)"),
|
||||
[KEY_NUMBERLOCK ] = str_attach("KEY_NUMBERLOCK (PRESSED)"),
|
||||
[KEY_SCROLLLOCK ] = str_attach("KEY_SCROLLLOCK (PRESSED)"),
|
||||
[KEY_KEYPAD_7 ] = str_attach("KEY_KEYPAD_7 (PRESSED)"),
|
||||
[KEY_KEYPAD_8 ] = str_attach("KEY_KEYPAD_8 (PRESSED)"),
|
||||
[KEY_KEYPAD_9 ] = str_attach("KEY_KEYPAD_9 (PRESSED)"),
|
||||
[KEY_KEYPAD_MINUS ] = str_attach("KEY_KEYPAD_MINUS (PRESSED)"),
|
||||
[KEY_KEYPAD_4 ] = str_attach("KEY_KEYPAD_4 (PRESSED)"),
|
||||
[KEY_KEYPAD_5 ] = str_attach("KEY_KEYPAD_5 (PRESSED)"),
|
||||
[KEY_KEYPAD_6 ] = str_attach("KEY_KEYPAD_6 (PRESSED)"),
|
||||
[KEY_KEYPAD_PLUS ] = str_attach("KEY_KEYPAD_PLUS (PRESSED)"),
|
||||
[KEY_KEYPAD_1 ] = str_attach("KEY_KEYPAD_1 (PRESSED)"),
|
||||
[KEY_KEYPAD_2 ] = str_attach("KEY_KEYPAD_2 (PRESSED)"),
|
||||
[KEY_KEYPAD_3 ] = str_attach("KEY_KEYPAD_3 (PRESSED)"),
|
||||
[KEY_KEYPAD_0 ] = str_attach("KEY_KEYPAD_0 (PRESSED)"),
|
||||
[KEY_KEYPAD_DOT ] = str_attach("KEY_KEYPAD_DOT (PRESSED)"),
|
||||
[KEY_F11 ] = str_attach("KEY_F11 (PRESSED)"),
|
||||
[KEY_F12 ] = str_attach("KEY_F12 (PRESSED)"),
|
||||
|
||||
[KEY_RELEASED | KEY_ESCAPE ] = str_attach("KEY_ESCAPE (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_1 ] = str_attach("KEY_1 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_2 ] = str_attach("KEY_2 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_3 ] = str_attach("KEY_3 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_4 ] = str_attach("KEY_4 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_5 ] = str_attach("KEY_5 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_6 ] = str_attach("KEY_6 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_7 ] = str_attach("KEY_7 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_8 ] = str_attach("KEY_8 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_9 ] = str_attach("KEY_9 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_0 ] = str_attach("KEY_0 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_MINUS ] = str_attach("KEY_MINUS (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_EQUALS ] = str_attach("KEY_EQUALS (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_BACKSPACE ] = str_attach("KEY_BACKSPACE (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_TAB ] = str_attach("KEY_TAB (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_Q ] = str_attach("KEY_Q (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_W ] = str_attach("KEY_W (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_E ] = str_attach("KEY_E (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_R ] = str_attach("KEY_R (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_T ] = str_attach("KEY_T (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_Y ] = str_attach("KEY_Y (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_U ] = str_attach("KEY_U (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_I ] = str_attach("KEY_I (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_O ] = str_attach("KEY_O (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_P ] = str_attach("KEY_P (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_SQUARE_BRACKET_LEFT ] = str_attach("KEY_SQUARE_BRACKET_LEFT (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_SQUARE_BRACKET_RIGHT] = str_attach("KEY_SQUARE_BRACKET_RIGHT (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_ENTER ] = str_attach("KEY_ENTER (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_LEFT_CONTROL ] = str_attach("KEY_LEFT_CONTROL (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_A ] = str_attach("KEY_A (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_S ] = str_attach("KEY_S (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_D ] = str_attach("KEY_D (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F ] = str_attach("KEY_F (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_G ] = str_attach("KEY_G (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_H ] = str_attach("KEY_H (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_J ] = str_attach("KEY_J (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_K ] = str_attach("KEY_K (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_L ] = str_attach("KEY_L (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_SEMICOLON ] = str_attach("KEY_SEMICOLON (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_SINGLE_QUOTE ] = str_attach("KEY_SINGLE_QUOTE (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_BACKTICK ] = str_attach("KEY_BACKTICK (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_LEFT_SHIFT ] = str_attach("KEY_LEFT_SHIFT (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_BACKSLASH ] = str_attach("KEY_BACKSLASH (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_Z ] = str_attach("KEY_Z (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_X ] = str_attach("KEY_X (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_C ] = str_attach("KEY_C (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_V ] = str_attach("KEY_V (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_B ] = str_attach("KEY_B (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_N ] = str_attach("KEY_N (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_M ] = str_attach("KEY_M (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_COMMA ] = str_attach("KEY_COMMA (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_DOT ] = str_attach("KEY_DOT (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_FORWARD_SLASH ] = str_attach("KEY_FORWARD_SLASH (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_RIGHT_SHIFT ] = str_attach("KEY_RIGHT_SHIFT (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_ASTERISK ] = str_attach("KEY_KEYPAD_ASTERISK (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_LEFT_ALT ] = str_attach("KEY_LEFT_ALT (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_SPACE ] = str_attach("KEY_SPACE (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_CAPSLOCK ] = str_attach("KEY_CAPSLOCK (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F1 ] = str_attach("KEY_F1 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F2 ] = str_attach("KEY_F2 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F3 ] = str_attach("KEY_F3 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F4 ] = str_attach("KEY_F4 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F5 ] = str_attach("KEY_F5 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F6 ] = str_attach("KEY_F6 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F7 ] = str_attach("KEY_F7 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F8 ] = str_attach("KEY_F8 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F9 ] = str_attach("KEY_F9 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F10 ] = str_attach("KEY_F10 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_NUMBERLOCK ] = str_attach("KEY_NUMBERLOCK (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_SCROLLLOCK ] = str_attach("KEY_SCROLLLOCK (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_7 ] = str_attach("KEY_KEYPAD_7 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_8 ] = str_attach("KEY_KEYPAD_8 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_9 ] = str_attach("KEY_KEYPAD_9 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_MINUS ] = str_attach("KEY_KEYPAD_MINUS (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_4 ] = str_attach("KEY_KEYPAD_4 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_5 ] = str_attach("KEY_KEYPAD_5 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_6 ] = str_attach("KEY_KEYPAD_6 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_PLUS ] = str_attach("KEY_KEYPAD_PLUS (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_1 ] = str_attach("KEY_KEYPAD_1 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_2 ] = str_attach("KEY_KEYPAD_2 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_3 ] = str_attach("KEY_KEYPAD_3 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_0 ] = str_attach("KEY_KEYPAD_0 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_KEYPAD_DOT ] = str_attach("KEY_KEYPAD_DOT (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F11 ] = str_attach("KEY_F11 (RELEASED)"),
|
||||
[KEY_RELEASED | KEY_F12 ] = str_attach("KEY_F12 (RELEASED)"),
|
||||
};
|
||||
|
||||
const char ps2_key_char[] = {
|
||||
[KEY_1 ] = '1',
|
||||
[KEY_2 ] = '2',
|
||||
[KEY_3 ] = '3',
|
||||
[KEY_4 ] = '4',
|
||||
[KEY_5 ] = '5',
|
||||
[KEY_6 ] = '6',
|
||||
[KEY_7 ] = '7',
|
||||
[KEY_8 ] = '8',
|
||||
[KEY_9 ] = '9',
|
||||
[KEY_0 ] = '0',
|
||||
|
||||
[KEY_A ] = 'a',
|
||||
[KEY_B ] = 'b',
|
||||
[KEY_C ] = 'c',
|
||||
[KEY_D ] = 'd',
|
||||
[KEY_E ] = 'e',
|
||||
[KEY_F ] = 'f',
|
||||
[KEY_G ] = 'g',
|
||||
[KEY_H ] = 'h',
|
||||
[KEY_I ] = 'i',
|
||||
[KEY_J ] = 'j',
|
||||
[KEY_K ] = 'k',
|
||||
[KEY_L ] = 'l',
|
||||
[KEY_M ] = 'm',
|
||||
[KEY_N ] = 'n',
|
||||
[KEY_O ] = 'o',
|
||||
[KEY_P ] = 'p',
|
||||
[KEY_Q ] = 'q',
|
||||
[KEY_R ] = 'r',
|
||||
[KEY_S ] = 's',
|
||||
[KEY_T ] = 't',
|
||||
[KEY_U ] = 'u',
|
||||
[KEY_V ] = 'v',
|
||||
[KEY_W ] = 'w',
|
||||
[KEY_X ] = 'x',
|
||||
[KEY_Y ] = 'y',
|
||||
[KEY_Z ] = 'z',
|
||||
|
||||
[KEY_MINUS ] = '-',
|
||||
[KEY_EQUALS ] = '=',
|
||||
[KEY_BACKSPACE ] = '\b',
|
||||
[KEY_TAB ] = '\t',
|
||||
[KEY_SQUARE_BRACKET_LEFT ] = '[',
|
||||
[KEY_SQUARE_BRACKET_RIGHT ] = ']',
|
||||
[KEY_ENTER ] = '\n',
|
||||
[KEY_SEMICOLON ] = ';',
|
||||
[KEY_SINGLE_QUOTE ] = '\'',
|
||||
[KEY_BACKTICK ] = '`',
|
||||
[KEY_BACKSLASH ] = '\\',
|
||||
[KEY_COMMA ] = ',',
|
||||
[KEY_DOT ] = '.',
|
||||
[KEY_FORWARD_SLASH ] = '/',
|
||||
[KEY_KEYPAD_ASTERISK ] = '*',
|
||||
[KEY_SPACE ] = ' ',
|
||||
|
||||
[KEY_KEYPAD_0 ] = '0',
|
||||
[KEY_KEYPAD_1 ] = '1',
|
||||
[KEY_KEYPAD_2 ] = '2',
|
||||
[KEY_KEYPAD_3 ] = '3',
|
||||
[KEY_KEYPAD_4 ] = '4',
|
||||
[KEY_KEYPAD_5 ] = '5',
|
||||
[KEY_KEYPAD_6 ] = '6',
|
||||
[KEY_KEYPAD_7 ] = '7',
|
||||
[KEY_KEYPAD_8 ] = '8',
|
||||
[KEY_KEYPAD_9 ] = '9',
|
||||
[KEY_KEYPAD_DOT ] = '.',
|
||||
[KEY_KEYPAD_MINUS ] = '-',
|
||||
[KEY_KEYPAD_PLUS ] = '+',
|
||||
|
||||
[KEY_MODIFIER_SHIFT | KEY_0] = ')',
|
||||
[KEY_MODIFIER_SHIFT | KEY_9] = '(',
|
||||
[KEY_MODIFIER_SHIFT | KEY_8] = '*',
|
||||
[KEY_MODIFIER_SHIFT | KEY_7] = '&',
|
||||
[KEY_MODIFIER_SHIFT | KEY_6] = '^',
|
||||
[KEY_MODIFIER_SHIFT | KEY_5] = '%',
|
||||
[KEY_MODIFIER_SHIFT | KEY_4] = '$',
|
||||
[KEY_MODIFIER_SHIFT | KEY_3] = '#',
|
||||
[KEY_MODIFIER_SHIFT | KEY_2] = '@',
|
||||
[KEY_MODIFIER_SHIFT | KEY_1] = '!',
|
||||
|
||||
[KEY_MODIFIER_SHIFT | KEY_A] = 'A',
|
||||
[KEY_MODIFIER_SHIFT | KEY_B] = 'B',
|
||||
[KEY_MODIFIER_SHIFT | KEY_C] = 'C',
|
||||
[KEY_MODIFIER_SHIFT | KEY_D] = 'D',
|
||||
[KEY_MODIFIER_SHIFT | KEY_E] = 'E',
|
||||
[KEY_MODIFIER_SHIFT | KEY_F] = 'F',
|
||||
[KEY_MODIFIER_SHIFT | KEY_G] = 'G',
|
||||
[KEY_MODIFIER_SHIFT | KEY_H] = 'H',
|
||||
[KEY_MODIFIER_SHIFT | KEY_I] = 'I',
|
||||
[KEY_MODIFIER_SHIFT | KEY_J] = 'J',
|
||||
[KEY_MODIFIER_SHIFT | KEY_K] = 'K',
|
||||
[KEY_MODIFIER_SHIFT | KEY_L] = 'L',
|
||||
[KEY_MODIFIER_SHIFT | KEY_M] = 'M',
|
||||
[KEY_MODIFIER_SHIFT | KEY_N] = 'N',
|
||||
[KEY_MODIFIER_SHIFT | KEY_O] = 'O',
|
||||
[KEY_MODIFIER_SHIFT | KEY_P] = 'P',
|
||||
[KEY_MODIFIER_SHIFT | KEY_Q] = 'Q',
|
||||
[KEY_MODIFIER_SHIFT | KEY_R] = 'R',
|
||||
[KEY_MODIFIER_SHIFT | KEY_S] = 'S',
|
||||
[KEY_MODIFIER_SHIFT | KEY_T] = 'T',
|
||||
[KEY_MODIFIER_SHIFT | KEY_U] = 'U',
|
||||
[KEY_MODIFIER_SHIFT | KEY_V] = 'V',
|
||||
[KEY_MODIFIER_SHIFT | KEY_W] = 'W',
|
||||
[KEY_MODIFIER_SHIFT | KEY_X] = 'X',
|
||||
[KEY_MODIFIER_SHIFT | KEY_Y] = 'Y',
|
||||
[KEY_MODIFIER_SHIFT | KEY_Z] = 'Z',
|
||||
|
||||
[KEY_MODIFIER_SHIFT | KEY_MINUS ] = '_',
|
||||
[KEY_MODIFIER_SHIFT | KEY_EQUALS ] = '+',
|
||||
[KEY_MODIFIER_SHIFT | KEY_BACKSPACE ] = '\b',
|
||||
[KEY_MODIFIER_SHIFT | KEY_TAB ] = '\t',
|
||||
[KEY_MODIFIER_SHIFT | KEY_SQUARE_BRACKET_LEFT ] = '{',
|
||||
[KEY_MODIFIER_SHIFT | KEY_SQUARE_BRACKET_RIGHT ] = '}',
|
||||
[KEY_MODIFIER_SHIFT | KEY_ENTER ] = '\n',
|
||||
[KEY_MODIFIER_SHIFT | KEY_SEMICOLON ] = ':',
|
||||
[KEY_MODIFIER_SHIFT | KEY_SINGLE_QUOTE ] = '"',
|
||||
[KEY_MODIFIER_SHIFT | KEY_BACKTICK ] = '~',
|
||||
[KEY_MODIFIER_SHIFT | KEY_BACKSLASH ] = '|',
|
||||
[KEY_MODIFIER_SHIFT | KEY_COMMA ] = '<',
|
||||
[KEY_MODIFIER_SHIFT | KEY_DOT ] = '>',
|
||||
[KEY_MODIFIER_SHIFT | KEY_FORWARD_SLASH ] = '?',
|
||||
[KEY_MODIFIER_SHIFT | KEY_SPACE ] = ' ',
|
||||
};
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include "tty.h"
|
||||
#include "kernel/tty.h"
|
||||
#include "str.h"
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "libc.h"
|
||||
#include "kernel/tty.h"
|
||||
|
||||
typedef int (*printf_function)(struct printf_state* s, void* data);
|
||||
|
||||
@@ -132,6 +134,42 @@ static int print_char(struct printf_state* s)
|
||||
}
|
||||
}
|
||||
|
||||
static int print_cs(struct printf_state* s)
|
||||
{
|
||||
int n;
|
||||
int sum = 0;
|
||||
|
||||
const uint8_t cs = va_arg(s->ap, uint32_t);
|
||||
|
||||
const struct str cs_bit_names[] = {
|
||||
[0] = str_attach("ACCESSED"),
|
||||
[1] = str_attach("RW"),
|
||||
[2] = str_attach("DC"),
|
||||
[3] = str_attach("EXEC"),
|
||||
[4] = str_attach("DESCRIPTOR"),
|
||||
[7] = str_attach("PRESENT"),
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < sizeof cs_bit_names / sizeof *cs_bit_names; i++) {
|
||||
if (cs & (1<<i) && cs_bit_names[i].data) {
|
||||
n = printf(str_attach("{str} | "), cs_bit_names[i]);
|
||||
if (n == -1) {
|
||||
return -1;
|
||||
}
|
||||
sum += n;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int ring = (cs>>5) & 0b11;
|
||||
n = printf(str_attach("DPL({uint})"), ring);
|
||||
if (n == -1) {
|
||||
return -1;
|
||||
}
|
||||
sum += n;
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
static int parse_format_cmd(struct printf_state* s)
|
||||
{
|
||||
int c;
|
||||
@@ -174,6 +212,9 @@ static int parse_format_cmd(struct printf_state* s)
|
||||
case 'char':
|
||||
return print_char(s);
|
||||
|
||||
case 'cs':
|
||||
return print_cs(s);
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user