first commit
This commit is contained in:
commit
cab7a75780
264 changed files with 5833 additions and 0 deletions
5
kernel/.gitignore
vendored
Executable file
5
kernel/.gitignore
vendored
Executable file
|
@ -0,0 +1,5 @@
|
|||
/freestnd-c-hdrs
|
||||
/cc-runtime*
|
||||
/src/limine.h
|
||||
/bin-*
|
||||
/obj-*
|
220
kernel/GNUmakefile
Executable file
220
kernel/GNUmakefile
Executable file
|
@ -0,0 +1,220 @@
|
|||
# Nuke built-in rules and variables.
|
||||
MAKEFLAGS += -rR
|
||||
.SUFFIXES:
|
||||
|
||||
# This is the name that our final executable will have.
|
||||
# Change as needed.
|
||||
override OUTPUT := kernel
|
||||
|
||||
# Target architecture to build for. Default to x86_64.
|
||||
ARCH := x86_64
|
||||
|
||||
# Install prefix; /usr/local is a good, standard default pick.
|
||||
PREFIX := /usr/local
|
||||
|
||||
# Check if the architecture is supported.
|
||||
ifeq ($(filter $(ARCH),aarch64 loongarch64 riscv64 x86_64),)
|
||||
$(error Architecture $(ARCH) not supported)
|
||||
endif
|
||||
|
||||
# User controllable C compiler command.
|
||||
CC := cc
|
||||
|
||||
# User controllable archiver command.
|
||||
AR := ar
|
||||
|
||||
# User controllable C flags.
|
||||
CFLAGS := -g -O2 -pipe
|
||||
|
||||
# User controllable C preprocessor flags. We set none by default.
|
||||
CPPFLAGS :=
|
||||
|
||||
ifeq ($(ARCH),x86_64)
|
||||
# User controllable nasm flags.
|
||||
NASMFLAGS := -F dwarf -g
|
||||
endif
|
||||
|
||||
# User controllable linker flags. We set none by default.
|
||||
LDFLAGS :=
|
||||
|
||||
# Ensure the dependencies have been obtained.
|
||||
ifneq ($(shell ( test '$(MAKECMDGOALS)' = clean || test '$(MAKECMDGOALS)' = distclean ); echo $$?),0)
|
||||
ifeq ($(shell ( ! test -d freestnd-c-hdrs || ! test -d cc-runtime || ! test -f src/limine.h ); echo $$?),0)
|
||||
$(error Please run the ./get-deps script first)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Check if CC is Clang.
|
||||
override CC_IS_CLANG := $(shell ! $(CC) --version 2>/dev/null | grep 'clang' >/dev/null 2>&1; echo $$?)
|
||||
|
||||
# Internal C flags that should not be changed by the user.
|
||||
override CFLAGS += \
|
||||
-Wall \
|
||||
-Wextra \
|
||||
-std=gnu11 \
|
||||
-nostdinc \
|
||||
-ffreestanding \
|
||||
-fno-stack-protector \
|
||||
-fno-stack-check \
|
||||
-fno-PIC \
|
||||
-ffunction-sections \
|
||||
-fdata-sections
|
||||
|
||||
# Internal C preprocessor flags that should not be changed by the user.
|
||||
override CPPFLAGS := \
|
||||
-I src \
|
||||
-isystem freestnd-c-hdrs \
|
||||
$(CPPFLAGS) \
|
||||
-DLIMINE_API_REVISION=3 \
|
||||
-MMD \
|
||||
-MP
|
||||
|
||||
ifeq ($(ARCH),x86_64)
|
||||
# Internal nasm flags that should not be changed by the user.
|
||||
override NASMFLAGS += \
|
||||
-Wall
|
||||
endif
|
||||
|
||||
# Architecture specific internal flags.
|
||||
ifeq ($(ARCH),x86_64)
|
||||
ifeq ($(CC_IS_CLANG),1)
|
||||
override CC += \
|
||||
-target x86_64-unknown-none
|
||||
endif
|
||||
override CFLAGS += \
|
||||
-m64 \
|
||||
-march=x86-64 \
|
||||
-mno-80387 \
|
||||
-mno-mmx \
|
||||
-mno-sse \
|
||||
-mno-sse2 \
|
||||
-mno-red-zone \
|
||||
-mcmodel=kernel
|
||||
override LDFLAGS += \
|
||||
-Wl,-m,elf_x86_64
|
||||
override NASMFLAGS += \
|
||||
-f elf64
|
||||
endif
|
||||
ifeq ($(ARCH),aarch64)
|
||||
ifeq ($(CC_IS_CLANG),1)
|
||||
override CC += \
|
||||
-target aarch64-unknown-none
|
||||
endif
|
||||
override CFLAGS += \
|
||||
-mgeneral-regs-only
|
||||
override LDFLAGS += \
|
||||
-Wl,-m,aarch64elf
|
||||
endif
|
||||
ifeq ($(ARCH),riscv64)
|
||||
ifeq ($(CC_IS_CLANG),1)
|
||||
override CC += \
|
||||
-target riscv64-unknown-none
|
||||
override CFLAGS += \
|
||||
-march=rv64imac
|
||||
else
|
||||
override CFLAGS += \
|
||||
-march=rv64imac_zicsr_zifencei
|
||||
endif
|
||||
override CFLAGS += \
|
||||
-mabi=lp64 \
|
||||
-mno-relax
|
||||
override LDFLAGS += \
|
||||
-Wl,-m,elf64lriscv \
|
||||
-Wl,--no-relax
|
||||
endif
|
||||
ifeq ($(ARCH),loongarch64)
|
||||
ifeq ($(CC_IS_CLANG),1)
|
||||
override CC += \
|
||||
-target loongarch64-unknown-none
|
||||
endif
|
||||
override CFLAGS += \
|
||||
-march=loongarch64 \
|
||||
-mabi=lp64s
|
||||
override LDFLAGS += \
|
||||
-Wl,-m,elf64loongarch \
|
||||
-Wl,--no-relax
|
||||
endif
|
||||
|
||||
# Internal linker flags that should not be changed by the user.
|
||||
override LDFLAGS += \
|
||||
-Wl,--build-id=none \
|
||||
-nostdlib \
|
||||
-static \
|
||||
-z max-page-size=0x1000 \
|
||||
-Wl,--gc-sections \
|
||||
-T linker-$(ARCH).ld
|
||||
|
||||
# Use "find" to glob all *.c, *.S, and *.asm files in the tree and obtain the
|
||||
# object and header dependency file names.
|
||||
override SRCFILES := $(shell cd src && find -L * -type f | LC_ALL=C sort)
|
||||
override CFILES := $(filter %.c,$(SRCFILES))
|
||||
override ASFILES := $(filter %.S,$(SRCFILES))
|
||||
ifeq ($(ARCH),x86_64)
|
||||
override NASMFILES := $(filter %.asm,$(SRCFILES))
|
||||
endif
|
||||
override OBJ := $(addprefix obj-$(ARCH)/,$(CFILES:.c=.c.o) $(ASFILES:.S=.S.o))
|
||||
ifeq ($(ARCH),x86_64)
|
||||
override OBJ += $(addprefix obj-$(ARCH)/,$(NASMFILES:.asm=.asm.o))
|
||||
endif
|
||||
override HEADER_DEPS := $(addprefix obj-$(ARCH)/,$(CFILES:.c=.c.d) $(ASFILES:.S=.S.d))
|
||||
|
||||
# Default target. This must come first, before header dependencies.
|
||||
.PHONY: all
|
||||
all: bin-$(ARCH)/$(OUTPUT)
|
||||
|
||||
# Include header dependencies.
|
||||
-include $(HEADER_DEPS)
|
||||
|
||||
# Link rules for building the C compiler runtime.
|
||||
cc-runtime-$(ARCH)/cc-runtime.a: GNUmakefile cc-runtime/*
|
||||
rm -rf cc-runtime-$(ARCH)
|
||||
cp -r cc-runtime cc-runtime-$(ARCH)
|
||||
$(MAKE) -C cc-runtime-$(ARCH) -f cc-runtime.mk \
|
||||
CC="$(CC)" \
|
||||
AR="$(AR)" \
|
||||
CFLAGS="$(CFLAGS)" \
|
||||
CPPFLAGS='-isystem ../freestnd-c-hdrs -DCC_RUNTIME_NO_FLOAT'
|
||||
|
||||
# Link rules for the final executable.
|
||||
bin-$(ARCH)/$(OUTPUT): GNUmakefile linker-$(ARCH).ld $(OBJ) cc-runtime-$(ARCH)/cc-runtime.a
|
||||
mkdir -p "$$(dirname $@)"
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) cc-runtime-$(ARCH)/cc-runtime.a -o $@
|
||||
|
||||
# Compilation rules for *.c files.
|
||||
obj-$(ARCH)/%.c.o: src/%.c GNUmakefile
|
||||
mkdir -p "$$(dirname $@)"
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
# Compilation rules for *.S files.
|
||||
obj-$(ARCH)/%.S.o: src/%.S GNUmakefile
|
||||
mkdir -p "$$(dirname $@)"
|
||||
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
|
||||
|
||||
ifeq ($(ARCH),x86_64)
|
||||
# Compilation rules for *.asm (nasm) files.
|
||||
obj-$(ARCH)/%.asm.o: src/%.asm GNUmakefile
|
||||
mkdir -p "$$(dirname $@)"
|
||||
nasm $(NASMFLAGS) $< -o $@
|
||||
endif
|
||||
|
||||
# Remove object files and the final executable.
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf bin-$(ARCH) obj-$(ARCH) cc-runtime-$(ARCH)
|
||||
|
||||
# Remove everything built and generated including downloaded dependencies.
|
||||
.PHONY: distclean
|
||||
distclean:
|
||||
rm -rf bin-* obj-* freestnd-c-hdrs cc-runtime* src/limine.h
|
||||
|
||||
# Install the final built executable to its final on-root location.
|
||||
.PHONY: install
|
||||
install: all
|
||||
install -d "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)"
|
||||
install -m 644 bin-$(ARCH)/$(OUTPUT) "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)/$(OUTPUT)-$(ARCH)"
|
||||
|
||||
# Try to undo whatever the "install" target did.
|
||||
.PHONY: uninstall
|
||||
uninstall:
|
||||
rm -f "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)/$(OUTPUT)-$(ARCH)"
|
||||
-rmdir "$(DESTDIR)$(PREFIX)/share/$(OUTPUT)"
|
80
kernel/get-deps
Executable file
80
kernel/get-deps
Executable file
|
@ -0,0 +1,80 @@
|
|||
#! /bin/sh
|
||||
|
||||
set -ex
|
||||
|
||||
srcdir="$(dirname "$0")"
|
||||
test -z "$srcdir" && srcdir=.
|
||||
|
||||
cd "$srcdir"
|
||||
|
||||
clone_repo_commit() {
|
||||
if test -d "$2/.git"; then
|
||||
git -C "$2" reset --hard
|
||||
git -C "$2" clean -fd
|
||||
if ! git -C "$2" checkout $3; then
|
||||
rm -rf "$2"
|
||||
fi
|
||||
else
|
||||
if test -d "$2"; then
|
||||
set +x
|
||||
echo "error: '$2' is not a Git repository"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if ! test -d "$2"; then
|
||||
git clone $1 "$2"
|
||||
if ! git -C "$2" checkout $3; then
|
||||
rm -rf "$2"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
download_by_hash() {
|
||||
DOWNLOAD_COMMAND="curl -Lo"
|
||||
if ! command -v $DOWNLOAD_COMMAND >/dev/null 2>&1; then
|
||||
DOWNLOAD_COMMAND="wget -O"
|
||||
if ! command -v $DOWNLOAD_COMMAND >/dev/null 2>&1; then
|
||||
set +x
|
||||
echo "error: Neither curl nor wget found"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
SHA256_COMMAND="sha256sum"
|
||||
if ! command -v $SHA256_COMMAND >/dev/null 2>&1; then
|
||||
SHA256_COMMAND="sha256"
|
||||
if ! command -v $SHA256_COMMAND >/dev/null 2>&1; then
|
||||
set +x
|
||||
echo "error: Cannot find sha256(sum) command"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if ! test -f "$2" || ! $SHA256_COMMAND "$2" | grep $3 >/dev/null 2>&1; then
|
||||
rm -f "$2"
|
||||
mkdir -p "$2" && rm -rf "$2"
|
||||
$DOWNLOAD_COMMAND "$2" $1
|
||||
if ! $SHA256_COMMAND "$2" | grep $3 >/dev/null 2>&1; then
|
||||
set +x
|
||||
echo "error: Cannot download file '$2' by hash"
|
||||
echo "incorrect hash:"
|
||||
$SHA256_COMMAND "$2"
|
||||
rm -f "$2"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
clone_repo_commit \
|
||||
https://github.com/osdev0/freestnd-c-hdrs-0bsd.git \
|
||||
freestnd-c-hdrs \
|
||||
a87c192f3eb66b0806740dc67325f9ad23fc2d0b
|
||||
|
||||
clone_repo_commit \
|
||||
https://github.com/osdev0/cc-runtime.git \
|
||||
cc-runtime \
|
||||
576a01179f3298a4795b92f42c088f9f8800b56b
|
||||
|
||||
download_by_hash \
|
||||
https://github.com/limine-bootloader/limine/raw/4687a182be23939c2d9f15db970382dc353ed956/limine.h \
|
||||
src/limine.h \
|
||||
6879e626f34c1be25ac2f72bf43b083fc2b53887280bb0fcdaee790e258c6974
|
68
kernel/linker-aarch64.ld
Executable file
68
kernel/linker-aarch64.ld
Executable file
|
@ -0,0 +1,68 @@
|
|||
/* Tell the linker that we want an aarch64 ELF64 output file */
|
||||
OUTPUT_FORMAT(elf64-littleaarch64)
|
||||
|
||||
/* We want the symbol kmain to be our entry point */
|
||||
ENTRY(kmain)
|
||||
|
||||
/* Define the program headers we want so the bootloader gives us the right */
|
||||
/* MMU permissions; this also allows us to exert more control over the linking */
|
||||
/* process. */
|
||||
PHDRS
|
||||
{
|
||||
limine_requests PT_LOAD;
|
||||
text PT_LOAD;
|
||||
rodata PT_LOAD;
|
||||
data PT_LOAD;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* We want to be placed in the topmost 2GiB of the address space, for optimisations */
|
||||
/* and because that is what the Limine spec mandates. */
|
||||
/* Any address in this region will do, but often 0xffffffff80000000 is chosen as */
|
||||
/* that is the beginning of the region. */
|
||||
. = 0xffffffff80000000;
|
||||
|
||||
/* Define a section to contain the Limine requests and assign it to its own PHDR */
|
||||
.limine_requests : {
|
||||
KEEP(*(.limine_requests_start))
|
||||
KEEP(*(.limine_requests))
|
||||
KEEP(*(.limine_requests_end))
|
||||
} :limine_requests
|
||||
|
||||
/* Move to the next memory page for .text */
|
||||
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||
|
||||
.text : {
|
||||
*(.text .text.*)
|
||||
} :text
|
||||
|
||||
/* Move to the next memory page for .rodata */
|
||||
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||
|
||||
.rodata : {
|
||||
*(.rodata .rodata.*)
|
||||
} :rodata
|
||||
|
||||
/* Move to the next memory page for .data */
|
||||
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||
|
||||
.data : {
|
||||
*(.data .data.*)
|
||||
} :data
|
||||
|
||||
/* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */
|
||||
/* unnecessary zeros will be written to the binary. */
|
||||
/* If you need, for example, .init_array and .fini_array, those should be placed */
|
||||
/* above this. */
|
||||
.bss : {
|
||||
*(.bss .bss.*)
|
||||
*(COMMON)
|
||||
} :data
|
||||
|
||||
/* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */
|
||||
/DISCARD/ : {
|
||||
*(.eh_frame*)
|
||||
*(.note .note.*)
|
||||
}
|
||||
}
|
68
kernel/linker-loongarch64.ld
Executable file
68
kernel/linker-loongarch64.ld
Executable file
|
@ -0,0 +1,68 @@
|
|||
/* Tell the linker that we want a loongarch64 ELF64 output file */
|
||||
OUTPUT_FORMAT(elf64-loongarch)
|
||||
|
||||
/* We want the symbol kmain to be our entry point */
|
||||
ENTRY(kmain)
|
||||
|
||||
/* Define the program headers we want so the bootloader gives us the right */
|
||||
/* MMU permissions; this also allows us to exert more control over the linking */
|
||||
/* process. */
|
||||
PHDRS
|
||||
{
|
||||
limine_requests PT_LOAD;
|
||||
text PT_LOAD;
|
||||
rodata PT_LOAD;
|
||||
data PT_LOAD;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* We want to be placed in the topmost 2GiB of the address space, for optimisations */
|
||||
/* and because that is what the Limine spec mandates. */
|
||||
/* Any address in this region will do, but often 0xffffffff80000000 is chosen as */
|
||||
/* that is the beginning of the region. */
|
||||
. = 0xffffffff80000000;
|
||||
|
||||
/* Define a section to contain the Limine requests and assign it to its own PHDR */
|
||||
.limine_requests : {
|
||||
KEEP(*(.limine_requests_start))
|
||||
KEEP(*(.limine_requests))
|
||||
KEEP(*(.limine_requests_end))
|
||||
} :limine_requests
|
||||
|
||||
/* Move to the next memory page for .text */
|
||||
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||
|
||||
.text : {
|
||||
*(.text .text.*)
|
||||
} :text
|
||||
|
||||
/* Move to the next memory page for .rodata */
|
||||
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||
|
||||
.rodata : {
|
||||
*(.rodata .rodata.*)
|
||||
} :rodata
|
||||
|
||||
/* Move to the next memory page for .data */
|
||||
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||
|
||||
.data : {
|
||||
*(.data .data.*)
|
||||
} :data
|
||||
|
||||
/* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */
|
||||
/* unnecessary zeros will be written to the binary. */
|
||||
/* If you need, for example, .init_array and .fini_array, those should be placed */
|
||||
/* above this. */
|
||||
.bss : {
|
||||
*(.bss .bss.*)
|
||||
*(COMMON)
|
||||
} :data
|
||||
|
||||
/* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */
|
||||
/DISCARD/ : {
|
||||
*(.eh_frame*)
|
||||
*(.note .note.*)
|
||||
}
|
||||
}
|
70
kernel/linker-riscv64.ld
Executable file
70
kernel/linker-riscv64.ld
Executable file
|
@ -0,0 +1,70 @@
|
|||
/* Tell the linker that we want a riscv64 ELF64 output file */
|
||||
OUTPUT_FORMAT(elf64-littleriscv)
|
||||
|
||||
/* We want the symbol kmain to be our entry point */
|
||||
ENTRY(kmain)
|
||||
|
||||
/* Define the program headers we want so the bootloader gives us the right */
|
||||
/* MMU permissions; this also allows us to exert more control over the linking */
|
||||
/* process. */
|
||||
PHDRS
|
||||
{
|
||||
limine_requests PT_LOAD;
|
||||
text PT_LOAD;
|
||||
rodata PT_LOAD;
|
||||
data PT_LOAD;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* We want to be placed in the topmost 2GiB of the address space, for optimisations */
|
||||
/* and because that is what the Limine spec mandates. */
|
||||
/* Any address in this region will do, but often 0xffffffff80000000 is chosen as */
|
||||
/* that is the beginning of the region. */
|
||||
. = 0xffffffff80000000;
|
||||
|
||||
/* Define a section to contain the Limine requests and assign it to its own PHDR */
|
||||
.limine_requests : {
|
||||
KEEP(*(.limine_requests_start))
|
||||
KEEP(*(.limine_requests))
|
||||
KEEP(*(.limine_requests_end))
|
||||
} :limine_requests
|
||||
|
||||
/* Move to the next memory page for .text */
|
||||
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||
|
||||
.text : {
|
||||
*(.text .text.*)
|
||||
} :text
|
||||
|
||||
/* Move to the next memory page for .rodata */
|
||||
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||
|
||||
.rodata : {
|
||||
*(.rodata .rodata.*)
|
||||
} :rodata
|
||||
|
||||
/* Move to the next memory page for .data */
|
||||
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||
|
||||
.data : {
|
||||
*(.data .data.*)
|
||||
*(.sdata .sdata.*)
|
||||
} :data
|
||||
|
||||
/* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */
|
||||
/* unnecessary zeros will be written to the binary. */
|
||||
/* If you need, for example, .init_array and .fini_array, those should be placed */
|
||||
/* above this. */
|
||||
.bss : {
|
||||
*(.sbss .sbss.*)
|
||||
*(.bss .bss.*)
|
||||
*(COMMON)
|
||||
} :data
|
||||
|
||||
/* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */
|
||||
/DISCARD/ : {
|
||||
*(.eh_frame*)
|
||||
*(.note .note.*)
|
||||
}
|
||||
}
|
77
kernel/linker-x86_64.ld
Executable file
77
kernel/linker-x86_64.ld
Executable file
|
@ -0,0 +1,77 @@
|
|||
/* Tell the linker that we want an x86_64 ELF64 output file */
|
||||
OUTPUT_FORMAT(elf64-x86-64)
|
||||
|
||||
/* We want the symbol kmain to be our entry point */
|
||||
ENTRY(kmain)
|
||||
|
||||
/* Define the program headers we want so the bootloader gives us the right */
|
||||
/* MMU permissions; this also allows us to exert more control over the linking */
|
||||
/* process. */
|
||||
PHDRS
|
||||
{
|
||||
limine_requests PT_LOAD;
|
||||
text PT_LOAD;
|
||||
rodata PT_LOAD;
|
||||
data PT_LOAD;
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* We want to be placed in the topmost 2GiB of the address space, for optimisations */
|
||||
/* and because that is what the Limine spec mandates. */
|
||||
/* Any address in this region will do, but often 0xffffffff80000000 is chosen as */
|
||||
/* that is the beginning of the region. */
|
||||
. = 0xffffffff80000000;
|
||||
|
||||
|
||||
.text : {
|
||||
text_start_ld = .;
|
||||
*(.text .text.*)
|
||||
text_end_ld = .;
|
||||
} :text
|
||||
|
||||
/* Move to the next memory page for .limine_requests */
|
||||
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||
|
||||
/* Define a section to contain the Limine requests and assign it to its own PHDR */
|
||||
.limine_requests : {
|
||||
reqs_start_ld = .;
|
||||
KEEP(*(.limine_requests_start))
|
||||
KEEP(*(.limine_requests))
|
||||
KEEP(*(.limine_requests_end))
|
||||
reqs_end_ld = .;
|
||||
} :limine_requests
|
||||
|
||||
/* Move to the next memory page for .rodata */
|
||||
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||
|
||||
.rodata : {
|
||||
rodata_start_ld = .;
|
||||
*(.rodata .rodata.*)
|
||||
rodata_end_ld = .;
|
||||
} :rodata
|
||||
|
||||
/* Move to the next memory page for .data */
|
||||
. = ALIGN(CONSTANT(MAXPAGESIZE));
|
||||
|
||||
.data : {
|
||||
data_start_ld = .;
|
||||
*(.data .data.*)
|
||||
} :data
|
||||
|
||||
/* NOTE: .bss needs to be the last thing mapped to :data, otherwise lots of */
|
||||
/* unnecessary zeros will be written to the binary. */
|
||||
/* If you need, for example, .init_array and .fini_array, those should be placed */
|
||||
/* above this. */
|
||||
.bss : {
|
||||
*(.bss .bss.*)
|
||||
*(COMMON)
|
||||
data_end_ld = .;
|
||||
} :data
|
||||
|
||||
/* Discard .note.* and .eh_frame* since they may cause issues on some hosts. */
|
||||
/DISCARD/ : {
|
||||
*(.eh_frame*)
|
||||
*(.note .note.*)
|
||||
}
|
||||
}
|
261
kernel/src/font.h
Executable file
261
kernel/src/font.h
Executable file
|
@ -0,0 +1,261 @@
|
|||
#pragma once
|
||||
|
||||
// array size is 4096
|
||||
unsigned char VGA8[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
|
||||
0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00,
|
||||
0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00,
|
||||
0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
|
||||
0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
|
||||
0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00,
|
||||
0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
|
||||
0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, 0x00,
|
||||
0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00,
|
||||
0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
|
||||
0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
|
||||
0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
|
||||
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
|
||||
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
124
kernel/src/main.c
Executable file
124
kernel/src/main.c
Executable file
|
@ -0,0 +1,124 @@
|
|||
#include "mm/pmm.h"
|
||||
#include "mm/vmm.h"
|
||||
#include "rt.h"
|
||||
#include "sched/sched.h"
|
||||
#include "sys/arch/x86_64/cpuid.h"
|
||||
#include "sys/arch/x86_64/io.h"
|
||||
#include "sys/arch/x86_64/pit.h"
|
||||
#include "sys/arch/x86_64/rtc.h"
|
||||
#include "sys/arch/x86_64/sse.h"
|
||||
#include <sys/log.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <limine.h>
|
||||
|
||||
#include <sys/printf.h>
|
||||
#include <sys/arch/x86_64/gdt.h>
|
||||
#include <sys/arch/x86_64/idt.h>
|
||||
|
||||
// Set the base revision to 3, this is recommended as this is the latest
|
||||
// base revision described by the Limine boot protocol specification.
|
||||
// See specification for further info.
|
||||
|
||||
__attribute__((used, section(".limine_requests")))
|
||||
static volatile LIMINE_BASE_REVISION(3);
|
||||
|
||||
// The Limine requests can be placed anywhere, but it is important that
|
||||
// the compiler does not optimise them away, so, usually, they should
|
||||
// be made volatile or equivalent, _and_ they should be accessed at least
|
||||
// once or marked as used with the "used" attribute as done here.
|
||||
|
||||
__attribute__((used, section(".limine_requests")))
|
||||
static volatile struct limine_framebuffer_request framebuffer_request = {
|
||||
.id = LIMINE_FRAMEBUFFER_REQUEST,
|
||||
.revision = 0
|
||||
};
|
||||
|
||||
/*__attribute__((used, section(".limine_requests")))
|
||||
static volatile struct limine_entry_point_request entrypoint_request = {
|
||||
.id = LIMINE_ENTRY_POINT_REQUEST,
|
||||
.revision = 3
|
||||
};*/
|
||||
// Finally, define the start and end markers for the Limine requests.
|
||||
// These can also be moved anywhere, to any .c file, as seen fit.
|
||||
|
||||
__attribute__((used, section(".limine_requests_start")))
|
||||
static volatile LIMINE_REQUESTS_START_MARKER;
|
||||
|
||||
__attribute__((used, section(".limine_requests_end")))
|
||||
static volatile LIMINE_REQUESTS_END_MARKER;
|
||||
|
||||
|
||||
// Halt and catch fire function.
|
||||
static void hcf(void) {
|
||||
for (;;) {
|
||||
#if defined (__x86_64__)
|
||||
asm ("hlt");
|
||||
#elif defined (__aarch64__) || defined (__riscv)
|
||||
asm ("wfi");
|
||||
#elif defined (__loongarch64)
|
||||
asm ("idle 0");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int init() {
|
||||
asm("int $0x80");
|
||||
while (1)
|
||||
;;
|
||||
}
|
||||
|
||||
struct limine_framebuffer *fb;
|
||||
|
||||
// The following will be our kernel's entry point.
|
||||
// If renaming kmain() to something else, make sure to change the
|
||||
// linker script accordingly.
|
||||
void kmain(void) {
|
||||
// Ensure the bootloader actually understands our base revision (see spec).
|
||||
if (LIMINE_BASE_REVISION_SUPPORTED == false) {
|
||||
hcf();
|
||||
}
|
||||
|
||||
// Ensure we got a framebuffer.
|
||||
if (framebuffer_request.response == NULL
|
||||
|| framebuffer_request.response->framebuffer_count < 1) {
|
||||
hcf();
|
||||
}
|
||||
|
||||
// Fetch the first framebuffer.
|
||||
struct limine_framebuffer *framebuffer = framebuffer_request.response->framebuffers[0];
|
||||
fb = framebuffer;
|
||||
|
||||
rt_context ctx;
|
||||
ctx.framebuffer = fb->address;
|
||||
ctx.framebuffer_width = fb->width;
|
||||
ctx.framebuffer_height = fb->height;
|
||||
rt_init(ctx);
|
||||
|
||||
printf("\n Soaplin 1.0-sild is booting up your computer...\n\n");
|
||||
//printf("Physical kernel EP: %p", entrypoint_request.entry);
|
||||
|
||||
gdt_init();
|
||||
idt_init();
|
||||
|
||||
sse_init();
|
||||
|
||||
pmm_init();
|
||||
vmm_init();
|
||||
|
||||
pit_init(1000);
|
||||
sched_init();
|
||||
|
||||
uint64_t *mem = pmm_request_page();
|
||||
mem[0] = 0xCD;
|
||||
mem[1] = 0x80;
|
||||
mem[2] = 0xFE;
|
||||
mem[3] = 0xEB;
|
||||
sched_process *proc = sched_create("Init", 0x1000, SCHED_USER_PROCESS);
|
||||
vmm_map(proc->pm, 0x1000, (uint64_t)mem, VMM_PRESENT | VMM_USER);
|
||||
|
||||
log("kernel - Soaplin initialized sucessfully.\n");
|
||||
while (1)
|
||||
;;//__asm__ volatile ("hlt");
|
||||
}
|
59
kernel/src/mm/memop.c
Executable file
59
kernel/src/mm/memop.c
Executable file
|
@ -0,0 +1,59 @@
|
|||
// Copyright (C) 2024 Sipaa Projects
|
||||
// This code is part of the Soaplin kernel and is licensed under the terms of
|
||||
// the MIT License.
|
||||
|
||||
#include "mm/pmm.h"
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void *memcpy(void *dest, const void *src, size_t n) {
|
||||
uint8_t *pdest = (uint8_t *)dest;
|
||||
const uint8_t *psrc = (const uint8_t *)src;
|
||||
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
pdest[i] = psrc[i];
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *memset(void *s, int c, size_t n) {
|
||||
uint8_t *p = (uint8_t *)s;
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
p[i] = (uint8_t)c;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void *memmove(void *dest, const void *src, size_t n) {
|
||||
uint8_t *pdest = (uint8_t *)dest;
|
||||
const uint8_t *psrc = (const uint8_t *)src;
|
||||
|
||||
if (src > dest) {
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
pdest[i] = psrc[i];
|
||||
}
|
||||
} else if (src < dest) {
|
||||
for (size_t i = n; i > 0; i--) {
|
||||
pdest[i - 1] = psrc[i - 1];
|
||||
}
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
int memcmp(const void *s1, const void *s2, size_t n) {
|
||||
const uint8_t *p1 = (const uint8_t *)s1;
|
||||
const uint8_t *p2 = (const uint8_t *)s2;
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
if (p1[i] != p2[i]) {
|
||||
return p1[i] < p2[i] ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
13
kernel/src/mm/memop.h
Executable file
13
kernel/src/mm/memop.h
Executable file
|
@ -0,0 +1,13 @@
|
|||
// Copyright (C) 2024 Sipaa Projects
|
||||
// This code is part of the Soaplin kernel and is licensed under the terms of
|
||||
// the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void *memcpy(void *dest, const void *src, size_t n);
|
||||
void *memset(void *s, int c, size_t n);
|
||||
void *memmove(void *dest, const void *src, size_t n);
|
||||
int memcmp(const void *s1, const void *s2, size_t n);
|
114
kernel/src/mm/pmm.c
Executable file
114
kernel/src/mm/pmm.c
Executable file
|
@ -0,0 +1,114 @@
|
|||
#include "limine.h"
|
||||
#include <stddef.h>
|
||||
#include <mm/memop.h>
|
||||
#include <mm/pmm.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/log.h>
|
||||
|
||||
pmm_stack_t stack;
|
||||
struct limine_memmap_response *_memmap;
|
||||
|
||||
uint64_t hhdm_offset = 0x0;
|
||||
|
||||
__attribute__((used, section(".limine_requests")))
|
||||
struct limine_memmap_request mm_req = {
|
||||
.id = LIMINE_MEMMAP_REQUEST,
|
||||
.revision = 3
|
||||
};
|
||||
|
||||
|
||||
__attribute__((used, section(".limine_requests")))
|
||||
struct limine_hhdm_request hhdm_req = {
|
||||
.id = LIMINE_HHDM_REQUEST,
|
||||
.revision = 3
|
||||
};
|
||||
|
||||
int pmm_init()
|
||||
{
|
||||
uint64_t free_pages = 0;
|
||||
hhdm_offset = hhdm_req.response->offset;
|
||||
|
||||
struct limine_memmap_response *memmap = mm_req.response;
|
||||
_memmap = memmap;
|
||||
|
||||
//DEBUG("mm", "----- PMM //INFO -----");
|
||||
int freemem = 0;
|
||||
for (uint64_t i = 0; i < memmap->entry_count; i++)
|
||||
{
|
||||
if (memmap->entries[i]->type == LIMINE_MEMMAP_USABLE)
|
||||
{
|
||||
//DEBUG("mm", " - USABLE ENTRY\t\t@ 0x%.16llx, size: 0x%.16llx", memmap->entries[i]->base, memmap->entries[i]->length);
|
||||
free_pages += DIV_ROUND_UP(memmap->entries[i]->length, PMM_PAGE_SIZE);
|
||||
freemem += memmap->entries[i]->length;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t array_size = ALIGN_UP(free_pages * 8, PMM_PAGE_SIZE);
|
||||
|
||||
for (uint64_t i = 0; i < memmap->entry_count; i++)
|
||||
{
|
||||
struct limine_memmap_entry *entry = memmap->entries[i];
|
||||
if (entry->length >= array_size && entry->type == LIMINE_MEMMAP_USABLE)
|
||||
{
|
||||
stack.pages = (uintptr_t*)HIGHER_HALF(entry->base);
|
||||
entry->length -= array_size;
|
||||
entry->base += array_size;
|
||||
//DEBUG("mm", " - STACK START\t\t@ 0x%.16llx", stack.pages);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint64_t i = 0; i < memmap->entry_count; i++)
|
||||
{
|
||||
struct limine_memmap_entry *entry = memmap->entries[i];
|
||||
if (entry->type == LIMINE_MEMMAP_USABLE)
|
||||
{
|
||||
for (uint64_t j = 0; j < entry->length; j += PMM_PAGE_SIZE)
|
||||
{
|
||||
stack.pages[stack.idx++] = entry->base + j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stack.max = stack.idx;
|
||||
//DEBUG("mm", " - MAX INDEX:\t\t%d", stack.max);
|
||||
//DEBUG("mm", " - CURRENT INDEX:\t%d", stack.idx);
|
||||
//DEBUG("mm", "--------------------");
|
||||
|
||||
|
||||
log("pmm - %dmb is available to us.\n", freemem / (1024 * 1024));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *pmm_request_page()
|
||||
{
|
||||
if (stack.idx == 0)
|
||||
{
|
||||
//ERROR("mm", "No more pages available.");
|
||||
log("pmm - out of memory.\n");
|
||||
asm("cli");
|
||||
while (1) {
|
||||
asm("hlt");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint64_t page_addr = stack.pages[--stack.idx];
|
||||
memset(HIGHER_HALF(page_addr), 0, PMM_PAGE_SIZE);
|
||||
return (void *)page_addr;
|
||||
}
|
||||
|
||||
void pmm_free_page(void *ptr)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
return;
|
||||
|
||||
if (stack.idx >= stack.max)
|
||||
{
|
||||
//ERROR("mm", "Stack overflow attempt while freeing a page.");
|
||||
log("pmm - could not free the page: stack overflow.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
stack.pages[stack.idx++] = (uint64_t)ptr;
|
||||
}
|
28
kernel/src/mm/pmm.h
Executable file
28
kernel/src/mm/pmm.h
Executable file
|
@ -0,0 +1,28 @@
|
|||
#ifndef PMM_H
|
||||
#define PMM_H
|
||||
|
||||
#include <stdint.h>
|
||||
#define PMM_PAGE_SIZE 4096
|
||||
|
||||
typedef struct pmm_stack
|
||||
{
|
||||
uintptr_t *pages;
|
||||
uint64_t idx;
|
||||
uint64_t max;
|
||||
} pmm_stack_t;
|
||||
|
||||
extern uint64_t hhdm_offset;
|
||||
|
||||
#define DIV_ROUND_UP(x, y) (((uint64_t)(x) + ((uint64_t)(y) - 1)) / (uint64_t)(y))
|
||||
#define ALIGN_UP(x, y) (DIV_ROUND_UP(x, y) * (uint64_t)(y))
|
||||
#define ALIGN_DOWN(x, y) (((uint64_t)(x) / (uint64_t)(y)) * (uint64_t)(y))
|
||||
|
||||
#define HIGHER_HALF(ptr) ((void *)((uint64_t)ptr) + hhdm_offset)
|
||||
#define PHYSICAL(ptr) ((void *)((uint64_t)ptr) - hhdm_offset)
|
||||
|
||||
int pmm_init();
|
||||
void *pmm_request_page();
|
||||
void pmm_free_page(void *ptr);
|
||||
void pmm_dump();
|
||||
|
||||
#endif // PMM_H
|
187
kernel/src/mm/vmm.c
Executable file
187
kernel/src/mm/vmm.c
Executable file
|
@ -0,0 +1,187 @@
|
|||
#include "mm/vmm.h"
|
||||
#include "limine.h"
|
||||
#include "mm/pmm.h"
|
||||
#include "mm/memop.h"
|
||||
#include "sys/log.h"
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
__attribute__((used, section(".limine_requests")))
|
||||
static volatile struct limine_paging_mode_request pmrq = {
|
||||
.id = LIMINE_PAGING_MODE_REQUEST,
|
||||
.revision = 3,
|
||||
.mode = LIMINE_PAGING_MODE_X86_64_4LVL
|
||||
};
|
||||
|
||||
__attribute__((used, section(".limine_requests")))
|
||||
static volatile struct limine_executable_address_request karq = {
|
||||
.id = LIMINE_EXECUTABLE_ADDRESS_REQUEST,
|
||||
.revision = 0,
|
||||
};
|
||||
|
||||
pagemap_t *vmm_kernel_pm = NULL;
|
||||
pagemap_t *vmm_current_pm = NULL;
|
||||
int vmm_kernel_pm_exists = 0;
|
||||
|
||||
pagemap_t *vmm_alloc_pm() {
|
||||
pagemap_t *pm = (pagemap_t*)HIGHER_HALF((uint64_t)pmm_request_page());
|
||||
memset(pm, 0, PMM_PAGE_SIZE);
|
||||
|
||||
|
||||
/*if (vmm_kernel_pm_exists) {
|
||||
pm->toplevel = (uint64_t*)HIGHER_HALF((uint64_t)pmm_request_page());
|
||||
memset(pm->toplevel, 0, PMM_PAGE_SIZE);
|
||||
|
||||
for (int i = 256; i < 512; i++) {
|
||||
pm->toplevel[i] = vmm_kernel_pm->toplevel[i];
|
||||
}
|
||||
} else {
|
||||
|
||||
__asm__ volatile("mov %%cr3, %0" : "=r"(pm->toplevel) : : "memory");
|
||||
pm->toplevel = HIGHER_HALF(pm->toplevel);
|
||||
logln(info, "vmm", "Limine-provided kernel PML4: %p", pm->toplevel);
|
||||
|
||||
}*/
|
||||
|
||||
pm->toplevel = (uint64_t*)HIGHER_HALF((uint64_t)pmm_request_page());
|
||||
memset(pm->toplevel, 0, PMM_PAGE_SIZE);
|
||||
|
||||
if (vmm_kernel_pm_exists) {
|
||||
for (int i = 256; i < 512; i++) {
|
||||
pm->toplevel[i] = vmm_kernel_pm->toplevel[i];
|
||||
}
|
||||
}
|
||||
|
||||
return pm;
|
||||
}
|
||||
|
||||
void vmm_release_pm(pagemap_t *pm) {
|
||||
memset(pm->toplevel, 0, PMM_PAGE_SIZE);
|
||||
memset(pm, 0, PMM_PAGE_SIZE);
|
||||
pmm_free_page(pm->toplevel);
|
||||
pmm_free_page(pm);
|
||||
}
|
||||
|
||||
void vmm_sanity_check() {
|
||||
uint64_t *my_memory = pmm_request_page();
|
||||
*my_memory = 0x40;
|
||||
|
||||
pagemap_t *pm = vmm_alloc_pm();
|
||||
vmm_map(pm, 0x1000, (uint64_t)my_memory, VMM_PRESENT | VMM_WRITABLE);
|
||||
|
||||
uint64_t *my_ptr = (uint64_t*)0x1000;
|
||||
uint64_t ptr_val = 0;
|
||||
vmm_load_pagemap(pm);
|
||||
ptr_val = *my_ptr;
|
||||
vmm_load_pagemap(vmm_kernel_pm);
|
||||
|
||||
if (ptr_val != 0x40) {
|
||||
log("vmm - sanity check failed. system halted.\n");
|
||||
asm("cli");
|
||||
while (1)
|
||||
asm("hlt");
|
||||
}
|
||||
}
|
||||
|
||||
void vmm_init() {
|
||||
if (pmrq.response->mode != LIMINE_PAGING_MODE_X86_64_4LVL) {
|
||||
log("vmm - Soaplin only supports 4-level paging!\n");
|
||||
asm("cli; hlt;");
|
||||
}
|
||||
vmm_kernel_pm = vmm_alloc_pm();
|
||||
vmm_kernel_pm_exists = 1;
|
||||
|
||||
uint64_t kphysaddr = karq.response->physical_base;
|
||||
uint64_t kvirtaddr = karq.response->virtual_base;
|
||||
|
||||
uint64_t reqs_start = ALIGN_DOWN((uint64_t)reqs_start_ld, PMM_PAGE_SIZE);
|
||||
uint64_t reqs_end = ALIGN_UP((uint64_t)reqs_end_ld, PMM_PAGE_SIZE);
|
||||
uint64_t text_start = ALIGN_DOWN((uint64_t)text_start_ld, PMM_PAGE_SIZE);
|
||||
uint64_t text_end = ALIGN_UP((uint64_t)text_end_ld, PMM_PAGE_SIZE);
|
||||
uint64_t rodata_start = ALIGN_DOWN((uint64_t)rodata_start_ld, PMM_PAGE_SIZE);
|
||||
uint64_t rodata_end = ALIGN_UP((uint64_t)rodata_end_ld, PMM_PAGE_SIZE);
|
||||
uint64_t data_start = ALIGN_DOWN((uint64_t)data_start_ld, PMM_PAGE_SIZE);
|
||||
uint64_t data_end = ALIGN_UP((uint64_t)data_end_ld, PMM_PAGE_SIZE);
|
||||
|
||||
|
||||
log("vmm - mapping .requests section...\n");
|
||||
for (uint64_t req = reqs_start; req < reqs_end; req += PMM_PAGE_SIZE) {
|
||||
vmm_map(vmm_kernel_pm, req, req - kvirtaddr + kphysaddr, VMM_PRESENT | VMM_WRITABLE);
|
||||
}
|
||||
|
||||
log("vmm - mapping .text section...\n");
|
||||
for (uint64_t text = text_start; text < text_end; text += PMM_PAGE_SIZE) {
|
||||
vmm_map(vmm_kernel_pm, text, text - kvirtaddr + kphysaddr, VMM_PRESENT);
|
||||
}
|
||||
|
||||
log("vmm - mapping .rodata section...\n");
|
||||
for (uint64_t roData = rodata_start; roData < rodata_end; roData += PMM_PAGE_SIZE)
|
||||
vmm_map(vmm_kernel_pm, roData, roData - kvirtaddr + kphysaddr,
|
||||
VMM_PRESENT | VMM_NX);
|
||||
|
||||
log("vmm - mapping .data section...\n");
|
||||
for (uint64_t data = data_start; data < data_end; data += PMM_PAGE_SIZE)
|
||||
vmm_map(vmm_kernel_pm, data, data - kvirtaddr + kphysaddr,
|
||||
VMM_PRESENT | VMM_WRITABLE | VMM_NX);
|
||||
|
||||
log("vmm - mapping address from 0x0 to 0x100000000...\n");
|
||||
for (uint64_t gb4 = 0; gb4 < 0x100000000; gb4 += PMM_PAGE_SIZE) {
|
||||
vmm_map(vmm_kernel_pm, gb4, gb4, VMM_PRESENT | VMM_WRITABLE);
|
||||
vmm_map(vmm_kernel_pm, (uint64_t)HIGHER_HALF(gb4), gb4, VMM_PRESENT | VMM_WRITABLE);
|
||||
}
|
||||
|
||||
vmm_load_pagemap(vmm_kernel_pm);
|
||||
|
||||
vmm_sanity_check();
|
||||
log("vmm - initialized!\n");
|
||||
}
|
||||
|
||||
void vmm_load_pagemap(pagemap_t *pm) {
|
||||
if (!pm)
|
||||
return;
|
||||
|
||||
if (!pm->toplevel)
|
||||
return;
|
||||
|
||||
vmm_current_pm = pm;
|
||||
__asm__ volatile("mov %0, %%cr3" : : "r"(PHYSICAL(pm->toplevel)) : "memory");
|
||||
}
|
||||
|
||||
static uint64_t *__vmm_get_next_lvl(uint64_t *level, uint64_t entry, uint64_t flags) {
|
||||
if (level[entry] & 1)
|
||||
return HIGHER_HALF(PTE_GET_ADDR(level[entry]));
|
||||
uint64_t *pml = HIGHER_HALF(pmm_request_page());
|
||||
memset(pml, 0, PMM_PAGE_SIZE);
|
||||
level[entry] = (uint64_t)PHYSICAL(pml) | (flags & 0xFFF); // N'ajoute que les flags pertinents
|
||||
return pml;
|
||||
}
|
||||
|
||||
void vmm_map(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, uint64_t flags) {
|
||||
uint64_t pml4_entry = (vaddr >> 39) & 0x1ff;
|
||||
uint64_t pml3_entry = (vaddr >> 30) & 0x1ff;
|
||||
uint64_t pml2_entry = (vaddr >> 21) & 0x1ff;
|
||||
uint64_t pml1_entry = (vaddr >> 12) & 0x1ff;
|
||||
|
||||
uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, flags);
|
||||
uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, flags);
|
||||
uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, flags);
|
||||
|
||||
pml1[pml1_entry] = paddr | flags;
|
||||
}
|
||||
void vmm_unmap(pagemap_t *pm, uint64_t vaddr) {
|
||||
uint64_t pml1_entry = (vaddr >> 12) & 0x1ff;
|
||||
uint64_t pml2_entry = (vaddr >> 21) & 0x1ff;
|
||||
uint64_t pml3_entry = (vaddr >> 30) & 0x1ff;
|
||||
uint64_t pml4_entry = (vaddr >> 39) & 0x1ff;
|
||||
|
||||
uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, 0);
|
||||
if (pml3 == NULL) return;
|
||||
uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, 0);
|
||||
if (pml2 == NULL) return;
|
||||
uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, 0);
|
||||
if (pml1 == NULL) return;
|
||||
|
||||
pml1[pml1_entry] = 0;
|
||||
|
||||
__asm__ volatile ("invlpg (%0)" : : "b"(vaddr) : "memory");
|
||||
}
|
41
kernel/src/mm/vmm.h
Executable file
41
kernel/src/mm/vmm.h
Executable file
|
@ -0,0 +1,41 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define PTE_ADDR_MASK 0x000ffffffffff000
|
||||
#define PTE_GET_ADDR(VALUE) ((VALUE) & PTE_ADDR_MASK)
|
||||
#define PTE_GET_FLAGS(VALUE) ((VALUE) & ~PTE_ADDR_MASK)
|
||||
|
||||
#define VMM_PRESENT (1 << 0)
|
||||
#define VMM_WRITABLE (1 << 1)
|
||||
#define VMM_USER (1 << 2)
|
||||
#define VMM_NX (1ULL << 63)
|
||||
|
||||
typedef char sym[];
|
||||
|
||||
extern sym reqs_start_ld;
|
||||
extern sym reqs_end_ld;
|
||||
|
||||
extern sym text_start_ld;
|
||||
extern sym text_end_ld;
|
||||
|
||||
extern sym rodata_start_ld;
|
||||
extern sym rodata_end_ld;
|
||||
|
||||
extern sym data_start_ld;
|
||||
extern sym data_end_ld;
|
||||
|
||||
|
||||
typedef struct pagemap {
|
||||
uint64_t *toplevel;
|
||||
} pagemap_t;
|
||||
|
||||
extern pagemap_t *vmm_kernel_pm;
|
||||
extern pagemap_t *vmm_current_pm;
|
||||
|
||||
pagemap_t *vmm_alloc_pm();
|
||||
void vmm_init();
|
||||
void vmm_release_pm(pagemap_t *pm);
|
||||
void vmm_load_pagemap(pagemap_t *pm);
|
||||
void vmm_map(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, uint64_t flags);
|
||||
void vmm_unmap(pagemap_t *pm, uint64_t vaddr) ;
|
85
kernel/src/rt.c
Executable file
85
kernel/src/rt.c
Executable file
|
@ -0,0 +1,85 @@
|
|||
#include "rt.h"
|
||||
#include <font.h>
|
||||
#include <stdint.h>
|
||||
#include <mm/memop.h>
|
||||
|
||||
static rt_context _curctx;
|
||||
|
||||
void _rt_drawchar(unsigned char c, int x, int y, int fgcolor, int bgcolor)
|
||||
{
|
||||
int cx,cy;
|
||||
int mask[8]={128, 64, 32, 16, 8, 4, 2, 1};
|
||||
unsigned char *glyph=VGA8+(int)c*16;
|
||||
|
||||
uint32_t *buf = _curctx.framebuffer;
|
||||
|
||||
for(cy=0;cy<16;cy++){
|
||||
for(cx=0;cx<8;cx++){
|
||||
buf[((y + cy) * _curctx.framebuffer_width) + (x + cx)] = glyph[cy]&mask[cx]?fgcolor:bgcolor;
|
||||
}
|
||||
}
|
||||
}
|
||||
void _rt_draw_fillchar(int x, int y, int bgcolor, int fgcolor) {
|
||||
int cx,cy;
|
||||
uint32_t *buf = _curctx.framebuffer;
|
||||
for(cy=0;cy<16;cy++){
|
||||
for(cx=0;cx<8;cx++){
|
||||
buf[((y + cy) * _curctx.framebuffer_width) + (x + cx)] = cy > 12 ? fgcolor : bgcolor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int _rt_strlen(char *str) {
|
||||
int i = 0;
|
||||
while (str[i] != '\0') i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
void rt_init(rt_context ctx) {
|
||||
// Copy the structure
|
||||
char *src = (char*)&ctx;
|
||||
char *dst = (char*)&_curctx;
|
||||
for (unsigned long i = 0; i < sizeof(rt_context); i++) {
|
||||
dst[i] = src[i];
|
||||
}
|
||||
|
||||
// Fill fields
|
||||
_curctx.term_width = _curctx.framebuffer_width / 8;
|
||||
_curctx.term_height = _curctx.framebuffer_height / 16;
|
||||
}
|
||||
|
||||
void rt_print(char *str) {
|
||||
_rt_draw_fillchar(_curctx.x * 8, _curctx.y * 16, 0x0, 0x0);
|
||||
|
||||
for (int i = 0; i < _rt_strlen(str); i++) {
|
||||
if (str[i] == '\n' && _curctx.use_crlf_ending)
|
||||
if (_curctx.y * 16 >= _curctx.framebuffer_height) {
|
||||
_curctx.y = 0;
|
||||
memset(
|
||||
_curctx.framebuffer, _curctx.bg_color,
|
||||
_curctx.framebuffer_width * _curctx.framebuffer_height * sizeof(uint32_t));
|
||||
} else {
|
||||
_curctx.y++;
|
||||
}
|
||||
else if (str[i] == '\n')
|
||||
{
|
||||
if (_curctx.y * 16 >= _curctx.framebuffer_height) {
|
||||
_curctx.y = 0;
|
||||
memset(
|
||||
_curctx.framebuffer, _curctx.bg_color,
|
||||
_curctx.framebuffer_width * _curctx.framebuffer_height * sizeof(uint32_t));
|
||||
} else {
|
||||
_curctx.y++;
|
||||
}
|
||||
_curctx.x = 0;
|
||||
}
|
||||
else if (str[i] == '\r')
|
||||
_curctx.x = 0;
|
||||
else {
|
||||
_rt_drawchar(str[i], _curctx.x * 8, _curctx.y * 16, 0xFFFFFF, 0x0);
|
||||
_curctx.x++;
|
||||
}
|
||||
}
|
||||
|
||||
_rt_draw_fillchar(_curctx.x * 8, _curctx.y * 16, 0x0, 0xFFFFFF);
|
||||
}
|
41
kernel/src/rt.h
Executable file
41
kernel/src/rt.h
Executable file
|
@ -0,0 +1,41 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct _rt_ctx {
|
||||
// A pointer to the framebuffer.
|
||||
void *framebuffer;
|
||||
|
||||
// The framebuffer width, in pixels.
|
||||
uint32_t framebuffer_width;
|
||||
|
||||
// The framebuffer height, in pixels.
|
||||
uint32_t framebuffer_height;
|
||||
|
||||
// Set this to 1 if you prefer using DOS line endings to UNIX line endings.
|
||||
int use_crlf_ending;
|
||||
|
||||
// Do we need to show a cursor after printing text?
|
||||
int show_cursor;
|
||||
|
||||
// The background color
|
||||
uint32_t bg_color;
|
||||
|
||||
// The foreground color
|
||||
uint32_t fg_color;
|
||||
|
||||
/*
|
||||
* Do NOT modify everything below me!
|
||||
*/
|
||||
// The terminal's width, in columns of 8 pixels.
|
||||
int term_width;
|
||||
// The terminal's height, in rows of 16 pixels.
|
||||
int term_height;
|
||||
// The X position of the cursor, in columns of 8 pixels.
|
||||
int x;
|
||||
// The Y position of the cursor, in rows of 16 pixels.
|
||||
int y;
|
||||
} rt_context;
|
||||
|
||||
void rt_init(rt_context ctx);
|
||||
void rt_print(char *str);
|
111
kernel/src/sched/sched.c
Executable file
111
kernel/src/sched/sched.c
Executable file
|
@ -0,0 +1,111 @@
|
|||
#include "sched/sched.h"
|
||||
#include "mm/pmm.h"
|
||||
#include "mm/memop.h"
|
||||
#include "mm/vmm.h"
|
||||
#include "sys/arch/x86_64/idt.h"
|
||||
#include "sys/log.h"
|
||||
#include <stddef.h>
|
||||
|
||||
sched_process *proc_list;
|
||||
sched_process *curr_proc;
|
||||
int current_pid = 0;
|
||||
int standby = 0;
|
||||
|
||||
void sched_init() {
|
||||
// TODO: It may be good to implement heap memory to save space.
|
||||
|
||||
// We must initialize the process list.
|
||||
// By default, sched_create will append to this list.
|
||||
proc_list = pmm_request_page();
|
||||
memcpy(proc_list->name, "System\0", 7);
|
||||
proc_list->pid = -1;
|
||||
proc_list->type = SCHED_EMPTY;
|
||||
|
||||
curr_proc = proc_list;
|
||||
|
||||
standby = 1;
|
||||
log("sched - As there's nothing "
|
||||
"to schedule, the scheduler entered standby"
|
||||
"mode.\n");
|
||||
}
|
||||
|
||||
sched_process *sched_create(char *name, uint64_t entry_point, uint32_t flags)
|
||||
{
|
||||
// TODO: implement a separate strlen function
|
||||
// as there's like 4 strlen impls in the kernel.
|
||||
int i = 0;
|
||||
while (name[i] != 0)
|
||||
i++;
|
||||
|
||||
sched_process *proc = pmm_request_page();
|
||||
memset(proc, 0, sizeof(sched_process));
|
||||
|
||||
memcpy(proc->name, name, i);
|
||||
proc->pid = current_pid;
|
||||
proc->type = SCHED_RUNNING;
|
||||
|
||||
// We are about to setup the registers ourself.
|
||||
// If it's broken, it's a boom in the ass of your computer
|
||||
// (and a CPU exception)
|
||||
|
||||
proc->pm = vmm_alloc_pm();
|
||||
|
||||
uint64_t *stack_phys = pmm_request_page();
|
||||
uint64_t *stack_virt = (uint64_t*)0x40000000;
|
||||
|
||||
if (flags == SCHED_KERNEL_PROCESS) {
|
||||
proc->stack_base = stack_phys;
|
||||
proc->stack_end = proc_list->stack_base + PMM_PAGE_SIZE;
|
||||
} else if (flags == SCHED_USER_PROCESS) {
|
||||
vmm_map(proc->pm, (uint64_t)stack_virt, (uint64_t)stack_phys, VMM_PRESENT | VMM_WRITABLE | VMM_USER);
|
||||
proc->stack_base = stack_virt;
|
||||
proc->stack_end = proc_list->stack_base + PMM_PAGE_SIZE;
|
||||
}
|
||||
proc->regs.rip = (uint64_t)entry_point;
|
||||
|
||||
if (flags == SCHED_KERNEL_PROCESS) {
|
||||
proc->regs.cs = 0x28; // Run in kernel mode
|
||||
proc->regs.ss = 0x30;
|
||||
}
|
||||
else if (flags == SCHED_USER_PROCESS) {
|
||||
proc->regs.cs = 0x43; // Run in kernel mode
|
||||
proc->regs.ss = 0x3B;
|
||||
}
|
||||
proc->regs.rflags = 0x202; // Enable interrupts
|
||||
proc->regs.rsp = (uint64_t)proc->stack_end;
|
||||
proc->regs.rbp = 0;
|
||||
|
||||
proc->next = curr_proc->next;
|
||||
curr_proc->next = proc;
|
||||
|
||||
current_pid++;
|
||||
|
||||
if (standby) {
|
||||
// Disable standby mode as there's actually something to
|
||||
// run, now.
|
||||
standby = 0;
|
||||
log("sched - Standby mode has been"
|
||||
"disabled.\n");
|
||||
}
|
||||
return proc;
|
||||
}
|
||||
|
||||
void schedule(registers_t *regs)
|
||||
{
|
||||
if (standby) {
|
||||
//log("sched - Sched is in standby.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(&curr_proc->regs, regs, sizeof(registers_t));
|
||||
|
||||
curr_proc = curr_proc->next;
|
||||
if (curr_proc == NULL)
|
||||
curr_proc = proc_list;
|
||||
|
||||
//log("sched - I choosed process %d\n", curr_proc->pid);
|
||||
memcpy(regs, &curr_proc->regs, sizeof(registers_t));
|
||||
|
||||
// Finally, load our pagemap
|
||||
//vmm_load_pagemap(curr_proc->pm);
|
||||
}
|
39
kernel/src/sched/sched.h
Executable file
39
kernel/src/sched/sched.h
Executable file
|
@ -0,0 +1,39 @@
|
|||
#pragma once
|
||||
|
||||
#include "mm/vmm.h"
|
||||
#include "sys/arch/x86_64/idt.h"
|
||||
|
||||
#define SCHED_KERNEL_PROCESS 0 // A process that runs in kernel mode.
|
||||
#define SCHED_USER_PROCESS 1 // A process that runs in userspace. The code MUST be mapped directly after creating the process.
|
||||
|
||||
typedef enum {
|
||||
SCHED_RUNNING,
|
||||
SCHED_EXITED,
|
||||
SCHED_EMPTY
|
||||
} sched_proc_type;
|
||||
|
||||
typedef struct _sched_process {
|
||||
char name[128];
|
||||
int pid;
|
||||
int type;
|
||||
|
||||
registers_t regs;
|
||||
pagemap_t *pm;
|
||||
|
||||
uint64_t *stack_end;
|
||||
uint64_t *stack_base;
|
||||
|
||||
struct _sched_process *next;
|
||||
} sched_process;
|
||||
|
||||
extern sched_process *curr_proc;
|
||||
extern sched_process *proc_list;
|
||||
|
||||
// The idle process is ditched in favor of standby mode,
|
||||
// which activates when there's nothing to run.
|
||||
//extern sched_process *idle_process;
|
||||
|
||||
void sched_init();
|
||||
sched_process *sched_create(char *name, uint64_t entry_point, uint32_t flags);
|
||||
void sched_exit(sched_process *proc);
|
||||
void schedule(registers_t *regs);
|
5
kernel/src/sys/arch/arch.h
Executable file
5
kernel/src/sys/arch/arch.h
Executable file
|
@ -0,0 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#define ENSURE_X86_64 #ifdef __x86_64__
|
||||
|
||||
#define ENDENSURE
|
637
kernel/src/sys/arch/x86_64/cpuid.h
Executable file
637
kernel/src/sys/arch/x86_64/cpuid.h
Executable file
|
@ -0,0 +1,637 @@
|
|||
#ifndef __CPUID_H__
|
||||
#define __CPUID_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
//=================CPUID_VENDOR=================
|
||||
#define CPUID_VENDOR_INTEL "GenuineIntel"
|
||||
#define CPUID_VENDOR_AMD "AuthenticAMD"
|
||||
|
||||
//================CPUID_CPU_INFO================
|
||||
#define CPUID_CPU_INFO_EAX_STEPPING_MASK 0xF
|
||||
#define CPUID_CPU_INFO_EAX_MODEL_MASK 0xF << 4
|
||||
#define CPUID_CPU_INFO_EAX_FAMILY_MASK 0xF << 8
|
||||
#define CPUID_CPU_INFO_EAX_TYPE_MASK 0x3 << 12
|
||||
#define CPUID_CPU_INFO_EAX_EXT_MODEL_MASK 0xF << 16
|
||||
#define CPUID_CPU_INFO_EAX_EXT_FAMILY_MASK 0xFF << 20
|
||||
|
||||
#define CPUID_CPU_INFO_EBX_BRAND_INDEX 0xFF
|
||||
#define CPUID_CPU_INFO_EBX_CFLUSH_SIZE 0xFF << 8
|
||||
#define CPUID_CPU_INFO_EBX_MAX_LOGPROC 0xFF << 16
|
||||
#define CPUID_CPU_INFO_EBX_INIT_APIC_ID 0xFF << 25
|
||||
|
||||
#define CPUID_CPU_INFO_ECX_SSE3 1 << 0
|
||||
#define CPUID_CPU_INFO_ECX_PCLMULQDQ 1 << 1
|
||||
#define CPUID_CPU_INFO_ECX_DTES64 1 << 2
|
||||
#define CPUID_CPU_INFO_ECX_MONITOR 1 << 3
|
||||
#define CPUID_CPU_INFO_ECX_DS_CPL 1 << 4
|
||||
#define CPUID_CPU_INFO_ECX_VMX 1 << 5
|
||||
#define CPUID_CPU_INFO_ECX_SMX 1 << 6
|
||||
#define CPUID_CPU_INFO_ECX_EIST 1 << 7
|
||||
#define CPUID_CPU_INFO_ECX_TM2 1 << 8
|
||||
#define CPUID_CPU_INFO_ECX_SSSE3 1 << 9
|
||||
#define CPUID_CPU_INFO_ECX_CNXT_ID 1 << 10
|
||||
#define CPUID_CPU_INFO_ECX_SDBG 1 << 11
|
||||
#define CPUID_CPU_INFO_ECX_FMA 1 << 12
|
||||
#define CPUID_CPU_INFO_ECX_CMPXCHG16B 1 << 13
|
||||
#define CPUID_CPU_INFO_ECX_XTPR_UC 1 << 14
|
||||
#define CPUID_CPU_INFO_ECX_PDCM 1 << 15
|
||||
//bit 16 is reserved
|
||||
#define CPUID_CPU_INFO_ECX_PCID 1 << 17
|
||||
#define CPUID_CPU_INFO_ECX_DCA 1 << 18
|
||||
#define CPUID_CPU_INFO_ECX_SSE4_1 1 << 19
|
||||
#define CPUID_CPU_INFO_ECX_SSE4_2 1 << 20
|
||||
#define CPUID_CPU_INFO_ECX_X2APIC 1 << 21
|
||||
#define CPUID_CPU_INFO_ECX_MOVBE 1 << 22
|
||||
#define CPUID_CPU_INFO_ECX_POPCNT 1 << 23
|
||||
#define CPUID_CPU_INFO_ECX_TSC_DEADLINE 1 << 24
|
||||
#define CPUID_CPU_INFO_ECX_AESNI 1 << 25
|
||||
#define CPUID_CPU_INFO_ECX_XSAVE 1 << 26
|
||||
#define CPUID_CPU_INFO_ECX_OSXSAVE 1 << 27
|
||||
#define CPUID_CPU_INFO_ECX_AVX 1 << 28
|
||||
#define CPUID_CPU_INFO_ECX_F16C 1 << 29
|
||||
#define CPUID_CPU_INFO_ECX_RDRAND 1 << 30
|
||||
//bit 31 is unused
|
||||
|
||||
#define CPUID_CPU_INFO_EDX_FPU 1 << 0
|
||||
#define CPUID_CPU_INFO_EDX_VME 1 << 1
|
||||
#define CPUID_CPU_INFO_EDX_DE 1 << 2
|
||||
#define CPUID_CPU_INFO_EDX_PSE 1 << 3
|
||||
#define CPUID_CPU_INFO_EDX_TSC 1 << 4
|
||||
#define CPUID_CPU_INFO_EDX_MSR 1 << 5
|
||||
#define CPUID_CPU_INFO_EDX_PAE 1 << 6
|
||||
#define CPUID_CPU_INFO_EDX_MCE 1 << 7
|
||||
#define CPUID_CPU_INFO_EDX_CX8 1 << 8
|
||||
#define CPUID_CPU_INFO_EDX_APIC 1 << 9
|
||||
//bit 10 is reserved
|
||||
#define CPUID_CPU_INFO_EDX_SEP 1 << 11
|
||||
#define CPUID_CPU_INFO_EDX_MTRR 1 << 12
|
||||
#define CPUID_CPU_INFO_EDX_PGE 1 << 13
|
||||
#define CPUID_CPU_INFO_EDX_MCA 1 << 14
|
||||
#define CPUID_CPU_INFO_EDX_CMOV 1 << 15
|
||||
#define CPUID_CPU_INFO_EDX_PAT 1 << 16
|
||||
#define CPUID_CPU_INFO_EDX_PSE_36 1 << 17
|
||||
#define CPUID_CPU_INFO_EDX_PSN 1 << 18
|
||||
#define CPUID_CPU_INFO_EDX_CLFSH 1 << 19
|
||||
//bit 20 is reserved
|
||||
#define CPUID_CPU_INFO_EDX_DS 1 << 21
|
||||
#define CPUID_CPU_INFO_EDX_ACPI 1 << 22
|
||||
#define CPUID_CPU_INFO_EDX_MMX 1 << 23
|
||||
#define CPUID_CPU_INFO_EDX_FXSR 1 << 24
|
||||
#define CPUID_CPU_INFO_EDX_SSE 1 << 25
|
||||
#define CPUID_CPU_INFO_EDX_SSE2 1 << 26
|
||||
#define CPUID_CPU_INFO_EDX_SS 1 << 27
|
||||
#define CPUID_CPU_INFO_EDX_HTT 1 << 28
|
||||
#define CPUID_CPU_INFO_EDX_TM 1 << 29
|
||||
//bit 30 is reserved
|
||||
#define CPUID_CPU_INFO_EDX_PBE 1 << 31
|
||||
|
||||
//===============CPUID_CACHE_TLB===============
|
||||
//WARNING: I gave up and used ChatGPT for these
|
||||
#define CPUID_CACHE_TLB_DESC_NULL 0x00
|
||||
#define CPUID_CACHE_TLB_DESC_TLB_4_KBYTE_4WAY_32E 0x01
|
||||
#define CPUID_CACHE_TLB_DESC_TLB_4_MBYTE_FULLY_2E 0x02
|
||||
#define CPUID_CACHE_TLB_DESC_DTLB_4_KBYTE_4WAY_64E 0x03
|
||||
#define CPUID_CACHE_TLB_DESC_DTLB_4_MBYTE_4WAY_8E 0x04
|
||||
#define CPUID_CACHE_TLB_DESC_DTLB1_4_MBYTE_4WAY_32E 0x05
|
||||
#define CPUID_CACHE_TLB_DESC_L1_INST_8K_4WAY_32B 0x06
|
||||
#define CPUID_CACHE_TLB_DESC_L1_INST_16K_4WAY_32B 0x08
|
||||
#define CPUID_CACHE_TLB_DESC_L1_INST_32K_4WAY_64B 0x09
|
||||
#define CPUID_CACHE_TLB_DESC_L1_DATA_8K_2WAY_32B 0x0A
|
||||
#define CPUID_CACHE_TLB_DESC_TLB_4_MBYTE_4WAY_4E 0x0B
|
||||
#define CPUID_CACHE_TLB_DESC_L1_DATA_16K_4WAY_32B 0x0C
|
||||
#define CPUID_CACHE_TLB_DESC_L1_DATA_16K_4WAY_64B 0x0D
|
||||
#define CPUID_CACHE_TLB_DESC_L1_DATA_24K_6WAY_64B 0x0E
|
||||
#define CPUID_CACHE_TLB_DESC_L2_128K_2WAY_64B 0x1D
|
||||
#define CPUID_CACHE_TLB_DESC_L2_256K_8WAY_64B 0x21
|
||||
#define CPUID_CACHE_TLB_DESC_L3_512K_4WAY_64B_2LPS 0x22
|
||||
#define CPUID_CACHE_TLB_DESC_L3_1M_8WAY_64B_2LPS 0x23
|
||||
#define CPUID_CACHE_TLB_DESC_L2_1M_16WAY_64B 0x24
|
||||
#define CPUID_CACHE_TLB_DESC_L3_2M_8WAY_64B_2LPS 0x25
|
||||
#define CPUID_CACHE_TLB_DESC_L3_4M_8WAY_64B_2LPS 0x29
|
||||
#define CPUID_CACHE_TLB_DESC_L1_DATA_32K_8WAY_64B 0x2C
|
||||
#define CPUID_CACHE_TLB_DESC_L1_INST_32K_8WAY_64B 0x30
|
||||
#define CPUID_CACHE_TLB_DESC_NO_L2_OR_L3 0x40
|
||||
#define CPUID_CACHE_TLB_DESC_L2_128K_4WAY_32B 0x41
|
||||
#define CPUID_CACHE_TLB_DESC_L2_256K_4WAY_32B 0x42
|
||||
#define CPUID_CACHE_TLB_DESC_L2_512K_4WAY_32B 0x43
|
||||
#define CPUID_CACHE_TLB_DESC_L2_1M_4WAY_32B 0x44
|
||||
#define CPUID_CACHE_TLB_DESC_L2_2M_4WAY_32B 0x45
|
||||
#define CPUID_CACHE_TLB_DESC_L3_4M_4WAY_64B 0x46
|
||||
#define CPUID_CACHE_TLB_DESC_L3_8M_8WAY_64B 0x47
|
||||
#define CPUID_CACHE_TLB_DESC_L2_3M_12WAY_64B 0x48
|
||||
#define CPUID_CACHE_TLB_DESC_L3_4M_16WAY_64B 0x49
|
||||
#define CPUID_CACHE_TLB_DESC_L3_6M_12WAY_64B 0x4A
|
||||
#define CPUID_CACHE_TLB_DESC_L3_8M_16WAY_64B 0x4B
|
||||
#define CPUID_CACHE_TLB_DESC_L3_12M_12WAY_64B 0x4C
|
||||
#define CPUID_CACHE_TLB_DESC_L3_16M_16WAY_64B 0x4D
|
||||
#define CPUID_CACHE_TLB_DESC_L2_6M_24WAY_64B 0x4E
|
||||
#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_32E 0x4F
|
||||
#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_2M_4M_64E 0x50
|
||||
#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_2M_4M_128E 0x51
|
||||
#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_2M_4M_256E 0x52
|
||||
#define CPUID_CACHE_TLB_DESC_TLB_INST_2M_4M_FULLY_7E 0x55
|
||||
#define CPUID_CACHE_TLB_DESC_DTLB0_4M_4WAY_16E 0x56
|
||||
#define CPUID_CACHE_TLB_DESC_DTLB0_4K_4WAY_16E 0x57
|
||||
#define CPUID_CACHE_TLB_DESC_DTLB0_4K_FULLY_16E 0x59
|
||||
#define CPUID_CACHE_TLB_DESC_DTLB0_2M_4M_4WAY_32E 0x5A
|
||||
#define CPUID_CACHE_TLB_DESC_DTLB_4K_4M_64E 0x5B
|
||||
#define CPUID_CACHE_TLB_DESC_DTLB_4K_4M_128E 0x5C
|
||||
#define CPUID_CACHE_TLB_DESC_DTLB_4K_4M_256E 0x5D
|
||||
#define CPUID_CACHE_TLB_DESC_L1_DATA_16K_8WAY_64B 0x60
|
||||
#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_FULLY_48E 0x61
|
||||
#define CPUID_CACHE_TLB_DESC_DTLB_2M_4M_32E_1G_4WAY_4E 0x63
|
||||
#define CPUID_CACHE_TLB_DESC_DTLB_4K_4WAY_512E 0x64
|
||||
#define CPUID_CACHE_TLB_DESC_L1_DATA_8K_4WAY_64B 0x66
|
||||
#define CPUID_CACHE_TLB_DESC_L1_DATA_16K_4WAY_64B_DUPLICATE 0x67 //????????????
|
||||
#define CPUID_CACHE_TLB_DESC_L1_DATA_32K_4WAY_64B 0x68
|
||||
#define CPUID_CACHE_TLB_DESC_UTLB_4K_8WAY_64E 0x6A
|
||||
#define CPUID_CACHE_TLB_DESC_DTLB_4K_8WAY_256E 0x6B
|
||||
#define CPUID_CACHE_TLB_DESC_DTLB_2M_4M_8WAY_128E 0x6C
|
||||
#define CPUID_CACHE_TLB_DESC_DTLB_1G_FULLY_16E 0x6D
|
||||
#define CPUID_CACHE_TLB_DESC_TRACE_12K_8WAY 0x70
|
||||
#define CPUID_CACHE_TLB_DESC_TRACE_16K_8WAY 0x71
|
||||
#define CPUID_CACHE_TLB_DESC_TRACE_32K_8WAY 0x72
|
||||
#define CPUID_CACHE_TLB_DESC_TLB_INST_2M_4M_FULLY_8E 0x76
|
||||
#define CPUID_CACHE_TLB_DESC_L2_1M_4WAY_64B 0x78
|
||||
#define CPUID_CACHE_TLB_DESC_L2_128K_8WAY_64B_2LPS 0x79
|
||||
#define CPUID_CACHE_TLB_DESC_L2_256K_8WAY_64B_2LPS 0x7A
|
||||
#define CPUID_CACHE_TLB_DESC_L2_512K_8WAY_64B_2LPS 0x7B
|
||||
#define CPUID_CACHE_TLB_DESC_L2_1M_8WAY_64B_2LPS 0x7C
|
||||
#define CPUID_CACHE_TLB_DESC_L2_2M_8WAY_64B 0x7D
|
||||
#define CPUID_CACHE_TLB_DESC_L2_512K_2WAY_64B 0x7F
|
||||
#define CPUID_CACHE_TLB_DESC_L2_512K_8WAY_64B 0x80
|
||||
#define CPUID_CACHE_TLB_DESC_L2_256K_8WAY_32B 0x82
|
||||
#define CPUID_CACHE_TLB_DESC_L2_512K_8WAY_32B 0x83
|
||||
#define CPUID_CACHE_TLB_DESC_L2_1M_8WAY_32B 0x84
|
||||
#define CPUID_CACHE_TLB_DESC_L2_2M_8WAY_32B 0x85
|
||||
#define CPUID_CACHE_TLB_DESC_L2_512K_4WAY_64B 0x86
|
||||
#define CPUID_CACHE_TLB_DESC_L2_1M_8WAY_64B 0x87
|
||||
#define CPUID_CACHE_TLB_DESC_DTLB_4K_FULLY_ASSOC_32E 0xA0
|
||||
#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_4WAY_128E 0xB0
|
||||
#define CPUID_CACHE_TLB_DESC_TLB_INST_2M_4WAY_8E_4M_4WAY_4E 0xB1
|
||||
#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_4WAY_64E 0xB2
|
||||
#define CPUID_CACHE_TLB_DESC_TLB_DATA_4K_4WAY_128E 0xB3
|
||||
#define CPUID_CACHE_TLB_DESC_TLB_DATA_4K_4WAY_256E 0xB4
|
||||
#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_8WAY_64E 0xB5
|
||||
#define CPUID_CACHE_TLB_DESC_TLB_INST_4K_8WAY_128E 0xB6
|
||||
#define CPUID_CACHE_TLB_DESC_TLB_DATA_4K_4WAY_64E 0xBA
|
||||
#define CPUID_CACHE_TLB_DESC_TLB_DATA_4K_4M_4WAY_8E 0xC0
|
||||
#define CPUID_CACHE_TLB_DESC_STLB_2ND_LEVEL_4K_2M_8WAY_1024E 0xC1
|
||||
#define CPUID_CACHE_TLB_DESC_DTLB_4K_2M_4WAY_16E 0xC2
|
||||
#define CPUID_CACHE_TLB_DESC_STLB_2ND_LEVEL_4K_2M_6WAY_1536E_1GB_4WAY_16E 0xC3
|
||||
#define CPUID_CACHE_TLB_DESC_DTLB_2M_4M_4WAY_32E 0xC4
|
||||
#define CPUID_CACHE_TLB_DESC_STLB_2ND_LEVEL_4K_4WAY_512E 0xCA
|
||||
#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_512KB_4WAY_64B_LINE 0xD0
|
||||
#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_1MB_4WAY_64B_LINE 0xD1
|
||||
#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_2MB_4WAY_64B_LINE 0xD2
|
||||
#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_1MB_8WAY_64B_LINE 0xD6
|
||||
#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_2MB_8WAY_64B_LINE 0xD7
|
||||
#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_4MB_8WAY_64B_LINE 0xD8
|
||||
#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_1_5MB_12WAY_64B_LINE 0xDC
|
||||
#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_3MB_12WAY_64B_LINE 0xDD
|
||||
#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_6MB_12WAY_64B_LINE 0xDE
|
||||
#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_2MB_16WAY_64B_LINE 0xE2
|
||||
#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_4MB_16WAY_64B_LINE 0xE3
|
||||
#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_8MB_16WAY_64B_LINE 0xE4
|
||||
#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_12MB_24WAY_64B_LINE 0xEA
|
||||
#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_18MB_24WAY_64B_LINE 0xEB
|
||||
#define CPUID_CACHE_TLB_DESC_CACHE_3RD_LEVEL_24MB_24WAY_64B_LINE 0xEC
|
||||
#define CPUID_CACHE_TLB_DESC_PREFETCH_64_BYTE 0xF0
|
||||
#define CPUID_CACHE_TLB_DESC_PREFETCH_128_BYTE 0xF1
|
||||
#define CPUID_CACHE_TLB_DESC_NO_TLB_INFO_CPUID_LEAF_18H 0xFE
|
||||
#define CPUID_CACHE_TLB_DESC_NO_CACHE_INFO_CPUID_LEAF_4 0xFF
|
||||
|
||||
//=============CPUID_SERIAL_NUMBER=============
|
||||
#define CPUID_SERIAL_NUMBER_STITCH(ECX,EDX) (uint64_t)((EDX << 32) | ECX)
|
||||
|
||||
//=============CPUID_CACHE_PARAMS==============
|
||||
#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE 0xF
|
||||
#define CPUID_CACHE_PARAMS_EAX_CACHE_LEVEL 0x7 << 4
|
||||
#define CPUID_CACHE_PARAMS_EAX_IS_SELF_INIT 1 << 8
|
||||
#define CPUID_CACHE_PARAMS_EAX_IS_FULLY_ASSOCIATIVE 1 << 9
|
||||
// bits 10-13 are reserved
|
||||
#define CPUID_CACHE_PARAMS_EAX_MAX_PROC_SHARING 0xFFF << 14
|
||||
|
||||
#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE_NULL 0x0
|
||||
#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE_DATA 0x1
|
||||
#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE_INSTRUCTION 0x2
|
||||
#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE_UNIFIED 0x3
|
||||
|
||||
#define CPUID_CACHE_PARAMS_EBX_COHERENCY_LINE_SIZE 0xFFF
|
||||
#define CPUID_CACHE_PARAMS_EBX_PHYS_LINE_PARTITIONS 0x3FF << 12
|
||||
#define CPUID_CACHE_PARAMS_EBX_WAYS_OF_ASSOCIVITY 0x3FF
|
||||
|
||||
#define CPUID_CACHE_PARAMS_EDX_CACHE_INCLUSIVENESS 1
|
||||
#define CPUID_CACHE_PARAMS_EDX_COMPLEX_CACHE_INDEXING 1 << 1
|
||||
|
||||
//=============CPUID_MONITOR_MWAIT=============
|
||||
#define CPUID_MONITOR_MWAIT_ECX_ENUM_EXTENSIONS 1
|
||||
#define CPUID_MONITOR_MWAIT_ECX_BREAK_EVENTS 1 << 1
|
||||
|
||||
#define CPUID_MONITOR_MWAIT_EDX_C0_SUBC_STATES 0xF
|
||||
#define CPUID_MONITOR_MWAIT_EDX_C1_SUBC_STATES 0xF << 4
|
||||
#define CPUID_MONITOR_MWAIT_EDX_C2_SUBC_STATES 0xF << 8
|
||||
#define CPUID_MONITOR_MWAIT_EDX_C3_SUBC_STATES 0xF << 12
|
||||
#define CPUID_MONITOR_MWAIT_EDX_C4_SUBC_STATES 0xF << 16
|
||||
#define CPUID_MONITOR_MWAIT_EDX_C5_SUBC_STATES 0xF << 20
|
||||
#define CPUID_MONITOR_MWAIT_EDX_C6_SUBC_STATES 0xF << 24
|
||||
#define CPUID_MONITOR_MWAIT_EDX_C7_SUBC_STATES 0xF << 28
|
||||
|
||||
//===========CPUID_THERMAL_AND_POWER===========
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_TEMP_SENSOR 1
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_TURBO_BOOST 1 << 1
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_ARAT 1 << 2
|
||||
//Bit 3 is reserved
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_PLN 1 << 3
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_ECMD 1 << 5
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_PTM 1 << 6
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_HWP 1 << 7
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_HWP_NOTIFICATION 1 << 8
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_HWP_ACT_WINDOW 1 << 9
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_HWP_PERF_PREF 1 << 10
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_HWP_PKG_LVL_REQ 1 << 11
|
||||
//Bit 12 is reserved
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_HDC 1 << 13
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_TURBO_BOOST_MAX 1 << 14
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_HWP_CAPABILITIES 1 << 15
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_HWP_PECI 1 << 16
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_FLEXIBLE_HWP 1 << 17
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_FAST_HWP_REQUEST 1 << 18
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_HW_FEEDBACK 1 << 19
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_IGNORE_HWP_IDLE 1 << 20
|
||||
//Bits 21 and 22 are reserved
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_THREAD_DIRECTOR 1 << 23
|
||||
#define CPUID_THERMAL_AND_POWER_EAX_THERM_INTERRUPT 1 << 24
|
||||
|
||||
#define CPUID_THERMAL_AND_POWER_EBX_INT_TRESHOLD 0xf
|
||||
|
||||
#define CPUID_THERMAL_AND_POWER_ECX_HW_COORD_FEEDBACK 1
|
||||
#define CPUID_THERMAL_AND_POWER_ECX_ENERGY_PERF_BIAS 1 << 3
|
||||
#define CPUID_THERMAL_AND_POWER_ECX_TD_CLASSES 0xff << 8
|
||||
|
||||
#define CPUID_THERMAL_AND_POWER_EDX_PERF_REPORT 1
|
||||
#define CPUID_THERMAL_AND_POWER_EDX_EFFICIENCY_REPORT 1 << 1
|
||||
#define CPUID_THERMAL_AND_POWER_EDX_HW_FEEDBACK_SIZE 0xf << 8
|
||||
#define CPUID_THERMAL_AND_POWER_EDX_THIS_PROC_HW_FB 0xffff << 16
|
||||
|
||||
//===========CPUID_EXTENDED_FEATURES===========
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_FSGSBASE 1
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_TSC_ADJUST 1 << 1
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_SGX 1 << 2
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_BMI1 1 << 3
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_HLE 1 << 4
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_AVX2 1 << 5
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_FDP_EXCPTN_ONLY 1 << 6
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_SMEP 1 << 7
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_BMI2 1 << 8
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_ENHANCED_REP 1 << 9
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_INVCIP 1 << 10
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_RTM 1 << 11
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_RDT_M 1 << 12
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_NO_FPU_CS 1 << 13
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_MPX 1 << 14
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_RDT_A 1 << 15
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_AVX512F 1 << 16
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_AVX512DQ 1 << 17
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_RDSEED 1 << 18
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_ADX 1 << 19
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_SMAP 1 << 20
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_AVX512_IFMA 1 << 21
|
||||
// Bit 22 is reserved
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_CLFLUSHOPT 1 << 23
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_CLWB 1 << 24
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_TRACE 1 << 25
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_AVX512PF 1 << 26
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_AVX512ER 1 << 27
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_AVX512CD 1 << 28
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_SHA 1 << 29
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_AVX512BW 1 << 30
|
||||
#define CPUID_EXTENDED_FEATURES_EBX_AVX512VL 1 << 31
|
||||
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_PREFETCHWT1 1
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_AFX512_VBMI 1 << 1
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_UMIP 1 << 2
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_PKU 1 << 3
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_OSPKE 1 << 4
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_WAITPKG 1 << 5
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_AVX512_VBMI2 1 << 6
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_CET_SS 1 << 7
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_GFNI 1 << 8
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_VAES 1 << 9
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_VPCLMULQDQ 1 << 10
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_AVX512_VNNI 1 << 11
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_AVX512_BITLANG 1 << 12
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_TME_EN 1 << 13
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_AVX512_VPOPVNZDQ 1 << 14
|
||||
//bit 15 is reserved
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_LA57 1 << 16
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_MAWAU_VAL 0x1F << 17
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_RDPID 1 << 22
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_KL 1 << 23
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_BUS_LOCK_DETECT 1 << 24
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_CLDEMOTE 1 << 25
|
||||
//bit 26 is reserved
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_MOVDIRI 1 << 27
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_MOVDIR64B 1 << 28
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_ENQCMD 1 << 29
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_SGX_LC 1 << 30
|
||||
#define CPUID_EXTENDED_FEATURES_ECX_PKS 1 << 31
|
||||
|
||||
//bit 0 is reserved
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_SGX_KEYS 1 << 1
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_AVX512_4VNNIW 1 << 2
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_AVX512_4FMAPS 1 << 3
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_FAST_REP_MOV 1 << 4
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_UINTR 1 << 5
|
||||
//bits 6 and 7 are reserved
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_AVX512_VPINTERSECT 1 << 8 // intel you son of a bitch
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_SRBDS_CTRL 1 << 9
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_MD_CLEAR 1 << 10
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_RTM_ALWAYS_ABORT 1 << 11
|
||||
//bit 12 is reserved
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_RTM_FORCE_ABORT 1 << 13
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_SERIALIZE 1 << 14
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_HYBRID 1 << 15
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_TSXLDTRK 1 << 16
|
||||
//bit 17 is reserved
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_PCONFIG 1 << 18
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_ARCHITECTURAL_LBR 1 << 19
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_CET_IBT 1 << 20
|
||||
//bit 21 is reserved
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_AMX_BF16 1 << 22
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_AVX512_FP16 1 << 23
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_AMX_TILE 1 << 24
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_AMX_INT8 1 << 25
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_IBRS 1 << 26
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_STIBP 1 << 27
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_L1D_FLUSH 1 << 28
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_ARCH_CAPABS_MSR 1 << 29
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_CORE_CAPABS_MSR 1 << 30
|
||||
#define CPUID_EXTENDED_FEATURES_EDX_SSBD 1 << 31
|
||||
|
||||
//=========CPUID_EXTENDED_FEATURES_SL1=========
|
||||
//bits 0-3 are reserved
|
||||
#define CPUID_EXTENDED_FEATURES_SL1_EAX_AVX_VNNI 1 << 4
|
||||
#define CPUID_EXTENDED_FEATURES_SL1_EAX_AVX512_BF16 1 << 5
|
||||
//bits 6-9 are reserved
|
||||
#define CPUID_EXTENDED_FEATURES_SL1_EAX_0_REP_MOVSB 1 << 10
|
||||
#define CPUID_EXTENDED_FEATURES_SL1_EAX_FAST_STOSB 1 << 11
|
||||
#define CPUID_EXTENDED_FEATURES_SL1_EAX_FAST_CMPSB 1 << 12
|
||||
//bits 13-21 are reserved
|
||||
#define CPUID_EXTENDED_FEATURES_SL1_EAX_HRESET 1 << 22
|
||||
//bits 23-19 are reserved
|
||||
#define CPUID_EXTENDED_FEATURES_SL1_EAX_INVD_POSTPOST 1 << 30
|
||||
//bit 31 is reserved
|
||||
|
||||
#define CPUID_EXTENDED_FEATURES_SL1_EBX_PPIN 1
|
||||
|
||||
#define CPUID_EXTENDED_FEATURES_SL1_EDX_CET_SSS 1 << 18
|
||||
|
||||
//=========CPUID_EXTENDED_FEATURES_SL2=========
|
||||
#define CPUID_EXTENDED_FEATURES_SL2_EDX_PSFD 1
|
||||
#define CPUID_EXTENDED_FEATURES_SL2_EDX_IPRED_CTRL 1 << 1
|
||||
#define CPUID_EXTENDED_FEATURES_SL2_EDX_RRSBA_CTRL 1 << 2
|
||||
#define CPUID_EXTENDED_FEATURES_SL2_EDX_DDPD_U 1 << 3
|
||||
#define CPUID_EXTENDED_FEATURES_SL2_EDX_BHI_CTRL 1 << 4
|
||||
//The rest of the bits are reserved
|
||||
|
||||
|
||||
enum leaves {
|
||||
/* @ Basic CPU info
|
||||
* @ Returned EAX: Highest basic CPUID leaf present
|
||||
* @ Returned EBX: First 4 letters of the vendor identifier string
|
||||
* @ Returned ECX: Third 4 letters of the vendor identifier string
|
||||
* @ Retruned EDX: Second 4 letters of the vendor identifier string
|
||||
*/
|
||||
CPUID_VENDOR = 0x00000000,
|
||||
/* @ CPU Version information
|
||||
* @ Returned EAX: Family,Model,Stepping
|
||||
* @ Returned EBX: Brand Index,CLFLUSH line size, Max number of logical processors
|
||||
* @ Returned ECX: Featrue information
|
||||
* @ Retruned EDX: More feature information
|
||||
*/
|
||||
CPUID_CPU_INFO = 0x00000001,
|
||||
/* @ CPU Cache and TLB information
|
||||
* @ Returned EAX: 4 Cache, prefetch or TLB descriptors
|
||||
* @ Returned EBX: 4 Cache, prefetch or TLB descriptors
|
||||
* @ Returned ECX: 4 Cache, prefetch or TLB descriptors
|
||||
* @ Retruned EDX: 4 Cache, prefetch or TLB descriptors
|
||||
*/
|
||||
CPUID_CACHE_TLB = 0x00000002,
|
||||
/* @ CPU Serial Number !!! PENTIUM 3 ONLY !!!
|
||||
* @ Returned EAX: Reserved
|
||||
* @ Returned EBX: Reserved
|
||||
* @ Returned ECX: bits 0-31 of the serial number
|
||||
* @ Retruned EDX: bits 32-63 of the serial number
|
||||
*/
|
||||
CPUID_SERIAL_NUMBER = 0x00000003,
|
||||
/* @ CPU Deterministic cache parameters !!! Initial ECX = Cache level !!!
|
||||
* @ Returned EAX: Cache level,Is self init,Is fully associative,Maximum number of addressable IDs for logical processors sharing this cache
|
||||
* @ Returned EBX: L, P and W
|
||||
* @ Returned ECX: S
|
||||
* @ Retruned EDX: Cache inclusiveness and Complex Cache indexing
|
||||
*/
|
||||
CPUID_CACHE_PARAMS = 0x00000004,
|
||||
/* @ MONITOR/MWAIT params
|
||||
* @ Returned EAX: Smallest monitor-line size
|
||||
* @ Returned EBX: Largest monitor-line size
|
||||
* @ Returned ECX: Enumeration of Monitor-Mwait extensions,Supports treating interrupts as break-event for MWAIT
|
||||
* @ Retruned EDX: Number of sub C-states supported using MWAIT for each C number thingy IDK
|
||||
*/
|
||||
CPUID_MONITOR_MWAIT = 0x00000005,
|
||||
/* @ Thermal and power managment
|
||||
* @ Returned EAX: Thermal and power info
|
||||
* @ Returned EBX: Thermal and power info
|
||||
* @ Returned ECX: Thermal and power info
|
||||
* @ Retruned EDX: Thermal and power info
|
||||
*/
|
||||
CPUID_THERMAL_AND_POWER = 0x00000006,
|
||||
/* @ Extended features
|
||||
* @ Returned EAX: Number of subleaves supported
|
||||
* @ Returned EBX: Features
|
||||
* @ Returned ECX: Features
|
||||
* @ Retruned EDX: Features
|
||||
*/
|
||||
CPUID_EXTENDED_FEATURES = 0x00000007,
|
||||
/* @ Direct Cache Access Information
|
||||
* @ Returned EAX: Value of the MSR "IA32_PLATFORM_DCA_CAP"
|
||||
* @ Returned EBX: Reserved
|
||||
* @ Returned ECX: Reserved
|
||||
* @ Retruned EDX: Reserved
|
||||
*/
|
||||
CPUID_CACHE_ACCESS_INFO = 0x00000009,
|
||||
CPUID_PERFORMANCE_MONITORING = 0x0000000A,
|
||||
CPUID_EXTENDENDED_TOPOLOGY = 0x0000000B,
|
||||
CPUID_EXTENDENDED_TOPOLOGY2 = 0x0000000D,
|
||||
CPUID_INTEL_RDT = 0x0000000F,
|
||||
CPUID_INTEL_RDT2 = 0x00000010,
|
||||
CPUID_INTEL_SGX = 0x00000012,
|
||||
CPUID_CPU_TRACE_ENUM = 0x00000014,
|
||||
CPUID_TSC = 0x00000015,
|
||||
CPUID_CPU_FREQ_INFO = 0x00000016,
|
||||
CPUID_SOC_VENDOR = 0x00000017,
|
||||
CPUID_DETERMINISTIC_ADRESS_TRANSLATION_PARAMS = 0x00000018,
|
||||
CPUID_KEY_LOCKER = 0x000000019,
|
||||
CPUID_NATIVE_MODEL_ID = 0x0000001A,
|
||||
CPUID_PCONFIG_INFO = 0x0000001B,
|
||||
CPUID_LAST_BRACH = 0x00000001C,
|
||||
CPUID_TILE_INFO = 0x00000001D,
|
||||
CPUID_TMUL_INFO = 0x00000001E,
|
||||
CPUID_V2_EXTENDED_TOPOLOGY = 0x00000001F,
|
||||
CPUID_V2_EXTENDED_TOPOLOGY2 = 0x000000020,
|
||||
//TODO: add the bitmasks for these Microsoft ones
|
||||
/* @ Hypervisor CPUID Leaf Range
|
||||
* @ Returned EAX: Highest hypervisor CPUID leaf present
|
||||
* @ Returned EBX: Largest monitor-line size
|
||||
* @ Returned ECX: Enumeration of Monitor-Mwait extensions,Supports treating interrupts as break-event for MWAIT
|
||||
* @ Retruned EDX: Number of sub C-states supported using MWAIT for each C number thingy IDK
|
||||
*/
|
||||
CPUID_HYPERV_IDENT = 0x40000000,
|
||||
/* @ Hypervisor Vendor-Neutral Interface Identification
|
||||
* @ Returned EAX: Hypervisor interface signature
|
||||
* @ Returned EBX: Reserved
|
||||
* @ Returned ECX: Reserved
|
||||
* @ Retruned EDX: Reserved
|
||||
*/
|
||||
CPUID_MS_HYPERV_INTERFCE_IDENT = 0x40000001,
|
||||
/* @ Hypervisor System Identity
|
||||
* @ Returned EAX: Build number
|
||||
* @ Returned EBX: Major and minor version
|
||||
* @ Returned ECX: Reserved
|
||||
* @ Retruned EDX: Reserved
|
||||
*/
|
||||
CPUID_MS_HYPERV_SYSTEM_IDENT = 0x40000002,
|
||||
/* @ Hypervisor Feature Identification
|
||||
* @ Returned EAX: bits 0-31 of HV_PARTITION_PRIVILEGE_MASK
|
||||
* @ Returned EBX: bits 31-63 of HV_PARTITION_PRIVILEGE_MASK
|
||||
* @ Returned ECX: Hyper-V features
|
||||
* @ Retruned EDX: Hyper-V features
|
||||
*/
|
||||
CPUID_MS_HYPERV_FEATURE_IDENT = 0x40000003,
|
||||
/* @ Implementation Recommendations
|
||||
* @ Returned EAX: Hyper-V feature recommendations
|
||||
* @ Returned EBX: Hyper-V feature recommendations
|
||||
* @ Returned ECX: Hyper-V feature recommendations
|
||||
* @ Retruned EDX: Reserved
|
||||
*/
|
||||
CPUID_MS_HYPERV_RECOMMENDATIONS = 0x40000004,
|
||||
/* @ Hypervisor Implementation Limits
|
||||
* @ Returned EAX: The maximum number of virtual processors supported
|
||||
* @ Returned EBX: The maximum number of logical processors supported
|
||||
* @ Returned ECX: The maximum number of physical interrupt vectors available for interrupt remapping.
|
||||
* @ Retruned EDX: Reserved
|
||||
*/
|
||||
CPUID_MS_HYPERV_IMPL_LIMITS = 0x40000005,
|
||||
/* @ Implementation Hardware Features
|
||||
* @ Returned EAX: Hardware features
|
||||
* @ Returned EBX: Reserved
|
||||
* @ Returned ECX: Reserved
|
||||
* @ Retruned EDX: Reserved
|
||||
*/
|
||||
CPUID_MS_HYPERV_HARDWARE_FEATURES = 0x40000006,
|
||||
/* @ Nested Hypervisor Feature Identification
|
||||
* @ Returned EAX: Nested Hypervisor features
|
||||
* @ Returned EBX: Reserved
|
||||
* @ Returned ECX: Reserved
|
||||
* @ Retruned EDX: Nested Hypervisor features
|
||||
*/
|
||||
CPUID_MS_HYPERV_NESTED_FEATURES = 0x40000009,
|
||||
/* @ Nested Hypervisor Nested Virtualization Features
|
||||
* @ Returned EAX: Nested Hypervisor features
|
||||
* @ Returned EBX: Nested Hypervisor features
|
||||
* @ Returned ECX: Reserved
|
||||
* @ Retruned EDX: Reserved
|
||||
*/
|
||||
CPUID_MS_HYPERV_NESTED_OPTIMISATIONS = 0x4000000A,
|
||||
/* @ Extended processor signature
|
||||
* @ Returned EAX: Reserved
|
||||
* @ Returned EBX: Reserved
|
||||
* @ Returned ECX: Extended feature bits
|
||||
* @ Retruned EDX: Extended feature bits
|
||||
*/
|
||||
CPUID_EXTENDED_SIGNATURE = 0x800000001,
|
||||
/* @ Full CPU name
|
||||
* @ Returned EAX: First 4 characters of the full CPU name
|
||||
* @ Returned EBX: Second 4 characters of the full CPU name
|
||||
* @ Returned ECX: Third 4 characters of the full CPU name
|
||||
* @ Retruned EDX: Fourth 4 characters of the full CPU name
|
||||
*/
|
||||
CPUID_BRAND_STRING1 = 0x800000002,
|
||||
/* @ Full CPU name 2
|
||||
* @ Returned EAX: Fifth 4 characters of the full CPU name
|
||||
* @ Returned EBX: Sexth 4 characters of the full CPU name
|
||||
* @ Returned ECX: Seventh 4 characters of the full CPU name
|
||||
* @ Retruned EDX: Eightth 4 characters of the full CPU name
|
||||
*/
|
||||
CPUID_BRAND_STRING2 = 0x800000003,
|
||||
/* @ Full CPU name 3
|
||||
* @ Returned EAX: Nineth 4 characters of the full CPU name
|
||||
* @ Returned EBX: Tenth 4 characters of the full CPU name
|
||||
* @ Returned ECX: Eleventh 4 characters of the full CPU name
|
||||
* @ Retruned EDX: Twelveth 4 characters of the full CPU name
|
||||
*/
|
||||
CPUID_BRAND_STRING3 = 0x800000004,
|
||||
/* @ Cache line size and associativity
|
||||
* @ Returned EAX: Reserved
|
||||
* @ Returned EBX: Reserved
|
||||
* @ Returned ECX: Bits 0-7 = Cache line size in bytes, Bits 12-15 = L2 Associativity, Bits 16-31 = Cache size in 1K blocks
|
||||
* @ Retruned EDX: Reserved
|
||||
*/
|
||||
CPUID_MORE_CACHE = 0x800000006,
|
||||
/* @ Invariant TSC available
|
||||
* @ Returned EAX: Reserved
|
||||
* @ Returned EBX: Reserved
|
||||
* @ Returned ECX: Bit 8 = Invariant TSC available
|
||||
* @ Retruned EDX: Reserved
|
||||
*/
|
||||
CPUID_INVARIANT_TSC_AVAILABLE = 0x800000007,
|
||||
/* @ Physical adress size
|
||||
* @ Returned EAX: Bits 0-7 = Physical Adress bits, Bits 8-15 = Linear Address bits
|
||||
* @ Returned EBX: Bit 9 = WBNOINVD available
|
||||
* @ Returned ECX: Reserved
|
||||
* @ Retruned EDX: Reserved
|
||||
*/
|
||||
CPUID_PHYS_ADDR_SIZE = 0x800000008,
|
||||
};
|
||||
|
||||
enum sub_leaves{
|
||||
/* @ Extended features available subleaf 1 !!! All fields return 0 is info not available !!!
|
||||
* @ Returned EAX: Features
|
||||
* @ Returned EBX: PPIN
|
||||
* @ Returned ECX: Reserved
|
||||
* @ Retruned EDX: CET_SSS
|
||||
*/
|
||||
CPUID_EXTENDED_FEATURES_SL1 = 0x00000001,
|
||||
/* @ Extended features available subleaf 2 !!! All fields return 0 is info not available !!!
|
||||
* @ Returned EAX: Reserved
|
||||
* @ Returned EBX: Reserved
|
||||
* @ Returned ECX: Reserved
|
||||
* @ Retruned EDX: Features
|
||||
*/
|
||||
CPUID_EXTENDED_FEATURES_SL2 = 0x00000002,
|
||||
CPUID_INTEL_RDT_CAPABILITY = 0x00000001,
|
||||
CPUID_INTEL_RDT2_ALLOCATION = 0x00000000,
|
||||
CPUID_INTEL_RDT2_RESID1 = 0x00000001,
|
||||
CPUID_INTEL_RDT2_RESID2 = 0x00000002,
|
||||
CPUID_INTEL_RDT2_RESID3 = 0x00000003,
|
||||
CPUID_INTEL_SGX_SL1 = 0x00000001,
|
||||
CPUID_INTEL_SGX_SL2 = 0x00000002,
|
||||
CPUID_CPU_TRACE_ENUM_SL = 0x00000001,
|
||||
CPUID_SOC_VENDOR_SL1 = 0x00000001,
|
||||
CPUID_SOC_VENDOR_SL2 = 0x00000002,
|
||||
CPUID_SOC_VENDOR_SL3 = 0x00000003,
|
||||
//NOTE: goes higher than 1
|
||||
CPUID_DETERMINISTIC_ADRESS_TRANSLATION_PARAMS_SL = 0x00000001,
|
||||
CPUID_TILE_INFO_PALETTE1 = 0x000000001,
|
||||
};
|
||||
|
||||
static inline void cpuid(int leaf, int subleaf, int* a, int* b, int* c, int* d) {
|
||||
__asm__ __volatile__ (
|
||||
"cpuid"
|
||||
: "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d)
|
||||
: "a" (leaf), "c" (subleaf)
|
||||
);
|
||||
}
|
||||
|
||||
#endif // __CPUID_H__
|
53
kernel/src/sys/arch/x86_64/gdt.c
Executable file
53
kernel/src/sys/arch/x86_64/gdt.c
Executable file
|
@ -0,0 +1,53 @@
|
|||
//#include "sys/log.h"
|
||||
#include <stdint.h>
|
||||
#include <sys/arch/x86_64/gdt.h>
|
||||
#include <sys/log.h>
|
||||
|
||||
gdt_table def_table = {
|
||||
{
|
||||
0x0000000000000000, // 0x00
|
||||
|
||||
0x00009a000000ffff, // 0x08 16 bit code
|
||||
0x000093000000ffff, // 0x10 16 bit data
|
||||
|
||||
0x00cf9a000000ffff, // 0x18 32 bit code
|
||||
0x00cf93000000ffff, // 0x20 32 bit data
|
||||
|
||||
0x00af9b000000ffff, // 0x28 64 bit code cs
|
||||
0x00af93000000ffff, // 0x30 64 bit data ss
|
||||
|
||||
0x00aff3000000ffff, // 0x38 data ss
|
||||
0x00affb000000ffff, // 0x40 user mode code cs
|
||||
},
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
tssr tss_list[256]; // One tssr per CPU
|
||||
|
||||
void gdt_init() {
|
||||
|
||||
// TODO: adapt for multiprocessor kernel
|
||||
tss_list[0].iopb = sizeof(tssr);
|
||||
uintptr_t tss = (uintptr_t)&tss_list[0];
|
||||
|
||||
def_table.tss_entry.length = sizeof(tss_entry);
|
||||
def_table.tss_entry.base = (uint16_t)(tss & 0xffff);
|
||||
def_table.tss_entry.base1 = (uint8_t)((tss >> 16) & 0xff);
|
||||
def_table.tss_entry.flags = 0x89;
|
||||
def_table.tss_entry.flags1 = 0;
|
||||
def_table.tss_entry.base2 = (uint8_t)((tss >> 24) & 0xff);
|
||||
def_table.tss_entry.base3 = (uint32_t)(tss >> 32);
|
||||
def_table.tss_entry.resv = 0;
|
||||
|
||||
gdtr gdt = (gdtr){
|
||||
.size = (sizeof(gdt_table)) - 1,
|
||||
.address = (uint64_t)&def_table
|
||||
};
|
||||
|
||||
__asm__ volatile ("lgdt %0\n\t" : : "m"(gdt) : "memory");
|
||||
__asm__ volatile ("ltr %0\n\t" : : "r"((uint16_t)0x48));
|
||||
|
||||
//logln(progress, "kinit stage 1", "GDT initialized\n");
|
||||
log("gdt - initialized.\n");
|
||||
}
|
37
kernel/src/sys/arch/x86_64/gdt.h
Executable file
37
kernel/src/sys/arch/x86_64/gdt.h
Executable file
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint16_t length;
|
||||
uint16_t base;
|
||||
uint8_t base1;
|
||||
uint8_t flags;
|
||||
uint8_t flags1;
|
||||
uint8_t base2;
|
||||
uint32_t base3;
|
||||
uint32_t resv;
|
||||
} __attribute__((packed)) tss_entry;
|
||||
|
||||
typedef struct {
|
||||
uint64_t gdt_entries[9];
|
||||
tss_entry tss_entry;
|
||||
} __attribute__((packed)) gdt_table;
|
||||
|
||||
typedef struct {
|
||||
uint16_t size;
|
||||
uint64_t address;
|
||||
} __attribute__((packed)) gdtr;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t resv;
|
||||
uint64_t rsp[3];
|
||||
uint64_t resv1;
|
||||
uint64_t ist[7];
|
||||
uint64_t resv2;
|
||||
uint16_t resv3;
|
||||
uint16_t iopb;
|
||||
} __attribute__((packed)) tssr; // Per CPU
|
||||
|
||||
void gdt_init();
|
44
kernel/src/sys/arch/x86_64/idt.c
Executable file
44
kernel/src/sys/arch/x86_64/idt.c
Executable file
|
@ -0,0 +1,44 @@
|
|||
//#include "sys/log.h"
|
||||
#include "sys/arch/x86_64/pic.h"
|
||||
#include <sys/arch/x86_64/idt.h>
|
||||
#include <sys/log.h>
|
||||
|
||||
__attribute__((aligned(0x10)))
|
||||
static idt_entry_t idt[256];
|
||||
|
||||
static idtr_t idtr;
|
||||
|
||||
void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags) {
|
||||
idt_entry_t* descriptor = &idt[vector];
|
||||
|
||||
descriptor->isr_low = (uint64_t)isr & 0xFFFF;
|
||||
descriptor->kernel_cs = 0x28;
|
||||
descriptor->ist = 0;
|
||||
descriptor->attributes = flags;
|
||||
descriptor->isr_mid = ((uint64_t)isr >> 16) & 0xFFFF;
|
||||
descriptor->isr_high = ((uint64_t)isr >> 32) & 0xFFFFFFFF;
|
||||
descriptor->reserved = 0;
|
||||
}
|
||||
|
||||
static int vectors[256];
|
||||
|
||||
extern void* isr_stub_table[];
|
||||
|
||||
void idt_init() {
|
||||
idtr.base = (uintptr_t)&idt[0];
|
||||
idtr.limit = (uint16_t)sizeof(idt_entry_t) * 256 - 1;
|
||||
|
||||
for (uint16_t vector = 0; vector <= 256; vector++) {
|
||||
idt_set_descriptor(vector, isr_stub_table[vector], 0x8E);
|
||||
vectors[vector] = 1;
|
||||
}
|
||||
|
||||
pic_init();
|
||||
pic_unmask_irq(1);
|
||||
|
||||
__asm__ volatile ("lidt %0" : : "m"(idtr)); // load the new IDT
|
||||
__asm__ volatile ("sti"); // set the interrupt flag
|
||||
|
||||
//logln(progress, "kinit stage 1", "IDT initialized! Time to receive interrupts!\n");
|
||||
log("idt - initialized\n");
|
||||
}
|
51
kernel/src/sys/arch/x86_64/idt.h
Executable file
51
kernel/src/sys/arch/x86_64/idt.h
Executable file
|
@ -0,0 +1,51 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct {
|
||||
uint64_t r15;
|
||||
uint64_t r14;
|
||||
uint64_t r13;
|
||||
uint64_t r12;
|
||||
uint64_t r11;
|
||||
uint64_t r10;
|
||||
uint64_t r9;
|
||||
uint64_t r8;
|
||||
uint64_t rdi;
|
||||
uint64_t rsi;
|
||||
uint64_t rbp;
|
||||
uint64_t rbx;
|
||||
uint64_t rdx;
|
||||
uint64_t rcx;
|
||||
uint64_t rax;
|
||||
uint64_t int_no;
|
||||
uint64_t err_code;
|
||||
uint64_t rip;
|
||||
uint64_t cs;
|
||||
uint64_t rflags;
|
||||
uint64_t rsp;
|
||||
uint64_t ss;
|
||||
} __attribute__((packed)) registers_t;
|
||||
|
||||
typedef struct stackframe {
|
||||
struct stackframe* rbp;
|
||||
uint64_t rip;
|
||||
} stackframe_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t isr_low; // The lower 16 bits of the ISR's address
|
||||
uint16_t kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR
|
||||
uint8_t ist; // The IST in the TSS that the CPU will load into RSP; set to zero for now
|
||||
uint8_t attributes; // Type and attributes; see the IDT page
|
||||
uint16_t isr_mid; // The higher 16 bits of the lower 32 bits of the ISR's address
|
||||
uint32_t isr_high; // The higher 32 bits of the ISR's address
|
||||
uint32_t reserved; // Set to zero
|
||||
} __attribute__((packed)) idt_entry_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t limit;
|
||||
uint64_t base;
|
||||
} __attribute__((packed)) idtr_t;
|
||||
|
||||
void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags);
|
||||
void idt_init(void);
|
335
kernel/src/sys/arch/x86_64/interrupts.asm
Executable file
335
kernel/src/sys/arch/x86_64/interrupts.asm
Executable file
|
@ -0,0 +1,335 @@
|
|||
%macro pushall 0
|
||||
push rax
|
||||
push rcx
|
||||
push rdx
|
||||
push rbx
|
||||
push rbp
|
||||
push rsi
|
||||
push rdi
|
||||
push r8
|
||||
push r9
|
||||
push r10
|
||||
push r11
|
||||
push r12
|
||||
push r13
|
||||
push r14
|
||||
push r15
|
||||
%endmacro
|
||||
|
||||
%macro popall 0
|
||||
pop r15
|
||||
pop r14
|
||||
pop r13
|
||||
pop r12
|
||||
pop r11
|
||||
pop r10
|
||||
pop r9
|
||||
pop r8
|
||||
pop rdi
|
||||
pop rsi
|
||||
pop rbp
|
||||
pop rbx
|
||||
pop rdx
|
||||
pop rcx
|
||||
pop rax
|
||||
%endmacro
|
||||
|
||||
%macro isr_err_stub 1
|
||||
isr_stub_%+%1:
|
||||
|
||||
push %1
|
||||
pushall
|
||||
|
||||
mov rdi, rsp
|
||||
|
||||
call exception_handler
|
||||
|
||||
popall
|
||||
|
||||
add rsp, 16
|
||||
iretq
|
||||
%endmacro
|
||||
|
||||
%macro isr_no_err_stub 1
|
||||
isr_stub_%+%1:
|
||||
push 0
|
||||
push %1
|
||||
pushall
|
||||
|
||||
mov rdi, rsp
|
||||
|
||||
call exception_handler
|
||||
|
||||
popall
|
||||
|
||||
add rsp, 16
|
||||
iretq
|
||||
%endmacro
|
||||
|
||||
extern exception_handler
|
||||
isr_no_err_stub 0
|
||||
isr_no_err_stub 1
|
||||
isr_no_err_stub 2
|
||||
isr_no_err_stub 3
|
||||
isr_no_err_stub 4
|
||||
isr_no_err_stub 5
|
||||
isr_no_err_stub 6
|
||||
isr_no_err_stub 7
|
||||
isr_err_stub 8
|
||||
isr_no_err_stub 9
|
||||
isr_err_stub 10
|
||||
isr_err_stub 11
|
||||
isr_err_stub 12
|
||||
isr_err_stub 13
|
||||
isr_err_stub 14
|
||||
isr_no_err_stub 15
|
||||
isr_no_err_stub 16
|
||||
isr_err_stub 17
|
||||
isr_no_err_stub 18
|
||||
isr_no_err_stub 19
|
||||
isr_no_err_stub 20
|
||||
isr_no_err_stub 21
|
||||
isr_no_err_stub 22
|
||||
isr_no_err_stub 23
|
||||
isr_no_err_stub 24
|
||||
isr_no_err_stub 25
|
||||
isr_no_err_stub 26
|
||||
isr_no_err_stub 27
|
||||
isr_no_err_stub 28
|
||||
isr_no_err_stub 29
|
||||
isr_err_stub 30
|
||||
isr_no_err_stub 31
|
||||
|
||||
|
||||
isr_no_err_stub 32
|
||||
isr_no_err_stub 33
|
||||
isr_no_err_stub 34
|
||||
isr_no_err_stub 35
|
||||
isr_no_err_stub 36
|
||||
isr_no_err_stub 37
|
||||
isr_no_err_stub 38
|
||||
isr_no_err_stub 39
|
||||
isr_no_err_stub 40
|
||||
isr_no_err_stub 41
|
||||
isr_no_err_stub 42
|
||||
isr_no_err_stub 43
|
||||
isr_no_err_stub 44
|
||||
isr_no_err_stub 45
|
||||
isr_no_err_stub 46
|
||||
isr_no_err_stub 47
|
||||
isr_no_err_stub 48
|
||||
isr_no_err_stub 49
|
||||
isr_no_err_stub 50
|
||||
isr_no_err_stub 51
|
||||
isr_no_err_stub 52
|
||||
isr_no_err_stub 53
|
||||
isr_no_err_stub 54
|
||||
isr_no_err_stub 55
|
||||
isr_no_err_stub 56
|
||||
isr_no_err_stub 57
|
||||
isr_no_err_stub 58
|
||||
isr_no_err_stub 59
|
||||
isr_no_err_stub 60
|
||||
isr_no_err_stub 61
|
||||
isr_no_err_stub 62
|
||||
isr_no_err_stub 63
|
||||
isr_no_err_stub 64
|
||||
isr_no_err_stub 65
|
||||
isr_no_err_stub 66
|
||||
isr_no_err_stub 67
|
||||
isr_no_err_stub 68
|
||||
isr_no_err_stub 69
|
||||
isr_no_err_stub 70
|
||||
isr_no_err_stub 71
|
||||
isr_no_err_stub 72
|
||||
isr_no_err_stub 73
|
||||
isr_no_err_stub 74
|
||||
isr_no_err_stub 75
|
||||
isr_no_err_stub 76
|
||||
isr_no_err_stub 77
|
||||
isr_no_err_stub 78
|
||||
isr_no_err_stub 79
|
||||
isr_no_err_stub 80
|
||||
isr_no_err_stub 81
|
||||
isr_no_err_stub 82
|
||||
isr_no_err_stub 83
|
||||
isr_no_err_stub 84
|
||||
isr_no_err_stub 85
|
||||
isr_no_err_stub 86
|
||||
isr_no_err_stub 87
|
||||
isr_no_err_stub 88
|
||||
isr_no_err_stub 89
|
||||
isr_no_err_stub 90
|
||||
isr_no_err_stub 91
|
||||
isr_no_err_stub 92
|
||||
isr_no_err_stub 93
|
||||
isr_no_err_stub 94
|
||||
isr_no_err_stub 95
|
||||
isr_no_err_stub 96
|
||||
isr_no_err_stub 97
|
||||
isr_no_err_stub 98
|
||||
isr_no_err_stub 99
|
||||
isr_no_err_stub 100
|
||||
isr_no_err_stub 101
|
||||
isr_no_err_stub 102
|
||||
isr_no_err_stub 103
|
||||
isr_no_err_stub 104
|
||||
isr_no_err_stub 105
|
||||
isr_no_err_stub 106
|
||||
isr_no_err_stub 107
|
||||
isr_no_err_stub 108
|
||||
isr_no_err_stub 109
|
||||
isr_no_err_stub 110
|
||||
isr_no_err_stub 111
|
||||
isr_no_err_stub 112
|
||||
isr_no_err_stub 113
|
||||
isr_no_err_stub 114
|
||||
isr_no_err_stub 115
|
||||
isr_no_err_stub 116
|
||||
isr_no_err_stub 117
|
||||
isr_no_err_stub 118
|
||||
isr_no_err_stub 119
|
||||
isr_no_err_stub 120
|
||||
isr_no_err_stub 121
|
||||
isr_no_err_stub 122
|
||||
isr_no_err_stub 123
|
||||
isr_no_err_stub 124
|
||||
isr_no_err_stub 125
|
||||
isr_no_err_stub 126
|
||||
isr_no_err_stub 127
|
||||
isr_no_err_stub 128
|
||||
isr_no_err_stub 129
|
||||
isr_no_err_stub 130
|
||||
isr_no_err_stub 131
|
||||
isr_no_err_stub 132
|
||||
isr_no_err_stub 133
|
||||
isr_no_err_stub 134
|
||||
isr_no_err_stub 135
|
||||
isr_no_err_stub 136
|
||||
isr_no_err_stub 137
|
||||
isr_no_err_stub 138
|
||||
isr_no_err_stub 139
|
||||
isr_no_err_stub 140
|
||||
isr_no_err_stub 141
|
||||
isr_no_err_stub 142
|
||||
isr_no_err_stub 143
|
||||
isr_no_err_stub 144
|
||||
isr_no_err_stub 145
|
||||
isr_no_err_stub 146
|
||||
isr_no_err_stub 147
|
||||
isr_no_err_stub 148
|
||||
isr_no_err_stub 149
|
||||
isr_no_err_stub 150
|
||||
isr_no_err_stub 151
|
||||
isr_no_err_stub 152
|
||||
isr_no_err_stub 153
|
||||
isr_no_err_stub 154
|
||||
isr_no_err_stub 155
|
||||
isr_no_err_stub 156
|
||||
isr_no_err_stub 157
|
||||
isr_no_err_stub 158
|
||||
isr_no_err_stub 159
|
||||
isr_no_err_stub 160
|
||||
isr_no_err_stub 161
|
||||
isr_no_err_stub 162
|
||||
isr_no_err_stub 163
|
||||
isr_no_err_stub 164
|
||||
isr_no_err_stub 165
|
||||
isr_no_err_stub 166
|
||||
isr_no_err_stub 167
|
||||
isr_no_err_stub 168
|
||||
isr_no_err_stub 169
|
||||
isr_no_err_stub 170
|
||||
isr_no_err_stub 171
|
||||
isr_no_err_stub 172
|
||||
isr_no_err_stub 173
|
||||
isr_no_err_stub 174
|
||||
isr_no_err_stub 175
|
||||
isr_no_err_stub 176
|
||||
isr_no_err_stub 177
|
||||
isr_no_err_stub 178
|
||||
isr_no_err_stub 179
|
||||
isr_no_err_stub 180
|
||||
isr_no_err_stub 181
|
||||
isr_no_err_stub 182
|
||||
isr_no_err_stub 183
|
||||
isr_no_err_stub 184
|
||||
isr_no_err_stub 185
|
||||
isr_no_err_stub 186
|
||||
isr_no_err_stub 187
|
||||
isr_no_err_stub 188
|
||||
isr_no_err_stub 189
|
||||
isr_no_err_stub 190
|
||||
isr_no_err_stub 191
|
||||
isr_no_err_stub 192
|
||||
isr_no_err_stub 193
|
||||
isr_no_err_stub 194
|
||||
isr_no_err_stub 195
|
||||
isr_no_err_stub 196
|
||||
isr_no_err_stub 197
|
||||
isr_no_err_stub 198
|
||||
isr_no_err_stub 199
|
||||
isr_no_err_stub 200
|
||||
isr_no_err_stub 201
|
||||
isr_no_err_stub 202
|
||||
isr_no_err_stub 203
|
||||
isr_no_err_stub 204
|
||||
isr_no_err_stub 205
|
||||
isr_no_err_stub 206
|
||||
isr_no_err_stub 207
|
||||
isr_no_err_stub 208
|
||||
isr_no_err_stub 209
|
||||
isr_no_err_stub 210
|
||||
isr_no_err_stub 211
|
||||
isr_no_err_stub 212
|
||||
isr_no_err_stub 213
|
||||
isr_no_err_stub 214
|
||||
isr_no_err_stub 215
|
||||
isr_no_err_stub 216
|
||||
isr_no_err_stub 217
|
||||
isr_no_err_stub 218
|
||||
isr_no_err_stub 219
|
||||
isr_no_err_stub 220
|
||||
isr_no_err_stub 221
|
||||
isr_no_err_stub 222
|
||||
isr_no_err_stub 223
|
||||
isr_no_err_stub 224
|
||||
isr_no_err_stub 225
|
||||
isr_no_err_stub 226
|
||||
isr_no_err_stub 227
|
||||
isr_no_err_stub 228
|
||||
isr_no_err_stub 229
|
||||
isr_no_err_stub 230
|
||||
isr_no_err_stub 231
|
||||
isr_no_err_stub 232
|
||||
isr_no_err_stub 233
|
||||
isr_no_err_stub 234
|
||||
isr_no_err_stub 235
|
||||
isr_no_err_stub 236
|
||||
isr_no_err_stub 237
|
||||
isr_no_err_stub 238
|
||||
isr_no_err_stub 239
|
||||
isr_no_err_stub 240
|
||||
isr_no_err_stub 241
|
||||
isr_no_err_stub 242
|
||||
isr_no_err_stub 243
|
||||
isr_no_err_stub 244
|
||||
isr_no_err_stub 245
|
||||
isr_no_err_stub 246
|
||||
isr_no_err_stub 247
|
||||
isr_no_err_stub 248
|
||||
isr_no_err_stub 249
|
||||
isr_no_err_stub 250
|
||||
isr_no_err_stub 251
|
||||
isr_no_err_stub 252
|
||||
isr_no_err_stub 253
|
||||
isr_no_err_stub 254
|
||||
isr_no_err_stub 255
|
||||
|
||||
global isr_stub_table
|
||||
isr_stub_table:
|
||||
%assign i 0
|
||||
%rep 256
|
||||
dq isr_stub_%+i ; use DQ instead if targeting 64-bit
|
||||
%assign i i+1
|
||||
%endrep
|
70
kernel/src/sys/arch/x86_64/interrupts.c
Executable file
70
kernel/src/sys/arch/x86_64/interrupts.c
Executable file
|
@ -0,0 +1,70 @@
|
|||
//#include "mm/pmm.h"
|
||||
//#include "mm/vmm.h"
|
||||
#include "mm/vmm.h"
|
||||
#include "sched/sched.h"
|
||||
#include "sys/arch/x86_64/pic.h"
|
||||
#include "sys/arch/x86_64/rtc.h"
|
||||
#include "sys/log.h"
|
||||
//#include "sys/sched.h"
|
||||
#include <stdint.h>
|
||||
#include <sys/arch/x86_64/idt.h>
|
||||
#include <sys/arch/x86_64/io.h>
|
||||
//#include <sys/errhand/panic.h>
|
||||
|
||||
int pit_millis = 0;
|
||||
int pit_secs = 0;
|
||||
|
||||
struct Idt_StackFrame {
|
||||
struct Idt_StackFrame* rbp;
|
||||
uint64_t rip;
|
||||
}__attribute__((packed));
|
||||
|
||||
void dump_backtrace(registers_t *r)
|
||||
{
|
||||
log("ints - backtrace : \n");
|
||||
struct Idt_StackFrame* frame = (struct Idt_StackFrame*)r->rbp;
|
||||
|
||||
while (frame) {
|
||||
log("ints - %s (ip: %p)\n", frame->rip);
|
||||
frame = frame->rbp;
|
||||
}
|
||||
log("ints - <end of backtrace>\n");
|
||||
}
|
||||
|
||||
void pit_handler(registers_t *regs);
|
||||
|
||||
void exception_handler(registers_t *regs) {
|
||||
vmm_load_pagemap(vmm_kernel_pm);
|
||||
|
||||
if (regs->int_no < 32) {
|
||||
//panic(kmode_cpu_exception, regs);
|
||||
log("ints - %d (RIP: %p, ERR: %d)\n", regs->int_no, regs->rip, regs->err_code);
|
||||
dump_backtrace(regs);
|
||||
asm ("cli");
|
||||
while (1)
|
||||
asm ("hlt");
|
||||
}
|
||||
|
||||
if (regs->int_no == 1 + 32)
|
||||
{
|
||||
if (inb(0x60) & 0x80)
|
||||
{
|
||||
pic_ack(regs->int_no - 32);
|
||||
return;
|
||||
}
|
||||
|
||||
log("ints - keyboard\n");
|
||||
}
|
||||
else if (regs->int_no == 32 + 8) {
|
||||
rtc_handle_interrupt(regs);
|
||||
}
|
||||
else if (regs->int_no == 0x80 - 32 || regs->int_no == 32) {
|
||||
pit_handler(regs);
|
||||
}
|
||||
else if (regs->int_no == 0x80)
|
||||
{
|
||||
log("syscall - Hello World! Current process: %s", curr_proc->name);
|
||||
}
|
||||
//logln(info, "arch/ints", "Received interrupt %d\n", regs->int_no);
|
||||
pic_ack(regs->int_no - 32);
|
||||
}
|
17
kernel/src/sys/arch/x86_64/io.c
Executable file
17
kernel/src/sys/arch/x86_64/io.c
Executable file
|
@ -0,0 +1,17 @@
|
|||
// Copyright (C) 2024 Sipaa Projects
|
||||
// This code is part of the Soaplin kernel and is licensed under the terms of
|
||||
// the MIT License.
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t inb(uint16_t port) {
|
||||
uint8_t ret;
|
||||
__asm__ volatile("inb %w1, %b0" : "=a"(ret) : "Nd"(port) : "memory");
|
||||
return ret;
|
||||
}
|
||||
|
||||
void outb(uint16_t port, uint8_t val) {
|
||||
__asm__ volatile("outb %b0, %w1" : : "a"(val), "Nd"(port) : "memory");
|
||||
}
|
||||
|
||||
void io_wait(void) { outb(0x80, 0); }
|
19
kernel/src/sys/arch/x86_64/io.h
Executable file
19
kernel/src/sys/arch/x86_64/io.h
Executable file
|
@ -0,0 +1,19 @@
|
|||
// Copyright (C) 2024 Sipaa Projects
|
||||
// This code is part of the Soaplin kernel and is licensed under the terms of
|
||||
// the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint8_t inb(uint16_t port);
|
||||
void outb(uint16_t port, uint8_t val);
|
||||
void io_wait(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
76
kernel/src/sys/arch/x86_64/pic.c
Executable file
76
kernel/src/sys/arch/x86_64/pic.c
Executable file
|
@ -0,0 +1,76 @@
|
|||
//#include "sys/log.h"
|
||||
#include <sys/arch/x86_64/pic.h>
|
||||
//#include <sys/acpi.h>
|
||||
#include <sys/arch/x86_64/io.h>
|
||||
|
||||
void pic_init() {
|
||||
//if (acpi_available)
|
||||
// return;
|
||||
|
||||
uint8_t a1, a2;
|
||||
|
||||
a1 = inb(PIC1_DATA);
|
||||
a2 = inb(PIC2_DATA);
|
||||
|
||||
outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4);
|
||||
io_wait();
|
||||
outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4);
|
||||
io_wait();
|
||||
outb(PIC1_DATA, 0x20);
|
||||
io_wait();
|
||||
outb(PIC2_DATA, 8);
|
||||
io_wait();
|
||||
outb(PIC1_DATA, 4);
|
||||
io_wait();
|
||||
outb(PIC2_DATA, 2);
|
||||
io_wait();
|
||||
outb(PIC1_DATA, ICW4_8086);
|
||||
io_wait();
|
||||
outb(PIC2_DATA, ICW4_8086);
|
||||
io_wait();
|
||||
|
||||
outb(PIC1_DATA, a1);
|
||||
outb(PIC2_DATA, a2);
|
||||
}
|
||||
|
||||
void pic_ack(int intno) {
|
||||
if (intno >= 8) {
|
||||
outb(PIC2_COMMAND, 0x20);
|
||||
}
|
||||
|
||||
outb(PIC1_COMMAND, 0x20);
|
||||
}
|
||||
|
||||
void pic_disable() // if we want APIC
|
||||
{
|
||||
outb(PIC2_DATA, 0xff);
|
||||
outb(PIC1_DATA, 0xff);
|
||||
}
|
||||
|
||||
void pic_mask_irq(uint8_t irq) {
|
||||
uint16_t port;
|
||||
uint8_t value;
|
||||
|
||||
if (irq < 8) {
|
||||
port = PIC1_DATA;
|
||||
} else {
|
||||
port = PIC2_DATA;
|
||||
irq -= 8;
|
||||
}
|
||||
value = inb(port) | (1 << irq);
|
||||
outb(port, value);
|
||||
}
|
||||
|
||||
void pic_unmask_irq(uint8_t irq) {
|
||||
uint16_t port;
|
||||
uint8_t value;
|
||||
|
||||
if (irq < 8) {
|
||||
port = PIC1_DATA;
|
||||
} else {
|
||||
port = PIC2_DATA;
|
||||
irq -= 8;
|
||||
}
|
||||
value = inb(port) & ~(1 << irq);
|
||||
outb(port, value);
|
||||
}
|
23
kernel/src/sys/arch/x86_64/pic.h
Executable file
23
kernel/src/sys/arch/x86_64/pic.h
Executable file
|
@ -0,0 +1,23 @@
|
|||
// Copyright (C) 2024 Sipaa Projects
|
||||
// This code is part of the Soaplin kernel and is licensed under the terms of
|
||||
// the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define PIC1_COMMAND 0x20
|
||||
#define PIC1_DATA 0x21
|
||||
#define PIC2_COMMAND 0xA0
|
||||
#define PIC2_DATA 0xA1
|
||||
#define PIC_EOI 0x20
|
||||
|
||||
#define ICW1_INIT 0x10
|
||||
#define ICW1_ICW4 0x01
|
||||
#define ICW4_8086 0x01
|
||||
|
||||
void pic_init();
|
||||
void pic_ack(int intno);
|
||||
void pic_disable(); // if we want APIC
|
||||
void pic_mask_irq(uint8_t irq);
|
||||
void pic_unmask_irq(uint8_t irq);
|
60
kernel/src/sys/arch/x86_64/pit.c
Executable file
60
kernel/src/sys/arch/x86_64/pit.c
Executable file
|
@ -0,0 +1,60 @@
|
|||
#include "sched/sched.h"
|
||||
#include "sys/arch/x86_64/idt.h"
|
||||
#include "sys/arch/x86_64/pic.h"
|
||||
#include <sys/log.h>
|
||||
#include <stdint.h>
|
||||
#ifdef __x86_64__
|
||||
|
||||
#include <sys/arch/x86_64/pit.h>
|
||||
#include <sys/arch/x86_64/idt.h>
|
||||
//#include <sipaa/sched.h>
|
||||
|
||||
uint32_t tick = 0;
|
||||
|
||||
void pit_handler(registers_t *regs)
|
||||
{
|
||||
tick++;
|
||||
|
||||
schedule(regs);
|
||||
//Scheduler_Schedule(regs);
|
||||
}
|
||||
|
||||
void pit_init(uint32_t frequency)
|
||||
{
|
||||
uint32_t divisor = PIT_FREQUENCY / frequency;
|
||||
outb(0x43, 0x34);
|
||||
outb(0x40, (uint8_t)(divisor & 0xFF));
|
||||
outb(0x40, (uint8_t)((divisor >> 8) & 0xFF));
|
||||
|
||||
pic_unmask_irq(0);
|
||||
}
|
||||
|
||||
void sleep(uint32_t seconds)
|
||||
{
|
||||
uint32_t eticks = tick + seconds * HZ;
|
||||
while (tick < eticks)
|
||||
{
|
||||
__asm__ __volatile__("hlt");
|
||||
}
|
||||
}
|
||||
|
||||
void sleep_ms(uint32_t milliseconds)
|
||||
{
|
||||
uint32_t eticks = tick + (milliseconds * HZ) / 1000;
|
||||
while (tick < eticks)
|
||||
{
|
||||
__asm__ __volatile__("hlt");
|
||||
}
|
||||
}
|
||||
|
||||
// todo: unistd: add usleep function
|
||||
void usleep(uint32_t usecs)
|
||||
{
|
||||
uint32_t eticks = tick + (usecs * HZ);
|
||||
while (tick < eticks)
|
||||
{
|
||||
__asm__ __volatile__("hlt");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
17
kernel/src/sys/arch/x86_64/pit.h
Executable file
17
kernel/src/sys/arch/x86_64/pit.h
Executable file
|
@ -0,0 +1,17 @@
|
|||
#ifndef PIT_H
|
||||
#define PIT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/arch/x86_64/io.h>
|
||||
|
||||
#define PIT_FREQUENCY 1193182
|
||||
#define HZ 1000
|
||||
|
||||
extern uint32_t tick;
|
||||
|
||||
void pit_init(uint32_t frequency);
|
||||
void sleep(uint32_t seconds);
|
||||
void sleep_ms(uint32_t milliseconds);
|
||||
void usleep(uint32_t usecs);
|
||||
|
||||
#endif
|
25
kernel/src/sys/arch/x86_64/rtc.c
Executable file
25
kernel/src/sys/arch/x86_64/rtc.c
Executable file
|
@ -0,0 +1,25 @@
|
|||
#include "sys/arch/x86_64/idt.h"
|
||||
#include "sys/arch/x86_64/io.h"
|
||||
#include <sys/arch/x86_64/rtc.h>
|
||||
#include <sys/arch/x86_64/pic.h>
|
||||
#include <sys/printf.h>
|
||||
|
||||
void rtc_init() {
|
||||
asm("cli");
|
||||
outb(0x70, 0x8A);
|
||||
outb(0x71, 0x20);
|
||||
asm("sti");
|
||||
|
||||
asm("cli"); // disable interrupts
|
||||
outb(0x70, 0x8B); // select register B, and disable NMI
|
||||
char prev=inb(0x71); // read the current value of register B
|
||||
outb(0x70, 0x8B); // set the index again (a read will reset the index to register D)
|
||||
outb(0x71, prev | 0x40); // write the previous value ORed with 0x40. This turns on bit 6 of register B
|
||||
asm("sti");
|
||||
|
||||
//pic_unmask_irq(8);
|
||||
}
|
||||
|
||||
void rtc_handle_interrupt(registers_t *regs) {
|
||||
printf("RTC!\n");
|
||||
}
|
6
kernel/src/sys/arch/x86_64/rtc.h
Executable file
6
kernel/src/sys/arch/x86_64/rtc.h
Executable file
|
@ -0,0 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "sys/arch/x86_64/idt.h"
|
||||
|
||||
void rtc_init();
|
||||
void rtc_handle_interrupt(registers_t *regs);
|
59
kernel/src/sys/arch/x86_64/sse.c
Executable file
59
kernel/src/sys/arch/x86_64/sse.c
Executable file
|
@ -0,0 +1,59 @@
|
|||
#include <sys/arch/x86_64/sse.h>
|
||||
#include <sys/printf.h>
|
||||
#include <sys/log.h>
|
||||
|
||||
int cpuid_check_bit(int reg, int bit) {
|
||||
int eax, ebx, ecx, edx;
|
||||
|
||||
// Minimal inline assembly to execute CPUID
|
||||
__asm__ volatile (
|
||||
"cpuid" // Execute CPUID instruction
|
||||
: "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) // Output registers
|
||||
: "a"(0x1) // Input: EAX = 0x1 (query feature flags)
|
||||
: // No clobbered registers
|
||||
);
|
||||
|
||||
// Check bit 25 of EDX (SSE support) in plain C
|
||||
if (reg == 0) {
|
||||
if (edx & (1 << bit)) {
|
||||
return 1; // SSE is supported
|
||||
} else {
|
||||
return 0; // SSE is not supported
|
||||
}
|
||||
}else if (reg == 1) {
|
||||
if (ecx & (1 << bit)) {
|
||||
return 1; // SSE is supported
|
||||
} else {
|
||||
return 0; // SSE is not supported
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sse_init() {
|
||||
int sse = cpuid_check_bit(0, 25);
|
||||
int sse2 = cpuid_check_bit(0, 26);
|
||||
int sse3 = cpuid_check_bit(1, 0);
|
||||
int ssse3 = cpuid_check_bit(1, 9);
|
||||
|
||||
if (sse)
|
||||
log("sse - sse is supported!\n");
|
||||
else
|
||||
log("sse - sse isn't supported!\n");
|
||||
|
||||
if (sse2)
|
||||
log("sse - sse2 is supported!\n");
|
||||
else
|
||||
log("sse - sse2 isn't supported!\n");
|
||||
|
||||
if (sse3)
|
||||
log("sse - sse3 is supported!\n");
|
||||
else
|
||||
log("sse - sse3 isn't supported!\n");
|
||||
|
||||
if (ssse3)
|
||||
log("sse - ssse3 is supported!\n");
|
||||
else
|
||||
log("sse - ssse3 isn't supported!\n");
|
||||
}
|
4
kernel/src/sys/arch/x86_64/sse.h
Executable file
4
kernel/src/sys/arch/x86_64/sse.h
Executable file
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
int sse_is_supported();
|
||||
void sse_init();
|
32
kernel/src/sys/log.c
Executable file
32
kernel/src/sys/log.c
Executable file
|
@ -0,0 +1,32 @@
|
|||
#include "rt.h"
|
||||
#include "sys/arch/x86_64/io.h"
|
||||
#include <stdarg.h>
|
||||
#include <sys/printf.h>
|
||||
|
||||
void log(char *format, ...) {
|
||||
// TODO: replace this call with a call to printf() when the RTC is implemented.
|
||||
rt_print("1970-01-01 00:00:00 | ");
|
||||
|
||||
char buf[2048];
|
||||
va_list l;
|
||||
va_start(l, format);
|
||||
npf_vsnprintf(buf, 2048, format, l);
|
||||
va_end(l);
|
||||
|
||||
rt_print(buf);
|
||||
|
||||
char *date = "1970-01-01 00:00:00 | ";
|
||||
for (int i;;i++) {
|
||||
if (date[i] == '\0')
|
||||
break;
|
||||
|
||||
outb(0xE9, date[i]);
|
||||
}
|
||||
|
||||
for (int i;;i++) {
|
||||
if (buf[i] == '\0')
|
||||
break;
|
||||
|
||||
outb(0xE9, buf[i]);
|
||||
}
|
||||
}
|
3
kernel/src/sys/log.h
Executable file
3
kernel/src/sys/log.h
Executable file
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
|
||||
void log(char *format, ...);
|
26
kernel/src/sys/printf.c
Executable file
26
kernel/src/sys/printf.c
Executable file
|
@ -0,0 +1,26 @@
|
|||
// Copyright (C) 2024 Sipaa Projects
|
||||
// This code is part of the Soaplin kernel and is licensed under the terms of
|
||||
// the MIT License.
|
||||
#include <rt.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define NANOPRINTF_USE_FIELD_WIDTH_FORMAT_SPECIFIERS 1
|
||||
#define NANOPRINTF_USE_PRECISION_FORMAT_SPECIFIERS 1
|
||||
#define NANOPRINTF_USE_LARGE_FORMAT_SPECIFIERS 1
|
||||
#define NANOPRINTF_USE_FLOAT_FORMAT_SPECIFIERS 0
|
||||
#define NANOPRINTF_USE_BINARY_FORMAT_SPECIFIERS 1
|
||||
#define NANOPRINTF_USE_WRITEBACK_FORMAT_SPECIFIERS 0
|
||||
|
||||
// Compile nanoprintf in this translation unit.
|
||||
#define NANOPRINTF_IMPLEMENTATION
|
||||
#include <sys/printf.h>
|
||||
|
||||
void printf(char *format, ...) {
|
||||
char buf[2048];
|
||||
va_list lst;
|
||||
va_start(lst, format);
|
||||
npf_vsnprintf(buf, 2048, format, lst);
|
||||
va_end(lst);
|
||||
|
||||
rt_print(buf);
|
||||
}
|
1320
kernel/src/sys/printf.h
Executable file
1320
kernel/src/sys/printf.h
Executable file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue