makefile: introduce a format command to run clang-format all over the kernel source.

This commit is contained in:
RaphProductions 2025-05-11 11:45:04 +02:00
parent c4e98f5ef2
commit a379d66784
47 changed files with 5092 additions and 4603 deletions

View file

@ -266,3 +266,8 @@ clean:
distclean: distclean:
$(MAKE) -C kernel distclean $(MAKE) -C kernel distclean
rm -rf iso_root *.iso *.hdd kernel-deps limine ovmf rm -rf iso_root *.iso *.hdd kernel-deps limine ovmf
# Make some function to run clang-format all over the kernel
.PHONY: format
format:
clang-format -i -style=file $(shell find kernel/src -name '*.c' -or -name '*.h')

44
compile_commands.json Executable file → Normal file
View file

@ -33,8 +33,46 @@
"obj-x86_64/main.c.o", "obj-x86_64/main.c.o",
"src/main.c" "src/main.c"
], ],
"directory": "/home/raphm/Projets/sild/kernel", "directory": "/home/raphm/Projets/sild/soaplin/kernel",
"file": "/home/raphm/Projets/sild/kernel/src/main.c", "file": "/home/raphm/Projets/sild/soaplin/kernel/src/main.c",
"output": "/home/raphm/Projets/sild/kernel/obj-x86_64/main.c.o" "output": "/home/raphm/Projets/sild/soaplin/kernel/obj-x86_64/main.c.o"
},
{
"arguments": [
"/usr/bin/cc",
"-g",
"-O2",
"-pipe",
"-Wall",
"-Wextra",
"-std=gnu11",
"-nostdinc",
"-ffreestanding",
"-fno-stack-protector",
"-fno-stack-check",
"-fno-PIC",
"-ffunction-sections",
"-fdata-sections",
"-m64",
"-march=x86-64",
"-mno-80387",
"-mno-mmx",
"-mno-sse",
"-mno-sse2",
"-mno-red-zone",
"-mcmodel=kernel",
"-I",
"src",
"-isystem",
"freestnd-c-hdrs",
"-DLIMINE_API_REVISION=3",
"-c",
"-o",
"obj-x86_64/mm/vmm.c.o",
"src/mm/vmm.c"
],
"directory": "/home/raphm/Projets/sild/soaplin/kernel",
"file": "/home/raphm/Projets/sild/soaplin/kernel/src/mm/vmm.c",
"output": "/home/raphm/Projets/sild/soaplin/kernel/obj-x86_64/mm/vmm.c.o"
} }
] ]

View file

@ -2,18 +2,15 @@
#include "mm/memop.h" #include "mm/memop.h"
#include "mm/pmm.h" #include "mm/pmm.h"
#include "mm/vmm.h" #include "mm/vmm.h"
#include <mm/liballoc/liballoc.h>
#include <exec/elf.h> #include <exec/elf.h>
#include <mm/liballoc/liballoc.h>
#include <stdint.h> #include <stdint.h>
#include <sys/log.h> #include <sys/log.h>
program_t *elf_load(char *data) { program_t *elf_load(char *data, int user) {
Elf64_Ehdr *ehdr = (Elf64_Ehdr*)data; Elf64_Ehdr *ehdr = (Elf64_Ehdr *)data;
if ( ehdr->e_ident[EI_MAG0] != ELFMAG0 if (ehdr->e_ident[EI_MAG0] != ELFMAG0 || ehdr->e_ident[EI_MAG1] != ELFMAG1 ||
|| ehdr->e_ident[EI_MAG1] != ELFMAG1 ehdr->e_ident[EI_MAG2] != ELFMAG2 || ehdr->e_ident[EI_MAG3] != ELFMAG3) {
|| ehdr->e_ident[EI_MAG2] != ELFMAG2
|| ehdr->e_ident[EI_MAG3] != ELFMAG3)
{
log("elf - loading failed: magic is incorrect\n"); log("elf - loading failed: magic is incorrect\n");
return NULL; return NULL;
} }
@ -26,101 +23,105 @@ program_t *elf_load(char *data) {
log("elf - e_type: %p\n", ehdr->e_type); log("elf - e_type: %p\n", ehdr->e_type);
log("elf - e_phnum: %p\n", ehdr->e_phnum); log("elf - e_phnum: %p\n", ehdr->e_phnum);
if ( ehdr->e_ident[EI_CLASS] != ELFCLASS64 if (ehdr->e_ident[EI_CLASS] != ELFCLASS64 || ehdr->e_machine != EM_X86_64) {
|| ehdr->e_machine != EM_X86_64)
{
log("elf - loading failed: is the file built for amd64?\n"); log("elf - loading failed: is the file built for amd64?\n");
return NULL; return NULL;
} }
if (ehdr->e_type != ET_EXEC) if (ehdr->e_type != ET_EXEC) {
{
log("elf - loading failed: ELF type isn't ET_EXEC\n"); log("elf - loading failed: ELF type isn't ET_EXEC\n");
return NULL; return NULL;
} }
// There's the interesing part // There's the interesing part
elf_program_t *ret = malloc(sizeof(elf_program_t)); // Allocate memory for the program. elf_program_t *ret =
malloc(sizeof(elf_program_t)); // Allocate memory for the program.
pagemap_t *pm = vmm_alloc_pm(); // Allocate a pagemap, so that we can map the program inside. pagemap_t *pm = vmm_alloc_pm(); // Allocate a pagemap, so that we can map the
// program inside.
ret->program.pm = pm; ret->program.pm = pm;
ret->program.entry = ehdr->e_entry; ret->program.entry = ehdr->e_entry;
ret->ehdr = ehdr; ret->ehdr = ehdr;
Elf64_Phdr *phdr = (Elf64_Phdr *)((uint8_t *)data + ehdr->e_phoff); Elf64_Phdr *phdr = (Elf64_Phdr *)((uint8_t *)data + ehdr->e_phoff);
for (uint16_t i = 0; i <= ehdr->e_phnum; i++) for (uint16_t i = 0; i < ehdr->e_phnum; i++) {
{
log("elf - ELF segment type: %d\n", phdr[i].p_type); log("elf - ELF segment type: %d\n", phdr[i].p_type);
if (phdr[i].p_type != PT_LOAD) if (phdr[i].p_type != PT_LOAD)
continue; continue;
uint64_t vaddr_start = ALIGN_DOWN(phdr[i].p_vaddr, PMM_PAGE_SIZE); uint64_t vaddr_start = ALIGN_DOWN(phdr[i].p_vaddr, PMM_PAGE_SIZE);
uint64_t vaddr_end = ALIGN_UP(phdr[i].p_vaddr + phdr[i].p_memsz, PMM_PAGE_SIZE); uint64_t vaddr_end =
ALIGN_UP(phdr[i].p_vaddr + phdr[i].p_memsz, PMM_PAGE_SIZE);
uint64_t offset = phdr[i].p_offset; uint64_t offset = phdr[i].p_offset;
uint64_t flags = VMM_PRESENT; uint64_t flags = VMM_PRESENT;
//if (phdr[i].p_flags & PF_W) if (phdr[i].p_flags & PF_W)
flags |= VMM_WRITABLE; flags |= VMM_WRITABLE;
//if (!(phdr[i].p_flags & PF_X)) if (!(phdr[i].p_flags & PF_X))
// flags |= VMM_NX; flags |= VMM_NX;
if (user)
flags |= VMM_USER; flags |= VMM_USER;
log("elf - loading ELF program header %u: vaddr 0x%llx - 0x%llx, offset 0x%llx, filesz 0x%llx, size 0x%llx, flags 0x%llx\n", log("elf - loading ELF program header %u: vaddr 0x%llx - 0x%llx, offset "
i, vaddr_start, vaddr_end, offset, phdr[i].p_filesz, phdr[i].p_memsz, flags); "0x%llx, filesz 0x%llx, size 0x%llx, flags 0x%llx\n",
i, vaddr_start, vaddr_end, offset, phdr[i].p_filesz, phdr[i].p_memsz,
flags);
uint64_t page_offset = phdr[i].p_vaddr & (PMM_PAGE_SIZE - 1); uint64_t page_offset = phdr[i].p_vaddr & (PMM_PAGE_SIZE - 1);
for (uint64_t vaddr = vaddr_start; vaddr < vaddr_end; vaddr += PMM_PAGE_SIZE) for (uint64_t vaddr = vaddr_start; vaddr < vaddr_end;
{ vaddr += PMM_PAGE_SIZE) {
uint64_t phys = (uint64_t)pmm_request_page(); uint64_t phys = (uint64_t)pmm_request_page();
if (!phys) if (!phys) {
{
log("elf - pmm page alloc failed. out of memory?\n"); log("elf - pmm page alloc failed. out of memory?\n");
return 0; return 0;
} }
if (user) {
log("elf - vmm_map_user(%p, %p, %p, %d)\n", pm, vaddr, phys, flags);
vmm_map_user(pm, vaddr, phys, flags);
} else {
log("elf - vmm_map(%p, %p, %p, %d)\n", pm, vaddr, phys, flags); log("elf - vmm_map(%p, %p, %p, %d)\n", pm, vaddr, phys, flags);
vmm_map(pm, vaddr, phys, flags); vmm_map(pm, vaddr, phys, flags);
}
log("elf - memset(%p, 0, 0x1000)\n", HIGHER_HALF(phys)); log("elf - memset(%p, 0, 0x1000)\n", HIGHER_HALF(phys));
memset((void *)HIGHER_HALF(phys), 0, PMM_PAGE_SIZE); memset((void *)HIGHER_HALF(phys), 0, PMM_PAGE_SIZE);
uint64_t file_page_offset = offset + (vaddr - vaddr_start); uint64_t file_page_offset = offset + (vaddr - vaddr_start);
uint64_t file_data_end = offset + phdr[i].p_filesz; uint64_t file_data_end = offset + phdr[i].p_filesz;
if (file_page_offset < file_data_end) if (file_page_offset < file_data_end) {
{
uint64_t bytes_from_start = vaddr - vaddr_start; uint64_t bytes_from_start = vaddr - vaddr_start;
uint64_t page_data_offset = 0; uint64_t page_data_offset = 0;
if (bytes_from_start == 0 && page_offset > 0) if (bytes_from_start == 0 && page_offset > 0) {
{
page_data_offset = page_offset; page_data_offset = page_offset;
} }
uint64_t copy_offset = file_page_offset; uint64_t copy_offset = file_page_offset;
uint64_t copy_size = PMM_PAGE_SIZE - page_data_offset; uint64_t copy_size = PMM_PAGE_SIZE - page_data_offset;
if (copy_offset + copy_size > file_data_end) if (copy_offset + copy_size > file_data_end) {
{
copy_size = file_data_end - copy_offset; copy_size = file_data_end - copy_offset;
} }
if (copy_size > 0) if (copy_size > 0) {
{
void *dest = (void *)(HIGHER_HALF(phys) + page_data_offset); void *dest = (void *)(HIGHER_HALF(phys) + page_data_offset);
void *src = (uint8_t *)data + copy_offset; void *src = (uint8_t *)data + copy_offset;
log("elf - memcpy(%p, %p, %d)\n", dest, src, copy_size); log("elf - memcpy(%p, %p, %d)\n", dest, src, copy_size);
memcpy(dest, src, copy_size); memcpy(dest, src, copy_size);
//log("elf - copied 0x%llx bytes from ELF file offset 0x%llx to vaddr 0x%llx (phys 0x%llx)\n", // log("elf - copied 0x%llx bytes from ELF file offset 0x%llx to vaddr
// copy_size, copy_offset, vaddr + page_data_offset, phys + page_data_offset); // 0x%llx (phys 0x%llx)\n",
// copy_size, copy_offset, vaddr + page_data_offset, phys +
// page_data_offset);
} }
} }
} }
} }
log("elf - loaded ELF program in memory.\n"); log("elf - loaded ELF program in memory.\n");
return (program_t*)ret; return (program_t *)ret;
} }

View file

@ -122,4 +122,4 @@ typedef struct {
Elf64_Ehdr *ehdr; Elf64_Ehdr *ehdr;
} elf_program_t; } elf_program_t;
program_t *elf_load(char *data); program_t *elf_load(char *data, int user);

View file

@ -14,12 +14,15 @@ typedef struct {
// The pagemap where the program's code is loaded. // The pagemap where the program's code is loaded.
pagemap_t *pm; pagemap_t *pm;
// The path to the first instruction. This will be passed to the new process's rip register. // The path to the first instruction. This will be passed to the new process's
// rip register.
uint64_t entry; uint64_t entry;
// The program type. Used to get additional, unneeded information out of a program // The program type. Used to get additional, unneeded information out of a
// program
int type; int type;
// That is what Soaplin needs to know. Executable file loaders are encouraged to extend this structure // That is what Soaplin needs to know. Executable file loaders are encouraged
// to include info such as the EHDR for the ELF loader... // to extend this structure to include info such as the EHDR for the ELF
// loader...
} program_t; } program_t;

View file

@ -1,258 +1,343 @@
unsigned char VGA8[] = { unsigned char VGA8[] = {
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, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd,
0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff,
0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10,
0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe,
0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x1e, 0x0e, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd,
0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00, 0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e,
0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18,
0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30,
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63,
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18,
0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e,
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb,
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6,
0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x6c, 0xfe, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00,
0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c,
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 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, 0x6c,
0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c,
0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18,
0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c,
0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38,
0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c,
0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe,
0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18,
0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78,
0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06,
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde,
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,
0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc,
0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0,
0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c,
0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe,
0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68,
0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60,
0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xee,
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6,
0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66,
0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c,
0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c,
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x60, 0x38, 0x0c, 0x06, 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, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c,
0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38,
0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66,
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe,
0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30,
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c,
0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x76, 0xdc, 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, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c,
0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60,
0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c,
0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc,
0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x38, 0x6c, 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, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc,
0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60,
0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06,
0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60,
0x38, 0x6c, 0x38, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6,
0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66,
0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
0x00, 0x00, 0xc6, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0,
0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60,
0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30,
0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66,
0x00, 0xf8, 0xcc, 0xcc, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6,
0x00, 0x0c, 0x18, 0x30, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6,
0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e,
0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18,
0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 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, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, 0x00, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe,
0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c,
0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76,
0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c,
0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06,
0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c,
0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66,
0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6,
0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6,
0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc,
0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x3c,
0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc,
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, 0xcc,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xc4, 0xcc, 0xde, 0xcc, 0xcc, 0xcc, 0xc6, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30,
0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6,
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00,
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x7c, 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, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c,
0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x0c,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3e, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30,
0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00,
0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36,
0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44,
0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36,
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
0x00, 0x0f, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00,
0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
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, 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};

View file

@ -16,13 +16,13 @@ typedef struct __vnode {
struct __vnode *next; struct __vnode *next;
struct __vnode *parent; struct __vnode *parent;
void(*write)(void *buffer, uint64_t off, uint64_t size); void (*write)(void *buffer, uint64_t off, uint64_t size);
void(*read)(void *buffer, uint64_t off, uint64_t size); void (*read)(void *buffer, uint64_t off, uint64_t size);
} vnode; } vnode;
typedef struct __vfs_mount { typedef struct __vfs_mount {
struct vfs_node *mount_point; // The directory in the main VFS where this is mounted struct vfs_node
*mount_point; // The directory in the main VFS where this is mounted
struct vfs_node *mounted_root; // The root node of the mounted filesystem struct vfs_node *mounted_root; // The root node of the mounted filesystem
struct vfs_mount *next; // Pointer to next mount point struct vfs_mount *next; // Pointer to next mount point
} vfs_mount; } vfs_mount;

View file

@ -2,8 +2,7 @@
#include <stdint.h> #include <stdint.h>
typedef struct spinlock typedef struct spinlock {
{
volatile int locked; volatile int locked;
} spinlock_t; } spinlock_t;

99
kernel/src/main.c Executable file → Normal file
View file

@ -1,49 +1,49 @@
#include "exec/elf.h" #include "exec/elf.h"
#include "exec/exec.h" #include "exec/exec.h"
#include "mm/liballoc/liballoc.h"
#include "mm/pmm.h" #include "mm/pmm.h"
#include "mm/vma.h" #include "mm/vma.h"
#include "mm/vmm.h" #include "mm/vmm.h"
#include "mm/liballoc/liballoc.h"
#include "sched/sched.h" #include "sched/sched.h"
#include "sys/acpi.h"
#include "sys/arch/x86_64/pit.h" #include "sys/arch/x86_64/pit.h"
#include "sys/arch/x86_64/sse.h" #include "sys/arch/x86_64/sse.h"
#include "sys/syscall.h" #include "sys/syscall.h"
#include <sys/log.h> #include <font.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <limine.h> #include <limine.h>
#include <sys/printf.h> #include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/arch/x86_64/fpu.h>
#include <sys/arch/x86_64/gdt.h> #include <sys/arch/x86_64/gdt.h>
#include <sys/arch/x86_64/idt.h> #include <sys/arch/x86_64/idt.h>
#include <sys/arch/x86_64/fpu.h>
#include <sys/gfx/flanterm/flanterm.h>
#include <sys/gfx/flanterm/backends/fb.h> #include <sys/gfx/flanterm/backends/fb.h>
#include <font.h> #include <sys/gfx/flanterm/flanterm.h>
#include <sys/log.h>
#include <sys/printf.h>
// Set the base revision to 3, this is recommended as this is the latest // Set the base revision to 3, this is recommended as this is the latest
// base revision described by the Limine boot protocol specification. // base revision described by the Limine boot protocol specification.
// See specification for further info. // See specification for further info.
__attribute__((used, section(".limine_requests"))) __attribute__((
static volatile LIMINE_BASE_REVISION(3); used, section(".limine_requests"))) static volatile LIMINE_BASE_REVISION(3);
// The Limine requests can be placed anywhere, but it is important that // The Limine requests can be placed anywhere, but it is important that
// the compiler does not optimise them away, so, usually, they should // the compiler does not optimise them away, so, usually, they should
// be made volatile or equivalent, _and_ they should be accessed at least // be made volatile or equivalent, _and_ they should be accessed at least
// once or marked as used with the "used" attribute as done here. // once or marked as used with the "used" attribute as done here.
__attribute__((used, section(".limine_requests"))) __attribute__((
static volatile struct limine_framebuffer_request framebuffer_request = { used,
.id = LIMINE_FRAMEBUFFER_REQUEST, section(
.revision = 0 ".limine_requests"))) static volatile struct limine_framebuffer_request
}; framebuffer_request = {.id = LIMINE_FRAMEBUFFER_REQUEST, .revision = 0};
__attribute__((used, section(".limine_requests"))) __attribute__((
static volatile struct limine_module_request module_request = { used,
.id = LIMINE_MODULE_REQUEST, section(".limine_requests"))) static volatile struct limine_module_request
.revision = 0 module_request = {.id = LIMINE_MODULE_REQUEST, .revision = 0};
};
/*__attribute__((used, section(".limine_requests"))) /*__attribute__((used, section(".limine_requests")))
static volatile struct limine_entry_point_request entrypoint_request = { static volatile struct limine_entry_point_request entrypoint_request = {
@ -53,22 +53,24 @@ static volatile struct limine_entry_point_request entrypoint_request = {
// Finally, define the start and end markers for the Limine requests. // Finally, define the start and end markers for the Limine requests.
// These can also be moved anywhere, to any .c file, as seen fit. // These can also be moved anywhere, to any .c file, as seen fit.
__attribute__((used, section(".limine_requests_start"))) __attribute__((used,
static volatile LIMINE_REQUESTS_START_MARKER; section(".limine_requests_"
"start"))) static volatile LIMINE_REQUESTS_START_MARKER;
__attribute__((used, section(".limine_requests_end")))
static volatile LIMINE_REQUESTS_END_MARKER;
__attribute__((
used,
section(
".limine_requests_end"))) static volatile LIMINE_REQUESTS_END_MARKER;
// Halt and catch fire function. // Halt and catch fire function.
static void hcf(void) { static void hcf(void) {
for (;;) { for (;;) {
#if defined (__x86_64__) #if defined(__x86_64__)
asm ("hlt"); asm("hlt");
#elif defined (__aarch64__) || defined (__riscv) #elif defined(__aarch64__) || defined(__riscv)
asm ("wfi"); asm("wfi");
#elif defined (__loongarch64) #elif defined(__loongarch64)
asm ("idle 0"); asm("idle 0");
#endif #endif
} }
} }
@ -92,28 +94,21 @@ void kmain(void) {
if (framebuffer_request.response != NULL) { if (framebuffer_request.response != NULL) {
// Fetch the first framebuffer. // Fetch the first framebuffer.
struct limine_framebuffer *framebuffer = framebuffer_request.response->framebuffers[0]; struct limine_framebuffer *framebuffer =
framebuffer_request.response->framebuffers[0];
fb = framebuffer; fb = framebuffer;
ft_ctx = flanterm_fb_init( ft_ctx = flanterm_fb_init(
NULL, NULL, NULL, framebuffer->address, framebuffer->width,
NULL, framebuffer->height, framebuffer->pitch, framebuffer->red_mask_size,
framebuffer->address, framebuffer->width, framebuffer->height, framebuffer->pitch, framebuffer->red_mask_shift, framebuffer->green_mask_size,
framebuffer->red_mask_size, framebuffer->red_mask_shift, framebuffer->green_mask_shift, framebuffer->blue_mask_size,
framebuffer->green_mask_size, framebuffer->green_mask_shift, framebuffer->blue_mask_shift, NULL, NULL, NULL, NULL, &fg, NULL, NULL,
framebuffer->blue_mask_size, framebuffer->blue_mask_shift, VGA8, 8, 16, 0, 0, 0, 0);
NULL,
NULL, NULL,
NULL, &fg,
NULL, NULL,
VGA8, 8, 16, 0,
0, 0,
0
);
} }
printf("\n Soaplin 1.0-sild is booting up your computer...\n\n"); printf("\n Soaplin 1.0-sild is booting up your computer...\n\n");
//printf("Physical kernel EP: %p", entrypoint_request.entry); // printf("Physical kernel EP: %p", entrypoint_request.entry);
gdt_init(&kstack[8192]); gdt_init(&kstack[8192]);
idt_init(); idt_init();
@ -130,19 +125,21 @@ void kmain(void) {
asm("hlt"); asm("hlt");
} }
// acpi_init();
syscall_init(); syscall_init();
pit_init(1000); pit_init(1000);
sched_init(); sched_init();
//user_init(); // user_init();
struct limine_file *f = module_request.response->modules[0]; struct limine_file *f = module_request.response->modules[0];
log("kmain - %s\n", f->path); log("kmain - %s\n", f->path);
program_t *prog = elf_load((char*)f->address); program_t *prog = elf_load((char *)f->address, 1);
sched_create("Init", prog->entry, prog->pm, SCHED_USER_PROCESS); sched_create("Init", prog->entry, prog->pm, SCHED_USER_PROCESS);
log("kernel - Soaplin initialized sucessfully.\n"); log("kernel - Soaplin initialized sucessfully.\n");
while (1) while (1)
;;//__asm__ volatile ("hlt"); ;
; //__asm__ volatile ("hlt");
} }

View file

@ -17,26 +17,21 @@
#define USE_CASE5 #define USE_CASE5
#define ALIGN(ptr) \ #define ALIGN(ptr) \
if (ALIGNMENT > 1) \ if (ALIGNMENT > 1) { \
{ \
uintptr_t diff; \ uintptr_t diff; \
ptr = (void *)((uintptr_t)ptr + ALIGN_INFO); \ ptr = (void *)((uintptr_t)ptr + ALIGN_INFO); \
diff = (uintptr_t)ptr & (ALIGNMENT - 1); \ diff = (uintptr_t)ptr & (ALIGNMENT - 1); \
if (diff != 0) \ if (diff != 0) { \
{ \
diff = ALIGNMENT - diff; \ diff = ALIGNMENT - diff; \
ptr = (void *)((uintptr_t)ptr + diff); \ ptr = (void *)((uintptr_t)ptr + diff); \
} \ } \
*((ALIGN_TYPE *)((uintptr_t)ptr - ALIGN_INFO)) = \ *((ALIGN_TYPE *)((uintptr_t)ptr - ALIGN_INFO)) = diff + ALIGN_INFO; \
diff + ALIGN_INFO; \
} }
#define UNALIGN(ptr) \ #define UNALIGN(ptr) \
if (ALIGNMENT > 1) \ if (ALIGNMENT > 1) { \
{ \
uintptr_t diff = *((ALIGN_TYPE *)((uintptr_t)ptr - ALIGN_INFO)); \ uintptr_t diff = *((ALIGN_TYPE *)((uintptr_t)ptr - ALIGN_INFO)); \
if (diff < (ALIGNMENT + ALIGN_INFO)) \ if (diff < (ALIGNMENT + ALIGN_INFO)) { \
{ \
ptr = (void *)((uintptr_t)ptr - diff); \ ptr = (void *)((uintptr_t)ptr - diff); \
} \ } \
} }
@ -44,8 +39,7 @@
#define LIBALLOC_MAGIC 0xc001c0de #define LIBALLOC_MAGIC 0xc001c0de
#define LIBALLOC_DEAD 0xdeaddead #define LIBALLOC_DEAD 0xdeaddead
struct liballoc_major struct liballoc_major {
{
struct liballoc_major *prev; struct liballoc_major *prev;
struct liballoc_major *next; struct liballoc_major *next;
unsigned int pages; unsigned int pages;
@ -54,8 +48,7 @@ struct liballoc_major
struct liballoc_minor *first; struct liballoc_minor *first;
}; };
struct liballoc_minor struct liballoc_minor {
{
struct liballoc_minor *prev; struct liballoc_minor *prev;
struct liballoc_minor *next; struct liballoc_minor *next;
struct liballoc_major *block; struct liballoc_major *block;
@ -76,23 +69,20 @@ static long long l_warningCount = 0;
static long long l_errorCount = 0; static long long l_errorCount = 0;
static long long l_possibleOverruns = 0; static long long l_possibleOverruns = 0;
static void *liballoc_memset(void *s, int c, size_t n) static void *liballoc_memset(void *s, int c, size_t n) {
{
unsigned int i; unsigned int i;
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
((char *)s)[i] = c; ((char *)s)[i] = c;
return s; return s;
} }
static void *liballoc_memcpy(void *s1, const void *s2, size_t n) static void *liballoc_memcpy(void *s1, const void *s2, size_t n) {
{
char *cdest; char *cdest;
char *csrc; char *csrc;
unsigned int *ldest = (unsigned int *)s1; unsigned int *ldest = (unsigned int *)s1;
unsigned int *lsrc = (unsigned int *)s2; unsigned int *lsrc = (unsigned int *)s2;
while (n >= sizeof(unsigned int)) while (n >= sizeof(unsigned int)) {
{
*ldest++ = *lsrc++; *ldest++ = *lsrc++;
n -= sizeof(unsigned int); n -= sizeof(unsigned int);
} }
@ -100,8 +90,7 @@ static void *liballoc_memcpy(void *s1, const void *s2, size_t n)
cdest = (char *)ldest; cdest = (char *)ldest;
csrc = (char *)lsrc; csrc = (char *)lsrc;
while (n > 0) while (n > 0) {
{
*cdest++ = *csrc++; *cdest++ = *csrc++;
n -= 1; n -= 1;
} }
@ -110,8 +99,7 @@ static void *liballoc_memcpy(void *s1, const void *s2, size_t n)
} }
#if _DEBUG #if _DEBUG
void liballoc_dump() void liballoc_dump() {
{
#ifdef _DEBUG #ifdef _DEBUG
struct liballoc_major *maj = l_memRoot; struct liballoc_major *maj = l_memRoot;
struct liballoc_minor *min = NULL; struct liballoc_minor *min = NULL;
@ -125,19 +113,12 @@ void liballoc_dump()
info("Possible overruns: %i", l_possibleOverruns); info("Possible overruns: %i", l_possibleOverruns);
#ifdef _DEBUG #ifdef _DEBUG
while (maj != NULL) while (maj != NULL) {
{ info("%x: total = %i, used = %i", maj, maj->size, maj->usage);
info("%x: total = %i, used = %i",
maj,
maj->size,
maj->usage);
min = maj->first; min = maj->first;
while (min != NULL) while (min != NULL) {
{ info(" %x: %i bytes", min, min->size);
info(" %x: %i bytes",
min,
min->size);
min = min->next; min = min->next;
} }
@ -146,14 +127,10 @@ void liballoc_dump()
#endif #endif
} }
#else #else
void liballoc_dump() void liballoc_dump() { return; }
{
return;
}
#endif #endif
static struct liballoc_major *allocate_new_page(unsigned int size) static struct liballoc_major *allocate_new_page(unsigned int size) {
{
unsigned int st; unsigned int st;
struct liballoc_major *maj; struct liballoc_major *maj;
@ -170,8 +147,7 @@ static struct liballoc_major *allocate_new_page(unsigned int size)
maj = (struct liballoc_major *)liballoc_alloc(st); maj = (struct liballoc_major *)liballoc_alloc(st);
if (maj == NULL) if (maj == NULL) {
{
l_warningCount += 1; l_warningCount += 1;
log("liballoc - (warning) liballoc_alloc( %i ) return NULL", st); log("liballoc - (warning) liballoc_alloc( %i ) return NULL", st);
return NULL; return NULL;
@ -186,14 +162,14 @@ static struct liballoc_major *allocate_new_page(unsigned int size)
l_allocated += maj->size; l_allocated += maj->size;
log("liballoc - Resource allocated %x of %i pages (%i bytes) for %i size.", maj, st, maj->size, size); log("liballoc - Resource allocated %x of %i pages (%i bytes) for %i size.",
maj, st, maj->size, size);
log("liballoc - Total memory usage = %i KB", (int)((l_allocated / (1024)))); log("liballoc - Total memory usage = %i KB", (int)((l_allocated / (1024))));
return maj; return maj;
} }
void *PREFIX(malloc)(size_t req_size) void *PREFIX(malloc)(size_t req_size) {
{
int startedBet = 0; int startedBet = 0;
unsigned long long bestSize = 0; unsigned long long bestSize = 0;
void *p = NULL; void *p = NULL;
@ -203,15 +179,13 @@ void *PREFIX(malloc)(size_t req_size)
struct liballoc_minor *new_min; struct liballoc_minor *new_min;
unsigned long size = req_size; unsigned long size = req_size;
if (ALIGNMENT > 1) if (ALIGNMENT > 1) {
{
size += ALIGNMENT + ALIGN_INFO; size += ALIGNMENT + ALIGN_INFO;
} }
liballoc_lock(); liballoc_lock();
if (size == 0) if (size == 0) {
{
l_warningCount += 1; l_warningCount += 1;
log("liballoc - (warning) alloc( 0 ) called from %x", log("liballoc - (warning) alloc( 0 ) called from %x",
__builtin_return_address(0)); __builtin_return_address(0));
@ -220,12 +194,10 @@ void *PREFIX(malloc)(size_t req_size)
return PREFIX(malloc)(1); return PREFIX(malloc)(1);
} }
if (l_memRoot == NULL) if (l_memRoot == NULL) {
{
log("liballoc - initialization of liballoc " VERSION ""); log("liballoc - initialization of liballoc " VERSION "");
l_memRoot = allocate_new_page(size); l_memRoot = allocate_new_page(size);
if (l_memRoot == NULL) if (l_memRoot == NULL) {
{
liballoc_unlock(); liballoc_unlock();
log("liballoc - initial l_memRoot initialization failed", p); log("liballoc - initial l_memRoot initialization failed", p);
return NULL; return NULL;
@ -234,30 +206,25 @@ void *PREFIX(malloc)(size_t req_size)
log("liballoc - set up first memory major %x", l_memRoot); log("liballoc - set up first memory major %x", l_memRoot);
} }
log("liballoc - %x PREFIX(malloc)( %i ): ", log("liballoc - %x PREFIX(malloc)( %i ): ", __builtin_return_address(0),
__builtin_return_address(0),
size); size);
maj = l_memRoot; maj = l_memRoot;
startedBet = 0; startedBet = 0;
if (l_bestBet != NULL) if (l_bestBet != NULL) {
{
bestSize = l_bestBet->size - l_bestBet->usage; bestSize = l_bestBet->size - l_bestBet->usage;
if (bestSize > (size + sizeof(struct liballoc_minor))) if (bestSize > (size + sizeof(struct liballoc_minor))) {
{
maj = l_bestBet; maj = l_bestBet;
startedBet = 1; startedBet = 1;
} }
} }
while (maj != NULL) while (maj != NULL) {
{
diff = maj->size - maj->usage; diff = maj->size - maj->usage;
if (bestSize < diff) if (bestSize < diff) {
{
l_bestBet = maj; l_bestBet = maj;
bestSize = diff; bestSize = diff;
@ -265,18 +232,15 @@ void *PREFIX(malloc)(size_t req_size)
#ifdef USE_CASE1 #ifdef USE_CASE1
if (diff < (size + sizeof(struct liballoc_minor))) if (diff < (size + sizeof(struct liballoc_minor))) {
{
log("liballoc - (warning) CASE 1: Insufficient space in block %x", maj); log("liballoc - (warning) CASE 1: Insufficient space in block %x", maj);
if (maj->next != NULL) if (maj->next != NULL) {
{
maj = maj->next; maj = maj->next;
continue; continue;
} }
if (startedBet == 1) if (startedBet == 1) {
{
maj = l_memRoot; maj = l_memRoot;
startedBet = 0; startedBet = 0;
continue; continue;
@ -293,9 +257,9 @@ void *PREFIX(malloc)(size_t req_size)
#ifdef USE_CASE2 #ifdef USE_CASE2
if (maj->first == NULL) if (maj->first == NULL) {
{ maj->first = (struct liballoc_minor *)((uintptr_t)maj +
maj->first = (struct liballoc_minor *)((uintptr_t)maj + sizeof(struct liballoc_major)); sizeof(struct liballoc_major));
maj->first->magic = LIBALLOC_MAGIC; maj->first->magic = LIBALLOC_MAGIC;
maj->first->prev = NULL; maj->first->prev = NULL;
@ -324,10 +288,11 @@ void *PREFIX(malloc)(size_t req_size)
diff -= (uintptr_t)maj; diff -= (uintptr_t)maj;
diff -= sizeof(struct liballoc_major); diff -= sizeof(struct liballoc_major);
if (diff >= (size + sizeof(struct liballoc_minor))) if (diff >= (size + sizeof(struct liballoc_minor))) {
{
maj->first->prev = (struct liballoc_minor *)((uintptr_t)maj + sizeof(struct liballoc_major)); maj->first->prev =
(struct liballoc_minor *)((uintptr_t)maj +
sizeof(struct liballoc_major));
maj->first->prev->next = maj->first; maj->first->prev->next = maj->first;
maj->first = maj->first->prev; maj->first = maj->first->prev;
@ -354,21 +319,20 @@ void *PREFIX(malloc)(size_t req_size)
min = maj->first; min = maj->first;
while (min != NULL) while (min != NULL) {
{
if (min->next == NULL) if (min->next == NULL) {
{
diff = (uintptr_t)(maj) + maj->size; diff = (uintptr_t)(maj) + maj->size;
diff -= (uintptr_t)min; diff -= (uintptr_t)min;
diff -= sizeof(struct liballoc_minor); diff -= sizeof(struct liballoc_minor);
diff -= min->size; diff -= min->size;
if (diff >= (size + sizeof(struct liballoc_minor))) if (diff >= (size + sizeof(struct liballoc_minor))) {
{
min->next = (struct liballoc_minor *)((uintptr_t)min + sizeof(struct liballoc_minor) + min->size); min->next = (struct liballoc_minor *)((uintptr_t)min +
sizeof(struct liballoc_minor) +
min->size);
min->next->prev = min; min->next->prev = min;
min = min->next; min = min->next;
min->next = NULL; min->next = NULL;
@ -389,18 +353,18 @@ void *PREFIX(malloc)(size_t req_size)
} }
} }
if (min->next != NULL) if (min->next != NULL) {
{
diff = (uintptr_t)(min->next); diff = (uintptr_t)(min->next);
diff -= (uintptr_t)min; diff -= (uintptr_t)min;
diff -= sizeof(struct liballoc_minor); diff -= sizeof(struct liballoc_minor);
diff -= min->size; diff -= min->size;
if (diff >= (size + sizeof(struct liballoc_minor))) if (diff >= (size + sizeof(struct liballoc_minor))) {
{
new_min = (struct liballoc_minor *)((uintptr_t)min + sizeof(struct liballoc_minor) + min->size); new_min = (struct liballoc_minor *)((uintptr_t)min +
sizeof(struct liballoc_minor) +
min->size);
new_min->magic = LIBALLOC_MAGIC; new_min->magic = LIBALLOC_MAGIC;
new_min->next = min->next; new_min->next = min->next;
@ -430,12 +394,10 @@ void *PREFIX(malloc)(size_t req_size)
#ifdef USE_CASE5 #ifdef USE_CASE5
if (maj->next == NULL) if (maj->next == NULL) {
{
log("liballoc - (warning) CASE 5: block full"); log("liballoc - (warning) CASE 5: block full");
if (startedBet == 1) if (startedBet == 1) {
{
maj = l_memRoot; maj = l_memRoot;
startedBet = 0; startedBet = 0;
continue; continue;
@ -461,13 +423,11 @@ void *PREFIX(malloc)(size_t req_size)
return NULL; return NULL;
} }
void PREFIX(free)(void *ptr) void PREFIX(free)(void *ptr) {
{
struct liballoc_minor *min; struct liballoc_minor *min;
struct liballoc_major *maj; struct liballoc_major *maj;
if (ptr == NULL) if (ptr == NULL) {
{
l_warningCount += 1; l_warningCount += 1;
log("liballoc - (warning) PREFIX(free)( NULL ) called from %x", log("liballoc - (warning) PREFIX(free)( NULL ) called from %x",
__builtin_return_address(0)); __builtin_return_address(0));
@ -479,33 +439,25 @@ void PREFIX(free)(void *ptr)
liballoc_lock(); liballoc_lock();
min = (struct liballoc_minor *)((uintptr_t)ptr - sizeof(struct liballoc_minor)); min =
(struct liballoc_minor *)((uintptr_t)ptr - sizeof(struct liballoc_minor));
if (min->magic != LIBALLOC_MAGIC) if (min->magic != LIBALLOC_MAGIC) {
{
l_errorCount += 1; l_errorCount += 1;
if ( if (((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) ||
((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) ||
((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) || ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) ||
((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) {
{
l_possibleOverruns += 1; l_possibleOverruns += 1;
log("liballoc - (warning) Possible 1-3 byte overrun for magic %x != %x", log("liballoc - (warning) Possible 1-3 byte overrun for magic %x != %x",
min->magic, min->magic, LIBALLOC_MAGIC);
LIBALLOC_MAGIC);
} }
if (min->magic == LIBALLOC_DEAD) if (min->magic == LIBALLOC_DEAD) {
{ log("liballoc - multiple PREFIX(free)() attempt on %x from %x.", ptr,
log("liballoc - multiple PREFIX(free)() attempt on %x from %x.",
ptr,
__builtin_return_address(0)); __builtin_return_address(0));
} } else {
else log("liballoc - Bad PREFIX(free)( %x ) called from %x", ptr,
{
log("liballoc - Bad PREFIX(free)( %x ) called from %x",
ptr,
__builtin_return_address(0)); __builtin_return_address(0));
} }
@ -513,9 +465,7 @@ void PREFIX(free)(void *ptr)
return; return;
} }
log("liballoc - %x PREFIX(free)( %x ): ", log("liballoc - %x PREFIX(free)( %x ): ", __builtin_return_address(0), ptr);
__builtin_return_address(0),
ptr);
maj = min->block; maj = min->block;
@ -532,8 +482,7 @@ void PREFIX(free)(void *ptr)
if (min->prev == NULL) if (min->prev == NULL)
maj->first = min->next; maj->first = min->next;
if (maj->first == NULL) if (maj->first == NULL) {
{
if (l_memRoot == maj) if (l_memRoot == maj)
l_memRoot = maj->next; l_memRoot = maj->next;
if (l_bestBet == maj) if (l_bestBet == maj)
@ -545,11 +494,8 @@ void PREFIX(free)(void *ptr)
l_allocated -= maj->size; l_allocated -= maj->size;
liballoc_free(maj, maj->pages); liballoc_free(maj, maj->pages);
} } else {
else if (l_bestBet != NULL) {
{
if (l_bestBet != NULL)
{
int bestSize = l_bestBet->size - l_bestBet->usage; int bestSize = l_bestBet->size - l_bestBet->usage;
int majSize = maj->size - maj->usage; int majSize = maj->size - maj->usage;
@ -563,8 +509,7 @@ void PREFIX(free)(void *ptr)
liballoc_unlock(); liballoc_unlock();
} }
void *PREFIX(calloc)(size_t nobj, size_t size) void *PREFIX(calloc)(size_t nobj, size_t size) {
{
int real_size; int real_size;
void *p; void *p;
@ -577,14 +522,12 @@ void *PREFIX(calloc)(size_t nobj, size_t size)
return p; return p;
} }
void *PREFIX(realloc)(void *p, size_t size) void *PREFIX(realloc)(void *p, size_t size) {
{
void *ptr; void *ptr;
struct liballoc_minor *min; struct liballoc_minor *min;
unsigned int real_size; unsigned int real_size;
if (size == 0) if (size == 0) {
{
PREFIX(free) PREFIX(free)
(p); (p);
return NULL; return NULL;
@ -598,33 +541,25 @@ void *PREFIX(realloc)(void *p, size_t size)
liballoc_lock(); liballoc_lock();
min = (struct liballoc_minor *)((uintptr_t)ptr - sizeof(struct liballoc_minor)); min =
(struct liballoc_minor *)((uintptr_t)ptr - sizeof(struct liballoc_minor));
if (min->magic != LIBALLOC_MAGIC) if (min->magic != LIBALLOC_MAGIC) {
{
l_errorCount += 1; l_errorCount += 1;
if ( if (((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) ||
((min->magic & 0xFFFFFF) == (LIBALLOC_MAGIC & 0xFFFFFF)) ||
((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) || ((min->magic & 0xFFFF) == (LIBALLOC_MAGIC & 0xFFFF)) ||
((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) ((min->magic & 0xFF) == (LIBALLOC_MAGIC & 0xFF))) {
{
l_possibleOverruns += 1; l_possibleOverruns += 1;
log("liballoc - Possible 1-3 byte overrun for magic %x != %x", log("liballoc - Possible 1-3 byte overrun for magic %x != %x", min->magic,
min->magic,
LIBALLOC_MAGIC); LIBALLOC_MAGIC);
} }
if (min->magic == LIBALLOC_DEAD) if (min->magic == LIBALLOC_DEAD) {
{
log("liballoc - liballoc: multiple PREFIX(free)() attempt on %x from %x.", log("liballoc - liballoc: multiple PREFIX(free)() attempt on %x from %x.",
ptr, ptr, __builtin_return_address(0));
__builtin_return_address(0)); } else {
} log("liballoc - liballoc: Bad PREFIX(free)( %x ) called from %x", ptr,
else
{
log("liballoc - liballoc: Bad PREFIX(free)( %x ) called from %x",
ptr,
__builtin_return_address(0)); __builtin_return_address(0));
} }
@ -634,8 +569,7 @@ void *PREFIX(realloc)(void *p, size_t size)
real_size = min->req_size; real_size = min->req_size;
if (real_size >= size) if (real_size >= size) {
{
min->req_size = size; min->req_size = size;
liballoc_unlock(); liballoc_unlock();
return p; return p;

View file

@ -1,40 +1,34 @@
#include "mm/liballoc/liballoc.h" #include "mm/liballoc/liballoc.h"
#include "mm/vmm.h" #include "mm/vmm.h"
#include <mm/vma.h>
#include <lib/spinlock.h> #include <lib/spinlock.h>
#include <mm/vma.h>
#include <stddef.h> #include <stddef.h>
extern vma_context_t *kernel_vma_context; extern vma_context_t *kernel_vma_context;
static spinlock_t liballoc_lock_var = { 0 }; static spinlock_t liballoc_lock_var = {0};
int liballoc_lock() int liballoc_lock() {
{
spinlock_acquire(&liballoc_lock_var); spinlock_acquire(&liballoc_lock_var);
return 0; return 0;
} }
int liballoc_unlock() int liballoc_unlock() {
{
spinlock_release(&liballoc_lock_var); spinlock_release(&liballoc_lock_var);
return 0; return 0;
} }
void *liballoc_alloc(size_t pages) void *liballoc_alloc(size_t pages) {
{
return vma_alloc(kernel_vma_context, pages, VMM_PRESENT | VMM_WRITABLE); return vma_alloc(kernel_vma_context, pages, VMM_PRESENT | VMM_WRITABLE);
} }
int liballoc_free(void *ptr, size_t pages) int liballoc_free(void *ptr, size_t pages) {
{
(void)pages; (void)pages;
vma_free(kernel_vma_context, ptr); vma_free(kernel_vma_context, ptr);
return 0; return 0;
} }
// void *malloc(size_t s) { return PREFIX(malloc)(s); }
// void *realloc(void *v, size_t s) { return PREFIX(realloc)(v, s); }
//void *malloc(size_t s) { return PREFIX(malloc)(s); } // void *calloc(size_t s1, size_t s) { return PREFIX(calloc)(s1, s); }
//void *realloc(void *v, size_t s) { return PREFIX(realloc)(v, s); } // void free(void *v) { return PREFIX(free)(v); }
//void *calloc(size_t s1, size_t s) { return PREFIX(calloc)(s1, s); }
//void free(void *v) { return PREFIX(free)(v); }

1
kernel/src/mm/memop.c Executable file → Normal file
View file

@ -10,7 +10,6 @@ void *memcpy(void *dest, const void *src, size_t n) {
uint8_t *pdest = (uint8_t *)dest; uint8_t *pdest = (uint8_t *)dest;
const uint8_t *psrc = (const uint8_t *)src; const uint8_t *psrc = (const uint8_t *)src;
for (size_t i = 0; i < n; i++) { for (size_t i = 0; i < n; i++) {
pdest[i] = psrc[i]; pdest[i] = psrc[i];
} }

75
kernel/src/mm/pmm.c Executable file → Normal file
View file

@ -1,7 +1,7 @@
#include "limine.h" #include "limine.h"
#include <stddef.h>
#include <mm/memop.h> #include <mm/memop.h>
#include <mm/pmm.h> #include <mm/pmm.h>
#include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <sys/log.h> #include <sys/log.h>
@ -10,34 +10,27 @@ struct limine_memmap_response *_memmap;
uint64_t hhdm_offset = 0x0; uint64_t hhdm_offset = 0x0;
__attribute__((used, section(".limine_requests"))) __attribute__((
struct limine_memmap_request mm_req = { used, section(".limine_requests"))) struct limine_memmap_request mm_req = {
.id = LIMINE_MEMMAP_REQUEST, .id = LIMINE_MEMMAP_REQUEST, .revision = 3};
.revision = 3
};
__attribute__((
used, section(".limine_requests"))) struct limine_hhdm_request hhdm_req = {
.id = LIMINE_HHDM_REQUEST, .revision = 3};
__attribute__((used, section(".limine_requests"))) int pmm_init() {
struct limine_hhdm_request hhdm_req = {
.id = LIMINE_HHDM_REQUEST,
.revision = 3
};
int pmm_init()
{
uint64_t free_pages = 0; uint64_t free_pages = 0;
hhdm_offset = hhdm_req.response->offset; hhdm_offset = hhdm_req.response->offset;
struct limine_memmap_response *memmap = mm_req.response; struct limine_memmap_response *memmap = mm_req.response;
_memmap = memmap; _memmap = memmap;
//DEBUG("mm", "----- PMM //INFO -----"); // DEBUG("mm", "----- PMM //INFO -----");
int freemem = 0; int freemem = 0;
for (uint64_t i = 0; i < memmap->entry_count; i++) for (uint64_t i = 0; i < memmap->entry_count; i++) {
{ if (memmap->entries[i]->type == LIMINE_MEMMAP_USABLE) {
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);
//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); free_pages += DIV_ROUND_UP(memmap->entries[i]->length, PMM_PAGE_SIZE);
freemem += memmap->entries[i]->length; freemem += memmap->entries[i]->length;
} }
@ -45,46 +38,38 @@ int pmm_init()
uint64_t array_size = ALIGN_UP(free_pages * 8, PMM_PAGE_SIZE); uint64_t array_size = ALIGN_UP(free_pages * 8, PMM_PAGE_SIZE);
for (uint64_t i = 0; i < memmap->entry_count; i++) for (uint64_t i = 0; i < memmap->entry_count; i++) {
{
struct limine_memmap_entry *entry = memmap->entries[i]; struct limine_memmap_entry *entry = memmap->entries[i];
if (entry->length >= array_size && entry->type == LIMINE_MEMMAP_USABLE) if (entry->length >= array_size && entry->type == LIMINE_MEMMAP_USABLE) {
{ stack.pages = (uintptr_t *)HIGHER_HALF(entry->base);
stack.pages = (uintptr_t*)HIGHER_HALF(entry->base);
entry->length -= array_size; entry->length -= array_size;
entry->base += array_size; entry->base += array_size;
//DEBUG("mm", " - STACK START\t\t@ 0x%.16llx", stack.pages); // DEBUG("mm", " - STACK START\t\t@ 0x%.16llx", stack.pages);
break; break;
} }
} }
for (uint64_t i = 0; i < memmap->entry_count; i++) for (uint64_t i = 0; i < memmap->entry_count; i++) {
{
struct limine_memmap_entry *entry = memmap->entries[i]; struct limine_memmap_entry *entry = memmap->entries[i];
if (entry->type == LIMINE_MEMMAP_USABLE) if (entry->type == LIMINE_MEMMAP_USABLE) {
{ for (uint64_t j = 0; j < entry->length; j += PMM_PAGE_SIZE) {
for (uint64_t j = 0; j < entry->length; j += PMM_PAGE_SIZE)
{
stack.pages[stack.idx++] = entry->base + j; stack.pages[stack.idx++] = entry->base + j;
} }
} }
} }
stack.max = stack.idx; stack.max = stack.idx;
//DEBUG("mm", " - MAX INDEX:\t\t%d", stack.max); // DEBUG("mm", " - MAX INDEX:\t\t%d", stack.max);
//DEBUG("mm", " - CURRENT INDEX:\t%d", stack.idx); // DEBUG("mm", " - CURRENT INDEX:\t%d", stack.idx);
//DEBUG("mm", "--------------------"); // DEBUG("mm", "--------------------");
log("pmm - %dmb is available to us.\n", freemem / (1024 * 1024)); log("pmm - %dmb is available to us.\n", freemem / (1024 * 1024));
return 0; return 0;
} }
void *pmm_request_page() void *pmm_request_page() {
{ if (stack.idx == 0) {
if (stack.idx == 0) // ERROR("mm", "No more pages available.");
{
//ERROR("mm", "No more pages available.");
log("pmm - out of memory.\n"); log("pmm - out of memory.\n");
asm("cli"); asm("cli");
while (1) { while (1) {
@ -98,14 +83,12 @@ void *pmm_request_page()
return (void *)page_addr; return (void *)page_addr;
} }
void pmm_free_page(void *ptr) void pmm_free_page(void *ptr) {
{
if (ptr == NULL) if (ptr == NULL)
return; return;
if (stack.idx >= stack.max) if (stack.idx >= stack.max) {
{ // ERROR("mm", "Stack overflow attempt while freeing a page.");
//ERROR("mm", "Stack overflow attempt while freeing a page.");
log("pmm - could not free the page: stack overflow.\n"); log("pmm - could not free the page: stack overflow.\n");
return; return;
} }

6
kernel/src/mm/pmm.h Executable file → Normal file
View file

@ -4,8 +4,7 @@
#include <stdint.h> #include <stdint.h>
#define PMM_PAGE_SIZE 4096 #define PMM_PAGE_SIZE 4096
typedef struct pmm_stack typedef struct pmm_stack {
{
uintptr_t *pages; uintptr_t *pages;
uint64_t idx; uint64_t idx;
uint64_t max; uint64_t max;
@ -13,7 +12,8 @@ typedef struct pmm_stack
extern uint64_t hhdm_offset; extern uint64_t hhdm_offset;
#define DIV_ROUND_UP(x, y) (((uint64_t)(x) + ((uint64_t)(y) - 1)) / (uint64_t)(y)) #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_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 ALIGN_DOWN(x, y) (((uint64_t)(x) / (uint64_t)(y)) * (uint64_t)(y))

View file

@ -3,19 +3,18 @@
#include "mm/pmm.h" #include "mm/pmm.h"
#include "mm/vmm.h" #include "mm/vmm.h"
#include <mm/vma.h>
#include <mm/memop.h> #include <mm/memop.h>
#include <mm/vma.h>
#include <sys/log.h> #include <sys/log.h>
vma_context_t *kernel_vma_context; vma_context_t *kernel_vma_context;
vma_context_t *vma_create_context(pagemap_t *pagemap) vma_context_t *vma_create_context(pagemap_t *pagemap) {
{ log("vma - creating VMA context with pagemap: 0x%.16llx\n",
log("vma - creating VMA context with pagemap: 0x%.16llx\n", (uint64_t)pagemap); (uint64_t)pagemap);
vma_context_t *ctx = (vma_context_t *)HIGHER_HALF(pmm_request_page()); vma_context_t *ctx = (vma_context_t *)HIGHER_HALF(pmm_request_page());
if (ctx == NULL) if (ctx == NULL) {
{
log("vma - failed to allocate VMA context\n"); log("vma - failed to allocate VMA context\n");
return NULL; return NULL;
} }
@ -24,8 +23,7 @@ vma_context_t *vma_create_context(pagemap_t *pagemap)
log("vma - zeroed out VMA context at 0x%.16llx\n", (uint64_t)ctx); log("vma - zeroed out VMA context at 0x%.16llx\n", (uint64_t)ctx);
ctx->root = (vma_region_t *)HIGHER_HALF(pmm_request_page()); ctx->root = (vma_region_t *)HIGHER_HALF(pmm_request_page());
if (ctx->root == NULL) if (ctx->root == NULL) {
{
log("vma - failed to allocate root region\n"); log("vma - failed to allocate root region\n");
pmm_free_page((void *)PHYSICAL(ctx)); pmm_free_page((void *)PHYSICAL(ctx));
return NULL; return NULL;
@ -36,23 +34,21 @@ vma_context_t *vma_create_context(pagemap_t *pagemap)
ctx->root->start = PMM_PAGE_SIZE; ctx->root->start = PMM_PAGE_SIZE;
ctx->root->size = 0; ctx->root->size = 0;
log("vma - VMA context created at 0x%.16llx with root region at 0x%.16llx\n", (uint64_t)ctx, (uint64_t)ctx->root); log("vma - VMA context created at 0x%.16llx with root region at 0x%.16llx\n",
(uint64_t)ctx, (uint64_t)ctx->root);
return ctx; return ctx;
} }
void vma_destroy_context(vma_context_t *ctx) void vma_destroy_context(vma_context_t *ctx) {
{
log("vma - destroying VMA context at 0x%.16llx\n", (uint64_t)ctx); log("vma - destroying VMA context at 0x%.16llx\n", (uint64_t)ctx);
if (ctx->root == NULL || ctx->pagemap == NULL) if (ctx->root == NULL || ctx->pagemap == NULL) {
{
log("vma - invalid context or root passed to vma_destroy_context\n"); log("vma - invalid context or root passed to vma_destroy_context\n");
return; return;
} }
vma_region_t *region = ctx->root; vma_region_t *region = ctx->root;
while (region != NULL) while (region != NULL) {
{
log("vma - freeing region at 0x%.16llx\n", (uint64_t)region); log("vma - freeing region at 0x%.16llx\n", (uint64_t)region);
vma_region_t *next = region->next; vma_region_t *next = region->next;
pmm_free_page((void *)PHYSICAL(region)); pmm_free_page((void *)PHYSICAL(region));
@ -63,10 +59,8 @@ void vma_destroy_context(vma_context_t *ctx)
log("vma - destroyed VMA context at 0x%.16llx\n", (uint64_t)ctx); log("vma - destroyed VMA context at 0x%.16llx\n", (uint64_t)ctx);
} }
void *vma_alloc(vma_context_t *ctx, uint64_t size, uint64_t flags) void *vma_alloc(vma_context_t *ctx, uint64_t size, uint64_t flags) {
{ if (ctx == NULL || ctx->root == NULL || ctx->pagemap == NULL) {
if (ctx == NULL || ctx->root == NULL || ctx->pagemap == NULL)
{
log("vma - invalid context or root passed to vma_alloc\n"); log("vma - invalid context or root passed to vma_alloc\n");
return NULL; return NULL;
} }
@ -75,13 +69,11 @@ void *vma_alloc(vma_context_t *ctx, uint64_t size, uint64_t flags)
vma_region_t *new_region; vma_region_t *new_region;
vma_region_t *last_region = ctx->root; vma_region_t *last_region = ctx->root;
while (region != NULL) while (region != NULL) {
{ if (region->next == NULL ||
if (region->next == NULL || region->start + region->size < region->next->start) region->start + region->size < region->next->start) {
{
new_region = (vma_region_t *)HIGHER_HALF(pmm_request_page()); new_region = (vma_region_t *)HIGHER_HALF(pmm_request_page());
if (new_region == NULL) if (new_region == NULL) {
{
log("vma - failed to allocate new VMA region\n"); log("vma - failed to allocate new VMA region\n");
return NULL; return NULL;
} }
@ -94,16 +86,15 @@ void *vma_alloc(vma_context_t *ctx, uint64_t size, uint64_t flags)
new_region->prev = region; new_region->prev = region;
region->next = new_region; region->next = new_region;
for (uint64_t i = 0; i < size; i++) for (uint64_t i = 0; i < size; i++) {
{
uint64_t page = (uint64_t)pmm_request_page(); uint64_t page = (uint64_t)pmm_request_page();
if (page == 0) if (page == 0) {
{
log("vma - failed to allocate physical memory for VMA region\n"); log("vma - failed to allocate physical memory for VMA region\n");
return NULL; return NULL;
} }
vmm_map(ctx->pagemap, new_region->start + i * PMM_PAGE_SIZE, page, new_region->flags); vmm_map(ctx->pagemap, new_region->start + i * PMM_PAGE_SIZE, page,
new_region->flags);
} }
return (void *)new_region->start; return (void *)new_region->start;
@ -112,8 +103,7 @@ void *vma_alloc(vma_context_t *ctx, uint64_t size, uint64_t flags)
} }
new_region = (vma_region_t *)HIGHER_HALF(pmm_request_page()); new_region = (vma_region_t *)HIGHER_HALF(pmm_request_page());
if (new_region == NULL) if (new_region == NULL) {
{
log("vma - failed to allocate new VMA region\n"); log("vma - failed to allocate new VMA region\n");
return NULL; return NULL;
} }
@ -127,73 +117,63 @@ void *vma_alloc(vma_context_t *ctx, uint64_t size, uint64_t flags)
new_region->flags = flags; new_region->flags = flags;
new_region->next = NULL; new_region->next = NULL;
for (uint64_t i = 0; i < size; i++) for (uint64_t i = 0; i < size; i++) {
{
uint64_t page = (uint64_t)pmm_request_page(); uint64_t page = (uint64_t)pmm_request_page();
if (page == 0) if (page == 0) {
{
log("vma - failed to allocate physical memory for VMA region\n"); log("vma - failed to allocate physical memory for VMA region\n");
return NULL; return NULL;
} }
vmm_map(ctx->pagemap, new_region->start + i * PMM_PAGE_SIZE, page, new_region->flags); vmm_map(ctx->pagemap, new_region->start + i * PMM_PAGE_SIZE, page,
new_region->flags);
} }
return (void *)new_region->start; return (void *)new_region->start;
} }
void vma_free(vma_context_t *ctx, void *ptr) void vma_free(vma_context_t *ctx, void *ptr) {
{ if (ctx == NULL) {
if (ctx == NULL)
{
log("vma - invalid context passed to vma_free\n"); log("vma - invalid context passed to vma_free\n");
return; return;
} }
vma_region_t *region = ctx->root; vma_region_t *region = ctx->root;
while (region != NULL) while (region != NULL) {
{ if (region->start == (uint64_t)ptr) {
if (region->start == (uint64_t)ptr)
{
log("vma - found region to free at 0x%.16llx\n", (uint64_t)region); log("vma - found region to free at 0x%.16llx\n", (uint64_t)region);
break; break;
} }
region = region->next; region = region->next;
} }
if (region == NULL) if (region == NULL) {
{ log("vma - unable to find region to free at address 0x%.16llx\n",
log("vma - unable to find region to free at address 0x%.16llx\n", (uint64_t)ptr); (uint64_t)ptr);
return; return;
} }
vma_region_t *prev = region->prev; vma_region_t *prev = region->prev;
vma_region_t *next = region->next; vma_region_t *next = region->next;
for (uint64_t i = 0; i < region->size; i++) for (uint64_t i = 0; i < region->size; i++) {
{
uint64_t virt = region->start + i * PMM_PAGE_SIZE; uint64_t virt = region->start + i * PMM_PAGE_SIZE;
uint64_t phys = virt_to_phys(vmm_kernel_pm, virt); uint64_t phys = virt_to_phys(vmm_kernel_pm, virt);
if (phys != 0) if (phys != 0) {
{
pmm_free_page((void *)phys); pmm_free_page((void *)phys);
vmm_unmap(ctx->pagemap, virt); vmm_unmap(ctx->pagemap, virt);
} }
} }
if (prev != NULL) if (prev != NULL) {
{
prev->next = next; prev->next = next;
} }
if (next != NULL) if (next != NULL) {
{
next->prev = prev; next->prev = prev;
} }
if (region == ctx->root) if (region == ctx->root) {
{
ctx->root = next; ctx->root = next;
} }

View file

@ -3,12 +3,11 @@
#pragma once #pragma once
#include <mm/vmm.h>
#include <mm/pmm.h> #include <mm/pmm.h>
#include <mm/vmm.h>
#include <stdint.h> #include <stdint.h>
typedef struct vma_region typedef struct vma_region {
{
uint64_t start; uint64_t start;
uint64_t size; uint64_t size;
uint64_t flags; uint64_t flags;
@ -16,8 +15,7 @@ typedef struct vma_region
struct vma_region *prev; struct vma_region *prev;
} vma_region_t; } vma_region_t;
typedef struct vma_context typedef struct vma_context {
{
pagemap_t *pagemap; pagemap_t *pagemap;
vma_region_t *root; vma_region_t *root;
} vma_context_t; } vma_context_t;

80
kernel/src/mm/vmm.c Executable file → Normal file
View file

@ -4,6 +4,7 @@
#include "mm/pmm.h" #include "mm/pmm.h"
#include "sys/log.h" #include "sys/log.h"
#include "vmm.h" #include "vmm.h"
#include <stdbool.h>
#include <stddef.h> #include <stddef.h>
__attribute__(( __attribute__((
@ -150,15 +151,16 @@ void vmm_load_pagemap(pagemap_t *pm) {
} }
static uint64_t *__vmm_get_next_lvl(uint64_t *level, uint64_t entry, static uint64_t *__vmm_get_next_lvl(uint64_t *level, uint64_t entry,
uint64_t flags) { uint64_t flags, bool alloc) {
if (!(level[entry] & 1)) { if (level[entry] & VMM_PRESENT)
uint64_t *pml = HIGHER_HALF(pmm_request_page());
memset(pml, 0, PMM_PAGE_SIZE);
level[entry] = (uint64_t)PHYSICAL(pml);
}
level[entry] |= (flags & 0xFFF);
return HIGHER_HALF(PTE_GET_ADDR(level[entry])); return HIGHER_HALF(PTE_GET_ADDR(level[entry]));
if (alloc) {
uint64_t *pml = (uint64_t *)HIGHER_HALF(pmm_request_page());
memset(pml, 0, PMM_PAGE_SIZE);
level[entry] = (uint64_t)PHYSICAL(pml) | flags;
return pml;
}
return NULL;
} }
uint64_t vmm_get_flags(pagemap_t *pm, uint64_t vaddr) { uint64_t vmm_get_flags(pagemap_t *pm, uint64_t vaddr) {
@ -167,9 +169,15 @@ uint64_t vmm_get_flags(pagemap_t *pm, uint64_t vaddr) {
uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; uint64_t pml2_entry = (vaddr >> 21) & 0x1ff;
uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; uint64_t pml1_entry = (vaddr >> 12) & 0x1ff;
uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, 0); uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, 0, false);
uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, 0); if (!pml3)
uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, 0); return 0;
uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, 0, false);
if (!pml2)
return 0;
uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, 0, false);
if (!pml1)
return 0;
return pml1[pml1_entry] & 0x7000000000000FFF; return pml1[pml1_entry] & 0x7000000000000FFF;
} }
@ -180,14 +188,17 @@ uint64_t virt_to_phys(pagemap_t *pagemap, uint64_t virt) {
uint64_t pml2_idx = (virt >> 21) & 0x1FF; uint64_t pml2_idx = (virt >> 21) & 0x1FF;
uint64_t pml1_idx = (virt >> 12) & 0x1FF; uint64_t pml1_idx = (virt >> 12) & 0x1FF;
uint64_t *pml3 = __vmm_get_next_lvl(pagemap->toplevel, pml4_idx, 0); uint64_t *pml3 = __vmm_get_next_lvl(pagemap->toplevel, pml4_idx, 0, false);
uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_idx, 0); if (!pml3)
uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_idx, 0); return 0;
uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_idx, 0, false);
if (!pml2)
return 0;
uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_idx, 0, false);
if (!pml1)
return 0;
uint64_t phys_addr = uint64_t phys_addr = pml1[pml1_idx] & 0x000FFFFFFFFFF000;
pml1[pml1_idx] &
0x000FFFFFFFFFF000; // Masque pour obtenir l'adresse physique (en retirant
// les bits de flags)
return phys_addr; return phys_addr;
} }
@ -198,9 +209,30 @@ void vmm_map(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, uint64_t flags) {
uint64_t pml2_entry = (vaddr >> 21) & 0x1ff; uint64_t pml2_entry = (vaddr >> 21) & 0x1ff;
uint64_t pml1_entry = (vaddr >> 12) & 0x1ff; uint64_t pml1_entry = (vaddr >> 12) & 0x1ff;
uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, flags); uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry,
uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, flags); VMM_PRESENT | VMM_WRITABLE, true);
uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, flags); uint64_t *pml2 =
__vmm_get_next_lvl(pml3, pml3_entry, VMM_PRESENT | VMM_WRITABLE, true);
uint64_t *pml1 =
__vmm_get_next_lvl(pml2, pml2_entry, VMM_PRESENT | VMM_WRITABLE, true);
pml1[pml1_entry] = paddr | flags;
}
void vmm_map_user(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,
true); // PML3 / Page Directory Pointer Entry
uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, flags,
true); // PML2 / Page Directory Entry
uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, flags,
true); // PML1 / Page Table Entry
pml1[pml1_entry] = paddr | flags; pml1[pml1_entry] = paddr | flags;
} }
@ -211,13 +243,13 @@ void vmm_unmap(pagemap_t *pm, uint64_t vaddr) {
uint64_t pml3_entry = (vaddr >> 30) & 0x1ff; uint64_t pml3_entry = (vaddr >> 30) & 0x1ff;
uint64_t pml4_entry = (vaddr >> 39) & 0x1ff; uint64_t pml4_entry = (vaddr >> 39) & 0x1ff;
uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, 0); uint64_t *pml3 = __vmm_get_next_lvl(pm->toplevel, pml4_entry, 0, false);
if (pml3 == NULL) if (pml3 == NULL)
return; return;
uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, 0); uint64_t *pml2 = __vmm_get_next_lvl(pml3, pml3_entry, 0, false);
if (pml2 == NULL) if (pml2 == NULL)
return; return;
uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, 0); uint64_t *pml1 = __vmm_get_next_lvl(pml2, pml2_entry, 0, false);
if (pml1 == NULL) if (pml1 == NULL)
return; return;

9
kernel/src/mm/vmm.h Executable file → Normal file
View file

@ -25,7 +25,6 @@ extern sym rodata_end_ld;
extern sym data_start_ld; extern sym data_start_ld;
extern sym data_end_ld; extern sym data_end_ld;
typedef struct pagemap { typedef struct pagemap {
uint64_t *toplevel; uint64_t *toplevel;
} pagemap_t; } pagemap_t;
@ -37,7 +36,11 @@ pagemap_t *vmm_alloc_pm();
void vmm_init(); void vmm_init();
void vmm_release_pm(pagemap_t *pm); void vmm_release_pm(pagemap_t *pm);
void vmm_load_pagemap(pagemap_t *pm); void vmm_load_pagemap(pagemap_t *pm);
uint64_t vmm_get_flags(pagemap_t* pm, uint64_t vaddr); uint64_t vmm_get_flags(pagemap_t *pm, uint64_t vaddr);
uint64_t virt_to_phys(pagemap_t *pagemap, uint64_t virt); uint64_t virt_to_phys(pagemap_t *pagemap, uint64_t virt);
// NOTE: for user mode, please use vmm_map_user instead.
void vmm_map(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, uint64_t flags); void vmm_map(pagemap_t *pm, uint64_t vaddr, uint64_t paddr, uint64_t flags);
void vmm_unmap(pagemap_t *pm, uint64_t vaddr) ; void vmm_map_user(pagemap_t *pm, uint64_t vaddr, uint64_t paddr,
uint64_t flags);
void vmm_unmap(pagemap_t *pm, uint64_t vaddr);

51
kernel/src/sched/sched.c Executable file → Normal file
View file

@ -1,6 +1,6 @@
#include "sched/sched.h" #include "sched/sched.h"
#include "mm/pmm.h"
#include "mm/memop.h" #include "mm/memop.h"
#include "mm/pmm.h"
#include "mm/vmm.h" #include "mm/vmm.h"
#include "sys/arch/x86_64/idt.h" #include "sys/arch/x86_64/idt.h"
#include "sys/log.h" #include "sys/log.h"
@ -11,13 +11,15 @@ sched_process *curr_proc;
int current_pid = 0; int current_pid = 0;
int standby = 0; int standby = 0;
void map_range_to_pagemap(pagemap_t *dest_pagemap, pagemap_t *src_pagemap, uint64_t start, uint64_t size, uint64_t flags) void map_range_to_pagemap(pagemap_t *dest_pagemap, pagemap_t *src_pagemap,
{ uint64_t start, uint64_t size, int user,
for (uint64_t offset = 0; offset < size; offset += PMM_PAGE_SIZE) uint64_t flags) {
{ for (uint64_t offset = 0; offset < size; offset += PMM_PAGE_SIZE) {
uint64_t phys = virt_to_phys(src_pagemap, start + offset); uint64_t phys = virt_to_phys(src_pagemap, start + offset);
if (phys) if (phys) {
{ if (user)
vmm_map_user(dest_pagemap, start + offset, phys, flags);
else
vmm_map(dest_pagemap, start + offset, phys, flags); vmm_map(dest_pagemap, start + offset, phys, flags);
} }
} }
@ -41,8 +43,8 @@ void sched_init() {
"mode.\n"); "mode.\n");
} }
sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t* pm, uint32_t flags) sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm,
{ uint32_t flags) {
// TODO: implement a separate strlen function // TODO: implement a separate strlen function
// as there's like 4 strlen impls in the kernel. // as there's like 4 strlen impls in the kernel.
int i = 0; int i = 0;
@ -64,14 +66,15 @@ sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t* pm, uin
proc->pm = pm; proc->pm = pm;
uint64_t *stack_phys = pmm_request_page(); uint64_t *stack_phys = pmm_request_page();
uint64_t *stack_virt = (uint64_t*)0x40000000; uint64_t *stack_virt = (uint64_t *)0x40000000;
if (flags == SCHED_KERNEL_PROCESS) { if (flags == SCHED_KERNEL_PROCESS) {
proc->stack_base = stack_phys; proc->stack_base = stack_phys;
proc->stack_base_physical = stack_phys; proc->stack_base_physical = stack_phys;
proc->stack_end = proc_list->stack_base + PMM_PAGE_SIZE; proc->stack_end = proc_list->stack_base + PMM_PAGE_SIZE;
} else if (flags == SCHED_USER_PROCESS) { } else if (flags == SCHED_USER_PROCESS) {
vmm_map(proc->pm, (uint64_t)stack_virt, (uint64_t)stack_phys, VMM_PRESENT | VMM_WRITABLE | VMM_USER); vmm_map_user(proc->pm, (uint64_t)stack_virt, (uint64_t)stack_phys,
VMM_PRESENT | VMM_WRITABLE | VMM_USER);
proc->stack_base = stack_virt; proc->stack_base = stack_virt;
proc->stack_base_physical = stack_phys; proc->stack_base_physical = stack_phys;
proc->stack_end = proc_list->stack_base + PMM_PAGE_SIZE; proc->stack_end = proc_list->stack_base + PMM_PAGE_SIZE;
@ -81,8 +84,7 @@ sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t* pm, uin
if (flags == SCHED_KERNEL_PROCESS) { if (flags == SCHED_KERNEL_PROCESS) {
proc->regs.cs = 0x28; // Run in kernel mode proc->regs.cs = 0x28; // Run in kernel mode
proc->regs.ss = 0x30; proc->regs.ss = 0x30;
} } else if (flags == SCHED_USER_PROCESS) {
else if (flags == SCHED_USER_PROCESS) {
proc->regs.cs = 0x43; // Run in user mode proc->regs.cs = 0x43; // Run in user mode
proc->regs.ss = 0x3B; proc->regs.ss = 0x3B;
} }
@ -95,7 +97,12 @@ sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t* pm, uin
current_pid++; current_pid++;
map_range_to_pagemap(pm, vmm_kernel_pm, 0x1000, 0x10000, VMM_PRESENT | VMM_WRITABLE | VMM_USER); if (flags == SCHED_USER_PROCESS)
map_range_to_pagemap(pm, vmm_kernel_pm, 0x1000, 0x10000, 1,
VMM_PRESENT | VMM_WRITABLE | VMM_USER);
else
map_range_to_pagemap(pm, vmm_kernel_pm, 0x1000, 0x10000, 0,
VMM_PRESENT | VMM_WRITABLE);
if (standby) { if (standby) {
// Disable standby mode as there's actually something to // Disable standby mode as there's actually something to
@ -105,7 +112,8 @@ sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t* pm, uin
"disabled.\n"); "disabled.\n");
} }
log("sched - created process '%s' (pid: %d, rip: %p)\n", proc->name, proc->pid, proc->regs.rip); log("sched - created process '%s' (pid: %d, rip: %p)\n", proc->name,
proc->pid, proc->regs.rip);
return proc; return proc;
} }
@ -115,10 +123,9 @@ void sched_exit(int exit_code) {
schedule(&curr_proc->regs); schedule(&curr_proc->regs);
} }
void schedule(registers_t *regs) void schedule(registers_t *regs) {
{
if (standby) { if (standby) {
//log("sched - Sched is in standby.\n"); // log("sched - Sched is in standby.\n");
return; return;
} }
@ -146,13 +153,13 @@ void schedule(registers_t *regs)
if (curr_proc == NULL) if (curr_proc == NULL)
curr_proc = proc_list; curr_proc = proc_list;
//log("sched - I choosed process %d\n", curr_proc->pid); // log("sched - I choosed process %d\n", curr_proc->pid);
memcpy(regs, &curr_proc->regs, sizeof(registers_t)); memcpy(regs, &curr_proc->regs, sizeof(registers_t));
// Finally, load our pagemap // Finally, load our pagemap
//if (memcmp(curr_proc->name, "Init", 4)== 0) { // if (memcmp(curr_proc->name, "Init", 4)== 0) {
vmm_load_pagemap(curr_proc->pm); vmm_load_pagemap(curr_proc->pm);
//asm("cli"); // asm("cli");
//while (1) // while (1)
// asm("hlt");} // asm("hlt");}
} }

15
kernel/src/sched/sched.h Executable file → Normal file
View file

@ -4,13 +4,11 @@
#include "sys/arch/x86_64/idt.h" #include "sys/arch/x86_64/idt.h"
#define SCHED_KERNEL_PROCESS 0 // A process that runs in kernel mode. #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. #define SCHED_USER_PROCESS \
1 // A process that runs in userspace. The code MUST be mapped directly after
// creating the process.
typedef enum { typedef enum { SCHED_RUNNING, SCHED_DIED, SCHED_EMPTY } sched_proc_type;
SCHED_RUNNING,
SCHED_DIED,
SCHED_EMPTY
} sched_proc_type;
typedef struct _sched_process { typedef struct _sched_process {
char name[128]; char name[128];
@ -33,9 +31,10 @@ extern sched_process *proc_list;
// The idle process is ditched in favor of standby mode, // The idle process is ditched in favor of standby mode,
// which activates when there's nothing to run. // which activates when there's nothing to run.
//extern sched_process *idle_process; // extern sched_process *idle_process;
void sched_init(); void sched_init();
sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm, uint32_t flags); sched_process *sched_create(char *name, uint64_t entry_point, pagemap_t *pm,
uint32_t flags);
void sched_exit(int exit_code); void sched_exit(int exit_code);
void schedule(registers_t *regs); void schedule(registers_t *regs);

95
kernel/src/sys/acpi.c Normal file
View file

@ -0,0 +1,95 @@
#include "limine.h"
#include "mm/pmm.h"
#include "sys/log.h"
#include <mm/memop.h>
#include <stddef.h>
#include <sys/acpi.h>
__attribute__((
used,
section(".limine_requests"))) static volatile struct limine_rsdp_request
rsdp_req = {.revision = 0, .id = LIMINE_RSDP_REQUEST};
rsdp_t *rsdp;
int acpi_available = 0;
int is_xsdt = 0;
xsdt_t *xsdt;
rsdt_t *rsdt;
int item_count = 0;
static int acpi_validate_rsdp(char *byte_array, size_t size) {
uint32_t sum = 0;
for (int i = 0; i < size; i++) {
sum += byte_array[i];
}
return (sum & 0xFF) == 0;
}
void *acpi_find_table(char *sign, int sign_size) {
if (!acpi_available)
return NULL;
if (is_xsdt) {
for (int i = 0; i < item_count; i++) {
uint64_t *lst =
(uint64_t *)HIGHER_HALF((uint64_t)xsdt->PointerToOtherSDT);
acpi_table_header_t *ptr = (acpi_table_header_t *)HIGHER_HALF(lst[i]);
if (!memcmp(ptr->Signature, sign, sign_size))
return (void *)ptr;
}
} else {
for (int i = 0; i < item_count; i++) {
acpi_table_header_t *ptr = (acpi_table_header_t *)HIGHER_HALF(
(uint64_t)rsdt->PointerToOtherSDT[i]);
if (!memcmp(ptr->Signature, sign, sign_size))
return (void *)ptr;
}
}
return NULL;
}
void acpi_init() {
rsdp_t *rsdp = (rsdp_t *)HIGHER_HALF(rsdp_req.response->address);
if (!rsdp) {
log("acpi - not available: RSDP is NULL!\n");
return;
}
if (rsdp->rev < 2) {
if (!acpi_validate_rsdp((char *)rsdp, sizeof(rsdp_t))) {
log("acpi - not available: Was the RSDP hijacked?\n");
return;
}
rsdt = (rsdt_t *)HIGHER_HALF((uint64_t)rsdp->rsdt_addr);
log("acpi - RSDT found at %p\n", rsdt);
item_count = (rsdt->h.Length - sizeof(acpi_table_header_t)) / 4;
log("acpi - RSDT contains %d entries\n", item_count);
} else {
is_xsdt = 1;
if (!acpi_validate_rsdp((char *)rsdp, sizeof(xsdp_t))) {
log("acpi - not available: Was the XSDP hijacked?\n");
return;
}
xsdt = (xsdt_t *)HIGHER_HALF((uint64_t)((xsdp_t *)rsdp)->xsdt_addr);
log("acpi - XSDT found at %p\n", xsdt);
item_count = (xsdt->h.Length - sizeof(acpi_table_header_t)) / 8;
log("acpi - XSDT contains %d entries\n", item_count);
}
acpi_available = 1;
void *fadt = acpi_find_table("FACP", 4);
if (!fadt) {
log("acpi - FADT not found\n");
acpi_available = 0;
return;
} else {
log("acpi - FADT found at %p\n", fadt);
log("acpi - ACPI initialized successfully\n");
}
}

51
kernel/src/sys/acpi.h Normal file
View file

@ -0,0 +1,51 @@
#pragma once
#include <stdint.h>
#define ACPI_RSDP_SIGNATURE "RSD PTR "
#define ACPI_RSDP_SIGNATURE_LEN 7
typedef struct __acpi_table_header {
char Signature[4];
uint32_t Length;
uint8_t Revision;
uint8_t Checksum;
char OEMID[6];
char OEMTableID[8];
uint32_t OEMRevision;
uint32_t CreatorID;
uint32_t CreatorRevision;
} acpi_table_header_t;
typedef struct __rsdp {
char signature[8];
uint8_t chksum;
char oemid[6];
uint8_t rev;
uint32_t rsdt_addr;
} __attribute__((packed)) rsdp_t;
typedef struct __xsdp {
char signature[8];
uint8_t chksum;
char oemid[6];
uint8_t rev;
uint32_t rsdt_addr; // deprecated since version 2.0
uint32_t len;
uint64_t xsdt_addr;
uint8_t chksum_ex;
uint8_t reserved[3];
} __attribute__((packed)) xsdp_t;
typedef struct __rsdt {
acpi_table_header_t h;
uint32_t *PointerToOtherSDT;
} rsdt_t;
typedef struct __xsdt {
acpi_table_header_t h;
uint64_t *PointerToOtherSDT;
} xsdt_t;
void acpi_init();

100
kernel/src/sys/arch/x86_64/cpuid.h Executable file → Normal file
View file

@ -36,7 +36,7 @@
#define CPUID_CPU_INFO_ECX_CMPXCHG16B 1 << 13 #define CPUID_CPU_INFO_ECX_CMPXCHG16B 1 << 13
#define CPUID_CPU_INFO_ECX_XTPR_UC 1 << 14 #define CPUID_CPU_INFO_ECX_XTPR_UC 1 << 14
#define CPUID_CPU_INFO_ECX_PDCM 1 << 15 #define CPUID_CPU_INFO_ECX_PDCM 1 << 15
//bit 16 is reserved // bit 16 is reserved
#define CPUID_CPU_INFO_ECX_PCID 1 << 17 #define CPUID_CPU_INFO_ECX_PCID 1 << 17
#define CPUID_CPU_INFO_ECX_DCA 1 << 18 #define CPUID_CPU_INFO_ECX_DCA 1 << 18
#define CPUID_CPU_INFO_ECX_SSE4_1 1 << 19 #define CPUID_CPU_INFO_ECX_SSE4_1 1 << 19
@ -51,7 +51,7 @@
#define CPUID_CPU_INFO_ECX_AVX 1 << 28 #define CPUID_CPU_INFO_ECX_AVX 1 << 28
#define CPUID_CPU_INFO_ECX_F16C 1 << 29 #define CPUID_CPU_INFO_ECX_F16C 1 << 29
#define CPUID_CPU_INFO_ECX_RDRAND 1 << 30 #define CPUID_CPU_INFO_ECX_RDRAND 1 << 30
//bit 31 is unused // bit 31 is unused
#define CPUID_CPU_INFO_EDX_FPU 1 << 0 #define CPUID_CPU_INFO_EDX_FPU 1 << 0
#define CPUID_CPU_INFO_EDX_VME 1 << 1 #define CPUID_CPU_INFO_EDX_VME 1 << 1
@ -63,7 +63,7 @@
#define CPUID_CPU_INFO_EDX_MCE 1 << 7 #define CPUID_CPU_INFO_EDX_MCE 1 << 7
#define CPUID_CPU_INFO_EDX_CX8 1 << 8 #define CPUID_CPU_INFO_EDX_CX8 1 << 8
#define CPUID_CPU_INFO_EDX_APIC 1 << 9 #define CPUID_CPU_INFO_EDX_APIC 1 << 9
//bit 10 is reserved // bit 10 is reserved
#define CPUID_CPU_INFO_EDX_SEP 1 << 11 #define CPUID_CPU_INFO_EDX_SEP 1 << 11
#define CPUID_CPU_INFO_EDX_MTRR 1 << 12 #define CPUID_CPU_INFO_EDX_MTRR 1 << 12
#define CPUID_CPU_INFO_EDX_PGE 1 << 13 #define CPUID_CPU_INFO_EDX_PGE 1 << 13
@ -73,7 +73,7 @@
#define CPUID_CPU_INFO_EDX_PSE_36 1 << 17 #define CPUID_CPU_INFO_EDX_PSE_36 1 << 17
#define CPUID_CPU_INFO_EDX_PSN 1 << 18 #define CPUID_CPU_INFO_EDX_PSN 1 << 18
#define CPUID_CPU_INFO_EDX_CLFSH 1 << 19 #define CPUID_CPU_INFO_EDX_CLFSH 1 << 19
//bit 20 is reserved // bit 20 is reserved
#define CPUID_CPU_INFO_EDX_DS 1 << 21 #define CPUID_CPU_INFO_EDX_DS 1 << 21
#define CPUID_CPU_INFO_EDX_ACPI 1 << 22 #define CPUID_CPU_INFO_EDX_ACPI 1 << 22
#define CPUID_CPU_INFO_EDX_MMX 1 << 23 #define CPUID_CPU_INFO_EDX_MMX 1 << 23
@ -83,11 +83,11 @@
#define CPUID_CPU_INFO_EDX_SS 1 << 27 #define CPUID_CPU_INFO_EDX_SS 1 << 27
#define CPUID_CPU_INFO_EDX_HTT 1 << 28 #define CPUID_CPU_INFO_EDX_HTT 1 << 28
#define CPUID_CPU_INFO_EDX_TM 1 << 29 #define CPUID_CPU_INFO_EDX_TM 1 << 29
//bit 30 is reserved // bit 30 is reserved
#define CPUID_CPU_INFO_EDX_PBE 1 << 31 #define CPUID_CPU_INFO_EDX_PBE 1 << 31
//===============CPUID_CACHE_TLB=============== //===============CPUID_CACHE_TLB===============
//WARNING: I gave up and used ChatGPT for these // WARNING: I gave up and used ChatGPT for these
#define CPUID_CACHE_TLB_DESC_NULL 0x00 #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_KBYTE_4WAY_32E 0x01
#define CPUID_CACHE_TLB_DESC_TLB_4_MBYTE_FULLY_2E 0x02 #define CPUID_CACHE_TLB_DESC_TLB_4_MBYTE_FULLY_2E 0x02
@ -203,7 +203,7 @@
#define CPUID_CACHE_TLB_DESC_NO_CACHE_INFO_CPUID_LEAF_4 0xFF #define CPUID_CACHE_TLB_DESC_NO_CACHE_INFO_CPUID_LEAF_4 0xFF
//=============CPUID_SERIAL_NUMBER============= //=============CPUID_SERIAL_NUMBER=============
#define CPUID_SERIAL_NUMBER_STITCH(ECX,EDX) (uint64_t)((EDX << 32) | ECX) #define CPUID_SERIAL_NUMBER_STITCH(ECX, EDX) (uint64_t)((EDX << 32) | ECX)
//=============CPUID_CACHE_PARAMS============== //=============CPUID_CACHE_PARAMS==============
#define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE 0xF #define CPUID_CACHE_PARAMS_EAX_CACHE_TYPE 0xF
@ -242,7 +242,7 @@
#define CPUID_THERMAL_AND_POWER_EAX_TEMP_SENSOR 1 #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_TURBO_BOOST 1 << 1
#define CPUID_THERMAL_AND_POWER_EAX_ARAT 1 << 2 #define CPUID_THERMAL_AND_POWER_EAX_ARAT 1 << 2
//Bit 3 is reserved // Bit 3 is reserved
#define CPUID_THERMAL_AND_POWER_EAX_PLN 1 << 3 #define CPUID_THERMAL_AND_POWER_EAX_PLN 1 << 3
#define CPUID_THERMAL_AND_POWER_EAX_ECMD 1 << 5 #define CPUID_THERMAL_AND_POWER_EAX_ECMD 1 << 5
#define CPUID_THERMAL_AND_POWER_EAX_PTM 1 << 6 #define CPUID_THERMAL_AND_POWER_EAX_PTM 1 << 6
@ -251,7 +251,7 @@
#define CPUID_THERMAL_AND_POWER_EAX_HWP_ACT_WINDOW 1 << 9 #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_PERF_PREF 1 << 10
#define CPUID_THERMAL_AND_POWER_EAX_HWP_PKG_LVL_REQ 1 << 11 #define CPUID_THERMAL_AND_POWER_EAX_HWP_PKG_LVL_REQ 1 << 11
//Bit 12 is reserved // Bit 12 is reserved
#define CPUID_THERMAL_AND_POWER_EAX_HDC 1 << 13 #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_TURBO_BOOST_MAX 1 << 14
#define CPUID_THERMAL_AND_POWER_EAX_HWP_CAPABILITIES 1 << 15 #define CPUID_THERMAL_AND_POWER_EAX_HWP_CAPABILITIES 1 << 15
@ -260,7 +260,7 @@
#define CPUID_THERMAL_AND_POWER_EAX_FAST_HWP_REQUEST 1 << 18 #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_HW_FEEDBACK 1 << 19
#define CPUID_THERMAL_AND_POWER_EAX_IGNORE_HWP_IDLE 1 << 20 #define CPUID_THERMAL_AND_POWER_EAX_IGNORE_HWP_IDLE 1 << 20
//Bits 21 and 22 are reserved // Bits 21 and 22 are reserved
#define CPUID_THERMAL_AND_POWER_EAX_THREAD_DIRECTOR 1 << 23 #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_EAX_THERM_INTERRUPT 1 << 24
@ -324,41 +324,42 @@
#define CPUID_EXTENDED_FEATURES_ECX_AVX512_BITLANG 1 << 12 #define CPUID_EXTENDED_FEATURES_ECX_AVX512_BITLANG 1 << 12
#define CPUID_EXTENDED_FEATURES_ECX_TME_EN 1 << 13 #define CPUID_EXTENDED_FEATURES_ECX_TME_EN 1 << 13
#define CPUID_EXTENDED_FEATURES_ECX_AVX512_VPOPVNZDQ 1 << 14 #define CPUID_EXTENDED_FEATURES_ECX_AVX512_VPOPVNZDQ 1 << 14
//bit 15 is reserved // bit 15 is reserved
#define CPUID_EXTENDED_FEATURES_ECX_LA57 1 << 16 #define CPUID_EXTENDED_FEATURES_ECX_LA57 1 << 16
#define CPUID_EXTENDED_FEATURES_ECX_MAWAU_VAL 0x1F << 17 #define CPUID_EXTENDED_FEATURES_ECX_MAWAU_VAL 0x1F << 17
#define CPUID_EXTENDED_FEATURES_ECX_RDPID 1 << 22 #define CPUID_EXTENDED_FEATURES_ECX_RDPID 1 << 22
#define CPUID_EXTENDED_FEATURES_ECX_KL 1 << 23 #define CPUID_EXTENDED_FEATURES_ECX_KL 1 << 23
#define CPUID_EXTENDED_FEATURES_ECX_BUS_LOCK_DETECT 1 << 24 #define CPUID_EXTENDED_FEATURES_ECX_BUS_LOCK_DETECT 1 << 24
#define CPUID_EXTENDED_FEATURES_ECX_CLDEMOTE 1 << 25 #define CPUID_EXTENDED_FEATURES_ECX_CLDEMOTE 1 << 25
//bit 26 is reserved // bit 26 is reserved
#define CPUID_EXTENDED_FEATURES_ECX_MOVDIRI 1 << 27 #define CPUID_EXTENDED_FEATURES_ECX_MOVDIRI 1 << 27
#define CPUID_EXTENDED_FEATURES_ECX_MOVDIR64B 1 << 28 #define CPUID_EXTENDED_FEATURES_ECX_MOVDIR64B 1 << 28
#define CPUID_EXTENDED_FEATURES_ECX_ENQCMD 1 << 29 #define CPUID_EXTENDED_FEATURES_ECX_ENQCMD 1 << 29
#define CPUID_EXTENDED_FEATURES_ECX_SGX_LC 1 << 30 #define CPUID_EXTENDED_FEATURES_ECX_SGX_LC 1 << 30
#define CPUID_EXTENDED_FEATURES_ECX_PKS 1 << 31 #define CPUID_EXTENDED_FEATURES_ECX_PKS 1 << 31
//bit 0 is reserved // bit 0 is reserved
#define CPUID_EXTENDED_FEATURES_EDX_SGX_KEYS 1 << 1 #define CPUID_EXTENDED_FEATURES_EDX_SGX_KEYS 1 << 1
#define CPUID_EXTENDED_FEATURES_EDX_AVX512_4VNNIW 1 << 2 #define CPUID_EXTENDED_FEATURES_EDX_AVX512_4VNNIW 1 << 2
#define CPUID_EXTENDED_FEATURES_EDX_AVX512_4FMAPS 1 << 3 #define CPUID_EXTENDED_FEATURES_EDX_AVX512_4FMAPS 1 << 3
#define CPUID_EXTENDED_FEATURES_EDX_FAST_REP_MOV 1 << 4 #define CPUID_EXTENDED_FEATURES_EDX_FAST_REP_MOV 1 << 4
#define CPUID_EXTENDED_FEATURES_EDX_UINTR 1 << 5 #define CPUID_EXTENDED_FEATURES_EDX_UINTR 1 << 5
//bits 6 and 7 are reserved // 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_AVX512_VPINTERSECT \
1 << 8 // intel you son of a bitch
#define CPUID_EXTENDED_FEATURES_EDX_SRBDS_CTRL 1 << 9 #define CPUID_EXTENDED_FEATURES_EDX_SRBDS_CTRL 1 << 9
#define CPUID_EXTENDED_FEATURES_EDX_MD_CLEAR 1 << 10 #define CPUID_EXTENDED_FEATURES_EDX_MD_CLEAR 1 << 10
#define CPUID_EXTENDED_FEATURES_EDX_RTM_ALWAYS_ABORT 1 << 11 #define CPUID_EXTENDED_FEATURES_EDX_RTM_ALWAYS_ABORT 1 << 11
//bit 12 is reserved // bit 12 is reserved
#define CPUID_EXTENDED_FEATURES_EDX_RTM_FORCE_ABORT 1 << 13 #define CPUID_EXTENDED_FEATURES_EDX_RTM_FORCE_ABORT 1 << 13
#define CPUID_EXTENDED_FEATURES_EDX_SERIALIZE 1 << 14 #define CPUID_EXTENDED_FEATURES_EDX_SERIALIZE 1 << 14
#define CPUID_EXTENDED_FEATURES_EDX_HYBRID 1 << 15 #define CPUID_EXTENDED_FEATURES_EDX_HYBRID 1 << 15
#define CPUID_EXTENDED_FEATURES_EDX_TSXLDTRK 1 << 16 #define CPUID_EXTENDED_FEATURES_EDX_TSXLDTRK 1 << 16
//bit 17 is reserved // bit 17 is reserved
#define CPUID_EXTENDED_FEATURES_EDX_PCONFIG 1 << 18 #define CPUID_EXTENDED_FEATURES_EDX_PCONFIG 1 << 18
#define CPUID_EXTENDED_FEATURES_EDX_ARCHITECTURAL_LBR 1 << 19 #define CPUID_EXTENDED_FEATURES_EDX_ARCHITECTURAL_LBR 1 << 19
#define CPUID_EXTENDED_FEATURES_EDX_CET_IBT 1 << 20 #define CPUID_EXTENDED_FEATURES_EDX_CET_IBT 1 << 20
//bit 21 is reserved // bit 21 is reserved
#define CPUID_EXTENDED_FEATURES_EDX_AMX_BF16 1 << 22 #define CPUID_EXTENDED_FEATURES_EDX_AMX_BF16 1 << 22
#define CPUID_EXTENDED_FEATURES_EDX_AVX512_FP16 1 << 23 #define CPUID_EXTENDED_FEATURES_EDX_AVX512_FP16 1 << 23
#define CPUID_EXTENDED_FEATURES_EDX_AMX_TILE 1 << 24 #define CPUID_EXTENDED_FEATURES_EDX_AMX_TILE 1 << 24
@ -371,18 +372,18 @@
#define CPUID_EXTENDED_FEATURES_EDX_SSBD 1 << 31 #define CPUID_EXTENDED_FEATURES_EDX_SSBD 1 << 31
//=========CPUID_EXTENDED_FEATURES_SL1========= //=========CPUID_EXTENDED_FEATURES_SL1=========
//bits 0-3 are reserved // bits 0-3 are reserved
#define CPUID_EXTENDED_FEATURES_SL1_EAX_AVX_VNNI 1 << 4 #define CPUID_EXTENDED_FEATURES_SL1_EAX_AVX_VNNI 1 << 4
#define CPUID_EXTENDED_FEATURES_SL1_EAX_AVX512_BF16 1 << 5 #define CPUID_EXTENDED_FEATURES_SL1_EAX_AVX512_BF16 1 << 5
//bits 6-9 are reserved // bits 6-9 are reserved
#define CPUID_EXTENDED_FEATURES_SL1_EAX_0_REP_MOVSB 1 << 10 #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_STOSB 1 << 11
#define CPUID_EXTENDED_FEATURES_SL1_EAX_FAST_CMPSB 1 << 12 #define CPUID_EXTENDED_FEATURES_SL1_EAX_FAST_CMPSB 1 << 12
//bits 13-21 are reserved // bits 13-21 are reserved
#define CPUID_EXTENDED_FEATURES_SL1_EAX_HRESET 1 << 22 #define CPUID_EXTENDED_FEATURES_SL1_EAX_HRESET 1 << 22
//bits 23-19 are reserved // bits 23-19 are reserved
#define CPUID_EXTENDED_FEATURES_SL1_EAX_INVD_POSTPOST 1 << 30 #define CPUID_EXTENDED_FEATURES_SL1_EAX_INVD_POSTPOST 1 << 30
//bit 31 is reserved // bit 31 is reserved
#define CPUID_EXTENDED_FEATURES_SL1_EBX_PPIN 1 #define CPUID_EXTENDED_FEATURES_SL1_EBX_PPIN 1
@ -394,8 +395,7 @@
#define CPUID_EXTENDED_FEATURES_SL2_EDX_RRSBA_CTRL 1 << 2 #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_DDPD_U 1 << 3
#define CPUID_EXTENDED_FEATURES_SL2_EDX_BHI_CTRL 1 << 4 #define CPUID_EXTENDED_FEATURES_SL2_EDX_BHI_CTRL 1 << 4
//The rest of the bits are reserved // The rest of the bits are reserved
enum leaves { enum leaves {
/* @ Basic CPU info /* @ Basic CPU info
@ -407,7 +407,8 @@ enum leaves {
CPUID_VENDOR = 0x00000000, CPUID_VENDOR = 0x00000000,
/* @ CPU Version information /* @ CPU Version information
* @ Returned EAX: Family,Model,Stepping * @ Returned EAX: Family,Model,Stepping
* @ Returned EBX: Brand Index,CLFLUSH line size, Max number of logical processors * @ Returned EBX: Brand Index,CLFLUSH line size, Max number of logical
* processors
* @ Returned ECX: Featrue information * @ Returned ECX: Featrue information
* @ Retruned EDX: More feature information * @ Retruned EDX: More feature information
*/ */
@ -427,7 +428,8 @@ enum leaves {
*/ */
CPUID_SERIAL_NUMBER = 0x00000003, CPUID_SERIAL_NUMBER = 0x00000003,
/* @ CPU Deterministic cache parameters !!! Initial ECX = Cache level !!! /* @ 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 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 EBX: L, P and W
* @ Returned ECX: S * @ Returned ECX: S
* @ Retruned EDX: Cache inclusiveness and Complex Cache indexing * @ Retruned EDX: Cache inclusiveness and Complex Cache indexing
@ -436,8 +438,10 @@ enum leaves {
/* @ MONITOR/MWAIT params /* @ MONITOR/MWAIT params
* @ Returned EAX: Smallest monitor-line size * @ Returned EAX: Smallest monitor-line size
* @ Returned EBX: Largest monitor-line size * @ Returned EBX: Largest monitor-line size
* @ Returned ECX: Enumeration of Monitor-Mwait extensions,Supports treating interrupts as break-event for MWAIT * @ Returned ECX: Enumeration of Monitor-Mwait extensions,Supports treating
* @ Retruned EDX: Number of sub C-states supported using MWAIT for each C number thingy IDK * 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, CPUID_MONITOR_MWAIT = 0x00000005,
/* @ Thermal and power managment /* @ Thermal and power managment
@ -480,12 +484,14 @@ enum leaves {
CPUID_TMUL_INFO = 0x00000001E, CPUID_TMUL_INFO = 0x00000001E,
CPUID_V2_EXTENDED_TOPOLOGY = 0x00000001F, CPUID_V2_EXTENDED_TOPOLOGY = 0x00000001F,
CPUID_V2_EXTENDED_TOPOLOGY2 = 0x000000020, CPUID_V2_EXTENDED_TOPOLOGY2 = 0x000000020,
//TODO: add the bitmasks for these Microsoft ones // TODO: add the bitmasks for these Microsoft ones
/* @ Hypervisor CPUID Leaf Range /* @ Hypervisor CPUID Leaf Range
* @ Returned EAX: Highest hypervisor CPUID leaf present * @ Returned EAX: Highest hypervisor CPUID leaf present
* @ Returned EBX: Largest monitor-line size * @ Returned EBX: Largest monitor-line size
* @ Returned ECX: Enumeration of Monitor-Mwait extensions,Supports treating interrupts as break-event for MWAIT * @ Returned ECX: Enumeration of Monitor-Mwait extensions,Supports treating
* @ Retruned EDX: Number of sub C-states supported using MWAIT for each C number thingy IDK * 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, CPUID_HYPERV_IDENT = 0x40000000,
/* @ Hypervisor Vendor-Neutral Interface Identification /* @ Hypervisor Vendor-Neutral Interface Identification
@ -519,7 +525,8 @@ enum leaves {
/* @ Hypervisor Implementation Limits /* @ Hypervisor Implementation Limits
* @ Returned EAX: The maximum number of virtual processors supported * @ Returned EAX: The maximum number of virtual processors supported
* @ Returned EBX: The maximum number of logical processors supported * @ Returned EBX: The maximum number of logical processors supported
* @ Returned ECX: The maximum number of physical interrupt vectors available for interrupt remapping. * @ Returned ECX: The maximum number of physical interrupt vectors available
* for interrupt remapping.
* @ Retruned EDX: Reserved * @ Retruned EDX: Reserved
*/ */
CPUID_MS_HYPERV_IMPL_LIMITS = 0x40000005, CPUID_MS_HYPERV_IMPL_LIMITS = 0x40000005,
@ -575,7 +582,8 @@ enum leaves {
/* @ Cache line size and associativity /* @ Cache line size and associativity
* @ Returned EAX: Reserved * @ Returned EAX: Reserved
* @ Returned EBX: 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 * @ 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 * @ Retruned EDX: Reserved
*/ */
CPUID_MORE_CACHE = 0x800000006, CPUID_MORE_CACHE = 0x800000006,
@ -587,7 +595,8 @@ enum leaves {
*/ */
CPUID_INVARIANT_TSC_AVAILABLE = 0x800000007, CPUID_INVARIANT_TSC_AVAILABLE = 0x800000007,
/* @ Physical adress size /* @ Physical adress size
* @ Returned EAX: Bits 0-7 = Physical Adress bits, Bits 8-15 = Linear Address bits * @ Returned EAX: Bits 0-7 = Physical Adress bits, Bits 8-15 = Linear
* Address bits
* @ Returned EBX: Bit 9 = WBNOINVD available * @ Returned EBX: Bit 9 = WBNOINVD available
* @ Returned ECX: Reserved * @ Returned ECX: Reserved
* @ Retruned EDX: Reserved * @ Retruned EDX: Reserved
@ -595,15 +604,17 @@ enum leaves {
CPUID_PHYS_ADDR_SIZE = 0x800000008, CPUID_PHYS_ADDR_SIZE = 0x800000008,
}; };
enum sub_leaves{ enum sub_leaves {
/* @ Extended features available subleaf 1 !!! All fields return 0 is info not available !!! /* @ Extended features available subleaf 1 !!! All fields return 0 is info not
* available !!!
* @ Returned EAX: Features * @ Returned EAX: Features
* @ Returned EBX: PPIN * @ Returned EBX: PPIN
* @ Returned ECX: Reserved * @ Returned ECX: Reserved
* @ Retruned EDX: CET_SSS * @ Retruned EDX: CET_SSS
*/ */
CPUID_EXTENDED_FEATURES_SL1 = 0x00000001, CPUID_EXTENDED_FEATURES_SL1 = 0x00000001,
/* @ Extended features available subleaf 2 !!! All fields return 0 is info not available !!! /* @ Extended features available subleaf 2 !!! All fields return 0 is info not
* available !!!
* @ Returned EAX: Reserved * @ Returned EAX: Reserved
* @ Returned EBX: Reserved * @ Returned EBX: Reserved
* @ Returned ECX: Reserved * @ Returned ECX: Reserved
@ -621,17 +632,16 @@ enum sub_leaves{
CPUID_SOC_VENDOR_SL1 = 0x00000001, CPUID_SOC_VENDOR_SL1 = 0x00000001,
CPUID_SOC_VENDOR_SL2 = 0x00000002, CPUID_SOC_VENDOR_SL2 = 0x00000002,
CPUID_SOC_VENDOR_SL3 = 0x00000003, CPUID_SOC_VENDOR_SL3 = 0x00000003,
//NOTE: goes higher than 1 // NOTE: goes higher than 1
CPUID_DETERMINISTIC_ADRESS_TRANSLATION_PARAMS_SL = 0x00000001, CPUID_DETERMINISTIC_ADRESS_TRANSLATION_PARAMS_SL = 0x00000001,
CPUID_TILE_INFO_PALETTE1 = 0x000000001, CPUID_TILE_INFO_PALETTE1 = 0x000000001,
}; };
static inline void cpuid(int leaf, int subleaf, int* a, int* b, int* c, int* d) { static inline void cpuid(int leaf, int subleaf, int *a, int *b, int *c,
__asm__ __volatile__ ( int *d) {
"cpuid" __asm__ __volatile__("cpuid"
: "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d) : "=a"(*a), "=b"(*b), "=c"(*c), "=d"(*d)
: "a" (leaf), "c" (subleaf) : "a"(leaf), "c"(subleaf));
);
} }
#endif // __CPUID_H__ #endif // __CPUID_H__

View file

@ -1,14 +1,12 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
void fpu_set_cw(const uint16_t cw) { void fpu_set_cw(const uint16_t cw) { asm volatile("fldcw %0" ::"m"(cw)); }
asm volatile("fldcw %0" :: "m"(cw));
}
void fpu_activate() { void fpu_activate() {
size_t cr4; size_t cr4;
asm volatile ("mov %%cr4, %0" : "=r"(cr4)); asm volatile("mov %%cr4, %0" : "=r"(cr4));
cr4 |= 0x200; cr4 |= 0x200;
asm volatile ("mov %0, %%cr4" :: "r"(cr4)); asm volatile("mov %0, %%cr4" ::"r"(cr4));
fpu_set_cw(0x37F); fpu_set_cw(0x37F);
} }

25
kernel/src/sys/arch/x86_64/gdt.c Executable file → Normal file
View file

@ -1,11 +1,10 @@
//#include "sys/log.h" // #include "sys/log.h"
#include <mm/memop.h>
#include <stdint.h> #include <stdint.h>
#include <sys/arch/x86_64/gdt.h> #include <sys/arch/x86_64/gdt.h>
#include <sys/log.h> #include <sys/log.h>
#include <mm/memop.h>
gdt_table def_table = { gdt_table def_table = {{
{
0x0000000000000000, // 0x00 0x0000000000000000, // 0x00
0x00009a000000ffff, // 0x08 16 bit code 0x00009a000000ffff, // 0x08 16 bit code
@ -20,13 +19,11 @@ gdt_table def_table = {
0x00aff3000000ffff, // 0x38 data ss 0x00aff3000000ffff, // 0x38 data ss
0x00affb000000ffff, // 0x40 user mode code cs 0x00affb000000ffff, // 0x40 user mode code cs
}, },
{ {}};
}
};
tssr tss_list[256]; // One tssr per CPU tssr tss_list[256]; // One tssr per CPU
void gdt_init( char* kstack ) { void gdt_init(char *kstack) {
// TODO: adapt for multiprocessor kernel // TODO: adapt for multiprocessor kernel
tss_list[0].rsp[0] = (uint64_t)kstack; tss_list[0].rsp[0] = (uint64_t)kstack;
@ -41,14 +38,12 @@ void gdt_init( char* kstack ) {
def_table.tss_entry.base3 = (uint32_t)(tss >> 32); def_table.tss_entry.base3 = (uint32_t)(tss >> 32);
def_table.tss_entry.resv = 0; def_table.tss_entry.resv = 0;
gdtr gdt = (gdtr){ gdtr gdt =
.size = (sizeof(gdt_table)) - 1, (gdtr){.size = (sizeof(gdt_table)) - 1, .address = (uint64_t)&def_table};
.address = (uint64_t)&def_table
};
__asm__ volatile ("lgdt %0\n\t" : : "m"(gdt) : "memory"); __asm__ volatile("lgdt %0\n\t" : : "m"(gdt) : "memory");
__asm__ volatile ("ltr %0\n\t" : : "r"((uint16_t)0x48)); __asm__ volatile("ltr %0\n\t" : : "r"((uint16_t)0x48));
//logln(progress, "kinit stage 1", "GDT initialized\n"); // logln(progress, "kinit stage 1", "GDT initialized\n");
log("gdt - initialized.\n"); log("gdt - initialized.\n");
} }

3
kernel/src/sys/arch/x86_64/gdt.h Executable file → Normal file
View file

@ -23,7 +23,6 @@ typedef struct {
uint64_t address; uint64_t address;
} __attribute__((packed)) gdtr; } __attribute__((packed)) gdtr;
typedef struct { typedef struct {
uint32_t resv; uint32_t resv;
uint64_t rsp[4]; uint64_t rsp[4];
@ -34,4 +33,4 @@ typedef struct {
uint16_t iopb; uint16_t iopb;
} __attribute__((packed)) tssr; // Per CPU } __attribute__((packed)) tssr; // Per CPU
void gdt_init(char* kstack); void gdt_init(char *kstack);

21
kernel/src/sys/arch/x86_64/idt.c Executable file → Normal file
View file

@ -1,15 +1,14 @@
//#include "sys/log.h" // #include "sys/log.h"
#include "sys/arch/x86_64/pic.h" #include "sys/arch/x86_64/pic.h"
#include <sys/arch/x86_64/idt.h> #include <sys/arch/x86_64/idt.h>
#include <sys/log.h> #include <sys/log.h>
__attribute__((aligned(0x10))) __attribute__((aligned(0x10))) static idt_entry_t idt[256];
static idt_entry_t idt[256];
static idtr_t idtr; static idtr_t idtr;
void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags) { void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags) {
idt_entry_t* descriptor = &idt[vector]; idt_entry_t *descriptor = &idt[vector];
descriptor->isr_low = (uint64_t)isr & 0xFFFF; descriptor->isr_low = (uint64_t)isr & 0xFFFF;
descriptor->kernel_cs = 0x28; descriptor->kernel_cs = 0x28;
@ -22,7 +21,7 @@ void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags) {
static int vectors[256]; static int vectors[256];
extern void* isr_stub_table[]; extern void *isr_stub_table[];
void idt_init() { void idt_init() {
idtr.base = (uintptr_t)&idt[0]; idtr.base = (uintptr_t)&idt[0];
@ -30,7 +29,8 @@ void idt_init() {
for (uint16_t vector = 0; vector <= 256; vector++) { for (uint16_t vector = 0; vector <= 256; vector++) {
if (vector == 0x80) if (vector == 0x80)
continue; // We skip the syscall handler, since it should be called from user space. continue; // We skip the syscall handler, since it should be called from
// user space.
idt_set_descriptor(vector, isr_stub_table[vector], 0x8E); idt_set_descriptor(vector, isr_stub_table[vector], 0x8E);
vectors[vector] = 1; vectors[vector] = 1;
} }
@ -42,9 +42,10 @@ void idt_init() {
pic_init(); pic_init();
pic_unmask_irq(1); pic_unmask_irq(1);
__asm__ volatile ("lidt %0" : : "m"(idtr)); // load the new IDT __asm__ volatile("lidt %0" : : "m"(idtr)); // load the new IDT
__asm__ volatile ("sti"); // set the interrupt flag __asm__ volatile("sti"); // set the interrupt flag
//logln(progress, "kinit stage 1", "IDT initialized! Time to receive interrupts!\n"); // logln(progress, "kinit stage 1", "IDT initialized! Time to receive
// interrupts!\n");
log("idt - initialized\n"); log("idt - initialized\n");
} }

13
kernel/src/sys/arch/x86_64/idt.h Executable file → Normal file
View file

@ -28,16 +28,19 @@ typedef struct {
} __attribute__((packed)) registers_t; } __attribute__((packed)) registers_t;
typedef struct stackframe { typedef struct stackframe {
struct stackframe* rbp; struct stackframe *rbp;
uint64_t rip; uint64_t rip;
} stackframe_t; } stackframe_t;
typedef struct { typedef struct {
uint16_t isr_low; // The lower 16 bits of the ISR's address 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 uint16_t kernel_cs; // The GDT segment selector that the CPU will load into CS
uint8_t ist; // The IST in the TSS that the CPU will load into RSP; set to zero for now // 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 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 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 isr_high; // The higher 32 bits of the ISR's address
uint32_t reserved; // Set to zero uint32_t reserved; // Set to zero
} __attribute__((packed)) idt_entry_t; } __attribute__((packed)) idt_entry_t;
@ -47,5 +50,5 @@ typedef struct {
uint64_t base; uint64_t base;
} __attribute__((packed)) idtr_t; } __attribute__((packed)) idtr_t;
void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags); void idt_set_descriptor(uint8_t vector, void *isr, uint8_t flags);
void idt_init(void); void idt_init(void);

55
kernel/src/sys/arch/x86_64/interrupts.c Executable file → Normal file
View file

@ -1,5 +1,5 @@
//#include "mm/pmm.h" // #include "mm/pmm.h"
//#include "mm/vmm.h" // #include "mm/vmm.h"
#include "mm/pmm.h" #include "mm/pmm.h"
#include "mm/vmm.h" #include "mm/vmm.h"
#include "sched/sched.h" #include "sched/sched.h"
@ -7,24 +7,24 @@
#include "sys/arch/x86_64/rtc.h" #include "sys/arch/x86_64/rtc.h"
#include "sys/log.h" #include "sys/log.h"
#include "sys/syscall.h" #include "sys/syscall.h"
//#include "sys/sched.h" // #include "sys/sched.h"
#include <stdint.h> #include <stdint.h>
#include <sys/arch/x86_64/idt.h> #include <sys/arch/x86_64/idt.h>
#include <sys/arch/x86_64/io.h> #include <sys/arch/x86_64/io.h>
//#include <sys/errhand/panic.h> // #include <sys/errhand/panic.h>
int pit_millis = 0; int pit_millis = 0;
int pit_secs = 0; int pit_secs = 0;
extern int vmm_kernel_pm_exists;
struct Idt_StackFrame { struct Idt_StackFrame {
struct Idt_StackFrame* rbp; struct Idt_StackFrame *rbp;
uint64_t rip; uint64_t rip;
}__attribute__((packed)); } __attribute__((packed));
void dump_backtrace(registers_t *r) void dump_backtrace(registers_t *r) {
{
log("ints - backtrace : \n"); log("ints - backtrace : \n");
struct Idt_StackFrame* frame = (struct Idt_StackFrame*)r->rbp; struct Idt_StackFrame *frame = (struct Idt_StackFrame *)r->rbp;
while (frame) { while (frame) {
log("ints - %s (ip: %p)\n", frame->rip); log("ints - %s (ip: %p)\n", frame->rip);
@ -39,43 +39,40 @@ void exception_handler(registers_t *regs) {
vmm_load_pagemap(vmm_kernel_pm); vmm_load_pagemap(vmm_kernel_pm);
if (regs->int_no < 32) { if (regs->int_no < 32) {
//panic(kmode_cpu_exception, regs); // panic(kmode_cpu_exception, regs);
log("ints - %d (RIP: %p, ERR: %d)\n", regs->int_no, regs->rip, regs->err_code); log("ints - %d (RIP: %p, ERR: %d)\n", regs->int_no, regs->rip,
regs->err_code);
if(regs->int_no == 0xe) { if (regs->int_no == 0xe && vmm_kernel_pm_exists) {
uint64_t cr2; uint64_t cr2;
asm ("mov %%cr2, %0" : "=r"(cr2)); asm("mov %%cr2, %0" : "=r"(cr2));
log("ints - PF: Faulting location: %p (%p)\n", cr2, virt_to_phys(vmm_current_pm, cr2)); log("ints - PF: Faulting location: %p (%p)\n", cr2,
log("ints - PF: Faulting page flags: %p\n", vmm_get_flags(vmm_current_pm, cr2)); virt_to_phys(vmm_current_pm, cr2));
log("ints - PF: Faulting page flags: %p\n",
vmm_get_flags(vmm_current_pm, cr2));
log("ints - PF: Faulting page map: %p\n", PHYSICAL(vmm_current_pm)); log("ints - PF: Faulting page map: %p\n", PHYSICAL(vmm_current_pm));
} }
// dump_backtrace(regs); // dump_backtrace(regs);
asm ("cli"); asm("cli");
while (1) while (1)
asm ("hlt"); asm("hlt");
} }
if (regs->int_no == 1 + 32) if (regs->int_no == 1 + 32) {
{ if (inb(0x60) & 0x80) {
if (inb(0x60) & 0x80)
{
pic_ack(regs->int_no - 32); pic_ack(regs->int_no - 32);
return; return;
} }
log("ints - keyboard\n"); log("ints - keyboard\n");
} } else if (regs->int_no == 32 + 8) {
else if (regs->int_no == 32 + 8) {
rtc_handle_interrupt(regs); rtc_handle_interrupt(regs);
} } else if (regs->int_no == 0x80 - 32 || regs->int_no == 32) {
else if (regs->int_no == 0x80 - 32 || regs->int_no == 32) {
pit_handler(regs); pit_handler(regs);
} } else if (regs->int_no == 0x80) {
else if (regs->int_no == 0x80)
{
syscall_handle(regs); syscall_handle(regs);
} }
//logln(info, "arch/ints", "Received interrupt %d\n", regs->int_no); // logln(info, "arch/ints", "Received interrupt %d\n", regs->int_no);
pic_ack(regs->int_no - 32); pic_ack(regs->int_no - 32);
} }

6
kernel/src/sys/arch/x86_64/pic.c Executable file → Normal file
View file

@ -1,10 +1,10 @@
//#include "sys/log.h" // #include "sys/log.h"
#include <sys/arch/x86_64/pic.h> #include <sys/arch/x86_64/pic.h>
//#include <sys/acpi.h> // #include <sys/acpi.h>
#include <sys/arch/x86_64/io.h> #include <sys/arch/x86_64/io.h>
void pic_init() { void pic_init() {
//if (acpi_available) // if (acpi_available)
// return; // return;
uint8_t a1, a2; uint8_t a1, a2;

32
kernel/src/sys/arch/x86_64/pit.c Executable file → Normal file
View file

@ -1,26 +1,24 @@
#include "sched/sched.h" #include "sched/sched.h"
#include "sys/arch/x86_64/idt.h" #include "sys/arch/x86_64/idt.h"
#include "sys/arch/x86_64/pic.h" #include "sys/arch/x86_64/pic.h"
#include <sys/log.h>
#include <stdint.h> #include <stdint.h>
#include <sys/log.h>
#ifdef __x86_64__ #ifdef __x86_64__
#include <sys/arch/x86_64/pit.h>
#include <sys/arch/x86_64/idt.h> #include <sys/arch/x86_64/idt.h>
//#include <sipaa/sched.h> #include <sys/arch/x86_64/pit.h>
// #include <sipaa/sched.h>
uint32_t tick = 0; uint32_t tick = 0;
void pit_handler(registers_t *regs) void pit_handler(registers_t *regs) {
{
tick++; tick++;
schedule(regs); schedule(regs);
//Scheduler_Schedule(regs); // Scheduler_Schedule(regs);
} }
void pit_init(uint32_t frequency) void pit_init(uint32_t frequency) {
{
uint32_t divisor = PIT_FREQUENCY / frequency; uint32_t divisor = PIT_FREQUENCY / frequency;
outb(0x43, 0x34); outb(0x43, 0x34);
outb(0x40, (uint8_t)(divisor & 0xFF)); outb(0x40, (uint8_t)(divisor & 0xFF));
@ -29,30 +27,24 @@ void pit_init(uint32_t frequency)
pic_unmask_irq(0); pic_unmask_irq(0);
} }
void sleep(uint32_t seconds) void sleep(uint32_t seconds) {
{
uint32_t eticks = tick + seconds * HZ; uint32_t eticks = tick + seconds * HZ;
while (tick < eticks) while (tick < eticks) {
{
__asm__ __volatile__("hlt"); __asm__ __volatile__("hlt");
} }
} }
void sleep_ms(uint32_t milliseconds) void sleep_ms(uint32_t milliseconds) {
{
uint32_t eticks = tick + (milliseconds * HZ) / 1000; uint32_t eticks = tick + (milliseconds * HZ) / 1000;
while (tick < eticks) while (tick < eticks) {
{
__asm__ __volatile__("hlt"); __asm__ __volatile__("hlt");
} }
} }
// todo: unistd: add usleep function // todo: unistd: add usleep function
void usleep(uint32_t usecs) void usleep(uint32_t usecs) {
{
uint32_t eticks = tick + (usecs * HZ); uint32_t eticks = tick + (usecs * HZ);
while (tick < eticks) while (tick < eticks) {
{
__asm__ __volatile__("hlt"); __asm__ __volatile__("hlt");
} }
} }

12
kernel/src/sys/arch/x86_64/rtc.c Executable file → Normal file
View file

@ -1,7 +1,7 @@
#include "sys/arch/x86_64/idt.h" #include "sys/arch/x86_64/idt.h"
#include "sys/arch/x86_64/io.h" #include "sys/arch/x86_64/io.h"
#include <sys/arch/x86_64/rtc.h>
#include <sys/arch/x86_64/pic.h> #include <sys/arch/x86_64/pic.h>
#include <sys/arch/x86_64/rtc.h>
#include <sys/printf.h> #include <sys/printf.h>
void rtc_init() { void rtc_init() {
@ -12,12 +12,14 @@ void rtc_init() {
asm("cli"); // disable interrupts asm("cli"); // disable interrupts
outb(0x70, 0x8B); // select register B, and disable NMI outb(0x70, 0x8B); // select register B, and disable NMI
char prev=inb(0x71); // read the current value of register B 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(0x70,
outb(0x71, prev | 0x40); // write the previous value ORed with 0x40. This turns on bit 6 of register B 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"); asm("sti");
//pic_unmask_irq(8); // pic_unmask_irq(8);
} }
void rtc_handle_interrupt(registers_t *regs) { void rtc_handle_interrupt(registers_t *regs) {

View file

@ -1,6 +1,4 @@
#include "sys/arch/x86_64/smp.h" #include "sys/arch/x86_64/smp.h"
#include "limine.h" #include "limine.h"
void smp_init() { void smp_init() {}
}

10
kernel/src/sys/arch/x86_64/sse.c Executable file → Normal file
View file

@ -1,14 +1,14 @@
#include <sys/arch/x86_64/sse.h> #include <sys/arch/x86_64/sse.h>
#include <sys/printf.h>
#include <sys/log.h> #include <sys/log.h>
#include <sys/printf.h>
int cpuid_check_bit(int reg, int bit) { int cpuid_check_bit(int reg, int bit) {
int eax, ebx, ecx, edx; int eax, ebx, ecx, edx;
// Minimal inline assembly to execute CPUID // Minimal inline assembly to execute CPUID
__asm__ volatile ( __asm__ volatile("cpuid" // Execute CPUID instruction
"cpuid" // Execute CPUID instruction : "=a"(eax), "=b"(ebx), "=c"(ecx),
: "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) // Output registers "=d"(edx) // Output registers
: "a"(0x1) // Input: EAX = 0x1 (query feature flags) : "a"(0x1) // Input: EAX = 0x1 (query feature flags)
: // No clobbered registers : // No clobbered registers
); );
@ -20,7 +20,7 @@ int cpuid_check_bit(int reg, int bit) {
} else { } else {
return 0; // SSE is not supported return 0; // SSE is not supported
} }
}else if (reg == 1) { } else if (reg == 1) {
if (ecx & (1 << bit)) { if (ecx & (1 << bit)) {
return 1; // SSE is supported return 1; // SSE is supported
} else { } else {

View file

@ -1,3 +1 @@
void panic_ctx() { void panic_ctx() {}
}

View file

@ -24,7 +24,8 @@
*/ */
#ifdef __cplusplus #ifdef __cplusplus
#error "Please do not compile Flanterm as C++ code! Flanterm should be compiled as C99 or newer." #error \
"Please do not compile Flanterm as C++ code! Flanterm should be compiled as C99 or newer."
#endif #endif
#ifndef __STDC_VERSION__ #ifndef __STDC_VERSION__
@ -39,9 +40,9 @@
#define ALWAYS_INLINE inline #define ALWAYS_INLINE inline
#endif #endif
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#define FLANTERM_IN_FLANTERM #define FLANTERM_IN_FLANTERM
@ -434,15 +435,16 @@ static const uint8_t builtin_font[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 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, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00};
};
static ALWAYS_INLINE uint32_t convert_colour(struct flanterm_context *_ctx, uint32_t colour) { static ALWAYS_INLINE uint32_t convert_colour(struct flanterm_context *_ctx,
uint32_t colour) {
struct flanterm_fb_context *ctx = (void *)_ctx; struct flanterm_fb_context *ctx = (void *)_ctx;
uint32_t r = (colour >> 16) & 0xff; uint32_t r = (colour >> 16) & 0xff;
uint32_t g = (colour >> 8) & 0xff; uint32_t g = (colour >> 8) & 0xff;
uint32_t b = colour & 0xff; uint32_t b = colour & 0xff;
return (r << ctx->red_mask_shift) | (g << ctx->green_mask_shift) | (b << ctx->blue_mask_shift); return (r << ctx->red_mask_shift) | (g << ctx->green_mask_shift) |
(b << ctx->blue_mask_shift);
} }
static void flanterm_fb_save_state(struct flanterm_context *_ctx) { static void flanterm_fb_save_state(struct flanterm_context *_ctx) {
@ -468,7 +470,9 @@ static void flanterm_fb_swap_palette(struct flanterm_context *_ctx) {
ctx->text_fg = tmp; ctx->text_fg = tmp;
} }
static void plot_char_scaled_canvas(struct flanterm_context *_ctx, struct flanterm_fb_char *c, size_t x, size_t y) { static void plot_char_scaled_canvas(struct flanterm_context *_ctx,
struct flanterm_fb_char *c, size_t x,
size_t y) {
struct flanterm_fb_context *ctx = (void *)_ctx; struct flanterm_fb_context *ctx = (void *)_ctx;
if (x >= _ctx->cols || y >= _ctx->rows) { if (x >= _ctx->cols || y >= _ctx->rows) {
@ -482,7 +486,8 @@ static void plot_char_scaled_canvas(struct flanterm_context *_ctx, struct flante
// naming: fx,fy for font coordinates, gx,gy for glyph coordinates // naming: fx,fy for font coordinates, gx,gy for glyph coordinates
for (size_t gy = 0; gy < ctx->glyph_height; gy++) { for (size_t gy = 0; gy < ctx->glyph_height; gy++) {
uint8_t fy = gy / ctx->font_scale_y; uint8_t fy = gy / ctx->font_scale_y;
volatile uint32_t *fb_line = ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); volatile uint32_t *fb_line =
ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4);
uint32_t *canvas_line = ctx->canvas + x + (y + gy) * ctx->width; uint32_t *canvas_line = ctx->canvas + x + (y + gy) * ctx->width;
bool *glyph_pointer = glyph + (fy * ctx->font_width); bool *glyph_pointer = glyph + (fy * ctx->font_width);
for (size_t fx = 0; fx < ctx->font_width; fx++) { for (size_t fx = 0; fx < ctx->font_width; fx++) {
@ -497,7 +502,9 @@ static void plot_char_scaled_canvas(struct flanterm_context *_ctx, struct flante
} }
} }
static void plot_char_scaled_uncanvas(struct flanterm_context *_ctx, struct flanterm_fb_char *c, size_t x, size_t y) { static void plot_char_scaled_uncanvas(struct flanterm_context *_ctx,
struct flanterm_fb_char *c, size_t x,
size_t y) {
struct flanterm_fb_context *ctx = (void *)_ctx; struct flanterm_fb_context *ctx = (void *)_ctx;
if (x >= _ctx->cols || y >= _ctx->rows) { if (x >= _ctx->cols || y >= _ctx->rows) {
@ -516,7 +523,8 @@ static void plot_char_scaled_uncanvas(struct flanterm_context *_ctx, struct flan
// naming: fx,fy for font coordinates, gx,gy for glyph coordinates // naming: fx,fy for font coordinates, gx,gy for glyph coordinates
for (size_t gy = 0; gy < ctx->glyph_height; gy++) { for (size_t gy = 0; gy < ctx->glyph_height; gy++) {
uint8_t fy = gy / ctx->font_scale_y; uint8_t fy = gy / ctx->font_scale_y;
volatile uint32_t *fb_line = ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); volatile uint32_t *fb_line =
ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4);
bool *glyph_pointer = glyph + (fy * ctx->font_width); bool *glyph_pointer = glyph + (fy * ctx->font_width);
for (size_t fx = 0; fx < ctx->font_width; fx++) { for (size_t fx = 0; fx < ctx->font_width; fx++) {
for (size_t i = 0; i < ctx->font_scale_x; i++) { for (size_t i = 0; i < ctx->font_scale_x; i++) {
@ -528,7 +536,9 @@ static void plot_char_scaled_uncanvas(struct flanterm_context *_ctx, struct flan
} }
} }
static void plot_char_unscaled_canvas(struct flanterm_context *_ctx, struct flanterm_fb_char *c, size_t x, size_t y) { static void plot_char_unscaled_canvas(struct flanterm_context *_ctx,
struct flanterm_fb_char *c, size_t x,
size_t y) {
struct flanterm_fb_context *ctx = (void *)_ctx; struct flanterm_fb_context *ctx = (void *)_ctx;
if (x >= _ctx->cols || y >= _ctx->rows) { if (x >= _ctx->cols || y >= _ctx->rows) {
@ -541,7 +551,8 @@ static void plot_char_unscaled_canvas(struct flanterm_context *_ctx, struct flan
bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width]; bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width];
// naming: fx,fy for font coordinates, gx,gy for glyph coordinates // naming: fx,fy for font coordinates, gx,gy for glyph coordinates
for (size_t gy = 0; gy < ctx->glyph_height; gy++) { for (size_t gy = 0; gy < ctx->glyph_height; gy++) {
volatile uint32_t *fb_line = ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); volatile uint32_t *fb_line =
ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4);
uint32_t *canvas_line = ctx->canvas + x + (y + gy) * ctx->width; uint32_t *canvas_line = ctx->canvas + x + (y + gy) * ctx->width;
bool *glyph_pointer = glyph + (gy * ctx->font_width); bool *glyph_pointer = glyph + (gy * ctx->font_width);
for (size_t fx = 0; fx < ctx->font_width; fx++) { for (size_t fx = 0; fx < ctx->font_width; fx++) {
@ -552,7 +563,9 @@ static void plot_char_unscaled_canvas(struct flanterm_context *_ctx, struct flan
} }
} }
static void plot_char_unscaled_uncanvas(struct flanterm_context *_ctx, struct flanterm_fb_char *c, size_t x, size_t y) { static void plot_char_unscaled_uncanvas(struct flanterm_context *_ctx,
struct flanterm_fb_char *c, size_t x,
size_t y) {
struct flanterm_fb_context *ctx = (void *)_ctx; struct flanterm_fb_context *ctx = (void *)_ctx;
if (x >= _ctx->cols || y >= _ctx->rows) { if (x >= _ctx->cols || y >= _ctx->rows) {
@ -570,7 +583,8 @@ static void plot_char_unscaled_uncanvas(struct flanterm_context *_ctx, struct fl
bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width]; bool *glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width];
// naming: fx,fy for font coordinates, gx,gy for glyph coordinates // naming: fx,fy for font coordinates, gx,gy for glyph coordinates
for (size_t gy = 0; gy < ctx->glyph_height; gy++) { for (size_t gy = 0; gy < ctx->glyph_height; gy++) {
volatile uint32_t *fb_line = ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4); volatile uint32_t *fb_line =
ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4);
bool *glyph_pointer = glyph + (gy * ctx->font_width); bool *glyph_pointer = glyph + (gy * ctx->font_width);
for (size_t fx = 0; fx < ctx->font_width; fx++) { for (size_t fx = 0; fx < ctx->font_width; fx++) {
fb_line[fx] = *(glyph_pointer++) ? fg : bg; fb_line[fx] = *(glyph_pointer++) ? fg : bg;
@ -578,11 +592,13 @@ static void plot_char_unscaled_uncanvas(struct flanterm_context *_ctx, struct fl
} }
} }
static inline bool compare_char(struct flanterm_fb_char *a, struct flanterm_fb_char *b) { static inline bool compare_char(struct flanterm_fb_char *a,
struct flanterm_fb_char *b) {
return !(a->c != b->c || a->bg != b->bg || a->fg != b->fg); return !(a->c != b->c || a->bg != b->bg || a->fg != b->fg);
} }
static void push_to_queue(struct flanterm_context *_ctx, struct flanterm_fb_char *c, size_t x, size_t y) { static void push_to_queue(struct flanterm_context *_ctx,
struct flanterm_fb_char *c, size_t x, size_t y) {
struct flanterm_fb_context *ctx = (void *)_ctx; struct flanterm_fb_context *ctx = (void *)_ctx;
if (x >= _ctx->cols || y >= _ctx->rows) { if (x >= _ctx->cols || y >= _ctx->rows) {
@ -621,7 +637,8 @@ static void flanterm_fb_revscroll(struct flanterm_context *_ctx) {
} else { } else {
c = &ctx->grid[i]; c = &ctx->grid[i];
} }
push_to_queue(_ctx, c, (i + _ctx->cols) % _ctx->cols, (i + _ctx->cols) / _ctx->cols); push_to_queue(_ctx, c, (i + _ctx->cols) % _ctx->cols,
(i + _ctx->cols) / _ctx->cols);
} }
// Clear the first line of the screen. // Clear the first line of the screen.
@ -646,7 +663,8 @@ static void flanterm_fb_scroll(struct flanterm_context *_ctx) {
} else { } else {
c = &ctx->grid[i]; c = &ctx->grid[i];
} }
push_to_queue(_ctx, c, (i - _ctx->cols) % _ctx->cols, (i - _ctx->cols) / _ctx->cols); push_to_queue(_ctx, c, (i - _ctx->cols) % _ctx->cols,
(i - _ctx->cols) / _ctx->cols);
} }
// Clear the last line of the screen. // Clear the last line of the screen.
@ -676,7 +694,8 @@ static void flanterm_fb_clear(struct flanterm_context *_ctx, bool move) {
} }
} }
static void flanterm_fb_set_cursor_pos(struct flanterm_context *_ctx, size_t x, size_t y) { static void flanterm_fb_set_cursor_pos(struct flanterm_context *_ctx, size_t x,
size_t y) {
struct flanterm_fb_context *ctx = (void *)_ctx; struct flanterm_fb_context *ctx = (void *)_ctx;
if (x >= _ctx->cols) { if (x >= _ctx->cols) {
@ -697,18 +716,21 @@ static void flanterm_fb_set_cursor_pos(struct flanterm_context *_ctx, size_t x,
ctx->cursor_y = y; ctx->cursor_y = y;
} }
static void flanterm_fb_get_cursor_pos(struct flanterm_context *_ctx, size_t *x, size_t *y) { static void flanterm_fb_get_cursor_pos(struct flanterm_context *_ctx, size_t *x,
size_t *y) {
struct flanterm_fb_context *ctx = (void *)_ctx; struct flanterm_fb_context *ctx = (void *)_ctx;
*x = ctx->cursor_x >= _ctx->cols ? _ctx->cols - 1 : ctx->cursor_x; *x = ctx->cursor_x >= _ctx->cols ? _ctx->cols - 1 : ctx->cursor_x;
*y = ctx->cursor_y >= _ctx->rows ? _ctx->rows - 1 : ctx->cursor_y; *y = ctx->cursor_y >= _ctx->rows ? _ctx->rows - 1 : ctx->cursor_y;
} }
static void flanterm_fb_move_character(struct flanterm_context *_ctx, size_t new_x, size_t new_y, size_t old_x, size_t old_y) { static void flanterm_fb_move_character(struct flanterm_context *_ctx,
size_t new_x, size_t new_y, size_t old_x,
size_t old_y) {
struct flanterm_fb_context *ctx = (void *)_ctx; struct flanterm_fb_context *ctx = (void *)_ctx;
if (old_x >= _ctx->cols || old_y >= _ctx->rows if (old_x >= _ctx->cols || old_y >= _ctx->rows || new_x >= _ctx->cols ||
|| new_x >= _ctx->cols || new_y >= _ctx->rows) { new_y >= _ctx->rows) {
return; return;
} }
@ -737,25 +759,29 @@ static void flanterm_fb_set_text_bg(struct flanterm_context *_ctx, size_t bg) {
ctx->text_bg = ctx->ansi_colours[bg]; ctx->text_bg = ctx->ansi_colours[bg];
} }
static void flanterm_fb_set_text_fg_bright(struct flanterm_context *_ctx, size_t fg) { static void flanterm_fb_set_text_fg_bright(struct flanterm_context *_ctx,
size_t fg) {
struct flanterm_fb_context *ctx = (void *)_ctx; struct flanterm_fb_context *ctx = (void *)_ctx;
ctx->text_fg = ctx->ansi_bright_colours[fg]; ctx->text_fg = ctx->ansi_bright_colours[fg];
} }
static void flanterm_fb_set_text_bg_bright(struct flanterm_context *_ctx, size_t bg) { static void flanterm_fb_set_text_bg_bright(struct flanterm_context *_ctx,
size_t bg) {
struct flanterm_fb_context *ctx = (void *)_ctx; struct flanterm_fb_context *ctx = (void *)_ctx;
ctx->text_bg = ctx->ansi_bright_colours[bg]; ctx->text_bg = ctx->ansi_bright_colours[bg];
} }
static void flanterm_fb_set_text_fg_rgb(struct flanterm_context *_ctx, uint32_t fg) { static void flanterm_fb_set_text_fg_rgb(struct flanterm_context *_ctx,
uint32_t fg) {
struct flanterm_fb_context *ctx = (void *)_ctx; struct flanterm_fb_context *ctx = (void *)_ctx;
ctx->text_fg = convert_colour(_ctx, fg); ctx->text_fg = convert_colour(_ctx, fg);
} }
static void flanterm_fb_set_text_bg_rgb(struct flanterm_context *_ctx, uint32_t bg) { static void flanterm_fb_set_text_bg_rgb(struct flanterm_context *_ctx,
uint32_t bg) {
struct flanterm_fb_context *ctx = (void *)_ctx; struct flanterm_fb_context *ctx = (void *)_ctx;
ctx->text_bg = convert_colour(_ctx, bg); ctx->text_bg = convert_colour(_ctx, bg);
@ -773,13 +799,15 @@ static void flanterm_fb_set_text_bg_default(struct flanterm_context *_ctx) {
ctx->text_bg = 0xffffffff; ctx->text_bg = 0xffffffff;
} }
static void flanterm_fb_set_text_fg_default_bright(struct flanterm_context *_ctx) { static void
flanterm_fb_set_text_fg_default_bright(struct flanterm_context *_ctx) {
struct flanterm_fb_context *ctx = (void *)_ctx; struct flanterm_fb_context *ctx = (void *)_ctx;
ctx->text_fg = ctx->default_fg_bright; ctx->text_fg = ctx->default_fg_bright;
} }
static void flanterm_fb_set_text_bg_default_bright(struct flanterm_context *_ctx) { static void
flanterm_fb_set_text_bg_default_bright(struct flanterm_context *_ctx) {
struct flanterm_fb_context *ctx = (void *)_ctx; struct flanterm_fb_context *ctx = (void *)_ctx;
ctx->text_bg = ctx->default_bg_bright; ctx->text_bg = ctx->default_bg_bright;
@ -829,9 +857,13 @@ static void flanterm_fb_double_buffer_flush(struct flanterm_context *_ctx) {
ctx->map[offset] = NULL; ctx->map[offset] = NULL;
} }
if ((ctx->old_cursor_x != ctx->cursor_x || ctx->old_cursor_y != ctx->cursor_y) || _ctx->cursor_enabled == false) { if ((ctx->old_cursor_x != ctx->cursor_x ||
ctx->old_cursor_y != ctx->cursor_y) ||
_ctx->cursor_enabled == false) {
if (ctx->old_cursor_x < _ctx->cols && ctx->old_cursor_y < _ctx->rows) { if (ctx->old_cursor_x < _ctx->cols && ctx->old_cursor_y < _ctx->rows) {
ctx->plot_char(_ctx, &ctx->grid[ctx->old_cursor_x + ctx->old_cursor_y * _ctx->cols], ctx->old_cursor_x, ctx->old_cursor_y); ctx->plot_char(
_ctx, &ctx->grid[ctx->old_cursor_x + ctx->old_cursor_y * _ctx->cols],
ctx->old_cursor_x, ctx->old_cursor_y);
} }
} }
@ -844,7 +876,9 @@ static void flanterm_fb_double_buffer_flush(struct flanterm_context *_ctx) {
static void flanterm_fb_raw_putchar(struct flanterm_context *_ctx, uint8_t c) { static void flanterm_fb_raw_putchar(struct flanterm_context *_ctx, uint8_t c) {
struct flanterm_fb_context *ctx = (void *)_ctx; struct flanterm_fb_context *ctx = (void *)_ctx;
if (ctx->cursor_x >= _ctx->cols && (ctx->cursor_y < _ctx->scroll_bottom_margin - 1 || _ctx->scroll_enabled)) { if (ctx->cursor_x >= _ctx->cols &&
(ctx->cursor_y < _ctx->scroll_bottom_margin - 1 ||
_ctx->scroll_enabled)) {
ctx->cursor_x = 0; ctx->cursor_x = 0;
ctx->cursor_y++; ctx->cursor_y++;
if (ctx->cursor_y == _ctx->scroll_bottom_margin) { if (ctx->cursor_y == _ctx->scroll_bottom_margin) {
@ -871,7 +905,8 @@ static void flanterm_fb_full_refresh(struct flanterm_context *_ctx) {
for (size_t y = 0; y < ctx->height; y++) { for (size_t y = 0; y < ctx->height; y++) {
for (size_t x = 0; x < ctx->width; x++) { for (size_t x = 0; x < ctx->width; x++) {
if (ctx->canvas != NULL) { if (ctx->canvas != NULL) {
ctx->framebuffer[y * (ctx->pitch / sizeof(uint32_t)) + x] = ctx->canvas[y * ctx->width + x]; ctx->framebuffer[y * (ctx->pitch / sizeof(uint32_t)) + x] =
ctx->canvas[y * ctx->width + x];
} else { } else {
ctx->framebuffer[y * (ctx->pitch / sizeof(uint32_t)) + x] = default_bg; ctx->framebuffer[y * (ctx->pitch / sizeof(uint32_t)) + x] = default_bg;
} }
@ -890,7 +925,8 @@ static void flanterm_fb_full_refresh(struct flanterm_context *_ctx) {
} }
} }
static void flanterm_fb_deinit(struct flanterm_context *_ctx, void (*_free)(void *, size_t)) { static void flanterm_fb_deinit(struct flanterm_context *_ctx,
void (*_free)(void *, size_t)) {
struct flanterm_fb_context *ctx = (void *)_ctx; struct flanterm_fb_context *ctx = (void *)_ctx;
if (_free == NULL) { if (_free == NULL) {
@ -917,20 +953,15 @@ static void flanterm_fb_deinit(struct flanterm_context *_ctx, void (*_free)(void
} }
struct flanterm_context *flanterm_fb_init( struct flanterm_context *flanterm_fb_init(
void *(*_malloc)(size_t), void *(*_malloc)(size_t), void (*_free)(void *, size_t),
void (*_free)(void *, size_t),
uint32_t *framebuffer, size_t width, size_t height, size_t pitch, uint32_t *framebuffer, size_t width, size_t height, size_t pitch,
uint8_t red_mask_size, uint8_t red_mask_shift, uint8_t red_mask_size, uint8_t red_mask_shift, uint8_t green_mask_size,
uint8_t green_mask_size, uint8_t green_mask_shift, uint8_t green_mask_shift, uint8_t blue_mask_size, uint8_t blue_mask_shift,
uint8_t blue_mask_size, uint8_t blue_mask_shift, uint32_t *canvas, uint32_t *ansi_colours, uint32_t *ansi_bright_colours,
uint32_t *canvas, uint32_t *default_bg, uint32_t *default_fg, uint32_t *default_bg_bright,
uint32_t *ansi_colours, uint32_t *ansi_bright_colours, uint32_t *default_fg_bright, void *font, size_t font_width,
uint32_t *default_bg, uint32_t *default_fg, size_t font_height, size_t font_spacing, size_t font_scale_x,
uint32_t *default_bg_bright, uint32_t *default_fg_bright, size_t font_scale_y, size_t margin) {
void *font, size_t font_width, size_t font_height, size_t font_spacing,
size_t font_scale_x, size_t font_scale_y,
size_t margin
) {
if (font_scale_x == 0 || font_scale_y == 0) { if (font_scale_x == 0 || font_scale_y == 0) {
font_scale_x = 1; font_scale_x = 1;
font_scale_y = 1; font_scale_y = 1;
@ -944,8 +975,8 @@ struct flanterm_context *flanterm_fb_init(
} }
} }
/*if (red_mask_size < 8 || red_mask_size != green_mask_size || red_mask_size != blue_mask_size) { /*if (red_mask_size < 8 || red_mask_size != green_mask_size || red_mask_size
return NULL; != blue_mask_size) { return NULL;
}*/ }*/
if (_malloc == NULL) { if (_malloc == NULL) {
@ -956,10 +987,15 @@ struct flanterm_context *flanterm_fb_init(
_malloc = bump_alloc; _malloc = bump_alloc;
// Limit terminal size if needed // Limit terminal size if needed
if (width > FLANTERM_FB_WIDTH_LIMIT || height > FLANTERM_FB_HEIGHT_LIMIT) { if (width > FLANTERM_FB_WIDTH_LIMIT || height > FLANTERM_FB_HEIGHT_LIMIT) {
size_t width_limit = width > FLANTERM_FB_WIDTH_LIMIT ? FLANTERM_FB_WIDTH_LIMIT : width; size_t width_limit =
size_t height_limit = height > FLANTERM_FB_HEIGHT_LIMIT ? FLANTERM_FB_HEIGHT_LIMIT : height; width > FLANTERM_FB_WIDTH_LIMIT ? FLANTERM_FB_WIDTH_LIMIT : width;
size_t height_limit =
height > FLANTERM_FB_HEIGHT_LIMIT ? FLANTERM_FB_HEIGHT_LIMIT : height;
framebuffer = (uint32_t *)((uintptr_t)framebuffer + ((((height / 2) - (height_limit / 2)) * pitch) + (((width / 2) - (width_limit / 2)) * 4))); framebuffer =
(uint32_t *)((uintptr_t)framebuffer +
((((height / 2) - (height_limit / 2)) * pitch) +
(((width / 2) - (width_limit / 2)) * 4)));
width = width_limit; width = width_limit;
height = height_limit; height = height_limit;
@ -1005,7 +1041,8 @@ struct flanterm_context *flanterm_fb_init(
if (ansi_bright_colours != NULL) { if (ansi_bright_colours != NULL) {
for (size_t i = 0; i < 8; i++) { for (size_t i = 0; i < 8; i++) {
ctx->ansi_bright_colours[i] = convert_colour(_ctx, ansi_bright_colours[i]); ctx->ansi_bright_colours[i] =
convert_colour(_ctx, ansi_bright_colours[i]);
} }
} else { } else {
ctx->ansi_bright_colours[0] = convert_colour(_ctx, 0x00555555); // black ctx->ansi_bright_colours[0] = convert_colour(_ctx, 0x00555555); // black
@ -1033,13 +1070,15 @@ struct flanterm_context *flanterm_fb_init(
if (default_bg_bright != NULL) { if (default_bg_bright != NULL) {
ctx->default_bg_bright = convert_colour(_ctx, *default_bg_bright); ctx->default_bg_bright = convert_colour(_ctx, *default_bg_bright);
} else { } else {
ctx->default_bg_bright = convert_colour(_ctx, 0x00555555); // background (black) ctx->default_bg_bright =
convert_colour(_ctx, 0x00555555); // background (black)
} }
if (default_fg_bright != NULL) { if (default_fg_bright != NULL) {
ctx->default_fg_bright = convert_colour(_ctx, *default_fg_bright); ctx->default_fg_bright = convert_colour(_ctx, *default_fg_bright);
} else { } else {
ctx->default_fg_bright = convert_colour(_ctx, 0x00ffffff); // foreground (grey) ctx->default_fg_bright =
convert_colour(_ctx, 0x00ffffff); // foreground (grey)
} }
ctx->text_fg = ctx->default_fg; ctx->text_fg = ctx->default_fg;
@ -1077,7 +1116,8 @@ struct flanterm_context *flanterm_fb_init(
ctx->font_width += font_spacing; ctx->font_width += font_spacing;
ctx->font_bool_size = FLANTERM_FB_FONT_GLYPHS * font_height * ctx->font_width * sizeof(bool); ctx->font_bool_size =
FLANTERM_FB_FONT_GLYPHS * font_height * ctx->font_width * sizeof(bool);
ctx->font_bool = _malloc(ctx->font_bool_size); ctx->font_bool = _malloc(ctx->font_bool_size);
if (ctx->font_bool == NULL) { if (ctx->font_bool == NULL) {
goto fail; goto fail;
@ -1091,7 +1131,8 @@ struct flanterm_context *flanterm_fb_init(
// 9 dot wide fonts have 8 dots and one empty column, except // 9 dot wide fonts have 8 dots and one empty column, except
// characters 0xC0-0xDF replicate column 9. // characters 0xC0-0xDF replicate column 9.
for (size_t x = 0; x < 8; x++) { for (size_t x = 0; x < 8; x++) {
size_t offset = i * font_height * ctx->font_width + y * ctx->font_width + x; size_t offset =
i * font_height * ctx->font_width + y * ctx->font_width + x;
if ((glyph[y] & (0x80 >> x))) { if ((glyph[y] & (0x80 >> x))) {
ctx->font_bool[offset] = true; ctx->font_bool[offset] = true;
@ -1101,7 +1142,8 @@ struct flanterm_context *flanterm_fb_init(
} }
// fill columns above 8 like VGA Line Graphics Mode does // fill columns above 8 like VGA Line Graphics Mode does
for (size_t x = 8; x < ctx->font_width; x++) { for (size_t x = 8; x < ctx->font_width; x++) {
size_t offset = i * font_height * ctx->font_width + y * ctx->font_width + x; size_t offset =
i * font_height * ctx->font_width + y * ctx->font_width + x;
if (i >= 0xc0 && i <= 0xdf) { if (i >= 0xc0 && i <= 0xdf) {
ctx->font_bool[offset] = (glyph[y] & 1); ctx->font_bool[offset] = (glyph[y] & 1);
@ -1135,7 +1177,8 @@ struct flanterm_context *flanterm_fb_init(
ctx->grid[i].bg = ctx->text_bg; ctx->grid[i].bg = ctx->text_bg;
} }
ctx->queue_size = _ctx->rows * _ctx->cols * sizeof(struct flanterm_fb_queue_item); ctx->queue_size =
_ctx->rows * _ctx->cols * sizeof(struct flanterm_fb_queue_item);
ctx->queue = _malloc(ctx->queue_size); ctx->queue = _malloc(ctx->queue_size);
if (ctx->queue == NULL) { if (ctx->queue == NULL) {
goto fail; goto fail;
@ -1143,7 +1186,8 @@ struct flanterm_context *flanterm_fb_init(
ctx->queue_i = 0; ctx->queue_i = 0;
memset(ctx->queue, 0, ctx->queue_size); memset(ctx->queue, 0, ctx->queue_size);
ctx->map_size = _ctx->rows * _ctx->cols * sizeof(struct flanterm_fb_queue_item *); ctx->map_size =
_ctx->rows * _ctx->cols * sizeof(struct flanterm_fb_queue_item *);
ctx->map = _malloc(ctx->map_size); ctx->map = _malloc(ctx->map_size);
if (ctx->map == NULL) { if (ctx->map == NULL) {
goto fail; goto fail;

View file

@ -26,9 +26,9 @@
#ifndef FLANTERM_FB_H #ifndef FLANTERM_FB_H
#define FLANTERM_FB_H 1 #define FLANTERM_FB_H 1
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -43,23 +43,24 @@ extern "C" {
#endif #endif
struct flanterm_context *flanterm_fb_init( struct flanterm_context *flanterm_fb_init(
/* If _malloc and _free are nulled, use the bump allocated instance (1 use only). */ /* If _malloc and _free are nulled, use the bump allocated instance (1 use
only). */
void *(*_malloc)(size_t size), void *(*_malloc)(size_t size),
void (*_free)(void *ptr, size_t size), void (*_free)(void *ptr, size_t size), uint32_t *framebuffer, size_t width,
uint32_t *framebuffer, size_t width, size_t height, size_t pitch, size_t height, size_t pitch, uint8_t red_mask_size, uint8_t red_mask_shift,
uint8_t red_mask_size, uint8_t red_mask_shift, uint8_t green_mask_size, uint8_t green_mask_shift, uint8_t blue_mask_size,
uint8_t green_mask_size, uint8_t green_mask_shift, uint8_t blue_mask_shift, uint32_t *canvas, /* If nulled, no canvas. */
uint8_t blue_mask_size, uint8_t blue_mask_shift, uint32_t *ansi_colours,
uint32_t *canvas, /* If nulled, no canvas. */ uint32_t *ansi_bright_colours, /* If nulled, default. */
uint32_t *ansi_colours, uint32_t *ansi_bright_colours, /* If nulled, default. */
uint32_t *default_bg, uint32_t *default_fg, /* If nulled, default. */ uint32_t *default_bg, uint32_t *default_fg, /* If nulled, default. */
uint32_t *default_bg_bright, uint32_t *default_fg_bright, /* If nulled, default. */ uint32_t *default_bg_bright,
/* If font is null, use default font and font_width and font_height ignored. */ uint32_t *default_fg_bright, /* If nulled, default. */
/* If font is null, use default font and font_width and font_height ignored.
*/
void *font, size_t font_width, size_t font_height, size_t font_spacing, void *font, size_t font_width, size_t font_height, size_t font_spacing,
/* If scale_x and scale_y are 0, automatically scale font based on resolution. */ /* If scale_x and scale_y are 0, automatically scale font based on
size_t font_scale_x, size_t font_scale_y, resolution. */
size_t margin size_t font_scale_x, size_t font_scale_y, size_t margin);
);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -30,9 +30,9 @@
#error "Do not use fb_private.h. Use interfaces defined in fb.h only." #error "Do not use fb_private.h. Use interfaces defined in fb.h only."
#endif #endif
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -54,7 +54,8 @@ struct flanterm_fb_queue_item {
struct flanterm_fb_context { struct flanterm_fb_context {
struct flanterm_context term; struct flanterm_context term;
void (*plot_char)(struct flanterm_context *ctx, struct flanterm_fb_char *c, size_t x, size_t y); void (*plot_char)(struct flanterm_context *ctx, struct flanterm_fb_char *c,
size_t x, size_t y);
size_t font_width; size_t font_width;
size_t font_height; size_t font_height;

File diff suppressed because it is too large Load diff

View file

@ -26,9 +26,9 @@
#ifndef FLANTERM_H #ifndef FLANTERM_H
#define FLANTERM_H 1 #define FLANTERM_H 1
#include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -62,14 +62,19 @@ struct flanterm_context;
#endif #endif
void flanterm_write(struct flanterm_context *ctx, const char *buf, size_t count); void flanterm_write(struct flanterm_context *ctx, const char *buf,
size_t count);
void flanterm_flush(struct flanterm_context *ctx); void flanterm_flush(struct flanterm_context *ctx);
void flanterm_full_refresh(struct flanterm_context *ctx); void flanterm_full_refresh(struct flanterm_context *ctx);
void flanterm_deinit(struct flanterm_context *ctx, void (*_free)(void *ptr, size_t size)); void flanterm_deinit(struct flanterm_context *ctx,
void (*_free)(void *ptr, size_t size));
void flanterm_get_dimensions(struct flanterm_context *ctx, size_t *cols, size_t *rows); void flanterm_get_dimensions(struct flanterm_context *ctx, size_t *cols,
size_t *rows);
void flanterm_set_autoflush(struct flanterm_context *ctx, bool state); void flanterm_set_autoflush(struct flanterm_context *ctx, bool state);
void flanterm_set_callback(struct flanterm_context *ctx, void (*callback)(struct flanterm_context *, uint64_t, uint64_t, uint64_t, uint64_t)); void flanterm_set_callback(struct flanterm_context *ctx,
void (*callback)(struct flanterm_context *, uint64_t,
uint64_t, uint64_t, uint64_t));
uint64_t flanterm_get_oob_output(struct flanterm_context *ctx); uint64_t flanterm_get_oob_output(struct flanterm_context *ctx);
void flanterm_set_oob_output(struct flanterm_context *ctx, uint64_t oob_output); void flanterm_set_oob_output(struct flanterm_context *ctx, uint64_t oob_output);

View file

@ -27,12 +27,13 @@
#define FLANTERM_PRIVATE_H 1 #define FLANTERM_PRIVATE_H 1
#ifndef FLANTERM_IN_FLANTERM #ifndef FLANTERM_IN_FLANTERM
#error "Do not use flanterm_private.h. Use interfaces defined in flanterm.h only." #error \
"Do not use flanterm_private.h. Use interfaces defined in flanterm.h only."
#endif #endif
#include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -98,7 +99,8 @@ struct flanterm_context {
void (*set_text_bg_default)(struct flanterm_context *); void (*set_text_bg_default)(struct flanterm_context *);
void (*set_text_fg_default_bright)(struct flanterm_context *); void (*set_text_fg_default_bright)(struct flanterm_context *);
void (*set_text_bg_default_bright)(struct flanterm_context *); void (*set_text_bg_default_bright)(struct flanterm_context *);
void (*move_character)(struct flanterm_context *, size_t new_x, size_t new_y, size_t old_x, size_t old_y); void (*move_character)(struct flanterm_context *, size_t new_x, size_t new_y,
size_t old_x, size_t old_y);
void (*scroll)(struct flanterm_context *); void (*scroll)(struct flanterm_context *);
void (*revscroll)(struct flanterm_context *); void (*revscroll)(struct flanterm_context *);
void (*swap_palette)(struct flanterm_context *); void (*swap_palette)(struct flanterm_context *);
@ -110,7 +112,8 @@ struct flanterm_context {
/* to be set by client */ /* to be set by client */
void (*callback)(struct flanterm_context *, uint64_t, uint64_t, uint64_t, uint64_t); void (*callback)(struct flanterm_context *, uint64_t, uint64_t, uint64_t,
uint64_t);
}; };
void flanterm_context_reinit(struct flanterm_context *ctx); void flanterm_context_reinit(struct flanterm_context *ctx);

23
kernel/src/sys/log.c Executable file → Normal file
View file

@ -1,19 +1,23 @@
#include "sys/arch/x86_64/io.h" #include "sys/arch/x86_64/io.h"
#include "sys/gfx/flanterm/flanterm.h" #include "sys/gfx/flanterm/flanterm.h"
#include <lib/spinlock.h>
#include <stdarg.h> #include <stdarg.h>
#include <sys/printf.h> #include <sys/printf.h>
#include <lib/spinlock.h>
extern struct flanterm_context *ft_ctx; extern struct flanterm_context *ft_ctx;
static spinlock_t log_lock = {0}; static spinlock_t log_lock = {0};
void log(char *format, ...) { void log(char *format, ...) {
//spinlock_acquire(&log_lock); // spinlock_acquire(&log_lock);
// TODO: replace this call with a call to printf() when the RTC is implemented. // TODO: replace this call with a call to printf() when the RTC is
// implemented.
char *date = "1970-01-01 00:00:00 | "; char *date = "1970-01-01 00:00:00 | ";
int i2 = 0; for (i2; date[i2] != 0; i2++);; int i2 = 0;
for (i2; date[i2] != 0; i2++)
;
;
if (ft_ctx) if (ft_ctx)
flanterm_write(ft_ctx, date, i2); flanterm_write(ft_ctx, date, i2);
@ -23,23 +27,26 @@ void log(char *format, ...) {
npf_vsnprintf(buf, 2048, format, l); npf_vsnprintf(buf, 2048, format, l);
va_end(l); va_end(l);
int i = 0; for (i; buf[i] != 0; i++);; int i = 0;
for (i; buf[i] != 0; i++)
;
;
if (ft_ctx) if (ft_ctx)
flanterm_write(ft_ctx, buf, i); flanterm_write(ft_ctx, buf, i);
for (int i=0;;i++) { for (int i = 0;; i++) {
if (date[i] == '\0') if (date[i] == '\0')
break; break;
outb(0xE9, date[i]); outb(0xE9, date[i]);
} }
for (int i=0;;i++) { for (int i = 0;; i++) {
if (buf[i] == '\0') if (buf[i] == '\0')
break; break;
outb(0xE9, buf[i]); outb(0xE9, buf[i]);
} }
//spinlock_release(&log_lock); // spinlock_release(&log_lock);
} }

7
kernel/src/sys/printf.c Executable file → Normal file
View file

@ -24,8 +24,11 @@ void printf(char *format, ...) {
npf_vsnprintf(buf, 2048, format, lst); npf_vsnprintf(buf, 2048, format, lst);
va_end(lst); va_end(lst);
//rt_print(buf); // rt_print(buf);
int i = 0; for (i; buf[i] != 0; i++);; int i = 0;
for (i; buf[i] != 0; i++)
;
;
if (ft_ctx) if (ft_ctx)
flanterm_write(ft_ctx, buf, i); flanterm_write(ft_ctx, buf, i);

View file

@ -1,6 +1,6 @@
#include "sched/sched.h" #include "sched/sched.h"
#include <stdint.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h>
#include <sys/log.h> #include <sys/log.h>
#include <sys/syscall.h> #include <sys/syscall.h>
@ -13,7 +13,8 @@ static uint64_t __syscall_undefined() { return 0; }
void syscall_handle(registers_t *regs) { void syscall_handle(registers_t *regs) {
if (regs->rax > 1024) { if (regs->rax > 1024) {
log("syscall - syscall_handle was called with rax better than what Soaplin supports (1024). did you forget to set rax?\n"); log("syscall - syscall_handle was called with rax better than what Soaplin "
"supports (1024). did you forget to set rax?\n");
return; return;
} }
@ -23,18 +24,21 @@ void syscall_handle(registers_t *regs) {
} }
if (syscall_table[regs->rax] == (syscall)__syscall_undefined) { if (syscall_table[regs->rax] == (syscall)__syscall_undefined) {
log("syscall - syscall_handle was called with an undefined system call. (%d)\n", regs->rax); log("syscall - syscall_handle was called with an undefined system call. "
"(%d)\n",
regs->rax);
return; return;
} }
regs->rax = syscall_table[regs->rax](regs->rdi, regs->rsi, regs->rdx, regs->rcx, regs->r8, regs->r9); regs->rax = syscall_table[regs->rax](regs->rdi, regs->rsi, regs->rdx,
regs->rcx, regs->r8, regs->r9);
return; return;
} }
void syscall_register(int id, syscall handler) { void syscall_register(int id, syscall handler) {
if (syscall_table[id] != (syscall)__syscall_undefined) if (syscall_table[id] != (syscall)__syscall_undefined) {
{ log("syscall - warning: syscall_register has been called to try replacing "
log("syscall - warning: syscall_register has been called to try replacing an existing syscall.\n"); "an existing syscall.\n");
return; return;
} }

View file

@ -4,15 +4,17 @@
#include <stdint.h> #include <stdint.h>
/// A function that defines a system call. /// A function that defines a system call.
/// NOTE: Arguments are defined as uint64_t, but you can simply put your own type, and then cast your function to syscall. /// NOTE: Arguments are defined as uint64_t, but you can simply put your own
typedef uint64_t(*syscall)(uint64_t rdi, uint64_t rsi, uint64_t rdx, uint64_t rcx, uint64_t r8, uint64_t r9); /// type, and then cast your function to syscall.
typedef uint64_t (*syscall)(uint64_t rdi, uint64_t rsi, uint64_t rdx,
uint64_t rcx, uint64_t r8, uint64_t r9);
/// Registers a system call. /// Registers a system call.
/// NOTE: an existing system call cannot be replaced by another. /// NOTE: an existing system call cannot be replaced by another.
void syscall_register(int id, syscall handler); void syscall_register(int id, syscall handler);
/// Called by the interupt handler, or the "syscall" instruction handler /// Called by the interupt handler, or the "syscall" instruction handler
void syscall_handle(registers_t*); void syscall_handle(registers_t *);
/// Initialize the system calls. /// Initialize the system calls.
void syscall_init(); void syscall_init();

View file

@ -1,6 +1,6 @@
#include <sched/sched.h> #include <sched/sched.h>
int syscall_exit(int exit_code) { int syscall_exit(int exit_code) {
//sched_exit(exit_code); // sched_exit(exit_code);
return 0; return 0;
} }