Update files

This commit is contained in:
Alex
2022-10-08 04:33:53 +03:00
parent 6d5f7e9372
commit 8652d781ce
53 changed files with 7413 additions and 10 deletions

View File

12
include/bitmap.hpp Normal file
View File

@ -0,0 +1,12 @@
#pragma once
#include <types.h>
class Bitmap
{
public:
size_t Size;
uint8_t *Buffer;
bool operator[](uint64_t index);
bool Set(uint64_t index, bool value);
bool Get(uint64_t index);
};

120
include/boot/binfo.h Normal file
View File

@ -0,0 +1,120 @@
#ifndef __FENNIX_KERNEL_BOOT_INFO_H__
#define __FENNIX_KERNEL_BOOT_INFO_H__
#include <types.h>
enum MemoryType
{
Usable,
Reserved,
ACPIReclaimable,
ACPINVS,
BadMemory,
BootloaderReclaimable,
KernelAndModules,
Framebuffer,
Unknown
};
#define MAX_FRAMEBUFFERS 16
#define MAX_MEMORY_ENTRIES 256
#define MAX_MODULES 16
struct BootInfo
{
struct FramebufferInfo
{
void *BaseAddress;
uint64_t Width;
uint64_t Height;
uint64_t Pitch;
uint16_t BitsPerPixel;
uint8_t MemoryModel;
uint8_t RedMaskSize;
uint8_t RedMaskShift;
uint8_t GreenMaskSize;
uint8_t GreenMaskShift;
uint8_t BlueMaskSize;
uint8_t BlueMaskShift;
void *ExtendedDisplayIdentificationData;
uint64_t EDIDSize;
} Framebuffer[MAX_FRAMEBUFFERS];
struct MemoryInfo
{
struct MemoryEntryInfo
{
void *BaseAddress;
uint64_t Length;
enum MemoryType Type;
} Entry[MAX_MEMORY_ENTRIES];
uint64_t Entries;
uint64_t Size;
} Memory;
struct ModuleInfo
{
void *Address;
char Path[256];
char CommandLine[256];
uint64_t Size;
} Modules[MAX_MODULES];
struct RSDPInfo
{
/**
* @brief Signature
*/
unsigned char Signature[8];
/**
* @brief Checksum
*/
uint8_t Checksum;
/**
* @brief OEM ID
*/
uint8_t OEMID[6];
/**
* @brief Revision
*/
uint8_t Revision;
/**
* @brief Address of the Root System Description Table
*/
uint32_t RSDTAddress;
/* END OF RSDP 1.0 */
/**
* @brief Length
*/
uint32_t Length;
/**
* @brief Extended System Descriptor Table
*/
uint64_t XSDTAddress;
/**
* @brief Extended checksum
*/
uint8_t ExtendedChecksum;
/**
* @brief Reserved
*/
uint8_t Reserved[3];
} __attribute__((packed)) * RSDP;
struct KernelInfo
{
void *PhysicalBase;
void *VirtualBase;
char CommandLine[256];
uint64_t Size;
} Kernel;
struct BootloaderInfo
{
char Name[256];
char Version[64];
} Bootloader;
};
#endif // !__FENNIX_KERNEL_BOOT_INFO_H__

View File

@ -0,0 +1,420 @@
#ifndef _LIMINE_H
#define _LIMINE_H 1
#ifdef __cplusplus
extern "C" {
#endif
#include <types.h>
/* Misc */
#ifdef LIMINE_NO_POINTERS
# define LIMINE_PTR(TYPE) uint64_t
#else
# define LIMINE_PTR(TYPE) TYPE
#endif
#define LIMINE_COMMON_MAGIC 0xc7b1dd30df4c8b88, 0x0a82e883a194f07b
struct limine_uuid {
uint32_t a;
uint16_t b;
uint16_t c;
uint8_t d[8];
};
#define LIMINE_MEDIA_TYPE_GENERIC 0
#define LIMINE_MEDIA_TYPE_OPTICAL 1
#define LIMINE_MEDIA_TYPE_TFTP 2
struct limine_file {
uint64_t revision;
LIMINE_PTR(void *) address;
uint64_t size;
LIMINE_PTR(char *) path;
LIMINE_PTR(char *) cmdline;
uint32_t media_type;
uint32_t unused;
uint32_t tftp_ip;
uint32_t tftp_port;
uint32_t partition_index;
uint32_t mbr_disk_id;
struct limine_uuid gpt_disk_uuid;
struct limine_uuid gpt_part_uuid;
struct limine_uuid part_uuid;
};
/* Boot info */
#define LIMINE_BOOTLOADER_INFO_REQUEST { LIMINE_COMMON_MAGIC, 0xf55038d8e2a1202f, 0x279426fcf5f59740 }
struct limine_bootloader_info_response {
uint64_t revision;
LIMINE_PTR(char *) name;
LIMINE_PTR(char *) version;
};
struct limine_bootloader_info_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_bootloader_info_response *) response;
};
/* Stack size */
#define LIMINE_STACK_SIZE_REQUEST { LIMINE_COMMON_MAGIC, 0x224ef0460a8e8926, 0xe1cb0fc25f46ea3d }
struct limine_stack_size_response {
uint64_t revision;
};
struct limine_stack_size_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_stack_size_response *) response;
uint64_t stack_size;
};
/* HHDM */
#define LIMINE_HHDM_REQUEST { LIMINE_COMMON_MAGIC, 0x48dcf1cb8ad2b852, 0x63984e959a98244b }
struct limine_hhdm_response {
uint64_t revision;
uint64_t offset;
};
struct limine_hhdm_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_hhdm_response *) response;
};
/* Framebuffer */
#define LIMINE_FRAMEBUFFER_REQUEST { LIMINE_COMMON_MAGIC, 0x9d5827dcd881dd75, 0xa3148604f6fab11b }
#define LIMINE_FRAMEBUFFER_RGB 1
struct limine_framebuffer {
LIMINE_PTR(void *) address;
uint64_t width;
uint64_t height;
uint64_t pitch;
uint16_t bpp;
uint8_t memory_model;
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 blue_mask_shift;
uint8_t unused[7];
uint64_t edid_size;
LIMINE_PTR(void *) edid;
};
struct limine_framebuffer_response {
uint64_t revision;
uint64_t framebuffer_count;
LIMINE_PTR(struct limine_framebuffer **) framebuffers;
};
struct limine_framebuffer_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_framebuffer_response *) response;
};
/* Terminal */
#define LIMINE_TERMINAL_REQUEST { LIMINE_COMMON_MAGIC, 0xc8ac59310c2b0844, 0xa68d0c7265d38878 }
#define LIMINE_TERMINAL_CB_DEC 10
#define LIMINE_TERMINAL_CB_BELL 20
#define LIMINE_TERMINAL_CB_PRIVATE_ID 30
#define LIMINE_TERMINAL_CB_STATUS_REPORT 40
#define LIMINE_TERMINAL_CB_POS_REPORT 50
#define LIMINE_TERMINAL_CB_KBD_LEDS 60
#define LIMINE_TERMINAL_CB_MODE 70
#define LIMINE_TERMINAL_CB_LINUX 80
#define LIMINE_TERMINAL_CTX_SIZE ((uint64_t)(-1))
#define LIMINE_TERMINAL_CTX_SAVE ((uint64_t)(-2))
#define LIMINE_TERMINAL_CTX_RESTORE ((uint64_t)(-3))
#define LIMINE_TERMINAL_FULL_REFRESH ((uint64_t)(-4))
struct limine_terminal;
typedef void (*limine_terminal_write)(struct limine_terminal *, const char *, uint64_t);
typedef void (*limine_terminal_callback)(struct limine_terminal *, uint64_t, uint64_t, uint64_t, uint64_t);
struct limine_terminal {
uint64_t columns;
uint64_t rows;
LIMINE_PTR(struct limine_framebuffer *) framebuffer;
};
struct limine_terminal_response {
uint64_t revision;
uint64_t terminal_count;
LIMINE_PTR(struct limine_terminal **) terminals;
LIMINE_PTR(limine_terminal_write) write;
};
struct limine_terminal_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_terminal_response *) response;
LIMINE_PTR(limine_terminal_callback) callback;
};
/* 5-level paging */
#define LIMINE_5_LEVEL_PAGING_REQUEST { LIMINE_COMMON_MAGIC, 0x94469551da9b3192, 0xebe5e86db7382888 }
struct limine_5_level_paging_response {
uint64_t revision;
};
struct limine_5_level_paging_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_5_level_paging_response *) response;
};
/* SMP */
#define LIMINE_SMP_REQUEST { LIMINE_COMMON_MAGIC, 0x95a67b819a1b857e, 0xa0b61b723b6a73e0 }
struct limine_smp_info;
typedef void (*limine_goto_address)(struct limine_smp_info *);
#if defined (__x86_64__) || defined (__i386__)
#define LIMINE_SMP_X2APIC (1 << 0)
struct limine_smp_info {
uint32_t processor_id;
uint32_t lapic_id;
uint64_t reserved;
LIMINE_PTR(limine_goto_address) goto_address;
uint64_t extra_argument;
};
struct limine_smp_response {
uint64_t revision;
uint32_t flags;
uint32_t bsp_lapic_id;
uint64_t cpu_count;
LIMINE_PTR(struct limine_smp_info **) cpus;
};
#elif defined (__aarch64__)
struct limine_smp_info {
uint32_t processor_id;
uint32_t gic_iface_no;
uint64_t mpidr;
uint64_t reserved;
LIMINE_PTR(limine_goto_address) goto_address;
uint64_t extra_argument;
};
struct limine_smp_response {
uint64_t revision;
uint32_t flags;
uint64_t bsp_mpidr;
uint64_t cpu_count;
LIMINE_PTR(struct limine_smp_info **) cpus;
};
#else
#error Unknown architecture
#endif
struct limine_smp_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_smp_response *) response;
uint64_t flags;
};
/* Memory map */
#define LIMINE_MEMMAP_REQUEST { LIMINE_COMMON_MAGIC, 0x67cf3d9d378a806f, 0xe304acdfc50c3c62 }
#define LIMINE_MEMMAP_USABLE 0
#define LIMINE_MEMMAP_RESERVED 1
#define LIMINE_MEMMAP_ACPI_RECLAIMABLE 2
#define LIMINE_MEMMAP_ACPI_NVS 3
#define LIMINE_MEMMAP_BAD_MEMORY 4
#define LIMINE_MEMMAP_BOOTLOADER_RECLAIMABLE 5
#define LIMINE_MEMMAP_KERNEL_AND_MODULES 6
#define LIMINE_MEMMAP_FRAMEBUFFER 7
struct limine_memmap_entry {
uint64_t base;
uint64_t length;
uint64_t type;
};
struct limine_memmap_response {
uint64_t revision;
uint64_t entry_count;
LIMINE_PTR(struct limine_memmap_entry **) entries;
};
struct limine_memmap_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_memmap_response *) response;
};
/* Entry point */
#define LIMINE_ENTRY_POINT_REQUEST { LIMINE_COMMON_MAGIC, 0x13d86c035a1cd3e1, 0x2b0caa89d8f3026a }
typedef void (*limine_entry_point)(void);
struct limine_entry_point_response {
uint64_t revision;
};
struct limine_entry_point_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_entry_point_response *) response;
LIMINE_PTR(limine_entry_point) entry;
};
/* Kernel File */
#define LIMINE_KERNEL_FILE_REQUEST { LIMINE_COMMON_MAGIC, 0xad97e90e83f1ed67, 0x31eb5d1c5ff23b69 }
struct limine_kernel_file_response {
uint64_t revision;
LIMINE_PTR(struct limine_file *) kernel_file;
};
struct limine_kernel_file_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_kernel_file_response *) response;
};
/* Module */
#define LIMINE_MODULE_REQUEST { LIMINE_COMMON_MAGIC, 0x3e7e279702be32af, 0xca1c4f3bd1280cee }
struct limine_module_response {
uint64_t revision;
uint64_t module_count;
LIMINE_PTR(struct limine_file **) modules;
};
struct limine_module_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_module_response *) response;
};
/* RSDP */
#define LIMINE_RSDP_REQUEST { LIMINE_COMMON_MAGIC, 0xc5e77b6b397e7b43, 0x27637845accdcf3c }
struct limine_rsdp_response {
uint64_t revision;
LIMINE_PTR(void *) address;
};
struct limine_rsdp_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_rsdp_response *) response;
};
/* SMBIOS */
#define LIMINE_SMBIOS_REQUEST { LIMINE_COMMON_MAGIC, 0x9e9046f11e095391, 0xaa4a520fefbde5ee }
struct limine_smbios_response {
uint64_t revision;
LIMINE_PTR(void *) entry_32;
LIMINE_PTR(void *) entry_64;
};
struct limine_smbios_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_smbios_response *) response;
};
/* EFI system table */
#define LIMINE_EFI_SYSTEM_TABLE_REQUEST { LIMINE_COMMON_MAGIC, 0x5ceba5163eaaf6d6, 0x0a6981610cf65fcc }
struct limine_efi_system_table_response {
uint64_t revision;
LIMINE_PTR(void *) address;
};
struct limine_efi_system_table_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_efi_system_table_response *) response;
};
/* Boot time */
#define LIMINE_BOOT_TIME_REQUEST { LIMINE_COMMON_MAGIC, 0x502746e184c088aa, 0xfbc5ec83e6327893 }
struct limine_boot_time_response {
uint64_t revision;
int64_t boot_time;
};
struct limine_boot_time_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_boot_time_response *) response;
};
/* Kernel address */
#define LIMINE_KERNEL_ADDRESS_REQUEST { LIMINE_COMMON_MAGIC, 0x71ba76863cc55f63, 0xb2644a48c516a487 }
struct limine_kernel_address_response {
uint64_t revision;
uint64_t physical_base;
uint64_t virtual_base;
};
struct limine_kernel_address_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_kernel_address_response *) response;
};
/* Device Tree Blob */
#define LIMINE_DTB_REQUEST { LIMINE_COMMON_MAGIC, 0xb40ddb48fb54bac7, 0x545081493f81ffb7 }
struct limine_dtb_response {
uint64_t revision;
LIMINE_PTR(void *) dtb_ptr;
};
struct limine_dtb_request {
uint64_t id[4];
uint64_t revision;
LIMINE_PTR(struct limine_dtb_response *) response;
};
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,417 @@
/* multiboot2.h - Multiboot 2 header file. */
/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY
* DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef MULTIBOOT_HEADER
#define MULTIBOOT_HEADER 1
/* How many bytes from the start of the file we search for the header. */
#define MULTIBOOT_SEARCH 32768
#define MULTIBOOT_HEADER_ALIGN 8
/* The magic field should contain this. */
#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6
/* This should be in %eax. */
#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289
/* Alignment of multiboot modules. */
#define MULTIBOOT_MOD_ALIGN 0x00001000
/* Alignment of the multiboot info structure. */
#define MULTIBOOT_INFO_ALIGN 0x00000008
/* Flags set in the 'flags' member of the multiboot header. */
#define MULTIBOOT_TAG_ALIGN 8
#define MULTIBOOT_TAG_TYPE_END 0
#define MULTIBOOT_TAG_TYPE_CMDLINE 1
#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2
#define MULTIBOOT_TAG_TYPE_MODULE 3
#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4
#define MULTIBOOT_TAG_TYPE_BOOTDEV 5
#define MULTIBOOT_TAG_TYPE_MMAP 6
#define MULTIBOOT_TAG_TYPE_VBE 7
#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8
#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9
#define MULTIBOOT_TAG_TYPE_APM 10
#define MULTIBOOT_TAG_TYPE_EFI32 11
#define MULTIBOOT_TAG_TYPE_EFI64 12
#define MULTIBOOT_TAG_TYPE_SMBIOS 13
#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14
#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15
#define MULTIBOOT_TAG_TYPE_NETWORK 16
#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17
#define MULTIBOOT_TAG_TYPE_EFI_BS 18
#define MULTIBOOT_TAG_TYPE_EFI32_IH 19
#define MULTIBOOT_TAG_TYPE_EFI64_IH 20
#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21
#define MULTIBOOT_HEADER_TAG_END 0
#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1
#define MULTIBOOT_HEADER_TAG_ADDRESS 2
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3
#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4
#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5
#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6
#define MULTIBOOT_HEADER_TAG_EFI_BS 7
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8
#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9
#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10
#define MULTIBOOT_ARCHITECTURE_I386 0
#define MULTIBOOT_ARCHITECTURE_MIPS32 4
#define MULTIBOOT_HEADER_TAG_OPTIONAL 1
#define MULTIBOOT_LOAD_PREFERENCE_NONE 0
#define MULTIBOOT_LOAD_PREFERENCE_LOW 1
#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2
#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1
#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2
#ifndef ASM_FILE
typedef unsigned char multiboot_uint8_t;
typedef unsigned short multiboot_uint16_t;
typedef unsigned int multiboot_uint32_t;
typedef unsigned long long multiboot_uint64_t;
struct multiboot_header
{
/* Must be MULTIBOOT_MAGIC - see above. */
multiboot_uint32_t magic;
/* ISA */
multiboot_uint32_t architecture;
/* Total header length. */
multiboot_uint32_t header_length;
/* The above fields plus this one must equal 0 mod 2^32. */
multiboot_uint32_t checksum;
};
struct multiboot_header_tag
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
};
struct multiboot_header_tag_information_request
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t requests[0];
};
struct multiboot_header_tag_address
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t header_addr;
multiboot_uint32_t load_addr;
multiboot_uint32_t load_end_addr;
multiboot_uint32_t bss_end_addr;
};
struct multiboot_header_tag_entry_address
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t entry_addr;
};
struct multiboot_header_tag_console_flags
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t console_flags;
};
struct multiboot_header_tag_framebuffer
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t width;
multiboot_uint32_t height;
multiboot_uint32_t depth;
};
struct multiboot_header_tag_module_align
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
};
struct multiboot_header_tag_relocatable
{
multiboot_uint16_t type;
multiboot_uint16_t flags;
multiboot_uint32_t size;
multiboot_uint32_t min_addr;
multiboot_uint32_t max_addr;
multiboot_uint32_t align;
multiboot_uint32_t preference;
};
struct multiboot_color
{
multiboot_uint8_t red;
multiboot_uint8_t green;
multiboot_uint8_t blue;
};
struct multiboot_mmap_entry
{
multiboot_uint64_t addr;
multiboot_uint64_t len;
#define MULTIBOOT_MEMORY_AVAILABLE 1
#define MULTIBOOT_MEMORY_RESERVED 2
#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3
#define MULTIBOOT_MEMORY_NVS 4
#define MULTIBOOT_MEMORY_BADRAM 5
multiboot_uint32_t type;
multiboot_uint32_t zero;
};
typedef struct multiboot_mmap_entry multiboot_memory_map_t;
struct multiboot_tag
{
multiboot_uint32_t type;
multiboot_uint32_t size;
};
struct multiboot_tag_string
{
multiboot_uint32_t type;
multiboot_uint32_t size;
char string[0];
};
struct multiboot_tag_module
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t mod_start;
multiboot_uint32_t mod_end;
char cmdline[0];
};
struct multiboot_tag_basic_meminfo
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t mem_lower;
multiboot_uint32_t mem_upper;
};
struct multiboot_tag_bootdev
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t biosdev;
multiboot_uint32_t slice;
multiboot_uint32_t part;
};
struct multiboot_tag_mmap
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t entry_size;
multiboot_uint32_t entry_version;
struct multiboot_mmap_entry entries[0];
};
struct multiboot_vbe_info_block
{
multiboot_uint8_t external_specification[512];
};
struct multiboot_vbe_mode_info_block
{
multiboot_uint8_t external_specification[256];
};
struct multiboot_tag_vbe
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint16_t vbe_mode;
multiboot_uint16_t vbe_interface_seg;
multiboot_uint16_t vbe_interface_off;
multiboot_uint16_t vbe_interface_len;
struct multiboot_vbe_info_block vbe_control_info;
struct multiboot_vbe_mode_info_block vbe_mode_info;
};
struct multiboot_tag_framebuffer_common
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint64_t framebuffer_addr;
multiboot_uint32_t framebuffer_pitch;
multiboot_uint32_t framebuffer_width;
multiboot_uint32_t framebuffer_height;
multiboot_uint8_t framebuffer_bpp;
#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0
#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1
#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2
multiboot_uint8_t framebuffer_type;
multiboot_uint16_t reserved;
};
struct multiboot_tag_framebuffer
{
struct multiboot_tag_framebuffer_common common;
union
{
struct
{
multiboot_uint16_t framebuffer_palette_num_colors;
struct multiboot_color framebuffer_palette[0];
};
struct
{
multiboot_uint8_t framebuffer_red_field_position;
multiboot_uint8_t framebuffer_red_mask_size;
multiboot_uint8_t framebuffer_green_field_position;
multiboot_uint8_t framebuffer_green_mask_size;
multiboot_uint8_t framebuffer_blue_field_position;
multiboot_uint8_t framebuffer_blue_mask_size;
};
};
};
struct multiboot_tag_elf_sections
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t num;
multiboot_uint32_t entsize;
multiboot_uint32_t shndx;
char sections[0];
};
struct multiboot_tag_apm
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint16_t version;
multiboot_uint16_t cseg;
multiboot_uint32_t offset;
multiboot_uint16_t cseg_16;
multiboot_uint16_t dseg;
multiboot_uint16_t flags;
multiboot_uint16_t cseg_len;
multiboot_uint16_t cseg_16_len;
multiboot_uint16_t dseg_len;
};
struct multiboot_tag_efi32
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t pointer;
};
struct multiboot_tag_efi64
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint64_t pointer;
};
struct multiboot_tag_smbios
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint8_t major;
multiboot_uint8_t minor;
multiboot_uint8_t reserved[6];
multiboot_uint8_t tables[0];
};
struct multiboot_tag_old_acpi
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint8_t rsdp[0];
};
struct multiboot_tag_new_acpi
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint8_t rsdp[0];
};
struct multiboot_tag_network
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint8_t dhcpack[0];
};
struct multiboot_tag_efi_mmap
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t descr_size;
multiboot_uint32_t descr_vers;
multiboot_uint8_t efi_mmap[0];
};
struct multiboot_tag_efi32_ih
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t pointer;
};
struct multiboot_tag_efi64_ih
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint64_t pointer;
};
struct multiboot_tag_load_base_addr
{
multiboot_uint32_t type;
multiboot_uint32_t size;
multiboot_uint32_t load_base_addr;
};
#endif /* ! ASM_FILE */
#endif /* ! MULTIBOOT_HEADER */

134
include/cpu.hpp Normal file
View File

@ -0,0 +1,134 @@
#ifndef __FENNIX_KERNEL_CPU_H__
#define __FENNIX_KERNEL_CPU_H__
#include <types.h>
/**
* @brief CPU related functions.
*/
namespace CPU
{
/**
* @brief Enum for CPU::Interrupts() function.
*/
enum InterruptsType
{
/**
* @brief Check if interrupts are enabled.
*/
Check,
/**
* @brief Enable interrupts.
*/
Enable,
/**
* @brief Disable interrupts.
*/
Disable
};
/**
* @brief Pause the CPU
*/
void Pause();
/**
* @brief Halt the CPU
*/
void Halt();
/**
* @brief Check if interrupts are enabled
*
* @return true If InterruptsType::Check and interrupts are enabled, or if other InterruptsType were executed successfully
* @return false If InterruptsType::Check and interrupts are disabled, or if other InterruptsType failed
*/
bool Interrupts(InterruptsType Type = Check);
namespace MemBar
{
static inline void Barrier()
{
#if defined(__amd64__) || defined(__i386__)
asmv("" ::
: "memory");
#elif defined(__aarch64__)
asmv("dmb ish" ::
: "memory");
#endif
}
static inline void Fence()
{
#if defined(__amd64__) || defined(__i386__)
asmv("mfence" ::
: "memory");
#elif defined(__aarch64__)
asmv("dmb ish" ::
: "memory");
#endif
}
static inline void StoreFence()
{
#if defined(__amd64__) || defined(__i386__)
asmv("sfence" ::
: "memory");
#elif defined(__aarch64__)
asmv("dmb ishst" ::
: "memory");
#endif
}
static inline void LoadFence()
{
#if defined(__amd64__) || defined(__i386__)
asmv("lfence" ::
: "memory");
#elif defined(__aarch64__)
asmv("dmb ishld" ::
: "memory");
#endif
}
}
namespace x86
{
static inline void lgdt(void *gdt)
{
#if defined(__amd64__) || defined(__i386__)
asmv("lgdt (%0)"
:
: "r"(gdt));
#endif
}
static inline void lidt(void *idt)
{
#if defined(__amd64__) || defined(__i386__)
asmv("lidt (%0)"
:
: "r"(idt));
#endif
}
static inline void ltr(uint16_t Segment)
{
#if defined(__amd64__) || defined(__i386__)
asmv("ltr %0"
:
: "r"(Segment));
#endif
}
static inline void invlpg(void *Address)
{
#if defined(__amd64__) || defined(__i386__)
asmv("invlpg (%0)"
:
: "r"(Address)
: "memory");
#endif
}
}
}
#endif // !__FENNIX_KERNEL_CPU_H__

2
include/cstring Normal file
View File

@ -0,0 +1,2 @@
#pragma once
#include <string.h>

46
include/debug.h Normal file
View File

@ -0,0 +1,46 @@
#ifndef __FENNIX_KERNEL_DEBUGGER_H__
#define __FENNIX_KERNEL_DEBUGGER_H__
#include <types.h>
enum DebugLevel
{
DebugLevelNone = 0,
DebugLevelError = 1,
DebugLevelWarning = 2,
DebugLevelInfo = 3,
DebugLevelDebug = 4,
DebugLevelTrace = 5,
DebugLevelFixme = 6
};
#ifdef __cplusplus
namespace SysDbg
{
void Write(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...);
void WriteLine(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...);
}
#define error(Format, ...) SysDbg::WriteLine(DebugLevelError, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define warn(Format, ...) SysDbg::WriteLine(DebugLevelWarning, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define info(Format, ...) SysDbg::WriteLine(DebugLevelInfo, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define debug(Format, ...) SysDbg::WriteLine(DebugLevelDebug, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define trace(Format, ...) SysDbg::WriteLine(DebugLevelTrace, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define fixme(Format, ...) SysDbg::WriteLine(DebugLevelFixme, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#else
void SysDbgWrite(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...);
void SysDbgWriteLine(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...);
#define error(Format, ...) SysDbgWriteLine(DebugLevelError, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define warn(Format, ...) SysDbgWriteLine(DebugLevelWarning, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define info(Format, ...) SysDbgWriteLine(DebugLevelInfo, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define debug(Format, ...) SysDbgWriteLine(DebugLevelDebug, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define trace(Format, ...) SysDbgWriteLine(DebugLevelTrace, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#define fixme(Format, ...) SysDbgWriteLine(DebugLevelFixme, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
#endif // __cplusplus
#endif // !__FENNIX_KERNEL_DEBUGGER_H__

93
include/hashmap.hpp Normal file
View File

@ -0,0 +1,93 @@
#pragma once
template <typename K, typename V>
class HashNode
{
public:
V Value;
K Key;
HashNode(K Key, V Value)
{
this->Value = Value;
this->Key = Key;
}
};
template <typename K, typename V>
class HashMap
{
int HashMapSize;
int HashMapCapacity;
HashNode<K, V> **Nodes;
HashNode<K, V> *DummyNode;
public:
HashMap()
{
HashMapCapacity = 20;
HashMapSize = 0;
Nodes = new HashNode<K, V> *[HashMapCapacity];
for (int i = 0; i < HashMapCapacity; i++)
Nodes[i] = nullptr;
DummyNode = new HashNode<K, V>(-1, -1);
}
int HashCode(K Key) { return Key % HashMapCapacity; }
void AddNode(K Key, V Value)
{
HashNode<K, V> *tmp = new HashNode<K, V>(Key, Value);
int Index = HashCode(Key);
while (Nodes[Index] != nullptr && Nodes[Index]->Key != Key && Nodes[Index]->Key != -1)
{
Index++;
Index %= HashMapCapacity;
}
if (Nodes[Index] == nullptr || Nodes[Index]->Key == -1)
HashMapSize++;
Nodes[Index] = tmp;
}
V DeleteNode(int Key)
{
int Index = HashCode(Key);
while (Nodes[Index] != nullptr)
{
if (Nodes[Index]->Key == Key)
{
HashNode<K, V> *tmp = Nodes[Index];
Nodes[Index] = DummyNode;
HashMapSize--;
return tmp->Value;
}
Index++;
Index %= HashMapCapacity;
}
return nullptr;
}
V Get(int Key)
{
int Index = HashCode(Key);
int Iterate = 0;
while (Nodes[Index] != nullptr)
{
if (Iterate++ > HashMapCapacity)
return 0;
if (Nodes[Index]->Key == Key)
return Nodes[Index]->Value;
Index++;
Index %= HashMapCapacity;
}
return 0;
}
int Size() { return HashMapSize; }
bool IsEmpty() { return HashMapSize == 0; }
};

220
include/io.h Normal file
View File

@ -0,0 +1,220 @@
#ifndef __FENNIX_KERNEL_IO_H__
#define __FENNIX_KERNEL_IO_H__
#include <types.h>
#if defined(__amd64__) || defined(__i386__)
#ifdef __cplusplus
extern "C"
{
#endif
static inline uint8_t inportb(uint16_t Port)
{
uint8_t Result;
asm("in %%dx, %%al"
: "=a"(Result)
: "d"(Port));
return Result;
}
static inline uint16_t inportw(uint16_t Port)
{
uint16_t Result;
asm("in %%dx, %%ax"
: "=a"(Result)
: "d"(Port));
return Result;
}
static inline uint32_t inportl(uint16_t Port)
{
uint32_t Result;
asmv("inl %1, %0"
: "=a"(Result)
: "dN"(Port));
return Result;
}
static inline void outportb(uint16_t Port, uint8_t Data)
{
asmv("out %%al, %%dx"
:
: "a"(Data), "d"(Port));
}
static inline void outportw(uint16_t Port, uint16_t Data)
{
asmv("out %%ax, %%dx"
:
: "a"(Data), "d"(Port));
}
static inline void outportl(uint16_t Port, uint32_t Data)
{
asmv("outl %1, %0"
:
: "dN"(Port), "a"(Data));
}
static inline uint8_t mmioin8(uint64_t Address)
{
asmv("" ::
: "memory");
uint8_t Result = *(volatile uint8_t *)Address;
asmv("" ::
: "memory");
return Result;
}
static inline uint16_t mmioin16(uint64_t Address)
{
asmv("" ::
: "memory");
uint16_t Result = *(volatile uint16_t *)Address;
asmv("" ::
: "memory");
return Result;
}
static inline uint32_t mmioin32(uint64_t Address)
{
asmv("" ::
: "memory");
uint32_t Result = *(volatile uint32_t *)Address;
asmv("" ::
: "memory");
return Result;
}
static inline uint64_t mmioin64(uint64_t Address)
{
asmv("" ::
: "memory");
uint64_t Result = *(volatile uint64_t *)Address;
asmv("" ::
: "memory");
return Result;
}
static inline void mmioout8(uint64_t Address, uint8_t Data)
{
asmv("" ::
: "memory");
*(volatile uint8_t *)Address = Data;
asmv("" ::
: "memory");
}
static inline void mmioout16(uint64_t Address, uint16_t Data)
{
asmv("" ::
: "memory");
*(volatile uint16_t *)Address = Data;
asmv("" ::
: "memory");
}
static inline void mmioout32(uint64_t Address, uint32_t Data)
{
asmv("" ::
: "memory");
*(volatile uint32_t *)Address = Data;
asmv("" ::
: "memory");
}
static inline void mmioout64(uint64_t Address, uint64_t Data)
{
asmv("" ::
: "memory");
*(volatile uint64_t *)Address = Data;
asmv("" ::
: "memory");
}
static inline void mmoutb(void *Address, uint8_t Value)
{
asmv("mov %1, %0"
: "=m"((*(uint8_t *)(Address)))
: "r"(Value)
: "memory");
}
static inline void mmoutw(void *Address, uint16_t Value)
{
asmv("mov %1, %0"
: "=m"((*(uint16_t *)(Address)))
: "r"(Value)
: "memory");
}
static inline void mmoutl(void *Address, uint32_t Value)
{
asmv("mov %1, %0"
: "=m"((*(uint32_t *)(Address)))
: "r"(Value)
: "memory");
}
static inline void mmoutq(void *Address, uint64_t Value)
{
asmv("mov %1, %0"
: "=m"((*(uint64_t *)(Address)))
: "r"(Value)
: "memory");
}
static inline uint8_t mminb(void *Address)
{
uint8_t Result;
asmv("mov %1, %0"
: "=r"(Result)
: "m"((*(uint8_t *)(Address)))
: "memory");
return Result;
}
static inline uint16_t mminw(void *Address)
{
uint16_t Result;
asmv("mov %1, %0"
: "=r"(Result)
: "m"((*(uint16_t *)(Address)))
: "memory");
return Result;
}
static inline uint32_t mminl(void *Address)
{
uint32_t Result;
asmv("mov %1, %0"
: "=r"(Result)
: "m"((*(uint32_t *)(Address)))
: "memory");
return Result;
}
static inline uint64_t mminq(void *Address)
{
uint64_t Result;
asmv("mov %1, %0"
: "=r"(Result)
: "m"((*(uint64_t *)(Address)))
: "memory");
return Result;
}
#ifdef __cplusplus
}
#endif
#define inb(Port) inportb(Port)
#define inw(Port) inportw(Port)
#define inl(Port) inportl(Port)
#define outb(Port, Data) outportb(Port, Data)
#define outw(Port, Data) outportw(Port, Data)
#define outl(Port, Data) outportl(Port, Data)
#endif // defined(__amd64__) || defined(__i386__)
#endif // !__FENNIX_KERNEL_IO_H__

119
include/limits.h Normal file
View File

@ -0,0 +1,119 @@
#ifndef __FENNIX_KERNEL_LIMITS_H__
#define __FENNIX_KERNEL_LIMITS_H__
#undef CHAR_BIT
#define CHAR_BIT __CHAR_BIT__
#ifndef MB_LEN_MAX
#define MB_LEN_MAX 1
#endif
#undef SCHAR_MIN
#define SCHAR_MIN (-SCHAR_MAX - 1)
#undef SCHAR_MAX
#define SCHAR_MAX __SCHAR_MAX__
#undef UCHAR_MAX
#if __SCHAR_MAX__ == __INT_MAX__
#define UCHAR_MAX (SCHAR_MAX * 2U + 1U)
#else
#define UCHAR_MAX (SCHAR_MAX * 2 + 1)
#endif
#ifdef __CHAR_UNSIGNED__
#undef CHAR_MIN
#if __SCHAR_MAX__ == __INT_MAX__
#define CHAR_MIN 0U
#else
#define CHAR_MIN 0
#endif
#undef CHAR_MAX
#define CHAR_MAX UCHAR_MAX
#else
#undef CHAR_MIN
#define CHAR_MIN SCHAR_MIN
#undef CHAR_MAX
#define CHAR_MAX SCHAR_MAX
#endif
#undef SHRT_MIN
#define SHRT_MIN (-SHRT_MAX - 1)
#undef SHRT_MAX
#define SHRT_MAX __SHRT_MAX__
#undef USHRT_MAX
#if __SHRT_MAX__ == __INT_MAX__
#define USHRT_MAX (SHRT_MAX * 2U + 1U)
#else
#define USHRT_MAX (SHRT_MAX * 2 + 1)
#endif
#undef INT_MIN
#define INT_MIN (-INT_MAX - 1)
#undef INT_MAX
#define INT_MAX __INT_MAX__
#undef UINT_MAX
#define UINT_MAX (INT_MAX * 2U + 1U)
#undef LONG_MIN
#define LONG_MIN (-LONG_MAX - 1L)
#undef LONG_MAX
#define LONG_MAX __LONG_MAX__
#undef ULONG_MAX
#define ULONG_MAX (LONG_MAX * 2UL + 1UL)
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#undef LLONG_MIN
#define LLONG_MIN (-LLONG_MAX - 1LL)
#undef LLONG_MAX
#define LLONG_MAX __LONG_LONG_MAX__
#undef ULLONG_MAX
#define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
#endif
#if defined(__GNU_LIBRARY__) ? defined(__USE_GNU) : !defined(__STRICT_ANSI__)
#undef LONG_LONG_MIN
#define LONG_LONG_MIN (-LONG_LONG_MAX - 1LL)
#undef LONG_LONG_MAX
#define LONG_LONG_MAX __LONG_LONG_MAX__
#undef ULONG_LONG_MAX
#define ULONG_LONG_MAX (LONG_LONG_MAX * 2ULL + 1ULL)
#endif
#if (defined __STDC_WANT_IEC_60559_BFP_EXT__ || (defined(__STDC_VERSION__) && __STDC_VERSION__ > 201710L))
#undef CHAR_WIDTH
#define CHAR_WIDTH __SCHAR_WIDTH__
#undef SCHAR_WIDTH
#define SCHAR_WIDTH __SCHAR_WIDTH__
#undef UCHAR_WIDTH
#define UCHAR_WIDTH __SCHAR_WIDTH__
#undef SHRT_WIDTH
#define SHRT_WIDTH __SHRT_WIDTH__
#undef USHRT_WIDTH
#define USHRT_WIDTH __SHRT_WIDTH__
#undef INT_WIDTH
#define INT_WIDTH __INT_WIDTH__
#undef UINT_WIDTH
#define UINT_WIDTH __INT_WIDTH__
#undef LONG_WIDTH
#define LONG_WIDTH __LONG_WIDTH__
#undef ULONG_WIDTH
#define ULONG_WIDTH __LONG_WIDTH__
#undef LLONG_WIDTH
#define LLONG_WIDTH __LONG_LONG_WIDTH__
#undef ULLONG_WIDTH
#define ULLONG_WIDTH __LONG_LONG_WIDTH__
#endif
#if defined(__STDC_VERSION__) && __STDC_VERSION__ > 201710L
#undef BOOL_MAX
#define BOOL_MAX 1
#undef BOOL_WIDTH
#define BOOL_WIDTH 1
#endif
#endif // !__FENNIX_KERNEL_LIMITS_H__

53
include/lock.hpp Normal file
View File

@ -0,0 +1,53 @@
#ifndef __FENNIX_KERNEL_LOCK_H__
#define __FENNIX_KERNEL_LOCK_H__
#include <types.h>
#include <cpu.hpp>
#ifdef __cplusplus
class LockClass
{
private:
bool IsLocked = false;
public:
int Lock()
{
while (!__sync_bool_compare_and_swap(&IsLocked, false, true))
CPU::Pause();
__sync_synchronize();
return 0;
}
int Unlock()
{
__sync_synchronize();
__atomic_store_n(&IsLocked, false, __ATOMIC_SEQ_CST);
IsLocked = false;
return 0;
}
};
#define NEWLOCK(Name) LockClass Name
class SmartLock
{
private:
LockClass *LockPointer = nullptr;
public:
SmartLock(LockClass &Lock)
{
this->LockPointer = &Lock;
this->LockPointer->Lock();
}
~SmartLock() { this->LockPointer->Unlock(); }
};
#define SL_CONCAT(x, y) x##y
#define SMARTLOCK(LockClassName) SmartLock SL_CONCAT(lock##_, __COUNTER__)(LockClassName)
#endif
#endif // !__FENNIX_KERNEL_LOCK_H__

432
include/memory.hpp Normal file
View File

@ -0,0 +1,432 @@
#ifndef __FENNIX_KERNEL_INTERNAL_MEMORY_H__
#define __FENNIX_KERNEL_INTERNAL_MEMORY_H__
#include <boot/binfo.h>
#include <bitmap.hpp>
#include <lock.hpp>
#include <types.h>
extern uint64_t _kernel_start, _kernel_end;
extern uint64_t _kernel_text_end, _kernel_data_end, _kernel_rodata_end;
// kilobyte
#define TO_KB(d) (d / 1024)
// megabyte
#define TO_MB(d) (d / 1024 / 1024)
// gigabyte
#define TO_GB(d) (d / 1024 / 1024 / 1024)
// terabyte
#define TO_TB(d) (d / 1024 / 1024 / 1024 / 1024)
// petabyte
#define TO_PB(d) (d / 1024 / 1024 / 1024 / 1024 / 1024)
// exobyte
#define TO_EB(d) (d / 1024 / 1024 / 1024 / 1024 / 1024 / 1024)
// zettabyte
#define TO_ZB(d) (d / 1024 / 1024 / 1024 / 1024 / 1024 / 1024 / 1024)
// yottabyte
#define TO_YB(d) (d / 1024 / 1024 / 1024 / 1024 / 1024 / 1024 / 1024 / 1024)
// brontobyte
#define TO_BB(d) (d / 1024 / 1024 / 1024 / 1024 / 1024 / 1024 / 1024 / 1024 / 1024)
// geopbyte
#define TO_GPB(d) (d / 1024 / 1024 / 1024 / 1024 / 1024 / 1024 / 1024 / 1024 / 1024 / 1024)
#define PAGE_SIZE 0x1000
// to pages
#define TO_PAGES(d) (d / PAGE_SIZE + 1)
// from pages
#define FROM_PAGES(d) (d * PAGE_SIZE - 1)
#define NORMAL_VMA_OFFSET 0xFFFF800000000000
#define KERNEL_VMA_OFFSET 0xFFFFFFFF80000000
/**
* @brief KERNEL_HEAP_BASE is the base address of the kernel heap
*/
#define KERNEL_HEAP_BASE 0xFFFFC00000000000
/**
* @brief USER_HEAP_BASE is the base address of the user heap allocated by the kernel
*/
#define USER_HEAP_BASE 0xFFFFD00000000000
namespace Memory
{
/**
* @brief https://wiki.osdev.org/images/4/41/64-bit_page_tables1.png
* @brief https://wiki.osdev.org/images/6/6b/64-bit_page_tables2.png
*/
enum PTFlag
{
/** @brief Present */
P = 1 << 0,
/** @brief Read/Write */
RW = 1 << 1,
/** @brief User/Supervisor */
US = 1 << 2,
/** @brief Write-Through */
PWT = 1 << 3,
/** @brief Cache Disable */
PCD = 1 << 4,
/** @brief Accessed */
A = 1 << 5,
/** @brief Dirty */
D = 1 << 6,
/** @brief Page Size */
PS = 1 << 7,
/** @brief Global */
G = 1 << 8,
/** @brief Available 0 */
AVL0 = 1 << 9,
/** @brief Available 1 */
AVL1 = 1 << 10,
/** @brief Available 2 */
AVL2 = 1 << 11,
/** @brief Page Attribute Table */
PAT = 1 << 12,
/** @brief Available 3 */
AVL3 = (uint64_t)1 << 52,
/** @brief Available 4 */
AVL4 = (uint64_t)1 << 53,
/** @brief Available 5 */
AVL5 = (uint64_t)1 << 54,
/** @brief Available 6 */
AVL6 = (uint64_t)1 << 55,
/** @brief Available 7 */
AVL7 = (uint64_t)1 << 56,
/** @brief Available 8 */
AVL8 = (uint64_t)1 << 57,
/** @brief Available 9 */
AVL9 = (uint64_t)1 << 58,
/** @brief Protection Key 0 */
PK0 = (uint64_t)1 << 59,
/** @brief Protection Key 1 */
PK1 = (uint64_t)1 << 60,
/** @brief Protection Key 2 */
PK2 = (uint64_t)1 << 61,
/** @brief Protection Key 3 */
PK3 = (uint64_t)1 << 62,
/** @brief Execute Disable */
XD = (uint64_t)1 << 63
};
typedef union __attribute__((packed))
{
struct
{
bool Present : 1;
bool ReadWrite : 1;
bool UserSupervisor : 1;
bool WriteThrough : 1;
bool CacheDisable : 1;
bool Accessed : 1;
bool Dirty : 1;
bool PageSize : 1;
bool Global : 1;
uint8_t Available1 : 3;
bool PageAttributeTable : 1;
uint64_t Reserved : 39;
uint32_t Available2 : 7;
uint16_t ProtectionKey : 4;
bool ExecuteDisable : 1;
};
uint64_t raw;
} PDEData;
struct __attribute__((packed)) PageDirectoryEntry
{
PDEData Value;
void AddFlag(uint64_t Flag) { this->Value.raw |= Flag; }
void RemoveFlags(uint64_t Flag) { this->Value.raw &= ~Flag; }
void ClearFlags() { this->Value.raw = 0; }
void SetFlag(uint64_t Flag, bool Enabled)
{
this->Value.raw &= ~Flag;
if (Enabled)
this->Value.raw |= Flag;
}
bool GetFlag(uint64_t Flag) { return (this->Value.raw & Flag) > 0 ? true : false; }
uint64_t GetFlag() { return this->Value.raw; }
void SetAddress(uint64_t Address)
{
#if defined(__amd64__)
Address &= 0x000000FFFFFFFFFF;
this->Value.raw &= 0xFFF0000000000FFF;
this->Value.raw |= (Address << 12);
#elif defined(__i386__)
Address &= 0x000FFFFF;
this->Value.raw &= 0xFFC00003;
this->Value.raw |= (Address << 12);
#elif defined(__aarch64__)
Address &= 0x000000FFFFFFFFFF;
this->Value.raw &= 0xFFF0000000000FFF;
this->Value.raw |= (Address << 12);
#endif
}
uint64_t GetAddress()
{
#if defined(__amd64__)
return (this->Value.raw & 0x000FFFFFFFFFF000) >> 12;
#elif defined(__i386__)
return (this->Value.raw & 0x003FFFFF000) >> 12;
#elif defined(__aarch64__)
return (this->Value.raw & 0x000FFFFFFFFFF000) >> 12;
#endif
}
};
struct PageTable
{
PageDirectoryEntry Entries[512];
} __attribute__((aligned(0x1000)));
class Physical
{
private:
NEWLOCK(MemoryLock);
uint64_t TotalMemory = 0;
uint64_t FreeMemory = 0;
uint64_t ReservedMemory = 0;
uint64_t UsedMemory = 0;
uint64_t PageBitmapIndex = 0;
Bitmap PageBitmap;
void ReservePage(void *Address);
void ReservePages(void *Address, uint64_t PageCount);
void UnreservePage(void *Address);
void UnreservePages(void *Address, uint64_t PageCount);
public:
/**
* @brief Get Total Memory
*
* @return uint64_t
*/
uint64_t GetTotalMemory();
/**
* @brief Get Free Memory
*
* @return uint64_t
*/
uint64_t GetFreeMemory();
/**
* @brief Get Reserved Memory
*
* @return uint64_t
*/
uint64_t GetReservedMemory();
/**
* @brief Get Used Memory
*
* @return uint64_t
*/
uint64_t GetUsedMemory();
/**
* @brief Swap page
*
* @param Address Address of the page
* @return true if swap was successful
* @return false if swap was unsuccessful
*/
bool SwapPage(void *Address);
/**
* @brief Swap pages
*
* @param Address Address of the pages
* @param PageCount Number of pages
* @return true if swap was successful
* @return false if swap was unsuccessful
*/
bool SwapPages(void *Address, uint64_t PageCount);
/**
* @brief Unswap page
*
* @param Address Address of the page
* @return true if unswap was successful
* @return false if unswap was unsuccessful
*/
bool UnswapPage(void *Address);
/**
* @brief Unswap pages
*
* @param Address Address of the pages
* @param PageCount Number of pages
* @return true if unswap was successful
* @return false if unswap was unsuccessful
*/
bool UnswapPages(void *Address, uint64_t PageCount);
/**
* @brief Lock page
*
* @param Address Address of the page
*/
void LockPage(void *Address);
/**
* @brief Lock pages
*
* @param Address Address of the pages
* @param PageCount Number of pages
*/
void LockPages(void *Address, uint64_t PageCount);
/**
* @brief Request page
*
* @return void* Allocated page address
*/
void *RequestPage();
/**
* @brief Request pages
*
* @param PageCount Number of pages
* @return void* Allocated pages address
*/
void *RequestPages(uint64_t Count);
/**
* @brief Free page
*
* @param Address Address of the page
*/
void FreePage(void *Address);
/**
* @brief Free pages
*
* @param Address Address of the pages
* @param PageCount Number of pages
*/
void FreePages(void *Address, uint64_t Count);
/** @brief Do not use. */
void Init(BootInfo *Info);
/** @brief Do not use. */
Physical();
/** @brief Do not use. */
~Physical();
};
class Virtual
{
private:
NEWLOCK(MemoryLock);
PageTable *Table = nullptr;
class PageMapIndexer
{
public:
uint64_t PDP_i;
uint64_t PD_i;
uint64_t PT_i;
uint64_t P_i;
PageMapIndexer(uint64_t VirtualAddress)
{
#if defined(__amd64__)
PDP_i = (VirtualAddress & ((uint64_t)0x1FF << 39)) >> 39;
PD_i = (VirtualAddress & ((uint64_t)0x1FF << 30)) >> 30;
PT_i = (VirtualAddress & ((uint64_t)0x1FF << 21)) >> 21;
P_i = (VirtualAddress & ((uint64_t)0x1FF << 12)) >> 12;
#elif defined(__i386__)
PD_i = (VirtualAddress & ((uint64_t)0x3FF << 22)) >> 22;
PT_i = (VirtualAddress & ((uint64_t)0x3FF << 12)) >> 12;
P_i = (VirtualAddress & ((uint64_t)0xFFF << 0)) >> 0;
#elif defined(__aarch64__)
PD_i = (VirtualAddress & ((uint64_t)0x1FF << 30)) >> 30;
PT_i = (VirtualAddress & ((uint64_t)0x1FF << 21)) >> 21;
P_i = (VirtualAddress & ((uint64_t)0x1FF << 12)) >> 12;
#endif
}
};
public:
/**
* @brief Map page.
*
* @param VirtualAddress Virtual address of the page.
* @param PhysicalAddress Physical address of the page.
* @param Flags Flags of the page. Check PTFlag enum.
*/
void Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags);
/**
* @brief Map multiple pages.
*
* @param VirtualAddress First virtual address of the page.
* @param PhysicalAddress First physical address of the page.
* @param PageCount Number of pages.
* @param Flags Flags of the page. Check PTFlag enum.
*/
void Map(void *VirtualAddress, void *PhysicalAddress, uint64_t PageCount, uint64_t Flags);
/**
* @brief Unmap page.
*
* @param VirtualAddress Virtual address of the page.
*/
void Unmap(void *VirtualAddress);
/**
* @brief Unmap multiple pages.
*
* @param VirtualAddress First virtual address of the page.
* @param PageCount Number of pages.
*/
void Unmap(void *VirtualAddress, uint64_t PageCount);
/**
* @brief Construct a new Virtual object
*
* @param Table Page table
*/
Virtual(PageTable *Table);
/**
* @brief Destroy the Virtual object
*
*/
~Virtual();
};
}
void InitializeMemoryManagement(BootInfo *Info);
void *operator new(uint64_t Size);
void *operator new[](uint64_t Size);
void operator delete(void *Pointer);
void operator delete[](void *Pointer);
void operator delete(void *Pointer, long unsigned int Size);
void operator delete[](void *Pointer, long unsigned int Size);
void *HeapMalloc(uint64_t Size);
void *HeapCalloc(uint64_t n, uint64_t Size);
void *HeapRealloc(void *Address, uint64_t Size);
void HeapFree(void *Address);
#define kmalloc(Size) HeapMalloc(Size)
#define kcalloc(n, Size) HeapCalloc(n, Size)
#define krealloc(Address, Size) HeapRealloc(Address, Size)
#define kfree(Address) HeapFree(Address)
extern Memory::Physical KernelAllocator;
extern Memory::PageTable *KernelPageTable;
#endif // !__FENNIX_KERNEL_INTERNAL_MEMORY_H__

199
include/printf.h Normal file
View File

@ -0,0 +1,199 @@
/**
* @author (c) Eyal Rozenberg <eyalroz1@gmx.com>
* 2021-2022, Haifa, Palestine/Israel
* @author (c) Marco Paland (info@paland.com)
* 2014-2019, PALANDesign Hannover, Germany
*
* @note Others have made smaller contributions to this file: see the
* contributors page at https://github.com/eyalroz/printf/graphs/contributors
* or ask one of the authors.
*
* @brief Small stand-alone implementation of the printf family of functions
* (`(v)printf`, `(v)s(n)printf` etc., geared towards use on embedded systems with
* a very limited resources.
*
* @note the implementations are thread-safe; re-entrant; use no functions from
* the standard library; and do not dynamically allocate any memory.
*
* @license The MIT License (MIT)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef PRINTF_H_
#define PRINTF_H_
# include <stdarg.h>
# include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __GNUC__
# define ATTR_PRINTF(one_based_format_index, first_arg) \
__attribute__((format(__printf__, (one_based_format_index), (first_arg))))
# define ATTR_VPRINTF(one_based_format_index) ATTR_PRINTF((one_based_format_index), 0)
#else
# define ATTR_PRINTF((one_based_format_index), (first_arg))
# define ATTR_VPRINTF(one_based_format_index)
#endif
#ifndef PRINTF_ALIAS_STANDARD_FUNCTION_NAMES
#define PRINTF_ALIAS_STANDARD_FUNCTION_NAMES 0
#endif
#if PRINTF_ALIAS_STANDARD_FUNCTION_NAMES
# define printf_ printf
# define sprintf_ sprintf
# define vsprintf_ vsprintf
# define snprintf_ snprintf
# define vsnprintf_ vsnprintf
# define vprintf_ vprintf
#endif
// If you want to include this implementation file directly rather than
// link against, this will let you control the functions' visibility,
// e.g. make them static so as not to clash with other objects also
// using them.
#ifndef PRINTF_VISIBILITY
#define PRINTF_VISIBILITY
#endif
/**
* Prints/send a single character to some opaque output entity
*
* @note This function is not implemented by the library, only declared; you must provide an
* implementation if you wish to use the @ref printf / @ref vprintf function (and possibly
* for linking against the library, if your toolchain does not support discarding unused functions)
*
* @note The output could be as simple as a wrapper for the `write()` system call on a Unix-like
* system, or even libc's @ref putchar , for replicating actual functionality of libc's @ref printf
* function; but on an embedded system it may involve interaction with a special output device,
* like a UART, etc.
*
* @note in libc's @ref putchar, the parameter type is an int; this was intended to support the
* representation of either a proper character or EOF in a variable - but this is really not
* meaningful to pass into @ref putchar and is discouraged today. See further discussion in:
* @link https://stackoverflow.com/q/17452847/1593077
*
* @param c the single character to print
*/
PRINTF_VISIBILITY
void putchar(char c);
/**
* An implementation of the C standard's printf/vprintf
*
* @note you must implement a @ref putchar_ function for using this function - it invokes @ref putchar_
* rather than directly performing any I/O (which insulates it from any dependence on the operating system
* and external libraries).
*
* @param format A string specifying the format of the output, with %-marked specifiers of how to interpret
* additional arguments.
* @param arg Additional arguments to the function, one for each %-specifier in @p format string
* @return The number of characters written into @p s, not counting the terminating null character
*/
///@{
PRINTF_VISIBILITY
int printf_(const char* format, ...) ATTR_PRINTF(1, 2);
PRINTF_VISIBILITY
int vprintf_(const char* format, va_list arg) ATTR_VPRINTF(1);
///@}
/**
* An implementation of the C standard's sprintf/vsprintf
*
* @note For security considerations (the potential for exceeding the buffer bounds), please consider using
* the size-constrained variant, @ref snprintf / @ref vsnprintf , instead.
*
* @param s An array in which to store the formatted string. It must be large enough to fit the formatted
* output!
* @param format A string specifying the format of the output, with %-marked specifiers of how to interpret
* additional arguments.
* @param arg Additional arguments to the function, one for each specifier in @p format
* @return The number of characters written into @p s, not counting the terminating null character
*/
///@{
PRINTF_VISIBILITY
int sprintf_(char* s, const char* format, ...) ATTR_PRINTF(2, 3);
PRINTF_VISIBILITY
int vsprintf_(char* s, const char* format, va_list arg) ATTR_VPRINTF(2);
///@}
/**
* An implementation of the C standard's snprintf/vsnprintf
*
* @param s An array in which to store the formatted string. It must be large enough to fit either the
* entire formatted output, or at least @p n characters. Alternatively, it can be NULL, in which case
* nothing will be printed, and only the number of characters which _could_ have been printed is
* tallied and returned.
* @param n The maximum number of characters to write to the array, including a terminating null character
* @param format A string specifying the format of the output, with %-marked specifiers of how to interpret
* additional arguments.
* @param arg Additional arguments to the function, one for each specifier in @p format
* @return The number of characters that COULD have been written into @p s, not counting the terminating
* null character. A value equal or larger than @p n indicates truncation. Only when the returned value
* is non-negative and less than @p n, the null-terminated string has been fully and successfully printed.
*/
///@{
PRINTF_VISIBILITY
int snprintf_(char* s, size_t count, const char* format, ...) ATTR_PRINTF(3, 4);
PRINTF_VISIBILITY
int vsnprintf_(char* s, size_t count, const char* format, va_list arg) ATTR_VPRINTF(3);
///@}
/**
* printf/vprintf with user-specified output function
*
* An alternative to @ref printf_, in which the output function is specified dynamically
* (rather than @ref putchar_ being used)
*
* @param out An output function which takes one character and a type-erased additional parameters
* @param extra_arg The type-erased argument to pass to the output function @p out with each call
* @param format A string specifying the format of the output, with %-marked specifiers of how to interpret
* additional arguments.
* @param arg Additional arguments to the function, one for each specifier in @p format
* @return The number of characters for which the output f unction was invoked, not counting the terminating null character
*
*/
PRINTF_VISIBILITY
int fctprintf(void (*out)(char c, void* extra_arg), void* extra_arg, const char* format, ...) ATTR_PRINTF(3, 4);
PRINTF_VISIBILITY
int vfctprintf(void (*out)(char c, void* extra_arg), void* extra_arg, const char* format, va_list arg) ATTR_VPRINTF(3);
#if PRINTF_ALIAS_STANDARD_FUNCTION_NAMES
# undef printf_
# undef sprintf_
# undef vsprintf_
# undef snprintf_
# undef vsnprintf_
# undef vprintf_
#endif
#ifdef __cplusplus
}
#endif
#endif // PRINTF_H_

33
include/string.h Normal file
View File

@ -0,0 +1,33 @@
#pragma once
#include <types.h>
#ifdef __cplusplus
extern "C"
{
#endif
int isdigit(int c);
int isspace(int c);
int isempty(char *str);
unsigned int isdelim(char c, char *delim);
void *memcpy(void *dest, const void *src, size_t n);
void *memset(void *dest, int data, size_t nbytes);
void *memmove(void *dest, const void *src, size_t n);
int memcmp(const void *vl, const void *vr, size_t n);
long unsigned strlen(const char s[]);
int strncmp(const char *s1, const char *s2, unsigned long n);
char *strcat(char *destination, const char *source);
char *strcpy(char *destination, const char *source);
char *strncpy(char *destination, const char *source, unsigned long num);
int strcmp(const char *l, const char *r);
char *strstr(const char *haystack, const char *needle);
char *strdup(const char *String);
char *strchr(const char *String, int Char);
char *strrchr(const char *String, int Char);
int strncasecmp(const char *lhs, const char *rhs, long unsigned int Count);
int strcasecmp(const char *lhs, const char *rhs);
char *strtok(char *src, const char *delim);
#ifdef __cplusplus
}
#endif

8
include/sys.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef __FENNIX_KERNEL_SYSTEM_H__
#define __FENNIX_KERNEL_SYSTEM_H__
#include <types.h>
#endif // !__FENNIX_KERNEL_SYSTEM_H__

143
include/types.h Normal file
View File

@ -0,0 +1,143 @@
#ifndef __FENNIX_KERNEL_TYPES_H__
#define __FENNIX_KERNEL_TYPES_H__
#ifdef __cplusplus
#define EXTERNC extern "C"
#define START_EXTERNC \
EXTERNC \
{
#define END_EXTERNC \
}
#else
#define EXTERNC
#define START_EXTERNC
#define END_EXTERNC
#endif
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#define bool _Bool
#endif
#define asm __asm__
#define asmv __asm__ volatile
#define true 1
#define false 0
#ifdef __cplusplus
#define foreach for
#define in :
#endif
#ifndef __va_list__
typedef __builtin_va_list va_list;
#endif
#define va_start(v, l) __builtin_va_start(v, l)
#define va_end(v) __builtin_va_end(v)
#define va_arg(v, l) __builtin_va_arg(v, l)
#define ALIGN_UP(x, align) ((__typeof__(x))(((uint64_t)(x) + ((align)-1)) & (~((align)-1))))
#define ALIGN_DOWN(x, align) ((__typeof__(x))((x) & (~((align)-1))))
typedef __INT8_TYPE__ int8_t;
typedef __INT16_TYPE__ int16_t;
typedef __INT32_TYPE__ int32_t;
typedef __INT64_TYPE__ int64_t;
typedef __UINT8_TYPE__ uint8_t;
typedef __UINT16_TYPE__ uint16_t;
typedef __UINT32_TYPE__ uint32_t;
typedef __UINT64_TYPE__ uint64_t;
typedef __INT_LEAST8_TYPE__ int_least8_t;
typedef __INT_LEAST16_TYPE__ int_least16_t;
typedef __INT_LEAST32_TYPE__ int_least32_t;
typedef __INT_LEAST64_TYPE__ int_least64_t;
typedef __UINT_LEAST8_TYPE__ uint_least8_t;
typedef __UINT_LEAST16_TYPE__ uint_least16_t;
typedef __UINT_LEAST32_TYPE__ uint_least32_t;
typedef __UINT_LEAST64_TYPE__ uint_least64_t;
typedef __INT_FAST8_TYPE__ int_fast8_t;
typedef __INT_FAST16_TYPE__ int_fast16_t;
typedef __INT_FAST32_TYPE__ int_fast32_t;
typedef __INT_FAST64_TYPE__ int_fast64_t;
typedef __UINT_FAST8_TYPE__ uint_fast8_t;
typedef __UINT_FAST16_TYPE__ uint_fast16_t;
typedef __UINT_FAST32_TYPE__ uint_fast32_t;
typedef __UINT_FAST64_TYPE__ uint_fast64_t;
typedef __INTPTR_TYPE__ intptr_t;
typedef __UINTPTR_TYPE__ uintptr_t;
typedef __INTMAX_TYPE__ intmax_t;
typedef __UINTMAX_TYPE__ uintmax_t;
typedef __PTRDIFF_TYPE__ ptrdiff_t;
typedef __SIZE_TYPE__ size_t;
#define INT8_MAX __INT8_MAX__
#define INT8_MIN (-INT8_MAX - 1)
#define UINT8_MAX __UINT8_MAX__
#define INT16_MAX __INT16_MAX__
#define INT16_MIN (-INT16_MAX - 1)
#define UINT16_MAX __UINT16_MAX__
#define INT32_MAX __INT32_MAX__
#define INT32_MIN (-INT32_MAX - 1)
#define UINT32_MAX __UINT32_MAX__
#define INT64_MAX __INT64_MAX__
#define INT64_MIN (-INT64_MAX - 1)
#define UINT64_MAX __UINT64_MAX__
#define INT_LEAST8_MAX __INT_LEAST8_MAX__
#define INT_LEAST8_MIN (-INT_LEAST8_MAX - 1)
#define UINT_LEAST8_MAX __UINT_LEAST8_MAX__
#define INT_LEAST16_MAX __INT_LEAST16_MAX__
#define INT_LEAST16_MIN (-INT_LEAST16_MAX - 1)
#define UINT_LEAST16_MAX __UINT_LEAST16_MAX__
#define INT_LEAST32_MAX __INT_LEAST32_MAX__
#define INT_LEAST32_MIN (-INT_LEAST32_MAX - 1)
#define UINT_LEAST32_MAX __UINT_LEAST32_MAX__
#define INT_LEAST64_MAX __INT_LEAST64_MAX__
#define INT_LEAST64_MIN (-INT_LEAST64_MAX - 1)
#define UINT_LEAST64_MAX __UINT_LEAST64_MAX__
#define INT_FAST8_MAX __INT_FAST8_MAX__
#define INT_FAST8_MIN (-INT_FAST8_MAX - 1)
#define UINT_FAST8_MAX __UINT_FAST8_MAX__
#define INT_FAST16_MAX __INT_FAST16_MAX__
#define INT_FAST16_MIN (-INT_FAST16_MAX - 1)
#define UINT_FAST16_MAX __UINT_FAST16_MAX__
#define INT_FAST32_MAX __INT_FAST32_MAX__
#define INT_FAST32_MIN (-INT_FAST32_MAX - 1)
#define UINT_FAST32_MAX __UINT_FAST32_MAX__
#define INT_FAST64_MAX __INT_FAST64_MAX__
#define INT_FAST64_MIN (-INT_FAST64_MAX - 1)
#define UINT_FAST64_MAX __UINT_FAST64_MAX__
#define INTPTR_MAX __INTPTR_MAX__
#define INTPTR_MIN (-INTPTR_MAX - 1)
#define UINTPTR_MAX __UINTPTR_MAX__
#define INTMAX_MAX __INTMAX_MAX__
#define INTMAX_MIN (-INTMAX_MAX - 1)
#define UINTMAX_MAX __UINTMAX_MAX__
#define PTRDIFF_MAX __PTRDIFF_MAX__
#define PTRDIFF_MIN (-PTRDIFF_MAX - 1)
#define SIG_ATOMIC_MAX __SIG_ATOMIC_MAX__
#define SIG_ATOMIC_MIN __SIG_ATOMIC_MIN__
#define SIZE_MAX __SIZE_MAX__
#define WCHAR_MAX __WCHAR_MAX__
#define WCHAR_MIN __WCHAR_MIN__
#define WINT_MAX __WINT_MAX__
#define WINT_MIN __WINT_MIN__
#endif // !__FENNIX_KERNEL_TYPES_H__

71
include/uart.hpp Normal file
View File

@ -0,0 +1,71 @@
#ifndef __FENNIX_KERNEL_UART_H__
#define __FENNIX_KERNEL_UART_H__
#include <types.h>
namespace UniversalAsynchronousReceiverTransmitter
{
/**
* @brief Serial ports. (if available)
*/
enum SerialPorts
{
COMNULL = 0,
COM1 = 0x3F8,
COM2 = 0x2F8,
COM3 = 0x3E8,
COM4 = 0x2E8,
COM5 = 0x5F8,
COM6 = 0x4F8,
COM7 = 0x5E8,
COM8 = 0x4E8
};
class UART
{
private:
SerialPorts Port;
public:
UART(SerialPorts Port = COMNULL);
~UART();
void Write(uint8_t Char);
uint8_t Read();
};
class Events
{
private:
SerialPorts Port;
protected:
/**
* @brief UART events.
* @param Port if none, all ports are registered for events.
*/
Events(SerialPorts Port = COMNULL);
~Events();
public:
/**
* @brief Get the Registered Port object
* @return SerialPorts
*/
SerialPorts GetRegisteredPort() { return this->Port; }
/**
* @brief Called when a character is sent.
* @param Char the sent character.
*/
virtual void OnSent(uint8_t Char) {}
/**
* @brief Called when a character is received.
* @param Char the received character.
*/
virtual void OnReceived(uint8_t Char) {}
};
}
#endif // !__FENNIX_KERNEL_UART_H__

162
include/vector.hpp Normal file
View File

@ -0,0 +1,162 @@
#pragma once
#include <types.h>
#include <cstring>
template <class T>
class Vector
{
private:
uint64_t VectorSize = 0;
uint64_t VectorCapacity = 0;
T *VectorBuffer = nullptr;
public:
typedef T *iterator;
Vector()
{
VectorCapacity = 0;
VectorSize = 0;
VectorBuffer = 0;
}
Vector(uint64_t Size)
{
VectorCapacity = Size;
VectorSize = Size;
#ifdef DEBUG_MEM_ALLOCATION
debug("VECTOR ALLOCATION: Vector( %ld )", Size);
#endif
VectorBuffer = new T[Size];
}
Vector(uint64_t Size, const T &Initial)
{
VectorSize = Size;
VectorCapacity = Size;
#ifdef DEBUG_MEM_ALLOCATION
debug("VECTOR ALLOCATION: Vector( %ld %llx )", Size, Initial);
#endif
VectorBuffer = new T[Size];
for (uint64_t i = 0; i < Size; i++)
VectorBuffer[i] = Initial;
}
Vector(const Vector<T> &Vector)
{
VectorSize = Vector.VectorSize;
VectorCapacity = Vector.VectorCapacity;
#ifdef DEBUG_MEM_ALLOCATION
debug("VECTOR ALLOCATION: Vector( <vector> )->Size: %ld", VectorSize);
#endif
VectorBuffer = new T[VectorSize];
for (uint64_t i = 0; i < VectorSize; i++)
VectorBuffer[i] = Vector.VectorBuffer[i];
}
~Vector()
{
#ifdef DEBUG_MEM_ALLOCATION
debug("VECTOR ALLOCATION: ~Vector( ~%lx )", VectorBuffer);
#endif
delete[] VectorBuffer;
}
void remove(uint64_t Position)
{
if (Position >= VectorSize)
return;
memset(&*(VectorBuffer + Position), 0, sizeof(T));
for (uint64_t i = 0; i < VectorSize - 1; i++)
{
*(VectorBuffer + Position + i) = *(VectorBuffer + Position + i + 1);
}
VectorSize--;
}
uint64_t capacity() const { return VectorCapacity; }
uint64_t size() const { return VectorSize; }
bool empty() const;
iterator begin() { return VectorBuffer; }
iterator end() { return VectorBuffer + size(); }
T &front() { return VectorBuffer[0]; }
T &back() { return VectorBuffer[VectorSize - 1]; }
void push_back(const T &Value)
{
if (VectorSize >= VectorCapacity)
reserve(VectorCapacity + 5);
VectorBuffer[VectorSize++] = Value;
}
void pop_back() { VectorSize--; }
void reverse()
{
if (VectorSize <= 1)
return;
for (uint64_t i = 0, j = VectorSize - 1; i < j; i++, j--)
{
T c = *(VectorBuffer + i);
*(VectorBuffer + i) = *(VectorBuffer + j);
*(VectorBuffer + j) = c;
}
}
void reserve(uint64_t Capacity)
{
if (VectorBuffer == 0)
{
VectorSize = 0;
VectorCapacity = 0;
}
#ifdef DEBUG_MEM_ALLOCATION
debug("VECTOR ALLOCATION: reverse( %ld )", Capacity);
#endif
T *Newbuffer = new T[Capacity];
uint64_t _Size = Capacity < VectorSize ? Capacity : VectorSize;
for (uint64_t i = 0; i < _Size; i++)
Newbuffer[i] = VectorBuffer[i];
VectorCapacity = Capacity;
#ifdef DEBUG_MEM_ALLOCATION
debug("VECTOR ALLOCATION: reverse( <Capacity> )->Buffer:~%ld", VectorBuffer);
#endif
delete[] VectorBuffer;
VectorBuffer = Newbuffer;
}
void resize(uint64_t Size)
{
reserve(Size);
VectorSize = Size;
}
T &operator[](uint64_t Index) { return VectorBuffer[Index]; }
Vector<T> &operator=(const Vector<T> &Vector)
{
delete[] VectorBuffer;
VectorSize = Vector.VectorSize;
VectorCapacity = Vector.VectorCapacity;
#ifdef DEBUG_MEM_ALLOCATION
debug("VECTOR ALLOCATION: operator=( <vector> )->Size:%ld", VectorSize);
#endif
VectorBuffer = new T[VectorSize];
for (uint64_t i = 0; i < VectorSize; i++)
VectorBuffer[i] = Vector.VectorBuffer[i];
return *this;
}
void clear()
{
VectorCapacity = 0;
VectorSize = 0;
VectorBuffer = 0;
}
};