mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-07-14 00:39:16 +00:00
Merge remote-tracking branch 'Kernel/mb2_32_64_test' into Kernel-mb2_32_64_test
This commit is contained in:
91
Kernel/include/abi.h
Normal file
91
Kernel/include/abi.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_ABI_H__
|
||||
#define __FENNIX_KERNEL_ABI_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#define AT_NULL 0
|
||||
#define AT_IGNORE 1
|
||||
#define AT_EXECFD 2
|
||||
#define AT_PHDR 3
|
||||
#define AT_PHENT 4
|
||||
#define AT_PHNUM 5
|
||||
#define AT_PAGESZ 6
|
||||
#define AT_BASE 7
|
||||
#define AT_FLAGS 8
|
||||
#define AT_ENTRY 9
|
||||
#define AT_NOTELF 10
|
||||
#define AT_UID 11
|
||||
#define AT_EUID 12
|
||||
#define AT_GID 13
|
||||
#define AT_EGID 14
|
||||
#define AT_PLATFORM 15
|
||||
#define AT_HWCAP 16
|
||||
#define AT_CLKTCK 17
|
||||
#define AT_SECURE 23
|
||||
#define AT_BASE_PLATFORM 24
|
||||
#define AT_RANDOM 25
|
||||
#define AT_HWCAP2 26
|
||||
#define AT_EXECFN 31
|
||||
#define AT_SYSINFO 32
|
||||
#define AT_SYSINFO_EHDR 33
|
||||
#define AT_L1I_CACHESHAPE 34
|
||||
#define AT_L1D_CACHESHAPE 35
|
||||
#define AT_L2_CACHESHAPE 36
|
||||
#define AT_L3_CACHESHAPE 37
|
||||
#define AT_L1I_CACHESIZE 40
|
||||
#define AT_L1I_CACHEGEOMETRY 41
|
||||
#define AT_L1D_CACHESIZE 42
|
||||
#define AT_L1D_CACHEGEOMETRY 43
|
||||
#define AT_L2_CACHESIZE 44
|
||||
#define AT_L2_CACHEGEOMETRY 45
|
||||
#define AT_L3_CACHESIZE 46
|
||||
#define AT_L3_CACHEGEOMETRY 47
|
||||
#define AT_MINSIGSTKSZ 51
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t a_type;
|
||||
union
|
||||
{
|
||||
uint32_t a_val;
|
||||
} a_un;
|
||||
} Elf32_auxv_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint64_t a_type;
|
||||
union
|
||||
{
|
||||
uint64_t a_val;
|
||||
} a_un;
|
||||
} Elf64_auxv_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
#if defined(a64)
|
||||
Elf64_auxv_t archaux;
|
||||
#elif defined(a32)
|
||||
Elf32_auxv_t archaux;
|
||||
#elif defined(aa64)
|
||||
Elf64_auxv_t archaux;
|
||||
#endif
|
||||
} AuxiliaryVector;
|
||||
|
||||
#endif // !__FENNIX_KERNEL_ABI_H__
|
33
Kernel/include/bitmap.hpp
Normal file
33
Kernel/include/bitmap.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_BITMAP_H__
|
||||
#define __FENNIX_KERNEL_BITMAP_H__
|
||||
|
||||
#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);
|
||||
};
|
||||
|
||||
#endif // !__FENNIX_KERNEL_BITMAP_H__
|
147
Kernel/include/boot/binfo.h
Normal file
147
Kernel/include/boot/binfo.h
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_BOOT_INFO_H__
|
||||
#define __FENNIX_KERNEL_BOOT_INFO_H__
|
||||
|
||||
enum MemoryType
|
||||
{
|
||||
Unknown_Memory_Type,
|
||||
Usable,
|
||||
Reserved,
|
||||
ACPIReclaimable,
|
||||
ACPINVS,
|
||||
BadMemory,
|
||||
BootloaderReclaimable,
|
||||
KernelAndModules,
|
||||
Framebuffer,
|
||||
Unknown
|
||||
};
|
||||
|
||||
enum FramebufferType
|
||||
{
|
||||
Unknown_Framebuffer_Type,
|
||||
Indexed,
|
||||
RGB,
|
||||
EGA
|
||||
};
|
||||
|
||||
#define MAX_FRAMEBUFFERS 16
|
||||
#define MAX_MEMORY_ENTRIES 256
|
||||
#define MAX_MODULES 16
|
||||
|
||||
struct BootInfo
|
||||
{
|
||||
struct FramebufferInfo
|
||||
{
|
||||
enum FramebufferType Type;
|
||||
void *BaseAddress;
|
||||
__UINT32_TYPE__ Width;
|
||||
__UINT32_TYPE__ Height;
|
||||
__UINT64_TYPE__ Pitch;
|
||||
__UINT16_TYPE__ BitsPerPixel;
|
||||
__UINT8_TYPE__ RedMaskSize;
|
||||
__UINT8_TYPE__ RedMaskShift;
|
||||
__UINT8_TYPE__ GreenMaskSize;
|
||||
__UINT8_TYPE__ GreenMaskShift;
|
||||
__UINT8_TYPE__ BlueMaskSize;
|
||||
__UINT8_TYPE__ BlueMaskShift;
|
||||
void *ExtendedDisplayIdentificationData;
|
||||
__UINT64_TYPE__ EDIDSize;
|
||||
} Framebuffer[MAX_FRAMEBUFFERS];
|
||||
|
||||
struct MemoryInfo
|
||||
{
|
||||
struct MemoryEntryInfo
|
||||
{
|
||||
void *BaseAddress;
|
||||
__UINT64_TYPE__ Length;
|
||||
enum MemoryType Type;
|
||||
} Entry[MAX_MEMORY_ENTRIES];
|
||||
__UINT64_TYPE__ Entries;
|
||||
__UINT64_TYPE__ Size;
|
||||
} Memory;
|
||||
|
||||
struct ModuleInfo
|
||||
{
|
||||
void *Address;
|
||||
char Path[256];
|
||||
char CommandLine[256];
|
||||
__UINT64_TYPE__ Size;
|
||||
} Modules[MAX_MODULES];
|
||||
|
||||
struct RSDPInfo
|
||||
{
|
||||
/**
|
||||
* @brief Signature
|
||||
*/
|
||||
__UINT8_TYPE__ Signature[8];
|
||||
/**
|
||||
* @brief Checksum
|
||||
*/
|
||||
__UINT8_TYPE__ Checksum;
|
||||
/**
|
||||
* @brief OEM ID
|
||||
*/
|
||||
__UINT8_TYPE__ OEMID[6];
|
||||
/**
|
||||
* @brief Revision
|
||||
*/
|
||||
__UINT8_TYPE__ Revision;
|
||||
/**
|
||||
* @brief Address of the Root System Description Table
|
||||
*/
|
||||
__UINT32_TYPE__ RSDTAddress;
|
||||
/* END OF RSDP 1.0 */
|
||||
|
||||
/**
|
||||
* @brief Length
|
||||
*/
|
||||
__UINT32_TYPE__ Length;
|
||||
/**
|
||||
* @brief Extended System Descriptor Table
|
||||
*/
|
||||
__UINT64_TYPE__ XSDTAddress;
|
||||
/**
|
||||
* @brief Extended checksum
|
||||
*/
|
||||
__UINT8_TYPE__ ExtendedChecksum;
|
||||
/**
|
||||
* @brief Reserved
|
||||
*/
|
||||
__UINT8_TYPE__ Reserved[3];
|
||||
} __attribute__((packed)) * RSDP;
|
||||
|
||||
struct KernelInfo
|
||||
{
|
||||
void *PhysicalBase;
|
||||
void *VirtualBase;
|
||||
void *FileBase;
|
||||
char CommandLine[256];
|
||||
__UINT64_TYPE__ Size;
|
||||
} Kernel;
|
||||
|
||||
struct BootloaderInfo
|
||||
{
|
||||
char Name[256];
|
||||
char Version[64];
|
||||
} Bootloader;
|
||||
|
||||
void *SMBIOSPtr;
|
||||
};
|
||||
|
||||
#endif // !__FENNIX_KERNEL_BOOT_INFO_H__
|
417
Kernel/include/boot/protocols/multiboot2.h
Normal file
417
Kernel/include/boot/protocols/multiboot2.h
Normal 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 */
|
187
Kernel/include/cargs.h
Normal file
187
Kernel/include/cargs.h
Normal file
@ -0,0 +1,187 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Leonard Iklé
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* This is a simple alternative cross-platform implementation of getopt, which
|
||||
* is used to parse argument strings submitted to the executable (argc and argv
|
||||
* which are received in the main function).
|
||||
*/
|
||||
|
||||
#ifndef CAG_LIBRARY_H
|
||||
#define CAG_LIBRARY_H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
typedef unsigned int FILE; // TODO: Implement FILE
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#define CAG_EXPORT __declspec(dllexport)
|
||||
#define CAG_IMPORT __declspec(dllimport)
|
||||
#elif __GNUC__ >= 4
|
||||
#define CAG_EXPORT __attribute__((visibility("default")))
|
||||
#define CAG_IMPORT __attribute__((visibility("default")))
|
||||
#else
|
||||
#define CAG_EXPORT
|
||||
#define CAG_IMPORT
|
||||
#endif
|
||||
|
||||
#if defined(CAG_SHARED)
|
||||
#if defined(CAG_EXPORTS)
|
||||
#define CAG_PUBLIC CAG_EXPORT
|
||||
#else
|
||||
#define CAG_PUBLIC CAG_IMPORT
|
||||
#endif
|
||||
#else
|
||||
#define CAG_PUBLIC
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* An option is used to describe a flag/argument option submitted when the
|
||||
* program is run.
|
||||
*/
|
||||
typedef struct cag_option
|
||||
{
|
||||
const char identifier;
|
||||
const char *access_letters;
|
||||
const char *access_name;
|
||||
const char *value_name;
|
||||
const char *description;
|
||||
} cag_option;
|
||||
|
||||
/**
|
||||
* A context is used to iterate over all options provided. It stores the parsing
|
||||
* state.
|
||||
*/
|
||||
typedef struct cag_option_context
|
||||
{
|
||||
const struct cag_option *options;
|
||||
size_t option_count;
|
||||
int argc;
|
||||
char **argv;
|
||||
int index;
|
||||
int inner_index;
|
||||
bool forced_end;
|
||||
char identifier;
|
||||
char *value;
|
||||
} cag_option_context;
|
||||
|
||||
/**
|
||||
* This is just a small macro which calculates the size of an array.
|
||||
*/
|
||||
#define CAG_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
|
||||
|
||||
/**
|
||||
* @brief Prints all options to the terminal.
|
||||
*
|
||||
* This function prints all options to the terminal. This can be used to
|
||||
* generate the output for a "--help" option.
|
||||
*
|
||||
* @param options The options which will be printed.
|
||||
* @param option_count The option count which will be printed.
|
||||
* @param destination The destination where the output will be printed.
|
||||
*/
|
||||
CAG_PUBLIC void cag_option_print(const cag_option *options, size_t option_count,
|
||||
FILE *destination);
|
||||
|
||||
/**
|
||||
* @brief Prepare argument options context for parsing.
|
||||
*
|
||||
* This function prepares the context for iteration and initializes the context
|
||||
* with the supplied options and arguments. After the context has been prepared,
|
||||
* it can be used to fetch arguments from it.
|
||||
*
|
||||
* @param context The context which will be initialized.
|
||||
* @param options The registered options which are available for the program.
|
||||
* @param option_count The amount of options which are available for the
|
||||
* program.
|
||||
* @param argc The amount of arguments the user supplied in the main function.
|
||||
* @param argv A pointer to the arguments of the main function.
|
||||
*/
|
||||
CAG_PUBLIC void cag_option_prepare(cag_option_context *context,
|
||||
const cag_option *options, size_t option_count, int argc, char **argv);
|
||||
|
||||
/**
|
||||
* @brief Fetches an option from the argument list.
|
||||
*
|
||||
* This function fetches a single option from the argument list. The context
|
||||
* will be moved to that item. Information can be extracted from the context
|
||||
* after the item has been fetched.
|
||||
* The arguments will be re-ordered, which means that non-option arguments will
|
||||
* be moved to the end of the argument list. After all options have been
|
||||
* fetched, all non-option arguments will be positioned after the index of
|
||||
* the context.
|
||||
*
|
||||
* @param context The context from which we will fetch the option.
|
||||
* @return Returns true if there was another option or false if the end is
|
||||
* reached.
|
||||
*/
|
||||
CAG_PUBLIC bool cag_option_fetch(cag_option_context *context);
|
||||
|
||||
/**
|
||||
* @brief Gets the identifier of the option.
|
||||
*
|
||||
* This function gets the identifier of the option, which should be unique to
|
||||
* this option and can be used to determine what kind of option this is.
|
||||
*
|
||||
* @param context The context from which the option was fetched.
|
||||
* @return Returns the identifier of the option.
|
||||
*/
|
||||
CAG_PUBLIC char cag_option_get(const cag_option_context *context);
|
||||
|
||||
/**
|
||||
* @brief Gets the value from the option.
|
||||
*
|
||||
* This function gets the value from the option, if any. If the option does not
|
||||
* contain a value, this function will return NULL.
|
||||
*
|
||||
* @param context The context from which the option was fetched.
|
||||
* @return Returns a pointer to the value or NULL if there is no value.
|
||||
*/
|
||||
CAG_PUBLIC const char *cag_option_get_value(const cag_option_context *context);
|
||||
|
||||
/**
|
||||
* @brief Gets the current index of the context.
|
||||
*
|
||||
* This function gets the index within the argv arguments of the context. The
|
||||
* context always points to the next item which it will inspect. This is
|
||||
* particularly useful to inspect the original argument array, or to get
|
||||
* non-option arguments after option fetching has finished.
|
||||
*
|
||||
* @param context The context from which the option was fetched.
|
||||
* @return Returns the current index of the context.
|
||||
*/
|
||||
CAG_PUBLIC int cag_option_get_index(const cag_option_context *context);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
133
Kernel/include/convert.h
Normal file
133
Kernel/include/convert.h
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
typedef struct mbstate_t
|
||||
{
|
||||
int count;
|
||||
unsigned int value;
|
||||
} mbstate_t;
|
||||
|
||||
#define NAN (__builtin_nanf(""))
|
||||
|
||||
int isdigit(int c);
|
||||
int isspace(int c);
|
||||
int isempty(char *str);
|
||||
int isalpha(int c);
|
||||
int isupper(int c);
|
||||
unsigned int isdelim(char c, const char *delim);
|
||||
long abs(long i);
|
||||
void swap(char *x, char *y);
|
||||
char *reverse(char *Buffer, int i, int j);
|
||||
|
||||
float sqrtf(float x);
|
||||
double clamp(double x, double low, double high);
|
||||
|
||||
float lerp(float a, float b, float t);
|
||||
float smoothstep(float a, float b, float t);
|
||||
float cubicInterpolate(float a, float b, float t);
|
||||
|
||||
void backspace(char s[]);
|
||||
void append(char s[], char n);
|
||||
|
||||
int atoi(const char *String);
|
||||
double atof(const char *String);
|
||||
char *itoa(int Value, char *Buffer, int Base);
|
||||
char *ltoa(long Value, char *Buffer, int Base);
|
||||
char *ultoa(unsigned long Value, char *Buffer, int Base);
|
||||
unsigned long int strtoul(const char *str, char **endptr, int base);
|
||||
|
||||
void *memcpy_unsafe(void *dest, const void *src, size_t n);
|
||||
void *memset_unsafe(void *dest, int c, size_t n);
|
||||
void *memmove_unsafe(void *dest, const void *src, size_t n);
|
||||
int memcmp(const void *vl, const void *vr, size_t n);
|
||||
|
||||
void *memcpy_sse(void *dest, const void *src, size_t n);
|
||||
void *memcpy_sse2(void *dest, const void *src, size_t n);
|
||||
void *memcpy_sse3(void *dest, const void *src, size_t n);
|
||||
void *memcpy_ssse3(void *dest, const void *src, size_t n);
|
||||
void *memcpy_sse4_1(void *dest, const void *src, size_t n);
|
||||
void *memcpy_sse4_2(void *dest, const void *src, size_t n);
|
||||
|
||||
void *memset_sse(void *dest, int c, size_t n);
|
||||
void *memset_sse2(void *dest, int c, size_t n);
|
||||
void *memset_sse3(void *dest, int c, size_t n);
|
||||
void *memset_ssse3(void *dest, int c, size_t n);
|
||||
void *memset_sse4_1(void *dest, int c, size_t n);
|
||||
void *memset_sse4_2(void *dest, int c, size_t n);
|
||||
|
||||
void *memmove_sse(void *dest, const void *src, size_t n);
|
||||
void *memmove_sse2(void *dest, const void *src, size_t n);
|
||||
void *memmove_sse3(void *dest, const void *src, size_t n);
|
||||
void *memmove_ssse3(void *dest, const void *src, size_t n);
|
||||
void *memmove_sse4_1(void *dest, const void *src, size_t n);
|
||||
void *memmove_sse4_2(void *dest, const void *src, size_t n);
|
||||
|
||||
long unsigned strlen(const char s[]);
|
||||
int strncmp(const char *s1, const char *s2, unsigned long n);
|
||||
char *strcat_unsafe(char *destination, const char *source);
|
||||
char *strcpy_unsafe(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 *s1, const char *s2);
|
||||
char *strtok(char *src, const char *delim);
|
||||
long int strtol(const char *str, char **endptr, int base);
|
||||
size_t wcslen(const wchar_t *s);
|
||||
size_t wcsrtombs(char *dst, const wchar_t **src, size_t len, mbstate_t *ps);
|
||||
int log2(unsigned int n);
|
||||
|
||||
void *__memcpy_chk(void *dest, const void *src, size_t len, size_t slen);
|
||||
void *__memset_chk(void *dest, int val, size_t len, size_t slen);
|
||||
void *__memmove_chk(void *dest, const void *src, size_t len, size_t slen);
|
||||
char *__strcat_chk(char *dest, const char *src, size_t slen);
|
||||
char *__strcpy_chk(char *dest, const char *src, size_t slen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef memcpy
|
||||
#define memcpy(dest, src, n) \
|
||||
__memcpy_chk(dest, src, n, __builtin_object_size(dest, 0))
|
||||
|
||||
#undef memset
|
||||
#define memset(dest, c, n) \
|
||||
__memset_chk(dest, c, n, __builtin_object_size(dest, 0))
|
||||
|
||||
#undef memmove
|
||||
#define memmove(dest, src, n) \
|
||||
__memmove_chk(dest, src, n, __builtin_object_size(dest, 0))
|
||||
|
||||
#undef strcat
|
||||
#define strcat(dest, src) \
|
||||
__strcat_chk(dest, src, __builtin_object_size(dest, 0))
|
||||
|
||||
#undef strcpy
|
||||
#define strcpy(dest, src) \
|
||||
__strcpy_chk(dest, src, __builtin_object_size(dest, 0))
|
803
Kernel/include/cpu.hpp
Normal file
803
Kernel/include/cpu.hpp
Normal file
@ -0,0 +1,803 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_CPU_H__
|
||||
#define __FENNIX_KERNEL_CPU_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <cpu/x86/cpuid_intel.hpp>
|
||||
#include <cpu/x86/cpuid_amd.hpp>
|
||||
#include <cpu/x86/x32/cr.hpp>
|
||||
#include <cpu/x86/x32/msr.hpp>
|
||||
#include <cpu/x86/x64/cr.hpp>
|
||||
#include <cpu/x86/x64/msr.hpp>
|
||||
#include <cpu/x86/exceptions.hpp>
|
||||
#include <cpu/x86/interrupts.hpp>
|
||||
#include <cpu/signatures.hpp>
|
||||
#include <cpu/membar.hpp>
|
||||
#include <cstring>
|
||||
|
||||
/**
|
||||
* @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
|
||||
};
|
||||
|
||||
enum x86SIMDType
|
||||
{
|
||||
SIMD_NONE = (1 << 0),
|
||||
|
||||
SIMD_SSE = (1 << 1),
|
||||
SIMD_SSE2 = (1 << 2),
|
||||
SIMD_SSE3 = (1 << 3),
|
||||
SIMD_SSSE3 = (1 << 4),
|
||||
SIMD_SSE41 = (1 << 5),
|
||||
SIMD_SSE42 = (1 << 6),
|
||||
|
||||
SIMD_AVX = (1 << 7),
|
||||
SIMD_AVX2 = (1 << 8),
|
||||
SIMD_AVX512 = (1 << 9),
|
||||
|
||||
SIMD_AVX512F = (1 << 10),
|
||||
SIMD_AVX512CD = (1 << 11),
|
||||
SIMD_AVX512ER = (1 << 12),
|
||||
SIMD_AVX512PF = (1 << 13),
|
||||
|
||||
SIMD_AVX512VL = (1 << 14),
|
||||
SIMD_AVX512DQ = (1 << 16),
|
||||
SIMD_AVX512BW = (1 << 15),
|
||||
|
||||
SIMD_AVX512IFMA = (1 << 17),
|
||||
SIMD_AVX512VBMI = (1 << 18),
|
||||
|
||||
SIMD_AVX5124VNNIW = (1 << 19),
|
||||
SIMD_AVX5124FMAPS = (1 << 20),
|
||||
|
||||
SIMD_AVX512VPOPCNTDQ = (1 << 21),
|
||||
|
||||
SIMD_AVX512VNNI = (1 << 22),
|
||||
SIMD_AVX512VBMI2 = (1 << 23),
|
||||
SIMD_AVX512BITALG = (1 << 24),
|
||||
|
||||
SIMD_AVX512VP2INTERSECT = (1 << 25),
|
||||
|
||||
SIMD_AVX512GFNI = (1 << 26),
|
||||
SIMD_AVX512VPCLMULQDQ = (1 << 27),
|
||||
SIMD_AVX512VAES = (1 << 28),
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Get CPU vendor identifier.
|
||||
*
|
||||
* @return char* CPU Vendor ID.
|
||||
*/
|
||||
char *Vendor();
|
||||
|
||||
/**
|
||||
* @brief Get CPU name.
|
||||
*
|
||||
* @return char* CPU Name.
|
||||
*/
|
||||
char *Name();
|
||||
|
||||
/**
|
||||
* @brief Get CPU hypervisor vendor.
|
||||
*
|
||||
* @return char* Hypervisor vendor.
|
||||
*/
|
||||
char *Hypervisor();
|
||||
|
||||
/**
|
||||
* @brief Check SIMD support. It will return the highest supported SIMD type.
|
||||
*
|
||||
* @return x86SIMDType flags.
|
||||
*/
|
||||
uint64_t CheckSIMD();
|
||||
|
||||
/**
|
||||
* @brief Check SIMD support.
|
||||
*
|
||||
* @param Type SIMD type.
|
||||
* @return true if supported.
|
||||
* @return false if not supported.
|
||||
*/
|
||||
bool CheckSIMD(x86SIMDType Type);
|
||||
|
||||
/**
|
||||
* @brief Pause the CPU
|
||||
*/
|
||||
SafeFunction static inline void Pause(bool Loop = false)
|
||||
{
|
||||
do
|
||||
{
|
||||
#if defined(a86)
|
||||
asmv("pause");
|
||||
#elif defined(aa64)
|
||||
asmv("yield");
|
||||
#endif
|
||||
} while (Loop);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop the CPU (infinite loop)
|
||||
*/
|
||||
#if defined(a86)
|
||||
SafeFunction __noreturn __naked __used inline void Stop()
|
||||
{
|
||||
asmv("CPUStopLoop:\n"
|
||||
"cli\n"
|
||||
"hlt\n"
|
||||
"jmp CPUStopLoop");
|
||||
#elif defined(aa64) // annoying warning: "‘noreturn’ function does return" and "‘naked’ attribute directive ignored"
|
||||
SafeFunction __used inline void Stop()
|
||||
{
|
||||
asmv("CPUStopLoop:\n"
|
||||
"msr daifset, #2\n" // Disable IRQs (bit 1 of the DAIF register)
|
||||
"wfi\n" // Wait for Interrupt (puts the processor in low-power state until an interrupt occurs)
|
||||
"b CPUStopLoop"); // Branch to the beginning of the loop
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Halt the CPU
|
||||
*/
|
||||
SafeFunction static inline void Halt(bool Loop = false)
|
||||
{
|
||||
do
|
||||
{
|
||||
#if defined(a86)
|
||||
asmv("hlt");
|
||||
#elif defined(aa64)
|
||||
asmv("wfe");
|
||||
#endif
|
||||
} while (Loop);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* @brief Get/Set the CPU's page table
|
||||
*
|
||||
* @param PT The new page table, if empty, the current page table will be returned
|
||||
* @return void* The current page table
|
||||
*/
|
||||
void *PageTable(void *PT = nullptr);
|
||||
|
||||
/** @brief To be used only once. */
|
||||
void InitializeFeatures(long Core);
|
||||
|
||||
/** @brief Get CPU counter value. */
|
||||
uintptr_t Counter();
|
||||
|
||||
namespace x32
|
||||
{
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Carry Flag */
|
||||
uint32_t CF : 1;
|
||||
/** @brief Reserved */
|
||||
uint32_t AlwaysOne : 1;
|
||||
/** @brief Parity Flag */
|
||||
uint32_t PF : 1;
|
||||
/** @brief Reserved */
|
||||
uint32_t Reserved0 : 1;
|
||||
/** @brief Auxiliary Carry Flag */
|
||||
uint32_t AF : 1;
|
||||
/** @brief Reserved */
|
||||
uint32_t Reserved1 : 1;
|
||||
/** @brief Zero Flag */
|
||||
uint32_t ZF : 1;
|
||||
/** @brief Sign Flag */
|
||||
uint32_t SF : 1;
|
||||
/** @brief Trap Flag */
|
||||
uint32_t TF : 1;
|
||||
/** @brief Interrupt Enable Flag */
|
||||
uint32_t IF : 1;
|
||||
/** @brief Direction Flag */
|
||||
uint32_t DF : 1;
|
||||
/** @brief Overflow Flag */
|
||||
uint32_t OF : 1;
|
||||
/** @brief I/O Privilege Level */
|
||||
uint32_t IOPL : 2;
|
||||
/** @brief Nested Task */
|
||||
uint32_t NT : 1;
|
||||
/** @brief Reserved */
|
||||
uint32_t Reserved2 : 1;
|
||||
/** @brief Resume Flag */
|
||||
uint32_t RF : 1;
|
||||
/** @brief Virtual 8086 Mode */
|
||||
uint32_t VM : 1;
|
||||
/** @brief Alignment Check */
|
||||
uint32_t AC : 1;
|
||||
/** @brief Virtual Interrupt Flag */
|
||||
uint32_t VIF : 1;
|
||||
/** @brief Virtual Interrupt Pending */
|
||||
uint32_t VIP : 1;
|
||||
/** @brief ID Flag */
|
||||
uint32_t ID : 1;
|
||||
};
|
||||
uint32_t raw;
|
||||
} EFLAGS;
|
||||
|
||||
typedef struct TrapFrame
|
||||
{
|
||||
uint32_t ebp; // Base Pointer (meant for stack frames)
|
||||
uint32_t edi; // Destination index for string operations
|
||||
uint32_t esi; // Source index for string operations
|
||||
uint32_t edx; // Data (commonly extends the A register)
|
||||
uint32_t ecx; // Counter
|
||||
uint32_t ebx; // Base
|
||||
uint32_t eax; // Accumulator
|
||||
|
||||
uint32_t InterruptNumber; // Interrupt Number
|
||||
uint32_t ErrorCode; // Error code
|
||||
uint32_t eip; // Instruction Pointer
|
||||
uint32_t cs; // Code Segment
|
||||
EFLAGS eflags; // Register Flags
|
||||
uint32_t esp; // Stack Pointer
|
||||
uint32_t ss; // Stack Segment
|
||||
} TrapFrame;
|
||||
|
||||
/* TODO: Does EFER exists in x32? */
|
||||
typedef union EFER
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Enable syscall & sysret instructions in 64-bit mode. */
|
||||
uint32_t SCE : 1;
|
||||
/** @brief Reserved */
|
||||
uint32_t Reserved0 : 7;
|
||||
/** @brief Enable long mode. */
|
||||
uint32_t LME : 1;
|
||||
/** @brief Reserved */
|
||||
uint32_t Reserved1 : 1;
|
||||
/** @brief Indicates long. */
|
||||
uint32_t LMA : 1;
|
||||
/** @brief Enable No-Execute Bit */
|
||||
uint32_t NXE : 1;
|
||||
/** @brief Enable Secure Virtual Machine */
|
||||
uint32_t SVME : 1;
|
||||
/** @brief Enable Long Mode Segment Limit */
|
||||
uint32_t LMSLE : 1;
|
||||
/** @brief Enable Fast FXSAVE/FXRSTOR */
|
||||
uint32_t FFXSR : 1;
|
||||
/** @brief Enable Translation Cache Extension */
|
||||
uint32_t TCE : 1;
|
||||
/** @brief Reserved */
|
||||
uint32_t Reserved2 : 32;
|
||||
};
|
||||
uint32_t raw;
|
||||
} __packed EFER;
|
||||
|
||||
// ! TODO: UNTESTED!
|
||||
typedef union DR7
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Local DR0 Breakpoint (0) */
|
||||
uint32_t LocalDR0 : 1;
|
||||
/** @brief Global DR0 Breakpoint (1) */
|
||||
uint32_t GlobalDR0 : 1;
|
||||
/** @brief Local DR1 Breakpoint (2) */
|
||||
uint32_t LocalDR1 : 1;
|
||||
/** @brief Global DR1 Breakpoint (3) */
|
||||
uint32_t GlobalDR1 : 1;
|
||||
/** @brief Local DR2 Breakpoint (4) */
|
||||
uint32_t LocalDR2 : 1;
|
||||
/** @brief Global DR2 Breakpoint (5) */
|
||||
uint32_t GlobalDR2 : 1;
|
||||
/** @brief Local DR3 Breakpoint (6) */
|
||||
uint32_t LocalDR3 : 1;
|
||||
/** @brief Global DR3 Breakpoint (7) */
|
||||
uint32_t GlobalDR3 : 1;
|
||||
/** @brief Reserved [7 - (16-17)] */
|
||||
uint32_t Reserved : 9;
|
||||
/** @brief Conditions for DR0 (16-17) */
|
||||
uint32_t ConditionsDR0 : 1;
|
||||
/** @brief Size of DR0 Breakpoint (18-19) */
|
||||
uint32_t SizeDR0 : 1;
|
||||
/** @brief Conditions for DR1 (20-21) */
|
||||
uint32_t ConditionsDR1 : 1;
|
||||
/** @brief Size of DR1 Breakpoint (22-23) */
|
||||
uint32_t SizeDR1 : 1;
|
||||
/** @brief Conditions for DR2 (24-25) */
|
||||
uint32_t ConditionsDR2 : 1;
|
||||
/** @brief Size of DR2 Breakpoint (26-27) */
|
||||
uint32_t SizeDR2 : 1;
|
||||
/** @brief Conditions for DR3 (28-29) */
|
||||
uint32_t ConditionsDR3 : 1;
|
||||
/** @brief Size of DR3 Breakpoint (30-31) */
|
||||
uint32_t SizeDR3 : 1;
|
||||
};
|
||||
uint32_t raw;
|
||||
} DR7;
|
||||
|
||||
struct FXState
|
||||
{
|
||||
/** @brief FPU control word */
|
||||
uint16_t fcw;
|
||||
/** @brief FPU status word */
|
||||
uint16_t fsw;
|
||||
/** @brief FPU tag words */
|
||||
uint8_t ftw;
|
||||
/** @brief Reserved (zero) */
|
||||
uint8_t Reserved;
|
||||
/** @brief FPU opcode */
|
||||
uint16_t fop;
|
||||
/** @brief PFU instruction pointer */
|
||||
uint64_t rip;
|
||||
/** @brief FPU data pointer */
|
||||
uint64_t rdp;
|
||||
/** @brief SSE control register */
|
||||
uint32_t mxcsr;
|
||||
/** @brief SSE control register mask */
|
||||
uint32_t mxcsrmask;
|
||||
/** @brief FPU registers (last 6 bytes reserved) */
|
||||
uint8_t st[8][16];
|
||||
/** @brief XMM registers */
|
||||
uint8_t xmm[16][16];
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* @brief CPUID
|
||||
*
|
||||
* @param Function Leaf
|
||||
* @param eax EAX
|
||||
* @param ebx EBX
|
||||
* @param ecx ECX
|
||||
* @param edx EDX
|
||||
*/
|
||||
static inline void cpuid(uint32_t Function, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
|
||||
{
|
||||
#if defined(a32)
|
||||
asmv("cpuid"
|
||||
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
|
||||
: "a"(Function));
|
||||
#else
|
||||
UNUSED(Function);
|
||||
UNUSED(eax);
|
||||
UNUSED(ebx);
|
||||
UNUSED(ecx);
|
||||
UNUSED(edx);
|
||||
#endif
|
||||
}
|
||||
|
||||
SafeFunction static inline void invlpg(void *Address)
|
||||
{
|
||||
#if defined(a32)
|
||||
asmv("invlpg (%0)"
|
||||
:
|
||||
: "r"(Address)
|
||||
: "memory");
|
||||
#else
|
||||
UNUSED(Address);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
namespace x64
|
||||
{
|
||||
/**
|
||||
* @brief MSR_APIC_BASE structure
|
||||
* @see MSR_APIC_BASE
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Reserved */
|
||||
uint32_t Reserved0 : 8;
|
||||
/**
|
||||
* @brief BSP Flag
|
||||
* @details If the BSP flag is set to 1, the processor is the bootstrap processor.
|
||||
*/
|
||||
uint32_t BSP : 1;
|
||||
/** @brief Reserved */
|
||||
uint32_t Reserved1 : 1;
|
||||
/** @brief Enable x2APIC mode */
|
||||
uint32_t EXTD : 1;
|
||||
/** @brief APIC Global Enable */
|
||||
uint32_t EN : 1;
|
||||
/** @brief APIC Base Low Address */
|
||||
uint32_t ApicBaseLo : 20;
|
||||
/** @brief APIC Base High Address */
|
||||
uint32_t ApicBaseHi : 32;
|
||||
};
|
||||
uint64_t raw;
|
||||
} __packed APIC_BASE;
|
||||
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Carry Flag */
|
||||
uint64_t CF : 1;
|
||||
/** @brief Reserved */
|
||||
uint64_t AlwaysOne : 1;
|
||||
/** @brief Parity Flag */
|
||||
uint64_t PF : 1;
|
||||
/** @brief Reserved */
|
||||
uint64_t Reserved0 : 1;
|
||||
/** @brief Auxiliary Carry Flag */
|
||||
uint64_t AF : 1;
|
||||
/** @brief Reserved */
|
||||
uint64_t Reserved1 : 1;
|
||||
/** @brief Zero Flag */
|
||||
uint64_t ZF : 1;
|
||||
/** @brief Sign Flag */
|
||||
uint64_t SF : 1;
|
||||
/** @brief Trap Flag */
|
||||
uint64_t TF : 1;
|
||||
/** @brief Interrupt Enable Flag */
|
||||
uint64_t IF : 1;
|
||||
/** @brief Direction Flag */
|
||||
uint64_t DF : 1;
|
||||
/** @brief Overflow Flag */
|
||||
uint64_t OF : 1;
|
||||
/** @brief I/O Privilege Level */
|
||||
uint64_t IOPL : 2;
|
||||
/** @brief Nested Task */
|
||||
uint64_t NT : 1;
|
||||
/** @brief Reserved */
|
||||
uint64_t Reserved2 : 1;
|
||||
/** @brief Resume Flag */
|
||||
uint64_t RF : 1;
|
||||
/** @brief Virtual 8086 Mode */
|
||||
uint64_t VM : 1;
|
||||
/** @brief Alignment Check */
|
||||
uint64_t AC : 1;
|
||||
/** @brief Virtual Interrupt Flag */
|
||||
uint64_t VIF : 1;
|
||||
/** @brief Virtual Interrupt Pending */
|
||||
uint64_t VIP : 1;
|
||||
/** @brief ID Flag (Allow using CPUID instruction) */
|
||||
uint64_t ID : 1;
|
||||
/** @brief Reserved */
|
||||
uint64_t Reserved3 : 10;
|
||||
};
|
||||
uint64_t raw;
|
||||
} RFLAGS;
|
||||
|
||||
typedef struct TrapFrame
|
||||
{
|
||||
uint64_t r15; // General purpose
|
||||
uint64_t r14; // General purpose
|
||||
uint64_t r13; // General purpose
|
||||
uint64_t r12; // General purpose
|
||||
uint64_t r11; // General purpose
|
||||
uint64_t r10; // General purpose
|
||||
uint64_t r9; // General purpose
|
||||
uint64_t r8; // General purpose
|
||||
|
||||
uint64_t rbp; // Base Pointer (meant for stack frames)
|
||||
uint64_t rdi; // Destination index for string operations
|
||||
uint64_t rsi; // Source index for string operations
|
||||
uint64_t rdx; // Data (commonly extends the A register)
|
||||
uint64_t rcx; // Counter
|
||||
uint64_t rbx; // Base
|
||||
uint64_t rax; // Accumulator
|
||||
|
||||
uint64_t InterruptNumber; // Interrupt Number
|
||||
uint64_t ErrorCode; // Error code
|
||||
uint64_t rip; // Instruction Pointer
|
||||
uint64_t cs; // Code Segment
|
||||
RFLAGS rflags; // Register Flags
|
||||
uint64_t rsp; // Stack Pointer
|
||||
uint64_t ss; // Stack Segment
|
||||
} TrapFrame;
|
||||
|
||||
typedef union EFER
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Enable syscall & sysret instructions in 64-bit mode. */
|
||||
uint64_t SCE : 1;
|
||||
/** @brief Reserved */
|
||||
uint64_t Reserved0 : 7;
|
||||
/** @brief Enable long mode. */
|
||||
uint64_t LME : 1;
|
||||
/** @brief Reserved */
|
||||
uint64_t Reserved1 : 1;
|
||||
/** @brief Indicates long. */
|
||||
uint64_t LMA : 1;
|
||||
/** @brief Enable No-Execute Bit */
|
||||
uint64_t NXE : 1;
|
||||
/** @brief Enable Secure Virtual Machine */
|
||||
uint64_t SVME : 1;
|
||||
/** @brief Enable Long Mode Segment Limit */
|
||||
uint64_t LMSLE : 1;
|
||||
/** @brief Enable Fast FXSAVE/FXRSTOR */
|
||||
uint64_t FFXSR : 1;
|
||||
/** @brief Enable Translation Cache Extension */
|
||||
uint64_t TCE : 1;
|
||||
/** @brief Reserved */
|
||||
uint64_t Reserved2 : 32;
|
||||
};
|
||||
uint64_t raw;
|
||||
} __packed EFER;
|
||||
|
||||
// ! TODO: UNTESTED!
|
||||
typedef union DR7
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Local DR0 Breakpoint (0) */
|
||||
uint64_t LocalDR0 : 1;
|
||||
/** @brief Global DR0 Breakpoint (1) */
|
||||
uint64_t GlobalDR0 : 1;
|
||||
/** @brief Local DR1 Breakpoint (2) */
|
||||
uint64_t LocalDR1 : 1;
|
||||
/** @brief Global DR1 Breakpoint (3) */
|
||||
uint64_t GlobalDR1 : 1;
|
||||
/** @brief Local DR2 Breakpoint (4) */
|
||||
uint64_t LocalDR2 : 1;
|
||||
/** @brief Global DR2 Breakpoint (5) */
|
||||
uint64_t GlobalDR2 : 1;
|
||||
/** @brief Local DR3 Breakpoint (6) */
|
||||
uint64_t LocalDR3 : 1;
|
||||
/** @brief Global DR3 Breakpoint (7) */
|
||||
uint64_t GlobalDR3 : 1;
|
||||
/** @brief Reserved [7 - (16-17)] */
|
||||
uint64_t Reserved : 9;
|
||||
/** @brief Conditions for DR0 (16-17) */
|
||||
uint64_t ConditionsDR0 : 1;
|
||||
/** @brief Size of DR0 Breakpoint (18-19) */
|
||||
uint64_t SizeDR0 : 1;
|
||||
/** @brief Conditions for DR1 (20-21) */
|
||||
uint64_t ConditionsDR1 : 1;
|
||||
/** @brief Size of DR1 Breakpoint (22-23) */
|
||||
uint64_t SizeDR1 : 1;
|
||||
/** @brief Conditions for DR2 (24-25) */
|
||||
uint64_t ConditionsDR2 : 1;
|
||||
/** @brief Size of DR2 Breakpoint (26-27) */
|
||||
uint64_t SizeDR2 : 1;
|
||||
/** @brief Conditions for DR3 (28-29) */
|
||||
uint64_t ConditionsDR3 : 1;
|
||||
/** @brief Size of DR3 Breakpoint (30-31) */
|
||||
uint64_t SizeDR3 : 1;
|
||||
};
|
||||
uint64_t raw;
|
||||
} DR7;
|
||||
|
||||
typedef union PageFaultErrorCode
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief When set, the page fault was caused by a page-protection violation. When not set, it was caused by a non-present page. */
|
||||
uint64_t P : 1;
|
||||
/** @brief When set, the page fault was caused by a write access. When not set, it was caused by a read access. */
|
||||
uint64_t W : 1;
|
||||
/** @brief When set, the page fault was caused while CPL = 3. This does not necessarily mean that the page fault was a privilege violation. */
|
||||
uint64_t U : 1;
|
||||
/** @brief When set, one or more page directory entries contain reserved bits which are set to 1. This only applies when the PSE or PAE flags in CR4 are set to 1. */
|
||||
uint64_t R : 1;
|
||||
/** @brief When set, the page fault was caused by an instruction fetch. This only applies when the No-Execute bit is supported and enabled. */
|
||||
uint64_t I : 1;
|
||||
/** @brief When set, the page fault was caused by a protection-key violation. The PKRU register (for user-mode accesses) or PKRS MSR (for supervisor-mode accesses) specifies the protection key rights. */
|
||||
uint64_t PK : 1;
|
||||
/** @brief When set, the page fault was caused by a shadow stack access. */
|
||||
uint64_t SS : 1;
|
||||
/** @brief Reserved */
|
||||
uint64_t Reserved0 : 8;
|
||||
/** @brief When set, the fault was due to an SGX violation. The fault is unrelated to ordinary paging. */
|
||||
uint64_t SGX : 1;
|
||||
/** @brief Reserved */
|
||||
uint64_t Reserved1 : 16;
|
||||
};
|
||||
uint64_t raw;
|
||||
} PageFaultErrorCode;
|
||||
|
||||
// ! TODO: UNTESTED!
|
||||
typedef union SelectorErrorCode
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief When set, the exception originated externally to the processor. */
|
||||
uint64_t External : 1;
|
||||
/** @brief IDT/GDT/LDT Table
|
||||
* @details 0b00 - The Selector Index references a descriptor in the GDT.
|
||||
* @details 0b01 - The Selector Index references a descriptor in the IDT.
|
||||
* @details 0b10 - The Selector Index references a descriptor in the LDT.
|
||||
* @details 0b11 - The Selector Index references a descriptor in the IDT.
|
||||
*/
|
||||
uint64_t Table : 2;
|
||||
/** @brief The index in the GDT, IDT or LDT. */
|
||||
uint64_t Idx : 13;
|
||||
/** @brief Reserved */
|
||||
uint64_t Reserved : 16;
|
||||
};
|
||||
uint64_t raw;
|
||||
} SelectorErrorCode;
|
||||
|
||||
struct FXState
|
||||
{
|
||||
/** @brief FPU control word */
|
||||
uint16_t fcw;
|
||||
/** @brief FPU status word */
|
||||
uint16_t fsw;
|
||||
/** @brief FPU tag words */
|
||||
uint8_t ftw;
|
||||
/** @brief Reserved (zero) */
|
||||
uint8_t Reserved;
|
||||
/** @brief FPU opcode */
|
||||
uint16_t fop;
|
||||
/** @brief PFU instruction pointer */
|
||||
uint64_t rip;
|
||||
/** @brief FPU data pointer */
|
||||
uint64_t rdp;
|
||||
/** @brief SSE control register */
|
||||
uint32_t mxcsr;
|
||||
/** @brief SSE control register mask */
|
||||
uint32_t mxcsrmask;
|
||||
/** @brief FPU registers (last 6 bytes reserved) */
|
||||
uint8_t st[8][16];
|
||||
/** @brief XMM registers */
|
||||
uint8_t xmm[16][16];
|
||||
} __packed;
|
||||
|
||||
SafeFunction static inline void lgdt(void *gdt)
|
||||
{
|
||||
#if defined(a64)
|
||||
asmv("lgdt (%0)"
|
||||
:
|
||||
: "r"(gdt));
|
||||
#endif
|
||||
}
|
||||
|
||||
SafeFunction static inline void lidt(void *idt)
|
||||
{
|
||||
#if defined(a64)
|
||||
asmv("lidt (%0)"
|
||||
:
|
||||
: "r"(idt));
|
||||
#endif
|
||||
}
|
||||
|
||||
SafeFunction static inline void ltr(uint16_t Segment)
|
||||
{
|
||||
#if defined(a64)
|
||||
asmv("ltr %0"
|
||||
:
|
||||
: "r"(Segment));
|
||||
#endif
|
||||
}
|
||||
|
||||
SafeFunction static inline void invlpg(void *Address)
|
||||
{
|
||||
#if defined(a64)
|
||||
asmv("invlpg (%0)"
|
||||
:
|
||||
: "r"(Address)
|
||||
: "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief CPUID
|
||||
*
|
||||
* @param Function Leaf
|
||||
* @param eax EAX
|
||||
* @param ebx EBX
|
||||
* @param ecx ECX
|
||||
* @param edx EDX
|
||||
*/
|
||||
SafeFunction static inline void cpuid(uint32_t Function, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
|
||||
{
|
||||
#if defined(a64)
|
||||
asmv("cpuid"
|
||||
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
|
||||
: "a"(Function));
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the highest leaf function supported by CPUID
|
||||
*
|
||||
* @example if (GetHighestLeaf() < 0x15) { error("CPU doesn't support leaf 0x15!"); }
|
||||
*
|
||||
* @return uint32_t
|
||||
*/
|
||||
SafeFunction static inline uint32_t GetHighestLeaf()
|
||||
{
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
cpuid(0x0, &eax, &ebx, &ecx, &edx);
|
||||
return eax;
|
||||
}
|
||||
|
||||
SafeFunction static inline void fxsave(void *FXSaveArea)
|
||||
{
|
||||
#if defined(a64)
|
||||
if (!FXSaveArea || FXSaveArea >= (char *)0xfffffffffffff000)
|
||||
return;
|
||||
|
||||
asmv("fxsaveq (%0)"
|
||||
:
|
||||
: "r"(FXSaveArea)
|
||||
: "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
SafeFunction static inline void fxrstor(void *FXRstorArea)
|
||||
{
|
||||
#if defined(a64)
|
||||
if (!FXRstorArea || FXRstorArea >= (char *)0xfffffffffffff000)
|
||||
return;
|
||||
|
||||
asmv("fxrstorq (%0)"
|
||||
:
|
||||
: "r"(FXRstorArea)
|
||||
: "memory");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
namespace aarch64
|
||||
{
|
||||
typedef struct TrapFrame
|
||||
{
|
||||
uint64_t x19; // General purpose
|
||||
uint64_t x20; // General purpose
|
||||
uint64_t x21; // General purpose
|
||||
uint64_t x22; // General purpose
|
||||
uint64_t x23; // General purpose
|
||||
uint64_t x24; // General purpose
|
||||
uint64_t x25; // General purpose
|
||||
uint64_t x26; // General purpose
|
||||
|
||||
uint64_t x27; // Stack frame pointer
|
||||
uint64_t x28; // Link register
|
||||
uint64_t x29; // Frame pointer
|
||||
uint64_t x30; // Program counter
|
||||
|
||||
uint64_t sp_el0; // Stack pointer
|
||||
uint64_t elr_el1; // Exception Link Register
|
||||
uint64_t spsr_el1; // Saved Program Status Register
|
||||
uint64_t ErrorCode /* esr_el1 */; // Exception Syndrome Register
|
||||
|
||||
uint64_t InterruptNumber /* iar_el1 */; // Interrupt Acknowledge Register
|
||||
} TrapFrame;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_CPU_H__
|
0
Kernel/include/cpu/arm/.gitkeep
Normal file
0
Kernel/include/cpu/arm/.gitkeep
Normal file
73
Kernel/include/cpu/membar.hpp
Normal file
73
Kernel/include/cpu/membar.hpp
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_CPU_MEMBAR_H__
|
||||
#define __FENNIX_KERNEL_CPU_MEMBAR_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
namespace CPU
|
||||
{
|
||||
namespace MemBar
|
||||
{
|
||||
SafeFunction static inline void Barrier()
|
||||
{
|
||||
#if defined(a86)
|
||||
asmv("" ::
|
||||
: "memory");
|
||||
#elif defined(aa64)
|
||||
asmv("dmb ish" ::
|
||||
: "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
SafeFunction static inline void Fence()
|
||||
{
|
||||
#if defined(a86)
|
||||
asmv("mfence" ::
|
||||
: "memory");
|
||||
#elif defined(aa64)
|
||||
asmv("dmb ish" ::
|
||||
: "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
SafeFunction static inline void StoreFence()
|
||||
{
|
||||
#if defined(a86)
|
||||
asmv("sfence" ::
|
||||
: "memory");
|
||||
#elif defined(aa64)
|
||||
asmv("dmb ishst" ::
|
||||
: "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
SafeFunction static inline void LoadFence()
|
||||
{
|
||||
#if defined(a86)
|
||||
asmv("lfence" ::
|
||||
: "memory");
|
||||
#elif defined(aa64)
|
||||
asmv("dmb ishld" ::
|
||||
: "memory");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_CPU_MEMBAR_H__
|
108
Kernel/include/cpu/signatures.hpp
Normal file
108
Kernel/include/cpu/signatures.hpp
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_CPU_SIGNATURES_H__
|
||||
#define __FENNIX_KERNEL_CPU_SIGNATURES_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#define x86_CPUID_VENDOR_OLDAMD "AMDisbetter!" /* Early engineering samples of AMD K5 processor */
|
||||
#define x86_CPUID_VENDOR_AMD "AuthenticAMD"
|
||||
#define x86_CPUID_VENDOR_INTEL "GenuineIntel"
|
||||
#define x86_CPUID_VENDOR_VIA "CentaurHauls"
|
||||
#define x86_CPUID_VENDOR_OLDTRANSMETA "TransmetaCPU"
|
||||
#define x86_CPUID_VENDOR_TRANSMETA "GenuineTMx86"
|
||||
#define x86_CPUID_VENDOR_CYRIX "CyrixInstead"
|
||||
#define x86_CPUID_VENDOR_CENTAUR "CentaurHauls"
|
||||
#define x86_CPUID_VENDOR_NEXGEN "NexGenDriven"
|
||||
#define x86_CPUID_VENDOR_UMC "UMC UMC UMC "
|
||||
#define x86_CPUID_VENDOR_SIS "SiS SiS SiS "
|
||||
#define x86_CPUID_VENDOR_NSC "Geode by NSC"
|
||||
#define x86_CPUID_VENDOR_RISE "RiseRiseRise"
|
||||
#define x86_CPUID_VENDOR_VORTEX "Vortex86 SoC"
|
||||
#define x86_CPUID_VENDOR_VIA2 "VIA VIA VIA "
|
||||
#define x86_CPUID_VENDOR_HYGON "HygonGenuine"
|
||||
#define x86_CPUID_VENDOR_E2K "E2K MACHINE"
|
||||
#define x86_CPUID_VENDOR_MISTER "MiSTer AO486"
|
||||
|
||||
/* Vendor-strings from Virtual Machines. */
|
||||
#define x86_CPUID_VENDOR_VMWARE "VMwareVMware"
|
||||
#define x86_CPUID_VENDOR_XENHVM "XenVMMXenVMM"
|
||||
#define x86_CPUID_VENDOR_MICROSOFT_HV "Microsoft Hv"
|
||||
#define x86_CPUID_VENDOR_MICROSOFT_XTA "MicrosoftXTA"
|
||||
#define x86_CPUID_VENDOR_PARALLELS " lrpepyh vr"
|
||||
#define x86_CPUID_VENDOR_KVM "KVMKVMKVM"
|
||||
#define x86_CPUID_VENDOR_VIRTUALBOX "VBoxVBoxVBox"
|
||||
#define x86_CPUID_VENDOR_TCG "TCGTCGTCGTCG"
|
||||
#define x86_CPUID_VENDOR_BHYVE "bhyve bhyve "
|
||||
#define x86_CPUID_VENDOR_ACRN "ACRNACRNACRN"
|
||||
#define x86_CPUID_VENDOR_QNX "QNXQVMBSQG"
|
||||
#define x86_CPUID_VENDOR_APPLE "VirtualApple"
|
||||
|
||||
#define x86_CPUID_SIGNATURE_INTEL_b 0x756e6547
|
||||
#define x86_CPUID_SIGNATURE_INTEL_c 0x6c65746e
|
||||
#define x86_CPUID_SIGNATURE_INTEL_d 0x49656e69
|
||||
|
||||
#define x86_CPUID_SIGNATURE_AMD_b 0x68747541
|
||||
#define x86_CPUID_SIGNATURE_AMD_c 0x444d4163
|
||||
#define x86_CPUID_SIGNATURE_AMD_d 0x69746e65
|
||||
|
||||
#define x86_CPUID_SIGNATURE_CENTAUR_b 0x746e6543
|
||||
#define x86_CPUID_SIGNATURE_CENTAUR_c 0x736c7561
|
||||
#define x86_CPUID_SIGNATURE_CENTAUR_d 0x48727561
|
||||
|
||||
#define x86_CPUID_SIGNATURE_CYRIX_b 0x69727943
|
||||
#define x86_CPUID_SIGNATURE_CYRIX_c 0x64616574
|
||||
#define x86_CPUID_SIGNATURE_CYRIX_d 0x736e4978
|
||||
|
||||
#define x86_CPUID_SIGNATURE_TM1_b 0x6e617254
|
||||
#define x86_CPUID_SIGNATURE_TM1_c 0x55504361
|
||||
#define x86_CPUID_SIGNATURE_TM1_d 0x74656d73
|
||||
|
||||
#define x86_CPUID_SIGNATURE_TM2_b 0x756e6547
|
||||
#define x86_CPUID_SIGNATURE_TM2_c 0x3638784d
|
||||
#define x86_CPUID_SIGNATURE_TM2_d 0x54656e69
|
||||
|
||||
#define x86_CPUID_SIGNATURE_NSC_b 0x646f6547
|
||||
#define x86_CPUID_SIGNATURE_NSC_c 0x43534e20
|
||||
#define x86_CPUID_SIGNATURE_NSC_d 0x79622065
|
||||
|
||||
#define x86_CPUID_SIGNATURE_NEXGEN_b 0x4778654e
|
||||
#define x86_CPUID_SIGNATURE_NEXGEN_c 0x6e657669
|
||||
#define x86_CPUID_SIGNATURE_NEXGEN_d 0x72446e65
|
||||
|
||||
#define x86_CPUID_SIGNATURE_RISE_b 0x65736952
|
||||
#define x86_CPUID_SIGNATURE_RISE_c 0x65736952
|
||||
#define x86_CPUID_SIGNATURE_RISE_d 0x65736952
|
||||
|
||||
#define x86_CPUID_SIGNATURE_SIS_b 0x20536953
|
||||
#define x86_CPUID_SIGNATURE_SIS_c 0x20536953
|
||||
#define x86_CPUID_SIGNATURE_SIS_d 0x20536953
|
||||
|
||||
#define x86_CPUID_SIGNATURE_UMC_b 0x20434d55
|
||||
#define x86_CPUID_SIGNATURE_UMC_c 0x20434d55
|
||||
#define x86_CPUID_SIGNATURE_UMC_d 0x20434d55
|
||||
|
||||
#define x86_CPUID_SIGNATURE_VIA_b 0x20414956
|
||||
#define x86_CPUID_SIGNATURE_VIA_c 0x20414956
|
||||
#define x86_CPUID_SIGNATURE_VIA_d 0x20414956
|
||||
|
||||
#define x86_CPUID_SIGNATURE_VORTEX_b 0x74726f56
|
||||
#define x86_CPUID_SIGNATURE_VORTEX_c 0x436f5320
|
||||
#define x86_CPUID_SIGNATURE_VORTEX_d 0x36387865
|
||||
|
||||
#endif // !__FENNIX_KERNEL_CPU_SIGNATURES_H__
|
2159
Kernel/include/cpu/x86/cpuid_amd.hpp
Normal file
2159
Kernel/include/cpu/x86/cpuid_amd.hpp
Normal file
File diff suppressed because it is too large
Load Diff
1420
Kernel/include/cpu/x86/cpuid_intel.hpp
Normal file
1420
Kernel/include/cpu/x86/cpuid_intel.hpp
Normal file
File diff suppressed because it is too large
Load Diff
54
Kernel/include/cpu/x86/exceptions.hpp
Normal file
54
Kernel/include/cpu/x86/exceptions.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_CPU_x86_EXCEPTIONS_H__
|
||||
#define __FENNIX_KERNEL_CPU_x86_EXCEPTIONS_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
namespace CPU
|
||||
{
|
||||
namespace x86
|
||||
{
|
||||
enum ISRExceptions
|
||||
{
|
||||
DivideByZero = 0x0,
|
||||
Debug = 0x1,
|
||||
NonMaskableInterrupt = 0x2,
|
||||
Breakpoint = 0x3,
|
||||
Overflow = 0x4,
|
||||
BoundRange = 0x5,
|
||||
InvalidOpcode = 0x6,
|
||||
DeviceNotAvailable = 0x7,
|
||||
DoubleFault = 0x8,
|
||||
CoprocessorSegmentOverrun = 0x9,
|
||||
InvalidTSS = 0xa,
|
||||
SegmentNotPresent = 0xb,
|
||||
StackSegmentFault = 0xc,
|
||||
GeneralProtectionFault = 0xd,
|
||||
PageFault = 0xe,
|
||||
x87FloatingPoint = 0x10,
|
||||
AlignmentCheck = 0x11,
|
||||
MachineCheck = 0x12,
|
||||
SIMDFloatingPoint = 0x13,
|
||||
Virtualization = 0x14,
|
||||
Security = 0x1e
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_CPU_x86_EXCEPTIONS_H__
|
80
Kernel/include/cpu/x86/hypervisor.hpp
Normal file
80
Kernel/include/cpu/x86/hypervisor.hpp
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_CPU_x86_CPUID_HYPERVISOR_H__
|
||||
#define __FENNIX_KERNEL_CPU_x86_CPUID_HYPERVISOR_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
namespace CPU
|
||||
{
|
||||
namespace x86
|
||||
{
|
||||
/** @brief EXPERIMENTAL IMPLEMENTATION */
|
||||
namespace Hypervisor
|
||||
{
|
||||
/** @brief Get CPU hypervisor information */
|
||||
struct CPUID0x40000000
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/**
|
||||
* @brief Maximum input value for hypervisor CPUID information.
|
||||
* @note Can be from 0x40000001 to 0x400000FF
|
||||
*/
|
||||
uint64_t MaximumInputValue : 32;
|
||||
};
|
||||
uint64_t raw;
|
||||
} EAX;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Hypervisor vendor signature */
|
||||
char Hypervisor[4];
|
||||
};
|
||||
uint64_t raw;
|
||||
} EBX;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Hypervisor vendor signature */
|
||||
char Hypervisor[4];
|
||||
};
|
||||
uint64_t raw;
|
||||
} ECX;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Hypervisor vendor signature */
|
||||
char Hypervisor[4];
|
||||
};
|
||||
uint64_t raw;
|
||||
} EDX;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_CPU_x86_CPUID_HYPERVISOR_H__
|
300
Kernel/include/cpu/x86/interrupts.hpp
Normal file
300
Kernel/include/cpu/x86/interrupts.hpp
Normal file
@ -0,0 +1,300 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_CPU_x86_INTERRUPTS_H__
|
||||
#define __FENNIX_KERNEL_CPU_x86_INTERRUPTS_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
namespace CPU
|
||||
{
|
||||
namespace x86
|
||||
{
|
||||
enum CPUInterrupts
|
||||
{
|
||||
/* ISR */
|
||||
|
||||
ISR0 = 0x0, // Divide-by-zero Error
|
||||
ISR1 = 0x1, // Debug
|
||||
ISR2 = 0x2, // Non-maskable Interrupt
|
||||
ISR3 = 0x3, // Breakpoint
|
||||
ISR4 = 0x4, // Overflow
|
||||
ISR5 = 0x5, // Bound Range Exceeded
|
||||
ISR6 = 0x6, // Invalid Opcode
|
||||
ISR7 = 0x7, // Device Not Available
|
||||
ISR8 = 0x8, // Double Fault
|
||||
ISR9 = 0x9, // Coprocessor Segment Overrun
|
||||
ISR10 = 0xa, // Invalid TSS
|
||||
ISR11 = 0xb, // Segment Not P
|
||||
ISR12 = 0xc, // Stack-Segment Fault
|
||||
ISR13 = 0xd, // General Protection Fault
|
||||
ISR14 = 0xe, // Page Fault
|
||||
ISR15 = 0xf, // Reserved
|
||||
ISR16 = 0x10, // x87 Floating-Point Exception
|
||||
ISR17 = 0x11, // Alignment Check
|
||||
ISR18 = 0x12, // Machine Check
|
||||
ISR19 = 0x13, // SIMD Floating-Point Exception
|
||||
ISR20 = 0x14, // Virtualization Exception
|
||||
ISR21 = 0x15, // Reserved
|
||||
ISR22 = 0x16, // Reserved
|
||||
ISR23 = 0x17, // Reserved
|
||||
ISR24 = 0x18, // Reserved
|
||||
ISR25 = 0x19, // Reserved
|
||||
ISR26 = 0x1a, // Reserved
|
||||
ISR27 = 0x1b, // Reserved
|
||||
ISR28 = 0x1c, // Reserved
|
||||
ISR29 = 0x1d, // Reserved
|
||||
ISR30 = 0x1e, // Security Exception
|
||||
ISR31 = 0x1f, // Reserved
|
||||
|
||||
/* IRQ */
|
||||
|
||||
IRQ0 = 0x20, // Programmable Interrupt Timer Interrupt
|
||||
IRQ1 = 0x21, // Keyboard Interrupt
|
||||
IRQ2 = 0x22, // Cascade (used internally by the two PICs. never raised)
|
||||
IRQ3 = 0x23, // COM2 (if enabled)
|
||||
IRQ4 = 0x24, // COM1 (if enabled)
|
||||
IRQ5 = 0x25, // LPT2 (if enabled)
|
||||
IRQ6 = 0x26, // Floppy Disk
|
||||
IRQ7 = 0x27, // LPT1 / Unreliable "spurious" interrupt (usually)
|
||||
IRQ8 = 0x28, // CMOS real-time clock (if enabled)
|
||||
IRQ9 = 0x29, // Free for peripherals / legacy SCSI / NIC
|
||||
IRQ10 = 0x2a, // Free for peripherals / SCSI / NIC
|
||||
IRQ11 = 0x2b, // Free for peripherals / SCSI / NIC
|
||||
IRQ12 = 0x2c, // PS2 Mouse
|
||||
IRQ13 = 0x2d, // FPU / Coprocessor / Inter-processor
|
||||
IRQ14 = 0x2e, // Primary ATA Hard Disk
|
||||
IRQ15 = 0x2f, // Secondary ATA Hard Disk
|
||||
|
||||
/* Reserved by OS */
|
||||
|
||||
IRQ16 = 0x30, // Reserved for multitasking
|
||||
IRQ17 = 0x31,
|
||||
IRQ18 = 0x32,
|
||||
IRQ19 = 0x33,
|
||||
IRQ20 = 0x34,
|
||||
IRQ21 = 0x35,
|
||||
IRQ22 = 0x36,
|
||||
IRQ23 = 0x37,
|
||||
IRQ24 = 0x38,
|
||||
IRQ25 = 0x39,
|
||||
IRQ26 = 0x3a,
|
||||
IRQ27 = 0x3b,
|
||||
IRQ28 = 0x3c,
|
||||
IRQ29 = 0x3d, // Reserved for icr stop core
|
||||
|
||||
/* Free */
|
||||
|
||||
IRQ30 = 0x3e,
|
||||
IRQ31 = 0x3f,
|
||||
IRQ32 = 0x40,
|
||||
IRQ33 = 0x41,
|
||||
IRQ34 = 0x42,
|
||||
IRQ35 = 0x43,
|
||||
IRQ36 = 0x44,
|
||||
IRQ37 = 0x45,
|
||||
IRQ38 = 0x46,
|
||||
IRQ39 = 0x47,
|
||||
IRQ40 = 0x48,
|
||||
IRQ41 = 0x49,
|
||||
IRQ42 = 0x4a,
|
||||
IRQ43 = 0x4b,
|
||||
IRQ44 = 0x4c,
|
||||
IRQ45 = 0x4d,
|
||||
IRQ46 = 0x4e,
|
||||
IRQ47 = 0x4f,
|
||||
IRQ48 = 0x50,
|
||||
IRQ49 = 0x51,
|
||||
IRQ50 = 0x52,
|
||||
IRQ51 = 0x53,
|
||||
IRQ52 = 0x54,
|
||||
IRQ53 = 0x55,
|
||||
IRQ54 = 0x56,
|
||||
IRQ55 = 0x57,
|
||||
IRQ56 = 0x58,
|
||||
IRQ57 = 0x59,
|
||||
IRQ58 = 0x5a,
|
||||
IRQ59 = 0x5b,
|
||||
IRQ60 = 0x5c,
|
||||
IRQ61 = 0x5d,
|
||||
IRQ62 = 0x5e,
|
||||
IRQ63 = 0x5f,
|
||||
IRQ64 = 0x60,
|
||||
IRQ65 = 0x61,
|
||||
IRQ66 = 0x62,
|
||||
IRQ67 = 0x63,
|
||||
IRQ68 = 0x64,
|
||||
IRQ69 = 0x65,
|
||||
IRQ70 = 0x66,
|
||||
IRQ71 = 0x67,
|
||||
IRQ72 = 0x68,
|
||||
IRQ73 = 0x69,
|
||||
IRQ74 = 0x6a,
|
||||
IRQ75 = 0x6b,
|
||||
IRQ76 = 0x6c,
|
||||
IRQ77 = 0x6d,
|
||||
IRQ78 = 0x6e,
|
||||
IRQ79 = 0x6f,
|
||||
IRQ80 = 0x70,
|
||||
IRQ81 = 0x71,
|
||||
IRQ82 = 0x72,
|
||||
IRQ83 = 0x73,
|
||||
IRQ84 = 0x74,
|
||||
IRQ85 = 0x75,
|
||||
IRQ86 = 0x76,
|
||||
IRQ87 = 0x77,
|
||||
IRQ88 = 0x78,
|
||||
IRQ89 = 0x79,
|
||||
IRQ90 = 0x7a,
|
||||
IRQ91 = 0x7b,
|
||||
IRQ92 = 0x7c,
|
||||
IRQ93 = 0x7d,
|
||||
IRQ94 = 0x7e,
|
||||
IRQ95 = 0x7f,
|
||||
IRQ96 = 0x80,
|
||||
IRQ97 = 0x81,
|
||||
IRQ98 = 0x82,
|
||||
IRQ99 = 0x83,
|
||||
IRQ100 = 0x84,
|
||||
IRQ101 = 0x85,
|
||||
IRQ102 = 0x86,
|
||||
IRQ103 = 0x87,
|
||||
IRQ104 = 0x88,
|
||||
IRQ105 = 0x89,
|
||||
IRQ106 = 0x8a,
|
||||
IRQ107 = 0x8b,
|
||||
IRQ108 = 0x8c,
|
||||
IRQ109 = 0x8d,
|
||||
IRQ110 = 0x8e,
|
||||
IRQ111 = 0x8f,
|
||||
IRQ112 = 0x90,
|
||||
IRQ113 = 0x91,
|
||||
IRQ114 = 0x92,
|
||||
IRQ115 = 0x93,
|
||||
IRQ116 = 0x94,
|
||||
IRQ117 = 0x95,
|
||||
IRQ118 = 0x96,
|
||||
IRQ119 = 0x97,
|
||||
IRQ120 = 0x98,
|
||||
IRQ121 = 0x99,
|
||||
IRQ122 = 0x9a,
|
||||
IRQ123 = 0x9b,
|
||||
IRQ124 = 0x9c,
|
||||
IRQ125 = 0x9d,
|
||||
IRQ126 = 0x9e,
|
||||
IRQ127 = 0x9f,
|
||||
IRQ128 = 0xa0,
|
||||
IRQ129 = 0xa1,
|
||||
IRQ130 = 0xa2,
|
||||
IRQ131 = 0xa3,
|
||||
IRQ132 = 0xa4,
|
||||
IRQ133 = 0xa5,
|
||||
IRQ134 = 0xa6,
|
||||
IRQ135 = 0xa7,
|
||||
IRQ136 = 0xa8,
|
||||
IRQ137 = 0xa9,
|
||||
IRQ138 = 0xaa,
|
||||
IRQ139 = 0xab,
|
||||
IRQ140 = 0xac,
|
||||
IRQ141 = 0xad,
|
||||
IRQ142 = 0xae,
|
||||
IRQ143 = 0xaf,
|
||||
IRQ144 = 0xb0,
|
||||
IRQ145 = 0xb1,
|
||||
IRQ146 = 0xb2,
|
||||
IRQ147 = 0xb3,
|
||||
IRQ148 = 0xb4,
|
||||
IRQ149 = 0xb5,
|
||||
IRQ150 = 0xb6,
|
||||
IRQ151 = 0xb7,
|
||||
IRQ152 = 0xb8,
|
||||
IRQ153 = 0xb9,
|
||||
IRQ154 = 0xba,
|
||||
IRQ155 = 0xbb,
|
||||
IRQ156 = 0xbc,
|
||||
IRQ157 = 0xbd,
|
||||
IRQ158 = 0xbe,
|
||||
IRQ159 = 0xbf,
|
||||
IRQ160 = 0xc0,
|
||||
IRQ161 = 0xc1,
|
||||
IRQ162 = 0xc2,
|
||||
IRQ163 = 0xc3,
|
||||
IRQ164 = 0xc4,
|
||||
IRQ165 = 0xc5,
|
||||
IRQ166 = 0xc6,
|
||||
IRQ167 = 0xc7,
|
||||
IRQ168 = 0xc8,
|
||||
IRQ169 = 0xc9,
|
||||
IRQ170 = 0xca,
|
||||
IRQ171 = 0xcb,
|
||||
IRQ172 = 0xcc,
|
||||
IRQ173 = 0xcd,
|
||||
IRQ174 = 0xce,
|
||||
IRQ175 = 0xcf,
|
||||
IRQ176 = 0xd0,
|
||||
IRQ177 = 0xd1,
|
||||
IRQ178 = 0xd2,
|
||||
IRQ179 = 0xd3,
|
||||
IRQ180 = 0xd4,
|
||||
IRQ181 = 0xd5,
|
||||
IRQ182 = 0xd6,
|
||||
IRQ183 = 0xd7,
|
||||
IRQ184 = 0xd8,
|
||||
IRQ185 = 0xd9,
|
||||
IRQ186 = 0xda,
|
||||
IRQ187 = 0xdb,
|
||||
IRQ188 = 0xdc,
|
||||
IRQ189 = 0xdd,
|
||||
IRQ190 = 0xde,
|
||||
IRQ191 = 0xdf,
|
||||
IRQ192 = 0xe0,
|
||||
IRQ193 = 0xe1,
|
||||
IRQ194 = 0xe2,
|
||||
IRQ195 = 0xe3,
|
||||
IRQ196 = 0xe4,
|
||||
IRQ197 = 0xe5,
|
||||
IRQ198 = 0xe6,
|
||||
IRQ199 = 0xe7,
|
||||
IRQ200 = 0xe8,
|
||||
IRQ201 = 0xe9,
|
||||
IRQ202 = 0xea,
|
||||
IRQ203 = 0xeb,
|
||||
IRQ204 = 0xec,
|
||||
IRQ205 = 0xed,
|
||||
IRQ206 = 0xee,
|
||||
IRQ207 = 0xef,
|
||||
IRQ208 = 0xf0,
|
||||
IRQ209 = 0xf1,
|
||||
IRQ210 = 0xf2,
|
||||
IRQ211 = 0xf3,
|
||||
IRQ212 = 0xf4,
|
||||
IRQ213 = 0xf5,
|
||||
IRQ214 = 0xf6,
|
||||
IRQ215 = 0xf7,
|
||||
IRQ216 = 0xf8,
|
||||
IRQ217 = 0xf9,
|
||||
IRQ218 = 0xfa,
|
||||
IRQ219 = 0xfb,
|
||||
IRQ220 = 0xfc,
|
||||
IRQ221 = 0xfd,
|
||||
IRQ222 = 0xfe,
|
||||
IRQ223 = 0xff,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_CPU_x86_INTERRUPTS_H__
|
238
Kernel/include/cpu/x86/x32/cr.hpp
Normal file
238
Kernel/include/cpu/x86/x32/cr.hpp
Normal file
@ -0,0 +1,238 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_CPU_x32_CR_H__
|
||||
#define __FENNIX_KERNEL_CPU_x32_CR_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
namespace CPU
|
||||
{
|
||||
namespace x32
|
||||
{
|
||||
typedef union CR0
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Protection Enable */
|
||||
uint32_t PE : 1;
|
||||
/** @brief Monitor Coprocessor */
|
||||
uint32_t MP : 1;
|
||||
/** @brief Emulation */
|
||||
uint32_t EM : 1;
|
||||
/** @brief Task Switched */
|
||||
uint32_t TS : 1;
|
||||
/** @brief Extension Type */
|
||||
uint32_t ET : 1;
|
||||
/** @brief Numeric Error */
|
||||
uint32_t NE : 1;
|
||||
/** @brief Reserved */
|
||||
uint32_t Reserved0 : 10;
|
||||
/** @brief Write Protect */
|
||||
uint32_t WP : 1;
|
||||
/** @brief Reserved */
|
||||
uint32_t Reserved1 : 1;
|
||||
/** @brief Alignment Mask */
|
||||
uint32_t AM : 1;
|
||||
/** @brief Reserved */
|
||||
uint32_t Reserved2 : 10;
|
||||
/** @brief Not Write-through */
|
||||
uint32_t NW : 1;
|
||||
/** @brief Cache Disable */
|
||||
uint32_t CD : 1;
|
||||
/** @brief Paging */
|
||||
uint32_t PG : 1;
|
||||
};
|
||||
uint32_t raw;
|
||||
} CR0;
|
||||
|
||||
typedef union CR2
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Page Fault Linear Address */
|
||||
uint32_t PFLA;
|
||||
};
|
||||
uint32_t raw;
|
||||
} CR2;
|
||||
|
||||
typedef union CR3
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Not used if bit 17 of CR4 is 1 */
|
||||
uint32_t PWT : 1;
|
||||
/** @brief Not used if bit 17 of CR4 is 1 */
|
||||
uint32_t PCD : 1;
|
||||
/** @brief Base of PML4T/PML5T */
|
||||
uint32_t PDBR;
|
||||
};
|
||||
uint32_t raw;
|
||||
} CR3;
|
||||
|
||||
typedef union CR4
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Virtual-8086 Mode Extensions */
|
||||
uint32_t VME : 1;
|
||||
/** @brief Protected-Mode Virtual Interrupts */
|
||||
uint32_t PVI : 1;
|
||||
/** @brief Time Stamp Disable */
|
||||
uint32_t TSD : 1;
|
||||
/** @brief Debugging Extensions */
|
||||
uint32_t DE : 1;
|
||||
/** @brief Page Size Extensions */
|
||||
uint32_t PSE : 1;
|
||||
/** @brief Physical Address Extension */
|
||||
uint32_t PAE : 1;
|
||||
/** @brief Machine Check Enable */
|
||||
uint32_t MCE : 1;
|
||||
/** @brief Page Global Enable */
|
||||
uint32_t PGE : 1;
|
||||
/** @brief Performance Monitoring Counter */
|
||||
uint32_t PCE : 1;
|
||||
/** @brief Operating System Support */
|
||||
uint32_t OSFXSR : 1;
|
||||
/** @brief Operating System Support */
|
||||
uint32_t OSXMMEXCPT : 1;
|
||||
/** @brief User-Mode Instruction Prevention */
|
||||
uint32_t UMIP : 1;
|
||||
/** @brief Linear Address 57bit */
|
||||
uint32_t LA57 : 1;
|
||||
/** @brief VMX Enable */
|
||||
uint32_t VMXE : 1;
|
||||
/** @brief SMX Enable */
|
||||
uint32_t SMXE : 1;
|
||||
/** @brief Reserved */
|
||||
uint32_t Reserved0 : 1;
|
||||
/** @brief FSGSBASE Enable */
|
||||
uint32_t FSGSBASE : 1;
|
||||
/** @brief PCID Enable */
|
||||
uint32_t PCIDE : 1;
|
||||
/** @brief XSAVE and Processor Extended States Enable */
|
||||
uint32_t OSXSAVE : 1;
|
||||
/** @brief Reserved */
|
||||
uint32_t Reserved1 : 1;
|
||||
/** @brief SMEP Enable */
|
||||
uint32_t SMEP : 1;
|
||||
/** @brief SMAP Enable */
|
||||
uint32_t SMAP : 1;
|
||||
/** @brief Protection-Key Enable */
|
||||
uint32_t PKE : 1;
|
||||
/** @brief Control-flow Enforcement Technology*/
|
||||
uint32_t CET : 1;
|
||||
/* @brief Enable Protection Keys for Supervisor Mode Pages */
|
||||
uint32_t PKS : 1;
|
||||
};
|
||||
uint32_t raw;
|
||||
} CR4;
|
||||
|
||||
typedef union CR8
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Task Priority Level */
|
||||
uint32_t TPL : 1;
|
||||
};
|
||||
uint32_t raw;
|
||||
} CR8;
|
||||
#if defined(a32)
|
||||
SafeFunction static inline CR0 readcr0()
|
||||
{
|
||||
uint32_t Result = 0;
|
||||
asmv("mov %%cr0, %[Result]"
|
||||
: [Result] "=q"(Result));
|
||||
return (CR0){.raw = Result};
|
||||
}
|
||||
|
||||
SafeFunction static inline CR2 readcr2()
|
||||
{
|
||||
uint32_t Result = 0;
|
||||
asmv("mov %%cr2, %[Result]"
|
||||
: [Result] "=q"(Result));
|
||||
return (CR2){.raw = Result};
|
||||
}
|
||||
|
||||
SafeFunction static inline CR3 readcr3()
|
||||
{
|
||||
uint32_t Result = 0;
|
||||
asmv("mov %%cr3, %[Result]"
|
||||
: [Result] "=q"(Result));
|
||||
return (CR3){.raw = Result};
|
||||
}
|
||||
|
||||
SafeFunction static inline CR4 readcr4()
|
||||
{
|
||||
uint32_t Result = 0;
|
||||
asmv("mov %%cr4, %[Result]"
|
||||
: [Result] "=q"(Result));
|
||||
return (CR4){.raw = Result};
|
||||
}
|
||||
|
||||
SafeFunction static inline CR8 readcr8()
|
||||
{
|
||||
uint32_t Result = 0;
|
||||
asmv("mov %%cr8, %[Result]"
|
||||
: [Result] "=q"(Result));
|
||||
return (CR8){.raw = Result};
|
||||
}
|
||||
|
||||
SafeFunction static inline void writecr0(CR0 ControlRegister)
|
||||
{
|
||||
asmv("mov %[ControlRegister], %%cr0"
|
||||
:
|
||||
: [ControlRegister] "q"(ControlRegister.raw)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
SafeFunction static inline void writecr2(CR2 ControlRegister)
|
||||
{
|
||||
asmv("mov %[ControlRegister], %%cr2"
|
||||
:
|
||||
: [ControlRegister] "q"(ControlRegister.raw)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
SafeFunction static inline void writecr3(CR3 ControlRegister)
|
||||
{
|
||||
asmv("mov %[ControlRegister], %%cr3"
|
||||
:
|
||||
: [ControlRegister] "q"(ControlRegister.raw)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
SafeFunction static inline void writecr4(CR4 ControlRegister)
|
||||
{
|
||||
asmv("mov %[ControlRegister], %%cr4"
|
||||
:
|
||||
: [ControlRegister] "q"(ControlRegister.raw)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
SafeFunction static inline void writecr8(CR8 ControlRegister)
|
||||
{
|
||||
asmv("mov %[ControlRegister], %%cr8"
|
||||
:
|
||||
: [ControlRegister] "q"(ControlRegister.raw)
|
||||
: "memory");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_CPU_x32_CR_H__
|
426
Kernel/include/cpu/x86/x32/msr.hpp
Normal file
426
Kernel/include/cpu/x86/x32/msr.hpp
Normal file
@ -0,0 +1,426 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_CPU_x32_MSR_H__
|
||||
#define __FENNIX_KERNEL_CPU_x32_MSR_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
namespace CPU
|
||||
{
|
||||
namespace x32
|
||||
{
|
||||
enum MSRID
|
||||
{
|
||||
MSR_MONITOR_FILTER_SIZE = 0x6,
|
||||
MSR_TIME_STAMP_COUNTER = 0x10,
|
||||
MSR_PLATFORM_ID = 0x17,
|
||||
MSR_APIC_BASE = 0x1B,
|
||||
MSR_FEATURE_CONTROL = 0x3A,
|
||||
MSR_TSC_ADJUST = 0x3B,
|
||||
MSR_SPEC_CTRL = 0x48,
|
||||
MSR_PRED_CMD = 0x49,
|
||||
MSR_BIOS_UPDT_TRIG = 0x79,
|
||||
MSR_BIOS_SIGN_ID = 0x8B,
|
||||
MSR_SGXLEPUBKEYHASH0 = 0x8C,
|
||||
MSR_SGXLEPUBKEYHASH1 = 0x8D,
|
||||
MSR_SGXLEPUBKEYHASH2 = 0x8E,
|
||||
MSR_SGXLEPUBKEYHASH3 = 0x8F,
|
||||
MSR_SMM_MONITOR_CTL = 0x9B,
|
||||
MSR_SMBASE = 0x9E,
|
||||
MSR_PMC0 = 0xC1,
|
||||
MSR_PMC1 = 0xC2,
|
||||
MSR_PMC2 = 0xC3,
|
||||
MSR_PMC3 = 0xC4,
|
||||
MSR_PMC4 = 0xC5,
|
||||
MSR_PMC5 = 0xC6,
|
||||
MSR_PMC6 = 0xC7,
|
||||
MSR_PMC7 = 0xC8,
|
||||
MSR_UMWAIT_CONTROL = 0xE1,
|
||||
MSR_MPERF = 0xE7,
|
||||
MSR_APERF = 0xE8,
|
||||
MSR_MTRRCAP = 0xFE,
|
||||
MSR_ARCH_CAPABILITIES = 0x10A,
|
||||
MSR_FLUSH_CMD = 0x10B,
|
||||
MSR_SYSENTER_CS = 0x17A,
|
||||
MSR_SYSENTER_ESP = 0x175,
|
||||
MSR_SYSENTER_EIP = 0x176,
|
||||
MSR_MCG_CAP = 0x179,
|
||||
MSR_MCG_STATUS = 0x17A,
|
||||
MSR_MCG_CTL = 0x17B,
|
||||
MSR_PERFEVTSEL0 = 0x186,
|
||||
MSR_PERFEVTSEL1 = 0x187,
|
||||
MSR_PERFEVTSEL2 = 0x188,
|
||||
MSR_PERFEVTSEL3 = 0x189,
|
||||
MSR_PERF_STATUS = 0x198,
|
||||
MSR_PERF_CTL = 0x199,
|
||||
MSR_CLOCK_MODULATION = 0x19A,
|
||||
MSR_THERM_INTERRUPT = 0x19B,
|
||||
MSR_THERM_STATUS = 0x19C,
|
||||
MSR_MISC_ENABLE = 0x1A0,
|
||||
MSR_ENERGY_PERF_BIAS = 0x1B0,
|
||||
MSR_PACKAGE_THERM_STATUS = 0x1B1,
|
||||
MSR_PACKAGE_THERM_INTERRUPT = 0x1B2,
|
||||
MSR_DEBUGCTL = 0x1D9,
|
||||
MSR_SMRR_PHYSBASE = 0x1F2,
|
||||
MSR_SMRR_PHYSMASK = 0x1F3,
|
||||
MSR_PLATFORM_DCA_CAP = 0x1F8,
|
||||
MSR_CPU_DCA_CAP = 0x1F9,
|
||||
MSR_DCA_0_CAP = 0x1FA,
|
||||
MSR_MTRR_PHYSBASE0 = 0x200,
|
||||
MSR_MTRR_PHYSMASK0 = 0x201,
|
||||
MSR_MTRR_PHYSBASE1 = 0x202,
|
||||
MSR_MTRR_PHYSMASK1 = 0x203,
|
||||
MSR_MTRR_PHYSBASE2 = 0x204,
|
||||
MSR_MTRR_PHYSMASK2 = 0x205,
|
||||
MSR_MTRR_PHYSBASE3 = 0x206,
|
||||
MSR_MTRR_PHYSMASK3 = 0x207,
|
||||
MSR_MTRR_PHYSBASE4 = 0x208,
|
||||
MSR_MTRR_PHYSMASK4 = 0x209,
|
||||
MSR_MTRR_PHYSBASE5 = 0x20A,
|
||||
MSR_MTRR_PHYSMASK5 = 0x20B,
|
||||
MSR_MTRR_PHYSBASE6 = 0x20C,
|
||||
MSR_MTRR_PHYSMASK6 = 0x20D,
|
||||
MSR_MTRR_PHYSBASE7 = 0x20E,
|
||||
MSR_MTRR_PHYSMASK7 = 0x20F,
|
||||
MSR_MTRR_PHYSBASE8 = 0x210,
|
||||
MSR_MTRR_PHYSMASK8 = 0x211,
|
||||
MSR_MTRR_PHYSBASE9 = 0x212,
|
||||
MSR_MTRR_PHYSMASK9 = 0x213,
|
||||
MSR_MTRR_FIX64K_00000 = 0x250,
|
||||
MSR_MTRR_FIX16K_80000 = 0x258,
|
||||
MSR_MTRR_FIX16K_A0000 = 0x259,
|
||||
MSR_MTRR_FIX4K_C0000 = 0x268,
|
||||
MSR_MTRR_FIX4K_C8000 = 0x269,
|
||||
MSR_MTRR_FIX4K_D0000 = 0x26A,
|
||||
MSR_MTRR_FIX4K_D8000 = 0x26B,
|
||||
MSR_MTRR_FIX4K_E0000 = 0x26C,
|
||||
MSR_MTRR_FIX4K_E8000 = 0x26D,
|
||||
MSR_MTRR_FIX4K_F0000 = 0x26E,
|
||||
MSR_MTRR_FIX4K_F8000 = 0x26F,
|
||||
MSR_PAT = 0x277,
|
||||
MSR_MC0_CTL2 = 0x280,
|
||||
MSR_MC1_CTL2 = 0x281,
|
||||
MSR_MC2_CTL2 = 0x282,
|
||||
MSR_MC3_CTL2 = 0x283,
|
||||
MSR_MC4_CTL2 = 0x284,
|
||||
MSR_MC5_CTL2 = 0x285,
|
||||
MSR_MC6_CTL2 = 0x286,
|
||||
MSR_MC7_CTL2 = 0x287,
|
||||
MSR_MC8_CTL2 = 0x288,
|
||||
MSR_MC9_CTL2 = 0x289,
|
||||
MSR_MC10_CTL2 = 0x28A,
|
||||
MSR_MC11_CTL2 = 0x28B,
|
||||
MSR_MC12_CTL2 = 0x28C,
|
||||
MSR_MC13_CTL2 = 0x28D,
|
||||
MSR_MC14_CTL2 = 0x28E,
|
||||
MSR_MC15_CTL2 = 0x28F,
|
||||
MSR_MC16_CTL2 = 0x290,
|
||||
MSR_MC17_CTL2 = 0x291,
|
||||
MSR_MC18_CTL2 = 0x292,
|
||||
MSR_MC19_CTL2 = 0x293,
|
||||
MSR_MC20_CTL2 = 0x294,
|
||||
MSR_MC21_CTL2 = 0x295,
|
||||
MSR_MC22_CTL2 = 0x296,
|
||||
MSR_MC23_CTL2 = 0x297,
|
||||
MSR_MC24_CTL2 = 0x298,
|
||||
MSR_MC25_CTL2 = 0x299,
|
||||
MSR_MC26_CTL2 = 0x29A,
|
||||
MSR_MC27_CTL2 = 0x29B,
|
||||
MSR_MC28_CTL2 = 0x29C,
|
||||
MSR_MC29_CTL2 = 0x29D,
|
||||
MSR_MC30_CTL2 = 0x29E,
|
||||
MSR_MC31_CTL2 = 0x29F,
|
||||
MSR_MTRR_DEF_TYPE = 0x2FF,
|
||||
MSR_FIXED_CTR0 = 0x309,
|
||||
MSR_FIXED_CTR1 = 0x30A,
|
||||
MSR_FIXED_CTR2 = 0x30B,
|
||||
MSR_PERF_CAPABILITIES = 0x345,
|
||||
MSR_FIXED_CTR_CTRL = 0x38D,
|
||||
MSR_PERF_GLOBAL_STATUS = 0x38E,
|
||||
MSR_PERF_GLOBAL_CTRL = 0x38F,
|
||||
MSR_PERF_GLOBAL_STATUS_RESET = 0x390,
|
||||
MSR_PERF_GLOBAL_STATUS_SET = 0x391,
|
||||
MSR_PERF_GLOBAL_INUSE = 0x392,
|
||||
MSR_PEBS_ENABLE = 0x3F1,
|
||||
MSR_MC0_CTL = 0x400,
|
||||
MSR_MC0_STATUS = 0x401,
|
||||
MSR_MC0_ADDR = 0x402,
|
||||
MSR_MC0_MISC = 0x403,
|
||||
MSR_MC1_CTL = 0x404,
|
||||
MSR_MC1_STATUS = 0x405,
|
||||
MSR_MC1_ADDR = 0x406,
|
||||
MSR_MC1_MISC = 0x407,
|
||||
MSR_MC2_CTL = 0x408,
|
||||
MSR_MC2_STATUS = 0x409,
|
||||
MSR_MC2_ADDR = 0x40A,
|
||||
MSR_MC2_MISC = 0x40B,
|
||||
MSR_MC3_CTL = 0x40C,
|
||||
MSR_MC3_STATUS = 0x40D,
|
||||
MSR_MC3_ADDR = 0x40E,
|
||||
MSR_MC3_MISC = 0x40F,
|
||||
MSR_MC4_CTL = 0x410,
|
||||
MSR_MC4_STATUS = 0x411,
|
||||
MSR_MC4_ADDR = 0x412,
|
||||
MSR_MC4_MISC = 0x413,
|
||||
MSR_MC5_CTL = 0x414,
|
||||
MSR_MC5_STATUS = 0x415,
|
||||
MSR_MC5_ADDR = 0x416,
|
||||
MSR_MC5_MISC = 0x417,
|
||||
MSR_MC6_CTL = 0x418,
|
||||
MSR_MC6_STATUS = 0x419,
|
||||
MSR_MC6_ADDR = 0x41A,
|
||||
MSR_MC6_MISC = 0x41B,
|
||||
MSR_MC7_CTL = 0x41C,
|
||||
MSR_MC7_STATUS = 0x41D,
|
||||
MSR_MC7_ADDR = 0x41E,
|
||||
MSR_MC7_MISC = 0x41F,
|
||||
MSR_MC8_CTL = 0x420,
|
||||
MSR_MC8_STATUS = 0x421,
|
||||
MSR_MC8_ADDR = 0x422,
|
||||
MSR_MC8_MISC = 0x423,
|
||||
MSR_MC9_CTL = 0x424,
|
||||
MSR_MC9_STATUS = 0x425,
|
||||
MSR_MC9_ADDR = 0x426,
|
||||
MSR_MC9_MISC = 0x427,
|
||||
MSR_MC10_CTL = 0x428,
|
||||
MSR_MC10_STATUS = 0x429,
|
||||
MSR_MC10_ADDR = 0x42A,
|
||||
MSR_MC10_MISC = 0x42B,
|
||||
MSR_MC11_CTL = 0x42C,
|
||||
MSR_MC11_STATUS = 0x42D,
|
||||
MSR_MC11_ADDR = 0x42E,
|
||||
MSR_MC11_MISC = 0x42F,
|
||||
MSR_MC12_CTL = 0x430,
|
||||
MSR_MC12_STATUS = 0x431,
|
||||
MSR_MC12_ADDR = 0x432,
|
||||
MSR_MC12_MISC = 0x433,
|
||||
MSR_MC13_CTL = 0x434,
|
||||
MSR_MC13_STATUS = 0x435,
|
||||
MSR_MC13_ADDR = 0x436,
|
||||
MSR_MC13_MISC = 0x437,
|
||||
MSR_MC14_CTL = 0x438,
|
||||
MSR_MC14_STATUS = 0x439,
|
||||
MSR_MC14_ADDR = 0x43A,
|
||||
MSR_MC14_MISC = 0x43B,
|
||||
MSR_MC15_CTL = 0x43C,
|
||||
MSR_MC15_STATUS = 0x43D,
|
||||
MSR_MC15_ADDR = 0x43E,
|
||||
MSR_MC15_MISC = 0x43F,
|
||||
MSR_MC16_CTL = 0x440,
|
||||
MSR_MC16_STATUS = 0x441,
|
||||
MSR_MC16_ADDR = 0x442,
|
||||
MSR_MC16_MISC = 0x443,
|
||||
MSR_MC17_CTL = 0x444,
|
||||
MSR_MC17_STATUS = 0x445,
|
||||
MSR_MC17_ADDR = 0x446,
|
||||
MSR_MC17_MISC = 0x447,
|
||||
MSR_MC18_CTL = 0x448,
|
||||
MSR_MC18_STATUS = 0x449,
|
||||
MSR_MC18_ADDR = 0x44A,
|
||||
MSR_MC18_MISC = 0x44B,
|
||||
MSR_MC19_CTL = 0x44C,
|
||||
MSR_MC19_STATUS = 0x44D,
|
||||
MSR_MC19_ADDR = 0x44E,
|
||||
MSR_MC19_MISC = 0x44F,
|
||||
MSR_MC20_CTL = 0x450,
|
||||
MSR_MC20_STATUS = 0x451,
|
||||
MSR_MC20_ADDR = 0x452,
|
||||
MSR_MC20_MISC = 0x453,
|
||||
MSR_MC21_CTL = 0x454,
|
||||
MSR_MC21_STATUS = 0x455,
|
||||
MSR_MC21_ADDR = 0x456,
|
||||
MSR_MC21_MISC = 0x457,
|
||||
MSR_MC22_CTL = 0x458,
|
||||
MSR_MC22_STATUS = 0x459,
|
||||
MSR_MC22_ADDR = 0x45A,
|
||||
MSR_MC22_MISC = 0x45B,
|
||||
MSR_MC23_CTL = 0x45C,
|
||||
MSR_MC23_STATUS = 0x45D,
|
||||
MSR_MC23_ADDR = 0x45E,
|
||||
MSR_MC23_MISC = 0x45F,
|
||||
MSR_MC24_CTL = 0x460,
|
||||
MSR_MC24_STATUS = 0x461,
|
||||
MSR_MC24_ADDR = 0x462,
|
||||
MSR_MC24_MISC = 0x463,
|
||||
MSR_MC25_CTL = 0x464,
|
||||
MSR_MC25_STATUS = 0x465,
|
||||
MSR_MC25_ADDR = 0x466,
|
||||
MSR_MC25_MISC = 0x467,
|
||||
MSR_MC26_CTL = 0x468,
|
||||
MSR_MC26_STATUS = 0x469,
|
||||
MSR_MC26_ADDR = 0x46A,
|
||||
MSR_MC26_MISC = 0x46B,
|
||||
MSR_MC27_CTL = 0x46C,
|
||||
MSR_MC27_STATUS = 0x46D,
|
||||
MSR_MC27_ADDR = 0x46E,
|
||||
MSR_MC27_MISC = 0x46F,
|
||||
MSR_MC28_CTL = 0x470,
|
||||
MSR_MC28_STATUS = 0x471,
|
||||
MSR_MC28_ADDR = 0x472,
|
||||
MSR_MC28_MISC = 0x473,
|
||||
MSR_VMX_BASIC = 0x480,
|
||||
MSR_VMX_PINBASED_CTLS = 0x481,
|
||||
MSR_VMX_PROCBASED_CTLS = 0x482,
|
||||
MSR_VMX_EXIT_CTLS = 0x483,
|
||||
MSR_VMX_ENTRY_CTLS = 0x484,
|
||||
MSR_VMX_MISC = 0x485,
|
||||
MSR_VMX_CR0_FIXED0 = 0x486,
|
||||
MSR_VMX_CR0_FIXED1 = 0x487,
|
||||
MSR_VMX_CR4_FIXED0 = 0x488,
|
||||
MSR_VMX_CR4_FIXED1 = 0x489,
|
||||
MSR_VMX_VMCS_ENUM = 0x48A,
|
||||
MSR_VMX_PROCBASED_CTLS2 = 0x48B,
|
||||
MSR_VMX_EPT_VPID_CAP = 0x48C,
|
||||
MSR_VMX_TRUE_PINBASED_CTLS = 0x48D,
|
||||
MSR_VMX_TRUE_PROCBASED_CTLS = 0x48E,
|
||||
MSR_VMX_TRUE_EXIT_CTLS = 0x48F,
|
||||
MSR_VMX_TRUE_ENTRY_CTLS = 0x490,
|
||||
MSR_VMX_VMFUNC = 0x491,
|
||||
MSR_A_PMC0 = 0x4C1,
|
||||
MSR_A_PMC1 = 0x4C2,
|
||||
MSR_A_PMC2 = 0x4C3,
|
||||
MSR_A_PMC3 = 0x4C4,
|
||||
MSR_A_PMC4 = 0x4C5,
|
||||
MSR_A_PMC5 = 0x4C6,
|
||||
MSR_A_PMC6 = 0x4C7,
|
||||
MSR_A_PMC7 = 0x4C8,
|
||||
MSR_MCG_EXT_CTL = 0x4D0,
|
||||
MSR_SGX_SVN_STATUS = 0x500,
|
||||
MSR_RTIT_OUTPUT_BASE = 0x560,
|
||||
MSR_RTIT_OUTPUT_MASK_PTRS = 0x561,
|
||||
MSR_RTIT_CTL = 0x570,
|
||||
MSR_RTIT_STATUS = 0x571,
|
||||
MSR_RTIT_CR3_MATCH = 0x572,
|
||||
MSR_RTIT_ADDR0_A = 0x580,
|
||||
MSR_RTIT_ADDR0_B = 0x581,
|
||||
MSR_RTIT_ADDR1_A = 0x582,
|
||||
MSR_RTIT_ADDR1_B = 0x583,
|
||||
MSR_RTIT_ADDR2_A = 0x584,
|
||||
MSR_RTIT_ADDR2_B = 0x585,
|
||||
MSR_RTIT_ADDR3_A = 0x586,
|
||||
MSR_RTIT_ADDR3_B = 0x587,
|
||||
MSR_DS_AREA = 0x600,
|
||||
MSR_TSC_DEADLINE = 0x6E0,
|
||||
MSR_PM_ENABLE = 0x770,
|
||||
MSR_HWP_CAPABILITIES = 0x771,
|
||||
MSR_HWP_REQUEST_PKG = 0x772,
|
||||
MSR_HWP_INTERRUPT = 0x773,
|
||||
MSR_HWP_REQUEST = 0x774,
|
||||
MSR_HWP_STATUS = 0x777,
|
||||
MSR_X2APIC_APICID = 0x802,
|
||||
MSR_X2APIC_VERSION = 0x803,
|
||||
MSR_X2APIC_TPR = 0x808,
|
||||
MSR_X2APIC_PPR = 0x80A,
|
||||
MSR_X2APIC_EOI = 0x80B,
|
||||
MSR_X2APIC_LDR = 0x80D,
|
||||
MSR_X2APIC_SIVR = 0x80F,
|
||||
MSR_X2APIC_ISR0 = 0x810,
|
||||
MSR_X2APIC_ISR1 = 0x811,
|
||||
MSR_X2APIC_ISR2 = 0x812,
|
||||
MSR_X2APIC_ISR3 = 0x813,
|
||||
MSR_X2APIC_ISR4 = 0x814,
|
||||
MSR_X2APIC_ISR5 = 0x815,
|
||||
MSR_X2APIC_ISR6 = 0x816,
|
||||
MSR_X2APIC_ISR7 = 0x817,
|
||||
MSR_X2APIC_TMR0 = 0x818,
|
||||
MSR_X2APIC_TMR1 = 0x819,
|
||||
MSR_X2APIC_TMR2 = 0x81A,
|
||||
MSR_X2APIC_TMR3 = 0x81B,
|
||||
MSR_X2APIC_TMR4 = 0x81C,
|
||||
MSR_X2APIC_TMR5 = 0x81D,
|
||||
MSR_X2APIC_TMR6 = 0x81E,
|
||||
MSR_X2APIC_TMR7 = 0x81F,
|
||||
MSR_X2APIC_IRR0 = 0x820,
|
||||
MSR_X2APIC_IRR1 = 0x821,
|
||||
MSR_X2APIC_IRR2 = 0x822,
|
||||
MSR_X2APIC_IRR3 = 0x823,
|
||||
MSR_X2APIC_IRR4 = 0x824,
|
||||
MSR_X2APIC_IRR5 = 0x825,
|
||||
MSR_X2APIC_IRR6 = 0x826,
|
||||
MSR_X2APIC_IRR7 = 0x827,
|
||||
MSR_X2APIC_ESR = 0x828,
|
||||
MSR_X2APIC_LVT_CMCI = 0x82F,
|
||||
MSR_X2APIC_ICR = 0x830,
|
||||
MSR_X2APIC_LVT_TIMER = 0x832,
|
||||
MSR_X2APIC_LVT_THERMAL = 0x833,
|
||||
MSR_X2APIC_LVT_PMI = 0x834,
|
||||
MSR_X2APIC_LVT_LINT0 = 0x835,
|
||||
MSR_X2APIC_LVT_LINT1 = 0x836,
|
||||
MSR_X2APIC_LVT_ERROR = 0x837,
|
||||
MSR_X2APIC_INIT_COUNT = 0x838,
|
||||
MSR_X2APIC_CUR_COUNT = 0x839,
|
||||
MSR_X2APIC_DIV_CONF = 0x83E,
|
||||
MSR_X2APIC_SELF_IPI = 0x83F,
|
||||
MSR_DEBUG_INTERFACE = 0xC80,
|
||||
MSR_L3_QOS_CFG = 0xC81,
|
||||
MSR_L2_QOS_CFG = 0xC82,
|
||||
MSR_QM_EVTSEL = 0xC8D,
|
||||
MSR_QM_CTR = 0xC8E,
|
||||
MSR_PQR_ASSOC = 0xC8F,
|
||||
MSR_L3_MASK_0 = 0xC90,
|
||||
MSR_L2_MASK_0 = 0xD10,
|
||||
MSR_BNDCFGS = 0xD90,
|
||||
MSR_XSS = 0xDA0,
|
||||
MSR_PKG_HDC_CTL = 0xDB0,
|
||||
MSR_PM_CTL1 = 0xDB1,
|
||||
MSR_THREAD_STALL = 0xDB2,
|
||||
/** @brief Extended Feature Enable Register (0xc0000080) */
|
||||
MSR_EFER = 0xC0000080,
|
||||
/** @brief legacy SYSCALL (0xC0000081) */
|
||||
MSR_STAR = 0xC0000081,
|
||||
/** @brief 64bit SYSCALL (0xC0000082) */
|
||||
MSR_LSTAR = 0xC0000082,
|
||||
/** @brief compatibility mode SYSCALL (0xC0000083) */
|
||||
MSR_CSTAR = 0xC0000083,
|
||||
/** @brief EFLAGS mask for syscall (0xC0000084) */
|
||||
MSR_SYSCALL_MASK = 0xC0000084,
|
||||
/** @brief 64bit FS base (0xC0000100) */
|
||||
MSR_FS_BASE = 0xC0000100,
|
||||
/** @brief 64bit GS base (0xC0000101) */
|
||||
MSR_GS_BASE = 0xC0000101,
|
||||
/** @brief SwapGS GS shadow (0xC0000102) */
|
||||
MSR_SHADOW_GS_BASE = 0xC0000102,
|
||||
/** @brief Auxiliary TSC (0xC0000103) */
|
||||
MSR_TSC_AUX = 0xC0000103,
|
||||
MSR_CR_PAT = 0x00000277,
|
||||
};
|
||||
|
||||
#if defined(a32)
|
||||
SafeFunction static inline uint64_t rdmsr(uint32_t msr)
|
||||
{
|
||||
uint32_t Low, High;
|
||||
asmv("rdmsr"
|
||||
: "=a"(Low), "=d"(High)
|
||||
: "c"(msr)
|
||||
: "memory");
|
||||
return ((uint64_t)Low) | (((uint64_t)High) << 32);
|
||||
}
|
||||
|
||||
SafeFunction static inline void wrmsr(uint32_t msr, uint64_t Value)
|
||||
{
|
||||
uint32_t Low = Value, High = Value >> 32;
|
||||
asmv("wrmsr"
|
||||
:
|
||||
: "c"(msr), "a"(Low), "d"(High)
|
||||
: "memory");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_CPU_x32_MSR_H__
|
294
Kernel/include/cpu/x86/x64/cr.hpp
Normal file
294
Kernel/include/cpu/x86/x64/cr.hpp
Normal file
@ -0,0 +1,294 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_CPU_x64_CR_H__
|
||||
#define __FENNIX_KERNEL_CPU_x64_CR_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
namespace CPU
|
||||
{
|
||||
namespace x64
|
||||
{
|
||||
typedef union CR0
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Protection Enable */
|
||||
uint64_t PE : 1;
|
||||
/** @brief Monitor Coprocessor */
|
||||
uint64_t MP : 1;
|
||||
/** @brief Emulation */
|
||||
uint64_t EM : 1;
|
||||
/** @brief Task Switched */
|
||||
uint64_t TS : 1;
|
||||
/** @brief Extension Type */
|
||||
uint64_t ET : 1;
|
||||
/** @brief Numeric Error */
|
||||
uint64_t NE : 1;
|
||||
/** @brief Reserved */
|
||||
uint64_t Reserved0 : 10;
|
||||
/** @brief Write Protect */
|
||||
uint64_t WP : 1;
|
||||
/** @brief Reserved */
|
||||
uint64_t Reserved1 : 1;
|
||||
/** @brief Alignment Mask */
|
||||
uint64_t AM : 1;
|
||||
/** @brief Reserved */
|
||||
uint64_t Reserved2 : 10;
|
||||
/** @brief Not Write-through */
|
||||
uint64_t NW : 1;
|
||||
/** @brief Cache Disable */
|
||||
uint64_t CD : 1;
|
||||
/** @brief Paging */
|
||||
uint64_t PG : 1;
|
||||
};
|
||||
uint64_t raw;
|
||||
} CR0;
|
||||
|
||||
typedef union CR2
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Page Fault Linear Address */
|
||||
uint64_t PFLA;
|
||||
};
|
||||
uint64_t raw;
|
||||
} CR2;
|
||||
|
||||
typedef union CR3
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Not used if bit 17 of CR4 is 1 */
|
||||
uint64_t PWT : 1;
|
||||
/** @brief Not used if bit 17 of CR4 is 1 */
|
||||
uint64_t PCD : 1;
|
||||
/** @brief Base of PML4T/PML5T */
|
||||
uint64_t PDBR;
|
||||
};
|
||||
uint64_t raw;
|
||||
} CR3;
|
||||
|
||||
typedef union CR4
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Virtual-8086 Mode Extensions */
|
||||
uint64_t VME : 1;
|
||||
/** @brief Protected-Mode Virtual Interrupts */
|
||||
uint64_t PVI : 1;
|
||||
/** @brief Time Stamp Disable */
|
||||
uint64_t TSD : 1;
|
||||
/** @brief Debugging Extensions */
|
||||
uint64_t DE : 1;
|
||||
/** @brief Page Size Extensions */
|
||||
uint64_t PSE : 1;
|
||||
/** @brief Physical Address Extension */
|
||||
uint64_t PAE : 1;
|
||||
/** @brief Machine Check Enable */
|
||||
uint64_t MCE : 1;
|
||||
/** @brief Page Global Enable */
|
||||
uint64_t PGE : 1;
|
||||
/** @brief Performance Monitoring Counter */
|
||||
uint64_t PCE : 1;
|
||||
/** @brief Operating System Support */
|
||||
uint64_t OSFXSR : 1;
|
||||
/** @brief Operating System Support */
|
||||
uint64_t OSXMMEXCPT : 1;
|
||||
/** @brief User-Mode Instruction Prevention */
|
||||
uint64_t UMIP : 1;
|
||||
/** @brief Linear Address 57bit */
|
||||
uint64_t LA57 : 1;
|
||||
/** @brief VMX Enable */
|
||||
uint64_t VMXE : 1;
|
||||
/** @brief SMX Enable */
|
||||
uint64_t SMXE : 1;
|
||||
/** @brief Reserved */
|
||||
uint64_t Reserved0 : 1;
|
||||
/** @brief FSGSBASE Enable */
|
||||
uint64_t FSGSBASE : 1;
|
||||
/** @brief PCID Enable */
|
||||
uint64_t PCIDE : 1;
|
||||
/** @brief XSAVE and Processor Extended States Enable */
|
||||
uint64_t OSXSAVE : 1;
|
||||
/** @brief Reserved */
|
||||
uint64_t Reserved1 : 1;
|
||||
/** @brief SMEP Enable */
|
||||
uint64_t SMEP : 1;
|
||||
/** @brief SMAP Enable */
|
||||
uint64_t SMAP : 1;
|
||||
/** @brief Protection-Key Enable */
|
||||
uint64_t PKE : 1;
|
||||
/** @brief Control-flow Enforcement Technology*/
|
||||
uint32_t CET : 1;
|
||||
/* @brief Enable Protection Keys for Supervisor Mode Pages */
|
||||
uint32_t PKS : 1;
|
||||
/** @brief Reserved */
|
||||
uint64_t Reserved2 : 7; // TODO: This could be wrong
|
||||
};
|
||||
uint64_t raw;
|
||||
} CR4;
|
||||
|
||||
typedef union CR8
|
||||
{
|
||||
struct
|
||||
{
|
||||
/** @brief Task Priority Level */
|
||||
uint64_t TPL : 1;
|
||||
};
|
||||
uint64_t raw;
|
||||
} CR8;
|
||||
|
||||
typedef union XCR0
|
||||
{
|
||||
/*
|
||||
On https://wiki.osdev.org/CPU_Registers_x86#XCR0 says that the PKRU bit is 9?
|
||||
*/
|
||||
struct
|
||||
{
|
||||
/** @brief X87 FPU/MMX/SSE Support (must be 1) */
|
||||
uint64_t X87 : 1;
|
||||
/** @brief XSAVE support for MXCSR and XMM registers */
|
||||
uint64_t SSE : 1;
|
||||
/** @brief AVX support for YMM registers */
|
||||
uint64_t AVX : 1;
|
||||
/** @brief MPX support for BND registers */
|
||||
uint64_t BNDREG : 1;
|
||||
/** @brief MPX support for BNDCFGU and BNDSTATUS registers */
|
||||
uint64_t BNDCSR : 1;
|
||||
/** @brief AVX-512 support for opmask registers */
|
||||
uint64_t OpMask : 1;
|
||||
/** @brief AVX-512 enabled and XSAVE support for upper halves of lower ZMM registers */
|
||||
uint64_t ZMM_HI256 : 1;
|
||||
/** @brief AVX-512 enabled and XSAVE support for upper ZMM registers */
|
||||
uint64_t HI16_ZMM : 1;
|
||||
/** @brief XSAVE support for PKRU register */
|
||||
uint64_t PKRU : 1;
|
||||
/** @brief Reserved */
|
||||
uint64_t Reserved0 : 53;
|
||||
/** @brief AMD lightweight profiling */
|
||||
uint64_t LWP : 1;
|
||||
/** @brief Reserved */
|
||||
uint64_t Reserved1 : 1;
|
||||
};
|
||||
uint64_t raw;
|
||||
} XCR0;
|
||||
|
||||
#if defined(a64)
|
||||
SafeFunction static inline CR0 readcr0()
|
||||
{
|
||||
uint64_t Result = 0;
|
||||
asmv("mov %%cr0, %[Result]"
|
||||
: [Result] "=q"(Result));
|
||||
return (CR0){.raw = Result};
|
||||
}
|
||||
|
||||
SafeFunction static inline CR2 readcr2()
|
||||
{
|
||||
uint64_t Result = 0;
|
||||
asmv("mov %%cr2, %[Result]"
|
||||
: [Result] "=q"(Result));
|
||||
return (CR2){.raw = Result};
|
||||
}
|
||||
|
||||
SafeFunction static inline CR3 readcr3()
|
||||
{
|
||||
uint64_t Result = 0;
|
||||
asmv("mov %%cr3, %[Result]"
|
||||
: [Result] "=q"(Result));
|
||||
return (CR3){.raw = Result};
|
||||
}
|
||||
|
||||
SafeFunction static inline CR4 readcr4()
|
||||
{
|
||||
uint64_t Result = 0;
|
||||
asmv("mov %%cr4, %[Result]"
|
||||
: [Result] "=q"(Result));
|
||||
return (CR4){.raw = Result};
|
||||
}
|
||||
|
||||
SafeFunction static inline CR8 readcr8()
|
||||
{
|
||||
uint64_t Result = 0;
|
||||
asmv("mov %%cr8, %[Result]"
|
||||
: [Result] "=q"(Result));
|
||||
return (CR8){.raw = Result};
|
||||
}
|
||||
|
||||
SafeFunction static inline XCR0 readxcr0()
|
||||
{
|
||||
uint64_t Result = 0;
|
||||
asmv("xgetbv"
|
||||
: "=a"(Result)
|
||||
: "c"(0)
|
||||
: "edx");
|
||||
return (XCR0){.raw = Result};
|
||||
}
|
||||
|
||||
SafeFunction static inline void writecr0(CR0 ControlRegister)
|
||||
{
|
||||
asmv("mov %[ControlRegister], %%cr0"
|
||||
:
|
||||
: [ControlRegister] "q"(ControlRegister.raw)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
SafeFunction static inline void writecr2(CR2 ControlRegister)
|
||||
{
|
||||
asmv("mov %[ControlRegister], %%cr2"
|
||||
:
|
||||
: [ControlRegister] "q"(ControlRegister.raw)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
SafeFunction static inline void writecr3(CR3 ControlRegister)
|
||||
{
|
||||
asmv("mov %[ControlRegister], %%cr3"
|
||||
:
|
||||
: [ControlRegister] "q"(ControlRegister.raw)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
SafeFunction static inline void writecr4(CR4 ControlRegister)
|
||||
{
|
||||
asmv("mov %[ControlRegister], %%cr4"
|
||||
:
|
||||
: [ControlRegister] "q"(ControlRegister.raw)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
SafeFunction static inline void writecr8(CR8 ControlRegister)
|
||||
{
|
||||
asmv("mov %[ControlRegister], %%cr8"
|
||||
:
|
||||
: [ControlRegister] "q"(ControlRegister.raw)
|
||||
: "memory");
|
||||
}
|
||||
|
||||
SafeFunction static inline void writexcr0(XCR0 ControlRegister)
|
||||
{
|
||||
asmv("xsetbv"
|
||||
:
|
||||
: "a"(ControlRegister.raw), "c"(0)
|
||||
: "edx");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_CPU_x64_CR_H__
|
427
Kernel/include/cpu/x86/x64/msr.hpp
Normal file
427
Kernel/include/cpu/x86/x64/msr.hpp
Normal file
@ -0,0 +1,427 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_CPU_x64_MSR_H__
|
||||
#define __FENNIX_KERNEL_CPU_x64_MSR_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
namespace CPU
|
||||
{
|
||||
namespace x64
|
||||
{
|
||||
enum MSRID
|
||||
{
|
||||
MSR_MONITOR_FILTER_SIZE = 0x6,
|
||||
MSR_TIME_STAMP_COUNTER = 0x10,
|
||||
MSR_PLATFORM_ID = 0x17,
|
||||
MSR_APIC_BASE = 0x1B,
|
||||
MSR_FEATURE_CONTROL = 0x3A,
|
||||
MSR_TSC_ADJUST = 0x3B,
|
||||
MSR_SPEC_CTRL = 0x48,
|
||||
MSR_PRED_CMD = 0x49,
|
||||
MSR_BIOS_UPDT_TRIG = 0x79,
|
||||
MSR_BIOS_SIGN_ID = 0x8B,
|
||||
MSR_SGXLEPUBKEYHASH0 = 0x8C,
|
||||
MSR_SGXLEPUBKEYHASH1 = 0x8D,
|
||||
MSR_SGXLEPUBKEYHASH2 = 0x8E,
|
||||
MSR_SGXLEPUBKEYHASH3 = 0x8F,
|
||||
MSR_SMM_MONITOR_CTL = 0x9B,
|
||||
MSR_SMBASE = 0x9E,
|
||||
MSR_PMC0 = 0xC1,
|
||||
MSR_PMC1 = 0xC2,
|
||||
MSR_PMC2 = 0xC3,
|
||||
MSR_PMC3 = 0xC4,
|
||||
MSR_PMC4 = 0xC5,
|
||||
MSR_PMC5 = 0xC6,
|
||||
MSR_PMC6 = 0xC7,
|
||||
MSR_PMC7 = 0xC8,
|
||||
MSR_UMWAIT_CONTROL = 0xE1,
|
||||
MSR_MPERF = 0xE7,
|
||||
MSR_APERF = 0xE8,
|
||||
MSR_MTRRCAP = 0xFE,
|
||||
MSR_ARCH_CAPABILITIES = 0x10A,
|
||||
MSR_FLUSH_CMD = 0x10B,
|
||||
MSR_SYSENTER_CS = 0x17A,
|
||||
MSR_SYSENTER_ESP = 0x175,
|
||||
MSR_SYSENTER_EIP = 0x176,
|
||||
MSR_MCG_CAP = 0x179,
|
||||
MSR_MCG_STATUS = 0x17A,
|
||||
MSR_MCG_CTL = 0x17B,
|
||||
MSR_PERFEVTSEL0 = 0x186,
|
||||
MSR_PERFEVTSEL1 = 0x187,
|
||||
MSR_PERFEVTSEL2 = 0x188,
|
||||
MSR_PERFEVTSEL3 = 0x189,
|
||||
MSR_PERF_STATUS = 0x198,
|
||||
MSR_PERF_CTL = 0x199,
|
||||
MSR_CLOCK_MODULATION = 0x19A,
|
||||
MSR_THERM_INTERRUPT = 0x19B,
|
||||
MSR_THERM_STATUS = 0x19C,
|
||||
MSR_MISC_ENABLE = 0x1A0,
|
||||
MSR_ENERGY_PERF_BIAS = 0x1B0,
|
||||
MSR_PACKAGE_THERM_STATUS = 0x1B1,
|
||||
MSR_PACKAGE_THERM_INTERRUPT = 0x1B2,
|
||||
MSR_DEBUGCTL = 0x1D9,
|
||||
MSR_SMRR_PHYSBASE = 0x1F2,
|
||||
MSR_SMRR_PHYSMASK = 0x1F3,
|
||||
MSR_PLATFORM_DCA_CAP = 0x1F8,
|
||||
MSR_CPU_DCA_CAP = 0x1F9,
|
||||
MSR_DCA_0_CAP = 0x1FA,
|
||||
MSR_MTRR_PHYSBASE0 = 0x200,
|
||||
MSR_MTRR_PHYSMASK0 = 0x201,
|
||||
MSR_MTRR_PHYSBASE1 = 0x202,
|
||||
MSR_MTRR_PHYSMASK1 = 0x203,
|
||||
MSR_MTRR_PHYSBASE2 = 0x204,
|
||||
MSR_MTRR_PHYSMASK2 = 0x205,
|
||||
MSR_MTRR_PHYSBASE3 = 0x206,
|
||||
MSR_MTRR_PHYSMASK3 = 0x207,
|
||||
MSR_MTRR_PHYSBASE4 = 0x208,
|
||||
MSR_MTRR_PHYSMASK4 = 0x209,
|
||||
MSR_MTRR_PHYSBASE5 = 0x20A,
|
||||
MSR_MTRR_PHYSMASK5 = 0x20B,
|
||||
MSR_MTRR_PHYSBASE6 = 0x20C,
|
||||
MSR_MTRR_PHYSMASK6 = 0x20D,
|
||||
MSR_MTRR_PHYSBASE7 = 0x20E,
|
||||
MSR_MTRR_PHYSMASK7 = 0x20F,
|
||||
MSR_MTRR_PHYSBASE8 = 0x210,
|
||||
MSR_MTRR_PHYSMASK8 = 0x211,
|
||||
MSR_MTRR_PHYSBASE9 = 0x212,
|
||||
MSR_MTRR_PHYSMASK9 = 0x213,
|
||||
MSR_MTRR_FIX64K_00000 = 0x250,
|
||||
MSR_MTRR_FIX16K_80000 = 0x258,
|
||||
MSR_MTRR_FIX16K_A0000 = 0x259,
|
||||
MSR_MTRR_FIX4K_C0000 = 0x268,
|
||||
MSR_MTRR_FIX4K_C8000 = 0x269,
|
||||
MSR_MTRR_FIX4K_D0000 = 0x26A,
|
||||
MSR_MTRR_FIX4K_D8000 = 0x26B,
|
||||
MSR_MTRR_FIX4K_E0000 = 0x26C,
|
||||
MSR_MTRR_FIX4K_E8000 = 0x26D,
|
||||
MSR_MTRR_FIX4K_F0000 = 0x26E,
|
||||
MSR_MTRR_FIX4K_F8000 = 0x26F,
|
||||
MSR_PAT = 0x277,
|
||||
MSR_MC0_CTL2 = 0x280,
|
||||
MSR_MC1_CTL2 = 0x281,
|
||||
MSR_MC2_CTL2 = 0x282,
|
||||
MSR_MC3_CTL2 = 0x283,
|
||||
MSR_MC4_CTL2 = 0x284,
|
||||
MSR_MC5_CTL2 = 0x285,
|
||||
MSR_MC6_CTL2 = 0x286,
|
||||
MSR_MC7_CTL2 = 0x287,
|
||||
MSR_MC8_CTL2 = 0x288,
|
||||
MSR_MC9_CTL2 = 0x289,
|
||||
MSR_MC10_CTL2 = 0x28A,
|
||||
MSR_MC11_CTL2 = 0x28B,
|
||||
MSR_MC12_CTL2 = 0x28C,
|
||||
MSR_MC13_CTL2 = 0x28D,
|
||||
MSR_MC14_CTL2 = 0x28E,
|
||||
MSR_MC15_CTL2 = 0x28F,
|
||||
MSR_MC16_CTL2 = 0x290,
|
||||
MSR_MC17_CTL2 = 0x291,
|
||||
MSR_MC18_CTL2 = 0x292,
|
||||
MSR_MC19_CTL2 = 0x293,
|
||||
MSR_MC20_CTL2 = 0x294,
|
||||
MSR_MC21_CTL2 = 0x295,
|
||||
MSR_MC22_CTL2 = 0x296,
|
||||
MSR_MC23_CTL2 = 0x297,
|
||||
MSR_MC24_CTL2 = 0x298,
|
||||
MSR_MC25_CTL2 = 0x299,
|
||||
MSR_MC26_CTL2 = 0x29A,
|
||||
MSR_MC27_CTL2 = 0x29B,
|
||||
MSR_MC28_CTL2 = 0x29C,
|
||||
MSR_MC29_CTL2 = 0x29D,
|
||||
MSR_MC30_CTL2 = 0x29E,
|
||||
MSR_MC31_CTL2 = 0x29F,
|
||||
MSR_MTRR_DEF_TYPE = 0x2FF,
|
||||
MSR_FIXED_CTR0 = 0x309,
|
||||
MSR_FIXED_CTR1 = 0x30A,
|
||||
MSR_FIXED_CTR2 = 0x30B,
|
||||
MSR_PERF_CAPABILITIES = 0x345,
|
||||
MSR_FIXED_CTR_CTRL = 0x38D,
|
||||
MSR_PERF_GLOBAL_STATUS = 0x38E,
|
||||
MSR_PERF_GLOBAL_CTRL = 0x38F,
|
||||
MSR_PERF_GLOBAL_STATUS_RESET = 0x390,
|
||||
MSR_PERF_GLOBAL_STATUS_SET = 0x391,
|
||||
MSR_PERF_GLOBAL_INUSE = 0x392,
|
||||
MSR_PEBS_ENABLE = 0x3F1,
|
||||
MSR_MC0_CTL = 0x400,
|
||||
MSR_MC0_STATUS = 0x401,
|
||||
MSR_MC0_ADDR = 0x402,
|
||||
MSR_MC0_MISC = 0x403,
|
||||
MSR_MC1_CTL = 0x404,
|
||||
MSR_MC1_STATUS = 0x405,
|
||||
MSR_MC1_ADDR = 0x406,
|
||||
MSR_MC1_MISC = 0x407,
|
||||
MSR_MC2_CTL = 0x408,
|
||||
MSR_MC2_STATUS = 0x409,
|
||||
MSR_MC2_ADDR = 0x40A,
|
||||
MSR_MC2_MISC = 0x40B,
|
||||
MSR_MC3_CTL = 0x40C,
|
||||
MSR_MC3_STATUS = 0x40D,
|
||||
MSR_MC3_ADDR = 0x40E,
|
||||
MSR_MC3_MISC = 0x40F,
|
||||
MSR_MC4_CTL = 0x410,
|
||||
MSR_MC4_STATUS = 0x411,
|
||||
MSR_MC4_ADDR = 0x412,
|
||||
MSR_MC4_MISC = 0x413,
|
||||
MSR_MC5_CTL = 0x414,
|
||||
MSR_MC5_STATUS = 0x415,
|
||||
MSR_MC5_ADDR = 0x416,
|
||||
MSR_MC5_MISC = 0x417,
|
||||
MSR_MC6_CTL = 0x418,
|
||||
MSR_MC6_STATUS = 0x419,
|
||||
MSR_MC6_ADDR = 0x41A,
|
||||
MSR_MC6_MISC = 0x41B,
|
||||
MSR_MC7_CTL = 0x41C,
|
||||
MSR_MC7_STATUS = 0x41D,
|
||||
MSR_MC7_ADDR = 0x41E,
|
||||
MSR_MC7_MISC = 0x41F,
|
||||
MSR_MC8_CTL = 0x420,
|
||||
MSR_MC8_STATUS = 0x421,
|
||||
MSR_MC8_ADDR = 0x422,
|
||||
MSR_MC8_MISC = 0x423,
|
||||
MSR_MC9_CTL = 0x424,
|
||||
MSR_MC9_STATUS = 0x425,
|
||||
MSR_MC9_ADDR = 0x426,
|
||||
MSR_MC9_MISC = 0x427,
|
||||
MSR_MC10_CTL = 0x428,
|
||||
MSR_MC10_STATUS = 0x429,
|
||||
MSR_MC10_ADDR = 0x42A,
|
||||
MSR_MC10_MISC = 0x42B,
|
||||
MSR_MC11_CTL = 0x42C,
|
||||
MSR_MC11_STATUS = 0x42D,
|
||||
MSR_MC11_ADDR = 0x42E,
|
||||
MSR_MC11_MISC = 0x42F,
|
||||
MSR_MC12_CTL = 0x430,
|
||||
MSR_MC12_STATUS = 0x431,
|
||||
MSR_MC12_ADDR = 0x432,
|
||||
MSR_MC12_MISC = 0x433,
|
||||
MSR_MC13_CTL = 0x434,
|
||||
MSR_MC13_STATUS = 0x435,
|
||||
MSR_MC13_ADDR = 0x436,
|
||||
MSR_MC13_MISC = 0x437,
|
||||
MSR_MC14_CTL = 0x438,
|
||||
MSR_MC14_STATUS = 0x439,
|
||||
MSR_MC14_ADDR = 0x43A,
|
||||
MSR_MC14_MISC = 0x43B,
|
||||
MSR_MC15_CTL = 0x43C,
|
||||
MSR_MC15_STATUS = 0x43D,
|
||||
MSR_MC15_ADDR = 0x43E,
|
||||
MSR_MC15_MISC = 0x43F,
|
||||
MSR_MC16_CTL = 0x440,
|
||||
MSR_MC16_STATUS = 0x441,
|
||||
MSR_MC16_ADDR = 0x442,
|
||||
MSR_MC16_MISC = 0x443,
|
||||
MSR_MC17_CTL = 0x444,
|
||||
MSR_MC17_STATUS = 0x445,
|
||||
MSR_MC17_ADDR = 0x446,
|
||||
MSR_MC17_MISC = 0x447,
|
||||
MSR_MC18_CTL = 0x448,
|
||||
MSR_MC18_STATUS = 0x449,
|
||||
MSR_MC18_ADDR = 0x44A,
|
||||
MSR_MC18_MISC = 0x44B,
|
||||
MSR_MC19_CTL = 0x44C,
|
||||
MSR_MC19_STATUS = 0x44D,
|
||||
MSR_MC19_ADDR = 0x44E,
|
||||
MSR_MC19_MISC = 0x44F,
|
||||
MSR_MC20_CTL = 0x450,
|
||||
MSR_MC20_STATUS = 0x451,
|
||||
MSR_MC20_ADDR = 0x452,
|
||||
MSR_MC20_MISC = 0x453,
|
||||
MSR_MC21_CTL = 0x454,
|
||||
MSR_MC21_STATUS = 0x455,
|
||||
MSR_MC21_ADDR = 0x456,
|
||||
MSR_MC21_MISC = 0x457,
|
||||
MSR_MC22_CTL = 0x458,
|
||||
MSR_MC22_STATUS = 0x459,
|
||||
MSR_MC22_ADDR = 0x45A,
|
||||
MSR_MC22_MISC = 0x45B,
|
||||
MSR_MC23_CTL = 0x45C,
|
||||
MSR_MC23_STATUS = 0x45D,
|
||||
MSR_MC23_ADDR = 0x45E,
|
||||
MSR_MC23_MISC = 0x45F,
|
||||
MSR_MC24_CTL = 0x460,
|
||||
MSR_MC24_STATUS = 0x461,
|
||||
MSR_MC24_ADDR = 0x462,
|
||||
MSR_MC24_MISC = 0x463,
|
||||
MSR_MC25_CTL = 0x464,
|
||||
MSR_MC25_STATUS = 0x465,
|
||||
MSR_MC25_ADDR = 0x466,
|
||||
MSR_MC25_MISC = 0x467,
|
||||
MSR_MC26_CTL = 0x468,
|
||||
MSR_MC26_STATUS = 0x469,
|
||||
MSR_MC26_ADDR = 0x46A,
|
||||
MSR_MC26_MISC = 0x46B,
|
||||
MSR_MC27_CTL = 0x46C,
|
||||
MSR_MC27_STATUS = 0x46D,
|
||||
MSR_MC27_ADDR = 0x46E,
|
||||
MSR_MC27_MISC = 0x46F,
|
||||
MSR_MC28_CTL = 0x470,
|
||||
MSR_MC28_STATUS = 0x471,
|
||||
MSR_MC28_ADDR = 0x472,
|
||||
MSR_MC28_MISC = 0x473,
|
||||
MSR_VMX_BASIC = 0x480,
|
||||
MSR_VMX_PINBASED_CTLS = 0x481,
|
||||
MSR_VMX_PROCBASED_CTLS = 0x482,
|
||||
MSR_VMX_EXIT_CTLS = 0x483,
|
||||
MSR_VMX_ENTRY_CTLS = 0x484,
|
||||
MSR_VMX_MISC = 0x485,
|
||||
MSR_VMX_CR0_FIXED0 = 0x486,
|
||||
MSR_VMX_CR0_FIXED1 = 0x487,
|
||||
MSR_VMX_CR4_FIXED0 = 0x488,
|
||||
MSR_VMX_CR4_FIXED1 = 0x489,
|
||||
MSR_VMX_VMCS_ENUM = 0x48A,
|
||||
MSR_VMX_PROCBASED_CTLS2 = 0x48B,
|
||||
MSR_VMX_EPT_VPID_CAP = 0x48C,
|
||||
MSR_VMX_TRUE_PINBASED_CTLS = 0x48D,
|
||||
MSR_VMX_TRUE_PROCBASED_CTLS = 0x48E,
|
||||
MSR_VMX_TRUE_EXIT_CTLS = 0x48F,
|
||||
MSR_VMX_TRUE_ENTRY_CTLS = 0x490,
|
||||
MSR_VMX_VMFUNC = 0x491,
|
||||
MSR_A_PMC0 = 0x4C1,
|
||||
MSR_A_PMC1 = 0x4C2,
|
||||
MSR_A_PMC2 = 0x4C3,
|
||||
MSR_A_PMC3 = 0x4C4,
|
||||
MSR_A_PMC4 = 0x4C5,
|
||||
MSR_A_PMC5 = 0x4C6,
|
||||
MSR_A_PMC6 = 0x4C7,
|
||||
MSR_A_PMC7 = 0x4C8,
|
||||
MSR_MCG_EXT_CTL = 0x4D0,
|
||||
MSR_SGX_SVN_STATUS = 0x500,
|
||||
MSR_RTIT_OUTPUT_BASE = 0x560,
|
||||
MSR_RTIT_OUTPUT_MASK_PTRS = 0x561,
|
||||
MSR_RTIT_CTL = 0x570,
|
||||
MSR_RTIT_STATUS = 0x571,
|
||||
MSR_RTIT_CR3_MATCH = 0x572,
|
||||
MSR_RTIT_ADDR0_A = 0x580,
|
||||
MSR_RTIT_ADDR0_B = 0x581,
|
||||
MSR_RTIT_ADDR1_A = 0x582,
|
||||
MSR_RTIT_ADDR1_B = 0x583,
|
||||
MSR_RTIT_ADDR2_A = 0x584,
|
||||
MSR_RTIT_ADDR2_B = 0x585,
|
||||
MSR_RTIT_ADDR3_A = 0x586,
|
||||
MSR_RTIT_ADDR3_B = 0x587,
|
||||
MSR_DS_AREA = 0x600,
|
||||
MSR_TSC_DEADLINE = 0x6E0,
|
||||
MSR_PM_ENABLE = 0x770,
|
||||
MSR_HWP_CAPABILITIES = 0x771,
|
||||
MSR_HWP_REQUEST_PKG = 0x772,
|
||||
MSR_HWP_INTERRUPT = 0x773,
|
||||
MSR_HWP_REQUEST = 0x774,
|
||||
MSR_HWP_STATUS = 0x777,
|
||||
MSR_X2APIC_APICID = 0x802,
|
||||
MSR_X2APIC_VERSION = 0x803,
|
||||
MSR_X2APIC_TPR = 0x808,
|
||||
MSR_X2APIC_PPR = 0x80A,
|
||||
MSR_X2APIC_EOI = 0x80B,
|
||||
MSR_X2APIC_LDR = 0x80D,
|
||||
MSR_X2APIC_SIVR = 0x80F,
|
||||
MSR_X2APIC_ISR0 = 0x810,
|
||||
MSR_X2APIC_ISR1 = 0x811,
|
||||
MSR_X2APIC_ISR2 = 0x812,
|
||||
MSR_X2APIC_ISR3 = 0x813,
|
||||
MSR_X2APIC_ISR4 = 0x814,
|
||||
MSR_X2APIC_ISR5 = 0x815,
|
||||
MSR_X2APIC_ISR6 = 0x816,
|
||||
MSR_X2APIC_ISR7 = 0x817,
|
||||
MSR_X2APIC_TMR0 = 0x818,
|
||||
MSR_X2APIC_TMR1 = 0x819,
|
||||
MSR_X2APIC_TMR2 = 0x81A,
|
||||
MSR_X2APIC_TMR3 = 0x81B,
|
||||
MSR_X2APIC_TMR4 = 0x81C,
|
||||
MSR_X2APIC_TMR5 = 0x81D,
|
||||
MSR_X2APIC_TMR6 = 0x81E,
|
||||
MSR_X2APIC_TMR7 = 0x81F,
|
||||
MSR_X2APIC_IRR0 = 0x820,
|
||||
MSR_X2APIC_IRR1 = 0x821,
|
||||
MSR_X2APIC_IRR2 = 0x822,
|
||||
MSR_X2APIC_IRR3 = 0x823,
|
||||
MSR_X2APIC_IRR4 = 0x824,
|
||||
MSR_X2APIC_IRR5 = 0x825,
|
||||
MSR_X2APIC_IRR6 = 0x826,
|
||||
MSR_X2APIC_IRR7 = 0x827,
|
||||
MSR_X2APIC_ESR = 0x828,
|
||||
MSR_X2APIC_LVT_CMCI = 0x82F,
|
||||
MSR_X2APIC_ICR = 0x830,
|
||||
MSR_X2APIC_LVT_TIMER = 0x832,
|
||||
MSR_X2APIC_LVT_THERMAL = 0x833,
|
||||
MSR_X2APIC_LVT_PMI = 0x834,
|
||||
MSR_X2APIC_LVT_LINT0 = 0x835,
|
||||
MSR_X2APIC_LVT_LINT1 = 0x836,
|
||||
MSR_X2APIC_LVT_ERROR = 0x837,
|
||||
MSR_X2APIC_INIT_COUNT = 0x838,
|
||||
MSR_X2APIC_CUR_COUNT = 0x839,
|
||||
MSR_X2APIC_DIV_CONF = 0x83E,
|
||||
MSR_X2APIC_SELF_IPI = 0x83F,
|
||||
MSR_DEBUG_INTERFACE = 0xC80,
|
||||
MSR_L3_QOS_CFG = 0xC81,
|
||||
MSR_L2_QOS_CFG = 0xC82,
|
||||
MSR_QM_EVTSEL = 0xC8D,
|
||||
MSR_QM_CTR = 0xC8E,
|
||||
MSR_PQR_ASSOC = 0xC8F,
|
||||
MSR_L3_MASK_0 = 0xC90,
|
||||
MSR_L2_MASK_0 = 0xD10,
|
||||
MSR_BNDCFGS = 0xD90,
|
||||
MSR_XSS = 0xDA0,
|
||||
MSR_PKG_HDC_CTL = 0xDB0,
|
||||
MSR_PM_CTL1 = 0xDB1,
|
||||
MSR_THREAD_STALL = 0xDB2,
|
||||
/** @brief Extended Feature Enable Register (0xc0000080) */
|
||||
MSR_EFER = 0xC0000080,
|
||||
/** @brief legacy SYSCALL (0xC0000081) */
|
||||
MSR_STAR = 0xC0000081,
|
||||
/** @brief 64bit SYSCALL (0xC0000082) */
|
||||
MSR_LSTAR = 0xC0000082,
|
||||
/** @brief compatibility mode SYSCALL (0xC0000083) */
|
||||
MSR_CSTAR = 0xC0000083,
|
||||
/** @brief EFLAGS mask for syscall (0xC0000084) */
|
||||
MSR_SYSCALL_MASK = 0xC0000084,
|
||||
/** @brief 64bit FS base (0xC0000100) */
|
||||
MSR_FS_BASE = 0xC0000100,
|
||||
/** @brief 64bit GS base (0xC0000101) */
|
||||
MSR_GS_BASE = 0xC0000101,
|
||||
/** @brief SwapGS GS shadow (0xC0000102) */
|
||||
MSR_SHADOW_GS_BASE = 0xC0000102,
|
||||
/** @brief Auxiliary TSC (0xC0000103) */
|
||||
MSR_TSC_AUX = 0xC0000103,
|
||||
MSR_CR_PAT = 0x00000277,
|
||||
MSR_CR_PAT_RESET = 0x0007040600070406ULL
|
||||
};
|
||||
|
||||
#if defined(a64)
|
||||
SafeFunction static inline uint64_t rdmsr(uint32_t msr)
|
||||
{
|
||||
uint32_t Low, High;
|
||||
asmv("rdmsr"
|
||||
: "=a"(Low), "=d"(High)
|
||||
: "c"(msr)
|
||||
: "memory");
|
||||
return ((uint64_t)Low) | (((uint64_t)High) << 32);
|
||||
}
|
||||
|
||||
SafeFunction static inline void wrmsr(uint32_t msr, uint64_t Value)
|
||||
{
|
||||
uint32_t Low = s_cst(uint32_t, Value), High = s_cst(uint32_t, Value >> 32);
|
||||
asmv("wrmsr"
|
||||
:
|
||||
: "c"(msr), "a"(Low), "d"(High)
|
||||
: "memory");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_CPU_x64_MSR_H__
|
25
Kernel/include/crc32.h
Normal file
25
Kernel/include/crc32.h
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_CRC32_H__
|
||||
#define __FENNIX_KERNEL_CRC32_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
EXTERNC uint32_t crc32(const uint8_t *Buffer, int Length);
|
||||
|
||||
#endif // !__FENNIX_KERNEL_CRC32_H__
|
521
Kernel/include/cwalk.h
Normal file
521
Kernel/include/cwalk.h
Normal file
@ -0,0 +1,521 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 Leonard Iklé
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef CWK_LIBRARY_H
|
||||
#define CWK_LIBRARY_H
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
#define CWK_EXPORT __declspec(dllexport)
|
||||
#define CWK_IMPORT __declspec(dllimport)
|
||||
#elif __GNUC__ >= 4
|
||||
#define CWK_EXPORT __attribute__((visibility("default")))
|
||||
#define CWK_IMPORT __attribute__((visibility("default")))
|
||||
#else
|
||||
#define CWK_EXPORT
|
||||
#define CWK_IMPORT
|
||||
#endif
|
||||
|
||||
#if defined(CWK_SHARED)
|
||||
#if defined(CWK_EXPORTS)
|
||||
#define CWK_PUBLIC CWK_EXPORT
|
||||
#else
|
||||
#define CWK_PUBLIC CWK_IMPORT
|
||||
#endif
|
||||
#else
|
||||
#define CWK_PUBLIC
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A segment represents a single component of a path. For instance, on linux a
|
||||
* path might look like this "/var/log/", which consists of two segments "var"
|
||||
* and "log".
|
||||
*/
|
||||
struct cwk_segment
|
||||
{
|
||||
const char *path;
|
||||
const char *segments;
|
||||
const char *begin;
|
||||
const char *end;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
/**
|
||||
* The segment type can be used to identify whether a segment is a special
|
||||
* segment or not.
|
||||
*
|
||||
* CWK_NORMAL - normal folder or file segment
|
||||
* CWK_CURRENT - "./" current folder segment
|
||||
* CWK_BACK - "../" relative back navigation segment
|
||||
*/
|
||||
enum cwk_segment_type
|
||||
{
|
||||
CWK_NORMAL,
|
||||
CWK_CURRENT,
|
||||
CWK_BACK
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Determines the style which is used for the path parsing and
|
||||
* generation.
|
||||
*/
|
||||
enum cwk_path_style
|
||||
{
|
||||
CWK_STYLE_WINDOWS,
|
||||
CWK_STYLE_UNIX
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Generates an absolute path based on a base.
|
||||
*
|
||||
* This function generates an absolute path based on a base path and another
|
||||
* path. It is guaranteed to return an absolute path. If the second submitted
|
||||
* path is absolute, it will override the base path. The result will be
|
||||
* written to a buffer, which might be truncated if the buffer is not large
|
||||
* enough to hold the full path. However, the truncated result will always be
|
||||
* null-terminated. The returned value is the amount of characters which the
|
||||
* resulting path would take if it was not truncated (excluding the
|
||||
* null-terminating character).
|
||||
*
|
||||
* @param base The absolute base path on which the relative path will be
|
||||
* applied.
|
||||
* @param path The relative path which will be applied on the base path.
|
||||
* @param buffer The buffer where the result will be written to.
|
||||
* @param buffer_size The size of the result buffer.
|
||||
* @return Returns the total amount of characters of the new absolute path.
|
||||
*/
|
||||
CWK_PUBLIC size_t cwk_path_get_absolute(const char *base, const char *path,
|
||||
char *buffer, size_t buffer_size);
|
||||
|
||||
/**
|
||||
* @brief Generates a relative path based on a base.
|
||||
*
|
||||
* This function generates a relative path based on a base path and another
|
||||
* path. It determines how to get to the submitted path, starting from the
|
||||
* base directory. The result will be written to a buffer, which might be
|
||||
* truncated if the buffer is not large enough to hold the full path. However,
|
||||
* the truncated result will always be null-terminated. The returned value is
|
||||
* the amount of characters which the resulting path would take if it was not
|
||||
* truncated (excluding the null-terminating character).
|
||||
*
|
||||
* @param base_directory The base path from which the relative path will
|
||||
* start.
|
||||
* @param path The target path where the relative path will point to.
|
||||
* @param buffer The buffer where the result will be written to.
|
||||
* @param buffer_size The size of the result buffer.
|
||||
* @return Returns the total amount of characters of the full path.
|
||||
*/
|
||||
CWK_PUBLIC size_t cwk_path_get_relative(const char *base_directory,
|
||||
const char *path, char *buffer, size_t buffer_size);
|
||||
|
||||
/**
|
||||
* @brief Joins two paths together.
|
||||
*
|
||||
* This function generates a new path by combining the two submitted paths. It
|
||||
* will remove double separators, and unlike cwk_path_get_absolute it permits
|
||||
* the use of two relative paths to combine. The result will be written to a
|
||||
* buffer, which might be truncated if the buffer is not large enough to hold
|
||||
* the full path. However, the truncated result will always be
|
||||
* null-terminated. The returned value is the amount of characters which the
|
||||
* resulting path would take if it was not truncated (excluding the
|
||||
* null-terminating character).
|
||||
*
|
||||
* @param path_a The first path which comes first.
|
||||
* @param path_b The second path which comes after the first.
|
||||
* @param buffer The buffer where the result will be written to.
|
||||
* @param buffer_size The size of the result buffer.
|
||||
* @return Returns the total amount of characters of the full, combined path.
|
||||
*/
|
||||
CWK_PUBLIC size_t cwk_path_join(const char *path_a, const char *path_b,
|
||||
char *buffer, size_t buffer_size);
|
||||
|
||||
/**
|
||||
* @brief Joins multiple paths together.
|
||||
*
|
||||
* This function generates a new path by joining multiple paths together. It
|
||||
* will remove double separators, and unlike cwk_path_get_absolute it permits
|
||||
* the use of multiple relative paths to combine. The last path of the
|
||||
* submitted string array must be set to NULL. The result will be written to a
|
||||
* buffer, which might be truncated if the buffer is not large enough to hold
|
||||
* the full path. However, the truncated result will always be
|
||||
* null-terminated. The returned value is the amount of characters which the
|
||||
* resulting path would take if it was not truncated (excluding the
|
||||
* null-terminating character).
|
||||
*
|
||||
* @param paths An array of paths which will be joined.
|
||||
* @param buffer The buffer where the result will be written to.
|
||||
* @param buffer_size The size of the result buffer.
|
||||
* @return Returns the total amount of characters of the full, combined path.
|
||||
*/
|
||||
CWK_PUBLIC size_t cwk_path_join_multiple(const char **paths, char *buffer,
|
||||
size_t buffer_size);
|
||||
|
||||
/**
|
||||
* @brief Determines the root of a path.
|
||||
*
|
||||
* This function determines the root of a path by finding its length. The
|
||||
* root always starts at the submitted path. If the path has no root, the
|
||||
* length will be set to zero.
|
||||
*
|
||||
* @param path The path which will be inspected.
|
||||
* @param length The output of the root length.
|
||||
*/
|
||||
CWK_PUBLIC void cwk_path_get_root(const char *path, size_t *length);
|
||||
|
||||
/**
|
||||
* @brief Changes the root of a path.
|
||||
*
|
||||
* This function changes the root of a path. It does not normalize the result.
|
||||
* The result will be written to a buffer, which might be truncated if the
|
||||
* buffer is not large enough to hold the full path. However, the truncated
|
||||
* result will always be null-terminated. The returned value is the amount of
|
||||
* characters which the resulting path would take if it was not truncated
|
||||
* (excluding the null-terminating character).
|
||||
*
|
||||
* @param path The original path which will get a new root.
|
||||
* @param new_root The new root which will be placed in the path.
|
||||
* @param buffer The output buffer where the result is written to.
|
||||
* @param buffer_size The size of the output buffer where the result is
|
||||
* written to.
|
||||
* @return Returns the total amount of characters of the new path.
|
||||
*/
|
||||
CWK_PUBLIC size_t cwk_path_change_root(const char *path, const char *new_root,
|
||||
char *buffer, size_t buffer_size);
|
||||
|
||||
/**
|
||||
* @brief Determine whether the path is absolute or not.
|
||||
*
|
||||
* This function checks whether the path is an absolute path or not. A path is
|
||||
* considered to be absolute if the root ends with a separator.
|
||||
*
|
||||
* @param path The path which will be checked.
|
||||
* @return Returns true if the path is absolute or false otherwise.
|
||||
*/
|
||||
CWK_PUBLIC bool cwk_path_is_absolute(const char *path);
|
||||
|
||||
/**
|
||||
* @brief Determine whether the path is relative or not.
|
||||
*
|
||||
* This function checks whether the path is a relative path or not. A path is
|
||||
* considered to be relative if the root does not end with a separator.
|
||||
*
|
||||
* @param path The path which will be checked.
|
||||
* @return Returns true if the path is relative or false otherwise.
|
||||
*/
|
||||
CWK_PUBLIC bool cwk_path_is_relative(const char *path);
|
||||
|
||||
/**
|
||||
* @brief Gets the basename of a file path.
|
||||
*
|
||||
* This function gets the basename of a file path. A pointer to the beginning
|
||||
* of the basename will be returned through the basename parameter. This
|
||||
* pointer will be positioned on the first letter after the separator. The
|
||||
* length of the file path will be returned through the length parameter. The
|
||||
* length will be set to zero and the basename to NULL if there is no basename
|
||||
* available.
|
||||
*
|
||||
* @param path The path which will be inspected.
|
||||
* @param basename The output of the basename pointer.
|
||||
* @param length The output of the length of the basename. This may be
|
||||
* null if not required.
|
||||
*/
|
||||
CWK_PUBLIC void cwk_path_get_basename(const char *path, const char **basename,
|
||||
size_t *length);
|
||||
|
||||
/**
|
||||
* @brief Changes the basename of a file path.
|
||||
*
|
||||
* This function changes the basename of a file path. This function will not
|
||||
* write out more than the specified buffer can contain. However, the
|
||||
* generated string is always null-terminated - even if not the whole path is
|
||||
* written out. The function returns the total number of characters the
|
||||
* complete buffer would have, even if it was not written out completely. The
|
||||
* path may be the same memory address as the buffer.
|
||||
*
|
||||
* @param path The original path which will be used for the modified path.
|
||||
* @param new_basename The new basename which will replace the old one.
|
||||
* @param buffer The buffer where the changed path will be written to.
|
||||
* @param buffer_size The size of the result buffer where the changed path is
|
||||
* written to.
|
||||
* @return Returns the size which the complete new path would have if it was
|
||||
* not truncated.
|
||||
*/
|
||||
CWK_PUBLIC size_t cwk_path_change_basename(const char *path,
|
||||
const char *new_basename, char *buffer, size_t buffer_size);
|
||||
|
||||
/**
|
||||
* @brief Gets the dirname of a file path.
|
||||
*
|
||||
* This function determines the dirname of a file path and returns the length
|
||||
* up to which character is considered to be part of it. If no dirname is
|
||||
* found, the length will be set to zero. The beginning of the dirname is
|
||||
* always equal to the submitted path pointer.
|
||||
*
|
||||
* @param path The path which will be inspected.
|
||||
* @param length The length of the dirname.
|
||||
*/
|
||||
CWK_PUBLIC void cwk_path_get_dirname(const char *path, size_t *length);
|
||||
|
||||
/**
|
||||
* @brief Gets the extension of a file path.
|
||||
*
|
||||
* This function extracts the extension portion of a file path. A pointer to
|
||||
* the beginning of the extension will be returned through the extension
|
||||
* parameter if an extension is found and true is returned. This pointer will
|
||||
* be positioned on the dot. The length of the extension name will be returned
|
||||
* through the length parameter. If no extension is found both parameters
|
||||
* won't be touched and false will be returned.
|
||||
*
|
||||
* @param path The path which will be inspected.
|
||||
* @param extension The output of the extension pointer.
|
||||
* @param length The output of the length of the extension.
|
||||
* @return Returns true if an extension is found or false otherwise.
|
||||
*/
|
||||
CWK_PUBLIC bool cwk_path_get_extension(const char *path, const char **extension,
|
||||
size_t *length);
|
||||
|
||||
/**
|
||||
* @brief Determines whether the file path has an extension.
|
||||
*
|
||||
* This function determines whether the submitted file path has an extension.
|
||||
* This will evaluate to true if the last segment of the path contains a dot.
|
||||
*
|
||||
* @param path The path which will be inspected.
|
||||
* @return Returns true if the path has an extension or false otherwise.
|
||||
*/
|
||||
CWK_PUBLIC bool cwk_path_has_extension(const char *path);
|
||||
|
||||
/**
|
||||
* @brief Changes the extension of a file path.
|
||||
*
|
||||
* This function changes the extension of a file name. The function will
|
||||
* append an extension if the basename does not have an extension, or use the
|
||||
* extension as a basename if the path does not have a basename. This function
|
||||
* will not write out more than the specified buffer can contain. However, the
|
||||
* generated string is always null-terminated - even if not the whole path is
|
||||
* written out. The function returns the total number of characters the
|
||||
* complete buffer would have, even if it was not written out completely. The
|
||||
* path may be the same memory address as the buffer.
|
||||
*
|
||||
* @param path The path which will be used to make the change.
|
||||
* @param new_extension The extension which will be placed within the new
|
||||
* path.
|
||||
* @param buffer The output buffer where the result will be written to.
|
||||
* @param buffer_size The size of the output buffer where the result will be
|
||||
* written to.
|
||||
* @return Returns the total size which the output would have if it was not
|
||||
* truncated.
|
||||
*/
|
||||
CWK_PUBLIC size_t cwk_path_change_extension(const char *path,
|
||||
const char *new_extension, char *buffer, size_t buffer_size);
|
||||
|
||||
/**
|
||||
* @brief Creates a normalized version of the path.
|
||||
*
|
||||
* This function creates a normalized version of the path within the specified
|
||||
* buffer. This function will not write out more than the specified buffer can
|
||||
* contain. However, the generated string is always null-terminated - even if
|
||||
* not the whole path is written out. The function returns the total number of
|
||||
* characters the complete buffer would have, even if it was not written out
|
||||
* completely. The path may be the same memory address as the buffer.
|
||||
*
|
||||
* The following will be true for the normalized path:
|
||||
* 1) "../" will be resolved.
|
||||
* 2) "./" will be removed.
|
||||
* 3) double separators will be fixed with a single separator.
|
||||
* 4) separator suffixes will be removed.
|
||||
*
|
||||
* @param path The path which will be normalized.
|
||||
* @param buffer The buffer where the new path is written to.
|
||||
* @param buffer_size The size of the buffer.
|
||||
* @return The size which the complete normalized path has if it was not
|
||||
* truncated.
|
||||
*/
|
||||
CWK_PUBLIC size_t cwk_path_normalize(const char *path, char *buffer,
|
||||
size_t buffer_size);
|
||||
|
||||
/**
|
||||
* @brief Finds common portions in two paths.
|
||||
*
|
||||
* This function finds common portions in two paths and returns the number
|
||||
* characters from the beginning of the base path which are equal to the other
|
||||
* path.
|
||||
*
|
||||
* @param path_base The base path which will be compared with the other path.
|
||||
* @param path_other The other path which will compared with the base path.
|
||||
* @return Returns the number of characters which are common in the base path.
|
||||
*/
|
||||
CWK_PUBLIC size_t cwk_path_get_intersection(const char *path_base,
|
||||
const char *path_other);
|
||||
|
||||
/**
|
||||
* @brief Gets the first segment of a path.
|
||||
*
|
||||
* This function finds the first segment of a path. The position of the
|
||||
* segment is set to the first character after the separator, and the length
|
||||
* counts all characters until the next separator (excluding the separator).
|
||||
*
|
||||
* @param path The path which will be inspected.
|
||||
* @param segment The segment which will be extracted.
|
||||
* @return Returns true if there is a segment or false if there is none.
|
||||
*/
|
||||
CWK_PUBLIC bool cwk_path_get_first_segment(const char *path,
|
||||
struct cwk_segment *segment);
|
||||
|
||||
/**
|
||||
* @brief Gets the last segment of the path.
|
||||
*
|
||||
* This function gets the last segment of a path. This function may return
|
||||
* false if the path doesn't contain any segments, in which case the submitted
|
||||
* segment parameter is not modified. The position of the segment is set to
|
||||
* the first character after the separator, and the length counts all
|
||||
* characters until the end of the path (excluding the separator).
|
||||
*
|
||||
* @param path The path which will be inspected.
|
||||
* @param segment The segment which will be extracted.
|
||||
* @return Returns true if there is a segment or false if there is none.
|
||||
*/
|
||||
CWK_PUBLIC bool cwk_path_get_last_segment(const char *path,
|
||||
struct cwk_segment *segment);
|
||||
|
||||
/**
|
||||
* @brief Advances to the next segment.
|
||||
*
|
||||
* This function advances the current segment to the next segment. If there
|
||||
* are no more segments left, the submitted segment structure will stay
|
||||
* unchanged and false is returned.
|
||||
*
|
||||
* @param segment The current segment which will be advanced to the next one.
|
||||
* @return Returns true if another segment was found or false otherwise.
|
||||
*/
|
||||
CWK_PUBLIC bool cwk_path_get_next_segment(struct cwk_segment *segment);
|
||||
|
||||
/**
|
||||
* @brief Moves to the previous segment.
|
||||
*
|
||||
* This function moves the current segment to the previous segment. If the
|
||||
* current segment is the first one, the submitted segment structure will stay
|
||||
* unchanged and false is returned.
|
||||
*
|
||||
* @param segment The current segment which will be moved to the previous one.
|
||||
* @return Returns true if there is a segment before this one or false
|
||||
* otherwise.
|
||||
*/
|
||||
CWK_PUBLIC bool cwk_path_get_previous_segment(struct cwk_segment *segment);
|
||||
|
||||
/**
|
||||
* @brief Gets the type of the submitted path segment.
|
||||
*
|
||||
* This function inspects the contents of the segment and determines the type
|
||||
* of it. Currently, there are three types CWK_NORMAL, CWK_CURRENT and
|
||||
* CWK_BACK. A CWK_NORMAL segment is a normal folder or file entry. A
|
||||
* CWK_CURRENT is a "./" and a CWK_BACK a "../" segment.
|
||||
*
|
||||
* @param segment The segment which will be inspected.
|
||||
* @return Returns the type of the segment.
|
||||
*/
|
||||
CWK_PUBLIC enum cwk_segment_type cwk_path_get_segment_type(
|
||||
const struct cwk_segment *segment);
|
||||
|
||||
/**
|
||||
* @brief Changes the content of a segment.
|
||||
*
|
||||
* This function overrides the content of a segment to the submitted value and
|
||||
* outputs the whole new path to the submitted buffer. The result might
|
||||
* require less or more space than before if the new value length differs from
|
||||
* the original length. The output is truncated if the new path is larger than
|
||||
* the submitted buffer size, but it is always null-terminated. The source of
|
||||
* the segment and the submitted buffer may be the same.
|
||||
*
|
||||
* @param segment The segment which will be modifier.
|
||||
* @param value The new content of the segment.
|
||||
* @param buffer The buffer where the modified path will be written to.
|
||||
* @param buffer_size The size of the output buffer.
|
||||
* @return Returns the total size which would have been written if the output
|
||||
* was not truncated.
|
||||
*/
|
||||
CWK_PUBLIC size_t cwk_path_change_segment(struct cwk_segment *segment,
|
||||
const char *value, char *buffer, size_t buffer_size);
|
||||
|
||||
/**
|
||||
* @brief Checks whether the submitted pointer points to a separator.
|
||||
*
|
||||
* This function simply checks whether the submitted pointer points to a
|
||||
* separator, which has to be null-terminated (but not necessarily after the
|
||||
* separator). The function will return true if it is a separator, or false
|
||||
* otherwise.
|
||||
*
|
||||
* @param symbol A pointer to a string.
|
||||
* @return Returns true if it is a separator, or false otherwise.
|
||||
*/
|
||||
CWK_PUBLIC bool cwk_path_is_separator(const char *str);
|
||||
|
||||
/**
|
||||
* @brief Guesses the path style.
|
||||
*
|
||||
* This function guesses the path style based on a submitted path-string. The
|
||||
* guessing will look at the root and the type of slashes contained in the
|
||||
* path and return the style which is more likely used in the path.
|
||||
*
|
||||
* @param path The path which will be inspected.
|
||||
* @return Returns the style which is most likely used for the path.
|
||||
*/
|
||||
CWK_PUBLIC enum cwk_path_style cwk_path_guess_style(const char *path);
|
||||
|
||||
/**
|
||||
* @brief Configures which path style is used.
|
||||
*
|
||||
* This function configures which path style is used. The following styles are
|
||||
* currently supported.
|
||||
*
|
||||
* CWK_STYLE_WINDOWS: Use backslashes as a separator and volume for the root.
|
||||
* CWK_STYLE_UNIX: Use slashes as a separator and a slash for the root.
|
||||
*
|
||||
* @param style The style which will be used from now on.
|
||||
*/
|
||||
CWK_PUBLIC void cwk_path_set_style(enum cwk_path_style style);
|
||||
|
||||
/**
|
||||
* @brief Gets the path style configuration.
|
||||
*
|
||||
* This function gets the style configuration which is currently used for the
|
||||
* paths. This configuration determines how paths are parsed and generated.
|
||||
*
|
||||
* @return Returns the current path style configuration.
|
||||
*/
|
||||
CWK_PUBLIC enum cwk_path_style cwk_path_get_style(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
106
Kernel/include/debug.h
Normal file
106
Kernel/include/debug.h
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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,
|
||||
DebugLevelUbsan = 7
|
||||
};
|
||||
|
||||
#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, ...);
|
||||
void LockedWrite(DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...);
|
||||
void LockedWriteLine(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__)
|
||||
#ifdef DEBUG
|
||||
#define debug(Format, ...) SysDbg::WriteLine(DebugLevelDebug, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
#define ubsan(Format, ...) SysDbg::WriteLine(DebugLevelUbsan, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
#else
|
||||
#define debug(Format, ...)
|
||||
#define ubsan(Format, ...)
|
||||
#endif
|
||||
#define trace(Format, ...) SysDbg::WriteLine(DebugLevelTrace, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
#define fixme(Format, ...) SysDbg::WriteLine(DebugLevelFixme, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
|
||||
#define locked_error(Format, ...) SysDbg::LockedWriteLine(DebugLevelError, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
#define locked_warn(Format, ...) SysDbg::LockedWriteLine(DebugLevelWarning, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
#define locked_info(Format, ...) SysDbg::LockedWriteLine(DebugLevelInfo, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
#ifdef DEBUG
|
||||
#define locked_debug(Format, ...) SysDbg::LockedWriteLine(DebugLevelDebug, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
#define locked_ubsan(Format, ...) SysDbg::LockedWriteLine(DebugLevelUbsan, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
#else
|
||||
#define locked_debug(Format, ...)
|
||||
#define locked_ubsan(Format, ...)
|
||||
#endif
|
||||
#define locked_trace(Format, ...) SysDbg::LockedWriteLine(DebugLevelTrace, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
#define locked_fixme(Format, ...) SysDbg::LockedWriteLine(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, ...);
|
||||
void SysDbgLockedWrite(enum DebugLevel Level, const char *File, int Line, const char *Function, const char *Format, ...);
|
||||
void SysDbgLockedWriteLine(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__)
|
||||
#ifdef DEBUG
|
||||
#define debug(Format, ...) SysDbgWriteLine(DebugLevelDebug, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
#define ubsan(Format, ...) SysDbgWriteLine(DebugLevelUbsan, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
#else
|
||||
#define debug(Format, ...)
|
||||
#define ubsan(Format, ...)
|
||||
#endif
|
||||
#define trace(Format, ...) SysDbgWriteLine(DebugLevelTrace, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
#define fixme(Format, ...) SysDbgWriteLine(DebugLevelFixme, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
|
||||
#define locked_error(Format, ...) SysDbgLockedWriteLine(DebugLevelError, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
#define locked_warn(Format, ...) SysDbgLockedWriteLine(DebugLevelWarning, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
#define locked_info(Format, ...) SysDbgLockedWriteLine(DebugLevelInfo, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
#ifdef DEBUG
|
||||
#define locked_debug(Format, ...) SysDbgLockedWriteLine(DebugLevelDebug, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
#define locked_ubsan(Format, ...) SysDbgLockedWriteLine(DebugLevelUbsan, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
#else
|
||||
#define locked_debug(Format, ...)
|
||||
#define locked_ubsan(Format, ...)
|
||||
#endif
|
||||
#define locked_trace(Format, ...) SysDbgLockedWriteLine(DebugLevelTrace, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
#define locked_fixme(Format, ...) SysDbgLockedWriteLine(DebugLevelFixme, __FILE__, __LINE__, __FUNCTION__, Format, ##__VA_ARGS__)
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // !__FENNIX_KERNEL_DEBUGGER_H__
|
182
Kernel/include/disk.hpp
Normal file
182
Kernel/include/disk.hpp
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_DISK_H__
|
||||
#define __FENNIX_KERNEL_DISK_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <vector>
|
||||
|
||||
namespace Disk
|
||||
{
|
||||
#define MBR_MAGIC0 0x55
|
||||
#define MBR_MAGIC1 0xAA
|
||||
|
||||
// "EFI PART"
|
||||
#define GPT_MAGIC 0x5452415020494645ULL
|
||||
|
||||
enum PartitionStyle
|
||||
{
|
||||
Unknown,
|
||||
MBR,
|
||||
GPT
|
||||
};
|
||||
|
||||
enum PartitionFlags
|
||||
{
|
||||
Present,
|
||||
Bootable,
|
||||
EFISystemPartition
|
||||
};
|
||||
|
||||
struct MasterBootRecordPartition
|
||||
{
|
||||
uint8_t Flags;
|
||||
uint8_t CHSFirst[3];
|
||||
uint8_t Type;
|
||||
uint8_t CHSLast[3];
|
||||
uint32_t LBAFirst;
|
||||
uint32_t Sectors;
|
||||
} __packed;
|
||||
|
||||
struct MasterBootRecord
|
||||
{
|
||||
uint8_t Bootstrap[440];
|
||||
uint32_t UniqueID;
|
||||
uint16_t Reserved;
|
||||
MasterBootRecordPartition Partitions[4];
|
||||
uint8_t Signature[2];
|
||||
} __packed;
|
||||
|
||||
struct GUIDPartitionTablePartition
|
||||
{
|
||||
uint64_t TypeLow;
|
||||
uint64_t TypeHigh;
|
||||
uint64_t GUIDLow;
|
||||
uint64_t GUIDHigh;
|
||||
uint64_t StartLBA;
|
||||
uint64_t EndLBA;
|
||||
uint64_t Attributes;
|
||||
char Label[72];
|
||||
} __packed;
|
||||
|
||||
struct GUIDPartitionTable
|
||||
{
|
||||
uint64_t Signature;
|
||||
uint32_t Revision;
|
||||
uint32_t HdrSize;
|
||||
uint32_t HdrCRC32;
|
||||
uint32_t Reserved;
|
||||
uint64_t LBA;
|
||||
uint64_t ALTLBA;
|
||||
uint64_t FirstBlock;
|
||||
uint64_t LastBlock;
|
||||
uint64_t GUIDLow;
|
||||
uint64_t GUIDHigh;
|
||||
uint64_t PartLBA;
|
||||
uint32_t PartCount;
|
||||
uint32_t EntrySize;
|
||||
uint32_t PartCRC32;
|
||||
} __packed;
|
||||
|
||||
struct PartitionTable
|
||||
{
|
||||
MasterBootRecord MBR;
|
||||
GUIDPartitionTable GPT;
|
||||
};
|
||||
|
||||
class Partition
|
||||
{
|
||||
public:
|
||||
char Label[72] = "Unidentified Partition";
|
||||
size_t StartLBA = 0xdeadbeef;
|
||||
size_t EndLBA = 0xdeadbeef;
|
||||
size_t Sectors = 0xdeadbeef;
|
||||
size_t Flags = 0xdeadbeef;
|
||||
unsigned char Port = 0;
|
||||
PartitionStyle Style = PartitionStyle::Unknown;
|
||||
size_t Index = 0;
|
||||
|
||||
size_t Read(size_t Offset, size_t Count, uint8_t *Buffer)
|
||||
{
|
||||
return 0;
|
||||
UNUSED(Offset);
|
||||
UNUSED(Count);
|
||||
UNUSED(Buffer);
|
||||
}
|
||||
|
||||
size_t Write(size_t Offset, size_t Count, uint8_t *Buffer)
|
||||
{
|
||||
return 0;
|
||||
UNUSED(Offset);
|
||||
UNUSED(Count);
|
||||
UNUSED(Buffer);
|
||||
}
|
||||
|
||||
Partition() {}
|
||||
~Partition() {}
|
||||
};
|
||||
|
||||
class Drive
|
||||
{
|
||||
public:
|
||||
char Name[64] = "Unidentified Drive";
|
||||
uint8_t *Buffer = nullptr;
|
||||
PartitionTable Table;
|
||||
PartitionStyle Style = PartitionStyle::Unknown;
|
||||
std::vector<Partition> Partitions;
|
||||
bool MechanicalDisk = false;
|
||||
size_t UniqueIdentifier = 0xdeadbeef;
|
||||
|
||||
size_t Read(size_t Offset, size_t Count, uint8_t *Buffer)
|
||||
{
|
||||
return 0;
|
||||
UNUSED(Offset);
|
||||
UNUSED(Count);
|
||||
UNUSED(Buffer);
|
||||
}
|
||||
|
||||
size_t Write(size_t Offset, size_t Count, uint8_t *Buffer)
|
||||
{
|
||||
return 0;
|
||||
UNUSED(Offset);
|
||||
UNUSED(Count);
|
||||
UNUSED(Buffer);
|
||||
}
|
||||
|
||||
Drive()
|
||||
{ // TODO: Allocate buffer
|
||||
}
|
||||
~Drive() {}
|
||||
};
|
||||
|
||||
class Manager
|
||||
{
|
||||
private:
|
||||
unsigned char AvailablePorts = 0;
|
||||
int BytesPerSector = 0;
|
||||
|
||||
std::vector<Drive> drives;
|
||||
|
||||
public:
|
||||
void FetchDisks(unsigned long DriverUID);
|
||||
Manager();
|
||||
~Manager();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_DISK_H__
|
165
Kernel/include/display.hpp
Normal file
165
Kernel/include/display.hpp
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_DISPLAY_H__
|
||||
#define __FENNIX_KERNEL_DISPLAY_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <boot/binfo.h>
|
||||
#include <memory.hpp>
|
||||
#include <debug.h>
|
||||
#include <cstring>
|
||||
|
||||
namespace Video
|
||||
{
|
||||
#define PSF1_MAGIC0 0x36
|
||||
#define PSF1_MAGIC1 0x04
|
||||
|
||||
#define PSF2_MAGIC0 0x72
|
||||
#define PSF2_MAGIC1 0xb5
|
||||
#define PSF2_MAGIC2 0x4a
|
||||
#define PSF2_MAGIC3 0x86
|
||||
|
||||
struct PSF1_HEADER
|
||||
{
|
||||
uint8_t magic[2];
|
||||
uint8_t mode;
|
||||
uint8_t charsize;
|
||||
};
|
||||
|
||||
struct PSF2_HEADER
|
||||
{
|
||||
uint8_t magic[4];
|
||||
uint32_t version;
|
||||
uint32_t headersize;
|
||||
uint32_t flags;
|
||||
uint32_t length;
|
||||
uint32_t charsize;
|
||||
uint32_t height, width;
|
||||
};
|
||||
|
||||
typedef struct _PSF1_FONT
|
||||
{
|
||||
PSF1_HEADER *Header;
|
||||
void *GlyphBuffer;
|
||||
} PSF1_FONT;
|
||||
|
||||
typedef struct _PSF2_FONT
|
||||
{
|
||||
PSF2_HEADER *Header;
|
||||
void *GlyphBuffer;
|
||||
} PSF2_FONT;
|
||||
|
||||
enum FontType
|
||||
{
|
||||
None,
|
||||
PCScreenFont1,
|
||||
PCScreenFont2
|
||||
};
|
||||
|
||||
struct FontInfo
|
||||
{
|
||||
uintptr_t *StartAddress;
|
||||
uintptr_t *EndAddress;
|
||||
PSF1_FONT *PSF1Font;
|
||||
PSF2_FONT *PSF2Font;
|
||||
uint32_t Width, Height;
|
||||
FontType Type;
|
||||
};
|
||||
|
||||
class Font
|
||||
{
|
||||
private:
|
||||
FontInfo Info;
|
||||
|
||||
public:
|
||||
FontInfo GetInfo() { return Info; }
|
||||
Font(uintptr_t *Start, uintptr_t *End, FontType Type);
|
||||
~Font();
|
||||
};
|
||||
|
||||
struct ScreenBuffer
|
||||
{
|
||||
void *Buffer = nullptr;
|
||||
uint32_t Width, Height;
|
||||
size_t Size;
|
||||
uint32_t Color;
|
||||
uint32_t CursorX, CursorY;
|
||||
char Brightness;
|
||||
bool DoNotScroll;
|
||||
long Checksum;
|
||||
};
|
||||
|
||||
class Display
|
||||
{
|
||||
private:
|
||||
BootInfo::FramebufferInfo framebuffer;
|
||||
Font *CurrentFont = nullptr;
|
||||
ScreenBuffer Buffers[256];
|
||||
bool ColorIteration = false;
|
||||
int ColorPickerIteration = 0;
|
||||
|
||||
public:
|
||||
Font *GetCurrentFont();
|
||||
void SetCurrentFont(Font *Font);
|
||||
uint16_t GetBitsPerPixel();
|
||||
uint64_t GetPitch();
|
||||
|
||||
/**
|
||||
* @brief Create a new buffer
|
||||
*
|
||||
* This function creates a new buffer.
|
||||
*
|
||||
* For @see Width and @see Height. Both values must be greater than 0.
|
||||
*
|
||||
* @note Some indexes are reserved for the kernel.
|
||||
* 0 - Main buffer
|
||||
* 1 - Loading screen buffer
|
||||
* 200 - GUI buffer
|
||||
* 250 - Empty (crash screen)
|
||||
* 251 - Console (crash screen)
|
||||
* 252 - Tasks (crash screen)
|
||||
* 253 - Frames (crash screen)
|
||||
* 254 - Details (crash screen)
|
||||
* 255 - Main (crash screen)
|
||||
*
|
||||
* @param Width The width of the buffer
|
||||
* @param Height The height of the buffer
|
||||
* @param Index The index of the buffer (0-255)
|
||||
*/
|
||||
void CreateBuffer(uint32_t Width, uint32_t Height, int Index);
|
||||
void SetBuffer(int Index);
|
||||
ScreenBuffer *GetBuffer(int Index);
|
||||
void ClearBuffer(int Index);
|
||||
void DeleteBuffer(int Index);
|
||||
void SetBrightness(int Value, int Index);
|
||||
void SetBufferCursor(int Index, uint32_t X, uint32_t Y);
|
||||
void GetBufferCursor(int Index, uint32_t *X, uint32_t *Y);
|
||||
void SetPixel(uint32_t X, uint32_t Y, uint32_t Color, int Index);
|
||||
uint32_t GetPixel(uint32_t X, uint32_t Y, int Index);
|
||||
void Scroll(int Index, int Lines);
|
||||
void SetDoNotScroll(bool Value, int Index);
|
||||
|
||||
char Print(char Char, int Index, bool WriteToUART = false);
|
||||
void DrawString(const char *String, uint32_t X, uint32_t Y, int Index, bool WriteToUART = false);
|
||||
Display(BootInfo::FramebufferInfo Info, bool LoadDefaultFont = true);
|
||||
~Display();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_DISPLAY_H__
|
142
Kernel/include/driver.hpp
Normal file
142
Kernel/include/driver.hpp
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_DRIVER_H__
|
||||
#define __FENNIX_KERNEL_DRIVER_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <memory.hpp>
|
||||
#include <ints.hpp>
|
||||
#include <debug.h>
|
||||
#include <cpu.hpp>
|
||||
#include <pci.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace Driver
|
||||
{
|
||||
enum DriverCode
|
||||
{
|
||||
ERROR,
|
||||
OK,
|
||||
NOT_AVAILABLE,
|
||||
INVALID_FEX_HEADER,
|
||||
INVALID_DRIVER_DATA,
|
||||
NOT_DRIVER,
|
||||
NOT_IMPLEMENTED,
|
||||
DRIVER_RETURNED_ERROR,
|
||||
UNKNOWN_DRIVER_TYPE,
|
||||
PCI_DEVICE_NOT_FOUND,
|
||||
DRIVER_CONFLICT
|
||||
};
|
||||
|
||||
class DriverInterruptHook;
|
||||
struct DriverFile
|
||||
{
|
||||
bool Enabled = false;
|
||||
unsigned long DriverUID = 0;
|
||||
void *Address = nullptr;
|
||||
void *InterruptCallback = nullptr;
|
||||
Memory::MemMgr *MemTrk = nullptr;
|
||||
DriverInterruptHook *InterruptHook[16]{};
|
||||
|
||||
bool operator==(const DriverFile &Other) const
|
||||
{
|
||||
return DriverUID == Other.DriverUID;
|
||||
}
|
||||
};
|
||||
|
||||
class DriverInterruptHook : public Interrupts::Handler
|
||||
{
|
||||
private:
|
||||
DriverFile Handle;
|
||||
bool Enabled = true;
|
||||
|
||||
#if defined(a64)
|
||||
void OnInterruptReceived(CPU::x64::TrapFrame *Frame);
|
||||
#elif defined(a32)
|
||||
void OnInterruptReceived(CPU::x32::TrapFrame *Frame);
|
||||
#elif defined(aa64)
|
||||
void OnInterruptReceived(CPU::aarch64::TrapFrame *Frame);
|
||||
#endif
|
||||
|
||||
public:
|
||||
void Enable() { Enabled = true; }
|
||||
void Disable() { Enabled = false; }
|
||||
bool IsEnabled() { return Enabled; }
|
||||
DriverInterruptHook(int Interrupt, DriverFile Handle);
|
||||
virtual ~DriverInterruptHook() = default;
|
||||
};
|
||||
|
||||
class Driver
|
||||
{
|
||||
private:
|
||||
std::vector<DriverFile> Drivers;
|
||||
unsigned long DriverUIDs = 0;
|
||||
DriverCode CallDriverEntryPoint(void *fex, void *KAPIAddress);
|
||||
|
||||
void MapPCIAddresses(PCI::PCIDeviceHeader *PCIDevice);
|
||||
DriverCode BindPCIGeneric(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice);
|
||||
DriverCode BindPCIDisplay(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice);
|
||||
DriverCode BindPCINetwork(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice);
|
||||
DriverCode BindPCIStorage(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice);
|
||||
DriverCode BindPCIFileSystem(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice);
|
||||
DriverCode BindPCIInput(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice);
|
||||
DriverCode BindPCIAudio(Memory::MemMgr *mem, void *fex, PCI::PCIDeviceHeader *PCIDevice);
|
||||
DriverCode DriverLoadBindPCI(void *DrvExtHdr, uintptr_t DriverAddress, size_t Size, bool IsElf = false);
|
||||
|
||||
DriverCode BindInterruptGeneric(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode BindInterruptDisplay(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode BindInterruptNetwork(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode BindInterruptStorage(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode BindInterruptFileSystem(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode BindInterruptInput(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode BindInterruptAudio(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode DriverLoadBindInterrupt(void *DrvExtHdr, uintptr_t DriverAddress, size_t Size, bool IsElf = false);
|
||||
|
||||
DriverCode BindInputGeneric(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode BindInputDisplay(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode BindInputNetwork(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode BindInputStorage(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode BindInputFileSystem(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode BindInputInput(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode BindInputAudio(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode DriverLoadBindInput(void *DrvExtHdr, uintptr_t DriverAddress, size_t Size, bool IsElf = false);
|
||||
|
||||
DriverCode BindProcessGeneric(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode BindProcessDisplay(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode BindProcessNetwork(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode BindProcessStorage(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode BindProcessFileSystem(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode BindProcessInput(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode BindProcessAudio(Memory::MemMgr *mem, void *fex);
|
||||
DriverCode DriverLoadBindProcess(void *DrvExtHdr, uintptr_t DriverAddress, size_t Size, bool IsElf = false);
|
||||
|
||||
public:
|
||||
std::vector<DriverFile> GetDrivers() { return Drivers; }
|
||||
void Panic();
|
||||
void UnloadAllDrivers();
|
||||
bool UnloadDriver(unsigned long DUID);
|
||||
int IOCB(unsigned long DUID, /* KernelCallback */ void *KCB);
|
||||
DriverCode LoadDriver(uintptr_t DriverAddress, size_t Size);
|
||||
DriverCode StartDrivers();
|
||||
Driver();
|
||||
~Driver();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_DRIVER_H__
|
25
Kernel/include/dumper.hpp
Normal file
25
Kernel/include/dumper.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_LIB_DUMPER_H__
|
||||
#define __FENNIX_LIB_DUMPER_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
void DumpData(const char *Description, void *Address, unsigned long Length);
|
||||
|
||||
#endif // !__FENNIX_LIB_DUMPER_H__
|
494
Kernel/include/elf.h
Normal file
494
Kernel/include/elf.h
Normal file
@ -0,0 +1,494 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_ELF_H__
|
||||
#define __FENNIX_KERNEL_ELF_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
// https://wiki.osdev.org/ELF_Tutorial
|
||||
// https://github.com/torvalds/linux/blob/master/include/uapi/linux/elf.h
|
||||
|
||||
/* 32-bit ELF base types. */
|
||||
typedef uint32_t Elf32_Addr;
|
||||
typedef uint16_t Elf32_Half;
|
||||
typedef uint32_t Elf32_Off;
|
||||
typedef int32_t Elf32_Sword;
|
||||
typedef uint32_t Elf32_Word;
|
||||
|
||||
/* 64-bit ELF base types. */
|
||||
typedef uint64_t Elf64_Addr;
|
||||
typedef uint16_t Elf64_Half;
|
||||
typedef int16_t Elf64_SHalf;
|
||||
typedef uint64_t Elf64_Off;
|
||||
typedef int32_t Elf64_Sword;
|
||||
typedef uint32_t Elf64_Word;
|
||||
typedef uint64_t Elf64_Xword;
|
||||
typedef int64_t Elf64_Sxword;
|
||||
|
||||
#define EI_NIDENT 16
|
||||
|
||||
typedef struct elf32_hdr
|
||||
{
|
||||
unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */
|
||||
Elf32_Half e_type;
|
||||
Elf32_Half e_machine;
|
||||
Elf32_Word e_version;
|
||||
Elf32_Addr e_entry; /* Entry point virtual address */
|
||||
Elf32_Off e_phoff; /* Program header table file offset */
|
||||
Elf32_Off e_shoff; /* Section header table file offset */
|
||||
Elf32_Word e_flags;
|
||||
Elf32_Half e_ehsize;
|
||||
Elf32_Half e_phentsize;
|
||||
Elf32_Half e_phnum;
|
||||
Elf32_Half e_shentsize;
|
||||
Elf32_Half e_shnum;
|
||||
Elf32_Half e_shstrndx;
|
||||
} Elf32_Ehdr;
|
||||
|
||||
typedef struct elf64_hdr
|
||||
{
|
||||
unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */
|
||||
Elf64_Half e_type;
|
||||
Elf64_Half e_machine;
|
||||
Elf64_Word e_version;
|
||||
Elf64_Addr e_entry; /* Entry point virtual address */
|
||||
Elf64_Off e_phoff; /* Program header table file offset */
|
||||
Elf64_Off e_shoff; /* Section header table file offset */
|
||||
Elf64_Word e_flags;
|
||||
Elf64_Half e_ehsize;
|
||||
Elf64_Half e_phentsize;
|
||||
Elf64_Half e_phnum;
|
||||
Elf64_Half e_shentsize;
|
||||
Elf64_Half e_shnum;
|
||||
Elf64_Half e_shstrndx;
|
||||
} Elf64_Ehdr;
|
||||
|
||||
typedef struct elf32_shdr
|
||||
{
|
||||
Elf32_Word sh_name;
|
||||
Elf32_Word sh_type;
|
||||
Elf32_Word sh_flags;
|
||||
Elf32_Addr sh_addr;
|
||||
Elf32_Off sh_offset;
|
||||
Elf32_Word sh_size;
|
||||
Elf32_Word sh_link;
|
||||
Elf32_Word sh_info;
|
||||
Elf32_Word sh_addralign;
|
||||
Elf32_Word sh_entsize;
|
||||
} Elf32_Shdr;
|
||||
|
||||
typedef struct elf64_shdr
|
||||
{
|
||||
Elf64_Word sh_name; /* Section name, index in string tbl */
|
||||
Elf64_Word sh_type; /* Type of section */
|
||||
Elf64_Xword sh_flags; /* Miscellaneous section attributes */
|
||||
Elf64_Addr sh_addr; /* Section virtual addr at execution */
|
||||
Elf64_Off sh_offset; /* Section file offset */
|
||||
Elf64_Xword sh_size; /* Size of section in bytes */
|
||||
Elf64_Word sh_link; /* Index of another section */
|
||||
Elf64_Word sh_info; /* Additional section information */
|
||||
Elf64_Xword sh_addralign; /* Section alignment */
|
||||
Elf64_Xword sh_entsize; /* Entry size if section holds table */
|
||||
} Elf64_Shdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf32_Word p_type;
|
||||
Elf32_Off p_offset;
|
||||
Elf32_Addr p_vaddr;
|
||||
Elf32_Addr p_paddr;
|
||||
Elf32_Word p_filesz;
|
||||
Elf32_Word p_memsz;
|
||||
Elf32_Word p_flags;
|
||||
Elf32_Word p_align;
|
||||
} Elf32_Phdr;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Word p_type;
|
||||
Elf64_Word p_flags;
|
||||
Elf64_Off p_offset;
|
||||
Elf64_Addr p_vaddr;
|
||||
Elf64_Addr p_paddr;
|
||||
Elf64_Xword p_filesz;
|
||||
Elf64_Xword p_memsz;
|
||||
Elf64_Xword p_align;
|
||||
} Elf64_Phdr;
|
||||
|
||||
typedef struct elf32_rel
|
||||
{
|
||||
Elf32_Addr r_offset;
|
||||
Elf32_Word r_info;
|
||||
} Elf32_Rel;
|
||||
|
||||
typedef struct elf64_rel
|
||||
{
|
||||
Elf64_Addr r_offset; /* Location at which to apply the action */
|
||||
Elf64_Xword r_info; /* index and type of relocation */
|
||||
} Elf64_Rel;
|
||||
|
||||
typedef struct elf32_sym
|
||||
{
|
||||
Elf32_Word st_name;
|
||||
Elf32_Addr st_value;
|
||||
Elf32_Word st_size;
|
||||
unsigned char st_info;
|
||||
unsigned char st_other;
|
||||
Elf32_Half st_shndx;
|
||||
} Elf32_Sym;
|
||||
|
||||
typedef struct elf64_sym
|
||||
{
|
||||
Elf64_Word st_name; /* Symbol name, index in string tbl */
|
||||
unsigned char st_info; /* Type and binding attributes */
|
||||
unsigned char st_other; /* No defined meaning, 0 */
|
||||
Elf64_Half st_shndx; /* Associated section index */
|
||||
Elf64_Addr st_value; /* Value of the symbol */
|
||||
Elf64_Xword st_size; /* Associated symbol size */
|
||||
} Elf64_Sym;
|
||||
|
||||
struct Elf32_Dyn
|
||||
{
|
||||
Elf32_Sword d_tag; /* Type of dynamic table entry. */
|
||||
union
|
||||
{
|
||||
Elf32_Word d_val; /* Integer value of entry. */
|
||||
Elf32_Addr d_ptr; /* Pointer value of entry. */
|
||||
} d_un;
|
||||
};
|
||||
|
||||
struct Elf64_Dyn
|
||||
{
|
||||
Elf64_Sxword d_tag; /* Type of dynamic table entry. */
|
||||
union
|
||||
{
|
||||
Elf64_Xword d_val; /* Integer value of entry. */
|
||||
Elf64_Addr d_ptr; /* Pointer value of entry. */
|
||||
} d_un;
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Elf64_Addr r_offset;
|
||||
Elf64_Xword r_info;
|
||||
Elf64_Sxword r_addend;
|
||||
} Elf64_Rela;
|
||||
|
||||
enum Elf_Ident
|
||||
{
|
||||
EI_MAG0 = 0, // 0x7F
|
||||
EI_MAG1 = 1, // 'E'
|
||||
EI_MAG2 = 2, // 'L'
|
||||
EI_MAG3 = 3, // 'F'
|
||||
EI_CLASS = 4, // Architecture (32/64)
|
||||
EI_DATA = 5, // Byte Order
|
||||
EI_VERSION = 6, // ELF Version
|
||||
EI_OSABI = 7, // OS Specific
|
||||
EI_ABIVERSION = 8, // OS Specific
|
||||
EI_PAD = 9 // Padding
|
||||
};
|
||||
|
||||
enum Elf_OSABI
|
||||
{
|
||||
ELFOSABI_NONE = 0,
|
||||
ELFOSABI_HPUX = 1,
|
||||
ELFOSABI_NETBSD = 2,
|
||||
ELFOSABI_LINUX = 3,
|
||||
ELFOSABI_HURD = 4,
|
||||
ELFOSABI_SOLARIS = 6,
|
||||
ELFOSABI_AIX = 7,
|
||||
ELFOSABI_IRIX = 8,
|
||||
ELFOSABI_FREEBSD = 9,
|
||||
ELFOSABI_TRU64 = 10,
|
||||
ELFOSABI_MODESTO = 11,
|
||||
ELFOSABI_OPENBSD = 12,
|
||||
ELFOSABI_OPENVMS = 13,
|
||||
ELFOSABI_NSK = 14,
|
||||
ELFOSABI_AROS = 15,
|
||||
ELFOSABI_FENIXOS = 16,
|
||||
ELFOSABI_CLOUDABI = 17,
|
||||
ELFOSABI_OPENVOS = 18,
|
||||
ELFOSABI_C6000_ELFABI = 64,
|
||||
ELFOSABI_C6000_LINUX = 65,
|
||||
ELFOSABI_ARM = 97,
|
||||
ELFOSABI_STANDALONE = 255
|
||||
};
|
||||
|
||||
enum Elf_Type
|
||||
{
|
||||
ET_NONE = 0, // Unknown Type
|
||||
ET_REL = 1, // Relocatable File
|
||||
ET_EXEC = 2, // Executable File
|
||||
ET_DYN = 3, // Shared Object File
|
||||
ET_CORE = 4, // Core File
|
||||
ET_LOPROC = 0xff00, // Processor Specific
|
||||
ET_HIPROC = 0xffff // Processor Specific
|
||||
};
|
||||
|
||||
enum RtT_Types
|
||||
{
|
||||
R_386_NONE = 0, // No relocation
|
||||
R_386_32 = 1, // Symbol + Offset
|
||||
R_386_PC32 = 2, // Symbol + Offset - Section Offset
|
||||
|
||||
R_X86_64_NONE = 0,
|
||||
R_X86_64_64 = 1,
|
||||
R_X86_64_PC32 = 2,
|
||||
R_X86_64_GOT32 = 3,
|
||||
R_X86_64_PLT32 = 4,
|
||||
R_X86_64_COPY = 5,
|
||||
R_X86_64_GLOB_DAT = 6,
|
||||
R_X86_64_JUMP_SLOT = 7,
|
||||
R_X86_64_RELATIVE = 8,
|
||||
R_X86_64_GOTPCREL = 9,
|
||||
R_X86_64_32 = 10,
|
||||
R_X86_64_32S = 11,
|
||||
R_X86_64_16 = 12,
|
||||
};
|
||||
|
||||
enum ProgFlags_Types
|
||||
{
|
||||
PF_X = 1,
|
||||
PF_W = 2,
|
||||
PF_R = 4
|
||||
};
|
||||
|
||||
enum StT_Bindings
|
||||
{
|
||||
/**
|
||||
* @brief Local symbol. Symbol is not visible outside the object file.
|
||||
*/
|
||||
STB_LOCAL = 0,
|
||||
/**
|
||||
* @brief Global symbol. These symbols are visible to all object files being combined.
|
||||
*/
|
||||
STB_GLOBAL = 1,
|
||||
/**
|
||||
* @brief Weak symbols. These symbols are like global symbols, but their definitions are not required. Weak symbols are not visible outside the object file containing their definition.
|
||||
*/
|
||||
STB_WEAK = 2,
|
||||
/**
|
||||
* @brief Values in this inclusive range are reserved for operating system-specific semantics.
|
||||
*/
|
||||
STB_LOOS = 10,
|
||||
/**
|
||||
* @brief Values in this inclusive range are reserved for operating system-specific semantics.
|
||||
*/
|
||||
STB_HIOS = 12,
|
||||
/**
|
||||
* @brief Values in this inclusive range are reserved for processor-specific semantics.
|
||||
*/
|
||||
STB_LOPROC = 13,
|
||||
/**
|
||||
* @brief Values in this inclusive range are reserved for processor-specific semantics.
|
||||
*/
|
||||
STB_HIPROC = 15
|
||||
};
|
||||
|
||||
enum StT_Types
|
||||
{
|
||||
STT_NOTYPE = 0, // No type
|
||||
STT_OBJECT = 1, // Variables, arrays, etc.
|
||||
STT_FUNC = 2 // Methods or functions
|
||||
};
|
||||
|
||||
enum SegmentTypes
|
||||
{
|
||||
PT_NULL = 0,
|
||||
PT_LOAD = 1,
|
||||
PT_DYNAMIC = 2,
|
||||
PT_INTERP = 3,
|
||||
PT_NOTE = 4,
|
||||
PT_SHLIB = 5,
|
||||
PT_PHDR = 6,
|
||||
PT_TLS = 7,
|
||||
PT_LOSUNW = 0x6ffffffa,
|
||||
PT_SUNWBSS = 0x6ffffffb,
|
||||
PT_SUNWSTACK = 0x6ffffffa,
|
||||
PT_HISUNW = 0x6fffffff,
|
||||
PT_LOPROC = 0x70000000,
|
||||
PT_HIPROC = 0x7fffffff
|
||||
};
|
||||
|
||||
/* https://docs.oracle.com/cd/E19683-01/817-3677/chapter6-42444/index.html */
|
||||
enum DynamicArrayTags
|
||||
{
|
||||
DT_NULL = 0,
|
||||
DT_NEEDED = 1,
|
||||
DT_PLTRELSZ = 2,
|
||||
DT_PLTGOT = 3,
|
||||
DT_HASH = 4,
|
||||
DT_STRTAB = 5,
|
||||
DT_SYMTAB = 6,
|
||||
DT_RELA = 7,
|
||||
DT_RELASZ = 8,
|
||||
DT_RELAENT = 9,
|
||||
DT_STRSZ = 10,
|
||||
DT_SYMENT = 11,
|
||||
DT_INIT = 12,
|
||||
DT_FINI = 13,
|
||||
DT_SONAME = 14,
|
||||
DT_RPATH = 15,
|
||||
DT_SYMBOLIC = 16,
|
||||
DT_REL = 17,
|
||||
DT_RELSZ = 18,
|
||||
DT_RELENT = 19,
|
||||
DT_PLTREL = 20,
|
||||
DT_DEBUG = 21,
|
||||
DT_TEXTREL = 22,
|
||||
DT_JMPREL = 23,
|
||||
DT_BIND_NOW = 24,
|
||||
DT_INIT_ARRAY = 25,
|
||||
DT_FINI_ARRAY = 26,
|
||||
DT_INIT_ARRAYSZ = 27,
|
||||
DT_FINI_ARRAYSZ = 28,
|
||||
DT_RUNPATH = 29,
|
||||
DT_FLAGS = 30,
|
||||
DT_ENCODING = 32,
|
||||
DT_PREINIT_ARRAY = 32,
|
||||
DT_PREINIT_ARRAYSZ = 33,
|
||||
DT_LOOS = 0x6000000d,
|
||||
DT_SUNW_RTLDINF = 0x6000000e,
|
||||
DT_HIOS = 0x6ffff000,
|
||||
DT_VALRNGLO = 0x6ffffd00,
|
||||
DT_CHECKSUM = 0x6ffffdf8,
|
||||
DT_PLTPADSZ = 0x6ffffdf9,
|
||||
DT_MOVEENT = 0x6ffffdfa,
|
||||
DT_MOVESZ = 0x6ffffdfb,
|
||||
DT_FEATURE_1 = 0x6ffffdfc,
|
||||
DT_POSFLAG_1 = 0x6ffffdfd,
|
||||
DT_SYMINSZ = 0x6ffffdfe,
|
||||
DT_SYMINENT = 0x6ffffdff,
|
||||
DT_VALRNGHI = 0x6ffffdff,
|
||||
DT_ADDRRNGLO = 0x6ffffe00,
|
||||
DT_CONFIG = 0x6ffffefa,
|
||||
DT_DEPAUDIT = 0x6ffffefb,
|
||||
DT_AUDIT = 0x6ffffefc,
|
||||
DT_PLTPAD = 0x6ffffefd,
|
||||
DT_MOVETAB = 0x6ffffefe,
|
||||
DT_SYMINFO = 0x6ffffeff,
|
||||
DT_ADDRRNGHI = 0x6ffffeff,
|
||||
DT_RELACOUNT = 0x6ffffff9,
|
||||
DT_RELCOUNT = 0x6ffffffa,
|
||||
DT_FLAGS_1 = 0x6ffffffb,
|
||||
DT_VERDEF = 0x6ffffffc,
|
||||
DT_VERDEFNUM = 0x6ffffffd,
|
||||
DT_VERNEED = 0x6ffffffe,
|
||||
DT_VERNEEDNUM = 0x6fffffff,
|
||||
DT_LOPROC = 0x70000000,
|
||||
DT_SPARC_REGISTER = 0x70000001,
|
||||
DT_AUXILIARY = 0x7ffffffd,
|
||||
DT_USED = 0x7ffffffe,
|
||||
DT_FILTER = 0x7fffffff,
|
||||
DT_HIPROC = 0x7fffffff
|
||||
};
|
||||
|
||||
// used for Elf64_Sym st_info
|
||||
#define ELF32_ST_BIND(info) ((info) >> 4)
|
||||
#define ELF32_ST_TYPE(info) ((info)&0xf)
|
||||
#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type)&0xf))
|
||||
#define ELF64_ST_BIND(info) ((info) >> 4)
|
||||
#define ELF64_ST_TYPE(info) ((info)&0xf)
|
||||
#define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type)&0xf))
|
||||
|
||||
// used for Elf64_Sym st_other
|
||||
#define ELF32_ST_VISIBILITY(o) ((o)&0x3)
|
||||
#define ELF64_ST_VISIBILITY(o) ((o)&0x3)
|
||||
|
||||
#define DO_386_32(S, A) ((S) + (A))
|
||||
#define DO_386_PC32(S, A, P) ((S) + (A) - (P))
|
||||
|
||||
#define DO_64_64(S, A) ((S) + (A))
|
||||
#define DO_64_PC32(S, A, P) ((S) + (A) - (P))
|
||||
|
||||
#define ELF32_R_SYM(i) ((i) >> 8)
|
||||
#define ELF32_R_TYPE(i) ((unsigned char)(i))
|
||||
#define ELF32_R_INFO(s, t) (((s) << 8) + (unsigned char)(t))
|
||||
|
||||
#define ELF64_R_SYM(i) ((i) >> 32)
|
||||
#define ELF64_R_TYPE(i) ((i)&0xffffffffL)
|
||||
#define ELF64_R_INFO(s, t) (((s) << 32) + ((t)&0xffffffffL))
|
||||
|
||||
#define SHN_UNDEF 0
|
||||
#define SHN_ABS 0xfff1
|
||||
|
||||
#define SHT_NOBITS 8
|
||||
#define SHT_REL 9
|
||||
|
||||
#define SHF_WRITE 0x1
|
||||
#define SHF_ALLOC 0x2
|
||||
|
||||
#define EM_386 0x3 // x86 Machine Type
|
||||
#define EM_X86_64 0x3E // 64bit
|
||||
#define EM_ARM 0x28 // ARM
|
||||
#define EM_AARCH64 0xb7 // ARM64
|
||||
|
||||
#define EV_CURRENT 0x1 // ELF Current Version
|
||||
|
||||
#define ELFMAG0 0x7F // e_ident[EI_MAG0]
|
||||
#define ELFMAG1 'E' // e_ident[EI_MAG1]
|
||||
#define ELFMAG2 'L' // e_ident[EI_MAG2]
|
||||
#define ELFMAG3 'F' // e_ident[EI_MAG3]
|
||||
|
||||
#define ELFDATANONE 0 /* e_ident[EI_DATA] */
|
||||
#define ELFDATA2LSB 1
|
||||
#define ELFDATA2MSB 2
|
||||
|
||||
#define ELFCLASSNONE 0 /* EI_CLASS */
|
||||
#define ELFCLASS32 1
|
||||
#define ELFCLASS64 2
|
||||
#define ELFCLASSNUM 3
|
||||
|
||||
#define SHT_NULL 0 /* Section header table entry unused */
|
||||
#define SHT_PROGBITS 1 /* Program data */
|
||||
#define SHT_SYMTAB 2 /* Symbol table */
|
||||
#define SHT_STRTAB 3 /* String table */
|
||||
#define SHT_RELA 4 /* Relocation entries with addends */
|
||||
#define SHT_HASH 5 /* Symbol hash table */
|
||||
#define SHT_DYNAMIC 6 /* Dynamic linking information */
|
||||
#define SHT_NOTE 7 /* Notes */
|
||||
#define SHT_NOBITS 8 /* Program space with no data (bss) */
|
||||
#define SHT_REL 9 /* Relocation entries, no addends */
|
||||
#define SHT_SHLIB 10 /* Reserved */
|
||||
#define SHT_DYNSYM 11 /* Dynamic linker symbol table */
|
||||
#define SHT_INIT_ARRAY 14 /* Array of constructors */
|
||||
#define SHT_FINI_ARRAY 15 /* Array of destructors */
|
||||
#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
|
||||
#define SHT_GROUP 17 /* Section group */
|
||||
#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
|
||||
#define SHT_NUM 19 /* Number of defined types. */
|
||||
#define SHT_LOOS 0x60000000 /* Start OS-specific. */
|
||||
#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */
|
||||
#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */
|
||||
#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */
|
||||
#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */
|
||||
#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */
|
||||
#define SHT_SUNW_move 0x6ffffffa
|
||||
#define SHT_SUNW_COMDAT 0x6ffffffb
|
||||
#define SHT_SUNW_syminfo 0x6ffffffc
|
||||
#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */
|
||||
#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */
|
||||
#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */
|
||||
#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */
|
||||
#define SHT_HIOS 0x6fffffff /* End OS-specific type */
|
||||
#define SHT_LOPROC 0x70000000 /* Start of processor-specific */
|
||||
#define SHT_HIPROC 0x7fffffff /* End of processor-specific */
|
||||
#define SHT_LOUSER 0x80000000 /* Start of application-specific */
|
||||
#define SHT_HIUSER 0x8fffffff /* End of application-specific */
|
||||
|
||||
#endif // !__FENNIX_KERNEL_ELF_H__
|
148
Kernel/include/exec.hpp
Normal file
148
Kernel/include/exec.hpp
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_FILE_EXECUTE_H__
|
||||
#define __FENNIX_KERNEL_FILE_EXECUTE_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <filesystem.hpp>
|
||||
#include <task.hpp>
|
||||
#include <std.hpp>
|
||||
#include <elf.h>
|
||||
|
||||
namespace Execute
|
||||
{
|
||||
enum BinaryType
|
||||
{
|
||||
BinTypeInvalid,
|
||||
BinTypeFex,
|
||||
BinTypeELF,
|
||||
BinTypePE,
|
||||
BinTypeNE,
|
||||
BinTypeMZ,
|
||||
BinTypeUnknown
|
||||
};
|
||||
|
||||
enum ExStatus
|
||||
{
|
||||
Unknown,
|
||||
OK,
|
||||
Unsupported,
|
||||
GenericError,
|
||||
InvalidFile,
|
||||
InvalidFileFormat,
|
||||
InvalidFileHeader,
|
||||
InvalidFileData,
|
||||
InvalidFileEntryPoint,
|
||||
InvalidFilePath
|
||||
};
|
||||
|
||||
struct SpawnData
|
||||
{
|
||||
ExStatus Status;
|
||||
Tasking::PCB *Process;
|
||||
Tasking::TCB *Thread;
|
||||
};
|
||||
|
||||
struct SharedLibraries
|
||||
{
|
||||
char Identifier[64];
|
||||
uint64_t Timeout;
|
||||
int RefCount;
|
||||
|
||||
uintptr_t Address;
|
||||
uintptr_t MemoryImage;
|
||||
size_t Length;
|
||||
};
|
||||
|
||||
struct ELFBaseLoad
|
||||
{
|
||||
bool Success;
|
||||
bool Interpreter;
|
||||
SpawnData sd;
|
||||
Tasking::IP InstructionPointer;
|
||||
|
||||
std::vector<const char *> NeededLibraries;
|
||||
void *MemoryImage;
|
||||
void *VirtualMemoryImage;
|
||||
|
||||
/* This should be deleted after copying the allocated pages to the thread
|
||||
Intended to be used only inside BaseLoad.cpp */
|
||||
Memory::MemMgr *TmpMem;
|
||||
|
||||
/* Same as above, for BaseLoad.cpp only */
|
||||
std::vector<AuxiliaryVector> auxv;
|
||||
};
|
||||
|
||||
struct MmImage
|
||||
{
|
||||
void *Phyiscal;
|
||||
void *Virtual;
|
||||
};
|
||||
|
||||
BinaryType GetBinaryType(void *Image);
|
||||
BinaryType GetBinaryType(char *Path);
|
||||
|
||||
SpawnData Spawn(char *Path, const char **argv, const char **envp);
|
||||
|
||||
ELFBaseLoad ELFLoad(char *Path, const char **argv, const char **envp,
|
||||
Tasking::TaskCompatibility Compatibility = Tasking::TaskCompatibility::Native);
|
||||
|
||||
Elf64_Shdr *GetELFSheader(Elf64_Ehdr *Header);
|
||||
Elf64_Shdr *GetELFSection(Elf64_Ehdr *Header, uint64_t Index);
|
||||
char *GetELFStringTable(Elf64_Ehdr *Header);
|
||||
char *ELFLookupString(Elf64_Ehdr *Header, uintptr_t Offset);
|
||||
Elf64_Sym *ELFLookupSymbol(Elf64_Ehdr *Header, const char *Name);
|
||||
uintptr_t ELFGetSymbolValue(Elf64_Ehdr *Header, uint64_t Table, uint64_t Index);
|
||||
Elf64_Dyn *ELFGetDynamicTag(void *ElfFile, enum DynamicArrayTags Tag);
|
||||
|
||||
/**
|
||||
* @brief Create a ELF Memory Image
|
||||
*
|
||||
* @param mem The memory manager to use
|
||||
* @param pV Memory::Virtual object to use
|
||||
* @param ElfFile ELF file loaded in memory (FULL FILE)
|
||||
* @param Length Length of @p ElfFile
|
||||
* @return The Memory Image (Physical and Virtual)
|
||||
*/
|
||||
MmImage ELFCreateMemoryImage(Memory::MemMgr *mem, Memory::Virtual &pV, void *ElfFile, size_t Length);
|
||||
|
||||
uintptr_t LoadELFInterpreter(Memory::MemMgr *mem, Memory::Virtual &pV, const char *Interpreter);
|
||||
|
||||
ELFBaseLoad ELFLoadRel(void *ElfFile,
|
||||
VirtualFileSystem::File &ExFile,
|
||||
Tasking::PCB *Process);
|
||||
|
||||
ELFBaseLoad ELFLoadExec(void *ElfFile,
|
||||
VirtualFileSystem::File &ExFile,
|
||||
Tasking::PCB *Process);
|
||||
|
||||
ELFBaseLoad ELFLoadDyn(void *ElfFile,
|
||||
VirtualFileSystem::File &ExFile,
|
||||
Tasking::PCB *Process);
|
||||
|
||||
void StartExecuteService();
|
||||
bool AddLibrary(char *Identifier,
|
||||
void *ElfImage,
|
||||
size_t Length,
|
||||
const Memory::Virtual &pV = Memory::Virtual());
|
||||
void SearchLibrary(char *Identifier);
|
||||
SharedLibraries GetLibrary(char *Identifier);
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_FILE_EXECUTE_H__
|
182
Kernel/include/filesystem.hpp
Normal file
182
Kernel/include/filesystem.hpp
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_FILESYSTEM_H__
|
||||
#define __FENNIX_KERNEL_FILESYSTEM_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <smart_ptr.hpp>
|
||||
#include <vector>
|
||||
|
||||
namespace VirtualFileSystem
|
||||
{
|
||||
#define FILENAME_LENGTH 256
|
||||
|
||||
struct Node;
|
||||
|
||||
typedef size_t (*OperationMount)(const char *, unsigned long, const void *);
|
||||
typedef size_t (*OperationUmount)(int);
|
||||
typedef size_t (*OperationRead)(Node *node, size_t Offset, size_t Size, uint8_t *Buffer);
|
||||
typedef size_t (*OperationWrite)(Node *node, size_t Offset, size_t Size, uint8_t *Buffer);
|
||||
typedef void (*OperationOpen)(Node *node, uint8_t Mode, uint8_t Flags);
|
||||
typedef void (*OperationClose)(Node *node);
|
||||
typedef size_t (*OperationSync)(void);
|
||||
typedef void (*OperationCreate)(Node *node, char *Name, uint16_t NameLength);
|
||||
typedef void (*OperationMkdir)(Node *node, char *Name, uint16_t NameLength);
|
||||
|
||||
#define MountFSFunction(name) size_t name(const char *unknown0, unsigned long unknown1, const uint8_t *unknown2)
|
||||
#define UMountFSFunction(name) size_t name(int unknown0)
|
||||
|
||||
#define ReadFSFunction(name) size_t name(VirtualFileSystem::Node *node, size_t Offset, size_t Size, uint8_t *Buffer)
|
||||
#define WriteFSFunction(name) size_t name(VirtualFileSystem::Node *node, size_t Offset, size_t Size, uint8_t *Buffer)
|
||||
#define OpenFSFunction(name) void name(VirtualFileSystem::Node *node, uint8_t Mode, uint8_t Flags)
|
||||
#define CloseFSFunction(name) void name(VirtualFileSystem::Node *node)
|
||||
#define SyncFSFunction(name) size_t name(void)
|
||||
#define CreateFSFunction(name) void name(VirtualFileSystem::Node *node, char *Name, uint16_t NameLength)
|
||||
#define MkdirFSFunction(name) void name(VirtualFileSystem::Node *node, char *Name, uint16_t NameLength)
|
||||
|
||||
enum FileStatus
|
||||
{
|
||||
OK,
|
||||
NotFound,
|
||||
NotEmpty,
|
||||
NotSupported,
|
||||
AccessDenied,
|
||||
Timeout,
|
||||
SectorNotFound,
|
||||
PartiallyCompleted,
|
||||
|
||||
InvalidName,
|
||||
InvalidParameter,
|
||||
InvalidHandle,
|
||||
InvalidPath,
|
||||
InvalidDevice,
|
||||
InvalidOperator,
|
||||
InvalidNode,
|
||||
|
||||
FileExists,
|
||||
FileIsADirectory,
|
||||
FileIsInvalid,
|
||||
|
||||
DirectoryNotEmpty,
|
||||
NotADirectory,
|
||||
|
||||
UnknownFileStatusError
|
||||
};
|
||||
|
||||
enum NodeFlags
|
||||
{
|
||||
NODE_FLAG_ERROR = 0x0,
|
||||
FILE = 0x01,
|
||||
DIRECTORY = 0x02,
|
||||
CHARDEVICE = 0x03,
|
||||
BLOCKDEVICE = 0x04,
|
||||
PIPE = 0x05,
|
||||
SYMLINK = 0x06,
|
||||
MOUNTPOINT = 0x08
|
||||
};
|
||||
|
||||
struct FileSystemOperations
|
||||
{
|
||||
char Name[FILENAME_LENGTH];
|
||||
OperationMount Mount = nullptr;
|
||||
OperationUmount Umount = nullptr;
|
||||
OperationRead Read = nullptr;
|
||||
OperationWrite Write = nullptr;
|
||||
OperationOpen Open = nullptr;
|
||||
OperationClose Close = nullptr;
|
||||
OperationCreate Create = nullptr;
|
||||
OperationMkdir MakeDirectory = nullptr;
|
||||
};
|
||||
|
||||
struct Node
|
||||
{
|
||||
char Name[FILENAME_LENGTH];
|
||||
uint64_t IndexNode = 0;
|
||||
uint64_t Mask = 0;
|
||||
uint64_t Mode = 0;
|
||||
NodeFlags Flags = NodeFlags::NODE_FLAG_ERROR;
|
||||
uint64_t UserIdentifier = 0, GroupIdentifier = 0;
|
||||
uintptr_t Address = 0;
|
||||
size_t Length = 0;
|
||||
Node *Parent = nullptr;
|
||||
FileSystemOperations *Operator = nullptr;
|
||||
/* For root node:
|
||||
0 - root "/"
|
||||
1 - etc
|
||||
...
|
||||
*/
|
||||
std::vector<Node *> Children;
|
||||
};
|
||||
|
||||
struct File
|
||||
{
|
||||
char Name[FILENAME_LENGTH];
|
||||
FileStatus Status;
|
||||
Node *node;
|
||||
|
||||
bool IsOK() { return Status == FileStatus::OK; }
|
||||
};
|
||||
|
||||
/* Manage / etc.. */
|
||||
class Virtual
|
||||
{
|
||||
private:
|
||||
Node *FileSystemRoot = nullptr;
|
||||
|
||||
public:
|
||||
std::shared_ptr<char> GetPathFromNode(Node *node);
|
||||
Node *GetNodeFromPath(const char *Path, Node *Parent = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Convert a Node to a File
|
||||
*
|
||||
* @param node Node to convert
|
||||
* @return Converted node
|
||||
*/
|
||||
File ConvertNodeToFILE(Node *node);
|
||||
|
||||
Node *GetParent(const char *Path, Node *Parent);
|
||||
Node *GetRootNode() { return FileSystemRoot; }
|
||||
|
||||
Node *AddNewChild(const char *Name, Node *Parent);
|
||||
Node *GetChild(const char *Name, Node *Parent);
|
||||
FileStatus RemoveChild(const char *Name, Node *Parent);
|
||||
|
||||
std::shared_ptr<char> NormalizePath(const char *Path, Node *Parent = nullptr);
|
||||
bool PathExists(const char *Path, Node *Parent = nullptr);
|
||||
Node *CreateRoot(const char *RootName, FileSystemOperations *Operator);
|
||||
Node *Create(const char *Path, NodeFlags Flag, Node *Parent = nullptr);
|
||||
|
||||
FileStatus Delete(const char *Path, bool Recursive = false, Node *Parent = nullptr);
|
||||
FileStatus Delete(Node *Path, bool Recursive = false, Node *Parent = nullptr);
|
||||
|
||||
File Mount(const char *Path, FileSystemOperations *Operator);
|
||||
FileStatus Unmount(File &File);
|
||||
|
||||
size_t Read(File &File, size_t Offset, uint8_t *Buffer, size_t Size);
|
||||
size_t Write(File &File, size_t Offset, uint8_t *Buffer, size_t Size);
|
||||
|
||||
File Open(const char *Path, Node *Parent = nullptr);
|
||||
FileStatus Close(File &File);
|
||||
|
||||
Virtual();
|
||||
~Virtual();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_FILESYSTEM_H__
|
91
Kernel/include/filesystem/ext2.hpp
Normal file
91
Kernel/include/filesystem/ext2.hpp
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_FILESYSTEM_EXT2_H__
|
||||
#define __FENNIX_KERNEL_FILESYSTEM_EXT2_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <filesystem.hpp>
|
||||
|
||||
namespace VirtualFileSystem
|
||||
{
|
||||
class EXT2
|
||||
{
|
||||
public:
|
||||
struct SuperBlock
|
||||
{
|
||||
uint32_t Inodes;
|
||||
uint32_t Blocks;
|
||||
uint32_t ReservedBlocks;
|
||||
uint32_t FreeBlock;
|
||||
uint32_t FreeInodes;
|
||||
uint32_t FirstDataBlock;
|
||||
uint32_t LogBlockSize;
|
||||
uint32_t LogFragSize;
|
||||
uint32_t BlocksPerGroup;
|
||||
uint32_t FragsPerGroup;
|
||||
uint32_t InodesPerGroup;
|
||||
uint32_t LastMountTime;
|
||||
uint32_t LastWrittenTime;
|
||||
uint16_t MountedTimes;
|
||||
uint16_t MaximumMountedTimes;
|
||||
uint16_t Magic;
|
||||
uint16_t State;
|
||||
uint16_t Errors;
|
||||
uint16_t MinorRevLevel;
|
||||
uint32_t LastCheck;
|
||||
uint32_t CheckInternval;
|
||||
uint32_t SystemID;
|
||||
uint32_t RevLevel;
|
||||
uint16_t ReservedBlocksUserID;
|
||||
uint16_t ReservedBlocksGroupID;
|
||||
|
||||
uint32_t FirstInode;
|
||||
uint16_t InodeSize;
|
||||
uint16_t BlockGroups;
|
||||
uint32_t FeatureCompatibility;
|
||||
uint32_t FeatureIncompatibility;
|
||||
uint32_t FeatureRoCompatibility;
|
||||
uint8_t UUID[16];
|
||||
char VolumeName[16];
|
||||
char LastMounted[64];
|
||||
uint32_t BitmapAlogrithm;
|
||||
|
||||
uint8_t PreallocatedBlocks;
|
||||
uint8_t PreallocatedDirectoryBlocks;
|
||||
|
||||
uint16_t Padding;
|
||||
uint8_t JournalUUID[16];
|
||||
uint32_t JournalInum;
|
||||
uint32_t JournalDev;
|
||||
uint32_t LastOrphan;
|
||||
uint32_t HashSeed[4];
|
||||
uint8_t DefHashVersion;
|
||||
uint8_t ReservedCharPad;
|
||||
uint16_t ReservedWordPad;
|
||||
uint32_t DefaultMountOptions;
|
||||
uint32_t FirstMetaBg;
|
||||
uint32_t Reserved[190];
|
||||
};
|
||||
|
||||
EXT2(void *partition);
|
||||
~EXT2();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_FILESYSTEM_EXT2_H__
|
77
Kernel/include/filesystem/fat.hpp
Normal file
77
Kernel/include/filesystem/fat.hpp
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_FILESYSTEM_FAT_H__
|
||||
#define __FENNIX_KERNEL_FILESYSTEM_FAT_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <filesystem.hpp>
|
||||
|
||||
namespace VirtualFileSystem
|
||||
{
|
||||
class FAT
|
||||
{
|
||||
public:
|
||||
enum FatType
|
||||
{
|
||||
Unknown,
|
||||
FAT12,
|
||||
FAT16,
|
||||
FAT32
|
||||
};
|
||||
|
||||
/* https://wiki.osdev.org/FAT */
|
||||
struct BIOSParameterBlock
|
||||
{
|
||||
/** @brief The first three bytes EB 3C 90 disassemble to JMP SHORT 3C NOP. (The 3C value may be different.) The reason for this is to jump over the disk format information (the BPB and EBPB). Since the first sector of the disk is loaded into ram at location 0x0000:0x7c00 and executed, without this jump, the processor would attempt to execute data that isn't code. Even for non-bootable volumes, code matching this pattern (or using the E9 jump opcode) is required to be present by both Windows and OS X. To fulfil this requirement, an infinite loop can be placed here with the bytes EB FE 90. */
|
||||
uint8_t JumpBoot[3];
|
||||
/** @brief OEM identifier. The first 8 Bytes (3 - 10) is the version of DOS being used. The next eight Bytes 29 3A 63 7E 2D 49 48 and 43 read out the name of the version. The official FAT Specification from Microsoft says that this field is really meaningless and is ignored by MS FAT Drivers, however it does recommend the value "MSWIN4.1" as some 3rd party drivers supposedly check it and expect it to have that value. Older versions of dos also report MSDOS5.1, linux-formatted floppy will likely to carry "mkdosfs" here, and FreeDOS formatted disks have been observed to have "FRDOS5.1" here. If the string is less than 8 bytes, it is padded with spaces. */
|
||||
uint8_t OEM[8];
|
||||
/** @brief The number of Bytes per sector (remember, all numbers are in the little-endian format). */
|
||||
uint16_t BytesPerSector;
|
||||
/** @brief Number of sectors per cluster. */
|
||||
uint8_t SectorsPerCluster;
|
||||
/** @brief Number of reserved sectors. The boot record sectors are included in this value. */
|
||||
uint16_t ReservedSectors;
|
||||
/** @brief Number of File Allocation Tables (FAT's) on the storage media. Often this value is 2. */
|
||||
uint8_t NumberOfFATs;
|
||||
/** @brief Number of root directory entries (must be set so that the root directory occupies entire sectors). */
|
||||
uint16_t RootDirectoryEntries;
|
||||
/** @brief The total sectors in the logical volume. If this value is 0, it means there are more than 65535 sectors in the volume, and the actual count is stored in the Large Sector Count entry at 0x20. */
|
||||
uint16_t Sectors16;
|
||||
/** @brief This Byte indicates the media descriptor type. */
|
||||
uint8_t Media;
|
||||
/** @brief Number of sectors per FAT. FAT12/FAT16 only. */
|
||||
uint16_t SectorsPerFAT;
|
||||
/** @brief Number of sectors per track. */
|
||||
uint16_t SectorsPerTrack;
|
||||
/** @brief Number of heads or sides on the storage media. */
|
||||
uint16_t NumberOfHeads;
|
||||
/** @brief Number of hidden sectors. (i.e. the LBA of the beginning of the partition). */
|
||||
uint32_t HiddenSectors;
|
||||
/** @brief Large sector count. This field is set if there are more than 65535 sectors in the volume, resulting in a value which does not fit in the Number of Sectors entry at 0x13. */
|
||||
uint32_t Sectors32;
|
||||
} __packed;
|
||||
|
||||
FatType GetFATType(BIOSParameterBlock *bpb);
|
||||
FAT(void *partition);
|
||||
~FAT();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_FILESYSTEM_FAT_H__
|
48
Kernel/include/filesystem/initrd.hpp
Normal file
48
Kernel/include/filesystem/initrd.hpp
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_FILESYSTEM_INITRD_H__
|
||||
#define __FENNIX_KERNEL_FILESYSTEM_INITRD_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <filesystem.hpp>
|
||||
|
||||
namespace VirtualFileSystem
|
||||
{
|
||||
class Initrd
|
||||
{
|
||||
public:
|
||||
struct InitrdHeader
|
||||
{
|
||||
uint32_t nfiles;
|
||||
};
|
||||
|
||||
struct InitrdFileHeader
|
||||
{
|
||||
uint8_t magic;
|
||||
char name[64];
|
||||
uint32_t offset;
|
||||
uint32_t length;
|
||||
};
|
||||
|
||||
Initrd(uintptr_t Address);
|
||||
~Initrd();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_FILESYSTEM_INITRD_H__
|
114
Kernel/include/filesystem/mounts.hpp
Normal file
114
Kernel/include/filesystem/mounts.hpp
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_FILESYSTEM_DEV_H__
|
||||
#define __FENNIX_KERNEL_FILESYSTEM_DEV_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <filesystem.hpp>
|
||||
|
||||
namespace VirtualFileSystem
|
||||
{
|
||||
/* Manage /system/dev */
|
||||
class Device
|
||||
{
|
||||
public:
|
||||
Node *AddFileSystem(FileSystemOperations *Operator, uint64_t Mode, const char *Name, int Flags);
|
||||
Device();
|
||||
~Device();
|
||||
};
|
||||
|
||||
/* Manage /system/mnt */
|
||||
class Mount
|
||||
{
|
||||
public:
|
||||
Node *MountFileSystem(FileSystemOperations *Operator, uint64_t Mode, const char *Name);
|
||||
void DetectAndMountFS(void *drive);
|
||||
Mount();
|
||||
~Mount();
|
||||
};
|
||||
|
||||
/* Manage /system/prc */
|
||||
class Process
|
||||
{
|
||||
public:
|
||||
Process();
|
||||
~Process();
|
||||
};
|
||||
|
||||
/* Manage /system/drv */
|
||||
class Driver
|
||||
{
|
||||
public:
|
||||
Node *AddDriver(struct FileSystemOperations *Operator, uint64_t Mode, const char *Name, int Flags);
|
||||
Driver();
|
||||
~Driver();
|
||||
};
|
||||
|
||||
/* Manage /system/net */
|
||||
class Network
|
||||
{
|
||||
public:
|
||||
Node *AddNetworkCard(struct FileSystemOperations *Operator, uint64_t Mode, const char *Name, int Flags);
|
||||
Network();
|
||||
~Network();
|
||||
};
|
||||
|
||||
/* Manage /system/dev/serialX */
|
||||
class Serial
|
||||
{
|
||||
public:
|
||||
Serial();
|
||||
~Serial();
|
||||
};
|
||||
|
||||
/* Manage /system/dev/random */
|
||||
class Random
|
||||
{
|
||||
public:
|
||||
Random();
|
||||
~Random();
|
||||
};
|
||||
|
||||
/* Manage /system/dev/null */
|
||||
class Null
|
||||
{
|
||||
public:
|
||||
Null();
|
||||
~Null();
|
||||
};
|
||||
|
||||
/* Manage /system/dev/zero */
|
||||
class Zero
|
||||
{
|
||||
public:
|
||||
Zero();
|
||||
~Zero();
|
||||
};
|
||||
|
||||
/* Manage /system/dev/fbX */
|
||||
class FB
|
||||
{
|
||||
public:
|
||||
void SetFrameBufferData(uintptr_t Address, size_t Size, uint32_t Width, uint32_t Height, uint32_t PixelsPerScanLine);
|
||||
FB();
|
||||
~FB();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_FILESYSTEM_DEV_H__
|
88
Kernel/include/filesystem/ustar.hpp
Normal file
88
Kernel/include/filesystem/ustar.hpp
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_FILESYSTEM_USTAR_H__
|
||||
#define __FENNIX_KERNEL_FILESYSTEM_USTAR_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <filesystem.hpp>
|
||||
|
||||
namespace VirtualFileSystem
|
||||
{
|
||||
class USTAR
|
||||
{
|
||||
enum FileType
|
||||
{
|
||||
REGULAR_FILE = '0',
|
||||
HARDLINK = '1',
|
||||
SYMLINK = '2',
|
||||
CHARDEV = '3',
|
||||
BLOCKDEV = '4',
|
||||
DIRECTORY = '5',
|
||||
FIFO = '6'
|
||||
};
|
||||
|
||||
struct FileHeader
|
||||
{
|
||||
char name[100];
|
||||
char mode[8];
|
||||
char uid[8];
|
||||
char gid[8];
|
||||
char size[12];
|
||||
char mtime[12];
|
||||
char chksum[8];
|
||||
char typeflag[1];
|
||||
char link[100];
|
||||
char signature[6];
|
||||
char version[2];
|
||||
char owner[32];
|
||||
char group[32];
|
||||
char dev_maj[8];
|
||||
char dev_min[8];
|
||||
char prefix[155];
|
||||
char pad[12];
|
||||
};
|
||||
|
||||
private:
|
||||
uint32_t getsize(const char *s)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
while (*s)
|
||||
{
|
||||
ret *= 8;
|
||||
ret += *s - '0';
|
||||
s++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int string2int(const char *str)
|
||||
{
|
||||
int res = 0;
|
||||
for (int i = 0; str[i] != '\0'; ++i)
|
||||
res = res * 10 + str[i] - '0';
|
||||
return res;
|
||||
}
|
||||
|
||||
public:
|
||||
USTAR(uintptr_t Address, Virtual *vfs_ctx);
|
||||
~USTAR();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_FILESYSTEM_USTAR_H__
|
408
Kernel/include/gui.hpp
Normal file
408
Kernel/include/gui.hpp
Normal file
@ -0,0 +1,408 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_GUI_H__
|
||||
#define __FENNIX_KERNEL_GUI_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <display.hpp>
|
||||
#include <memory.hpp>
|
||||
#include <debug.h>
|
||||
#include <vector>
|
||||
|
||||
namespace GraphicalUserInterface
|
||||
{
|
||||
typedef uintptr_t Handle;
|
||||
|
||||
struct MouseData
|
||||
{
|
||||
int64_t X;
|
||||
int64_t Y;
|
||||
int64_t Z;
|
||||
bool Left;
|
||||
bool Right;
|
||||
bool Middle;
|
||||
};
|
||||
|
||||
struct ScreenBitmap
|
||||
{
|
||||
int64_t Width;
|
||||
int64_t Height;
|
||||
uint64_t Size;
|
||||
uint64_t Pitch;
|
||||
uint64_t BitsPerPixel;
|
||||
uint8_t *Data;
|
||||
};
|
||||
|
||||
struct Rect
|
||||
{
|
||||
int64_t Left;
|
||||
int64_t Top;
|
||||
int64_t Width;
|
||||
int64_t Height;
|
||||
|
||||
bool Contains(int64_t X, int64_t Y)
|
||||
{
|
||||
return (X >= Left && X <= Left + Width && Y >= Top && Y <= Top + Height);
|
||||
}
|
||||
|
||||
bool Contains(Rect rect)
|
||||
{
|
||||
return (rect.Left >= Left && rect.Left + rect.Width <= Left + Width && rect.Top >= Top && rect.Top + rect.Height <= Top + Height);
|
||||
}
|
||||
};
|
||||
|
||||
enum CursorType
|
||||
{
|
||||
Visible = 0,
|
||||
Hidden,
|
||||
Arrow,
|
||||
Hand,
|
||||
Wait,
|
||||
IBeam,
|
||||
ResizeHorizontal,
|
||||
ResizeVertical,
|
||||
ResizeDiagonalLeft,
|
||||
ResizeDiagonalRight,
|
||||
ResizeAll,
|
||||
Cross,
|
||||
Help,
|
||||
No,
|
||||
AppStarting,
|
||||
};
|
||||
|
||||
struct Event
|
||||
{
|
||||
struct
|
||||
{
|
||||
int64_t Width;
|
||||
int64_t Height;
|
||||
} Resize;
|
||||
|
||||
struct
|
||||
{
|
||||
int64_t X;
|
||||
int64_t Y;
|
||||
bool Left;
|
||||
bool Right;
|
||||
bool Middle;
|
||||
} MouseDown;
|
||||
|
||||
struct
|
||||
{
|
||||
int64_t X;
|
||||
int64_t Y;
|
||||
bool Left;
|
||||
bool Right;
|
||||
bool Middle;
|
||||
} MouseUp;
|
||||
|
||||
struct
|
||||
{
|
||||
int64_t X;
|
||||
int64_t Y;
|
||||
bool Left;
|
||||
bool Right;
|
||||
bool Middle;
|
||||
} MouseMove;
|
||||
};
|
||||
|
||||
/*
|
||||
virtual void OnMouseMove(Event *e) {}
|
||||
virtual void OnMouseClick(Event *e) {}
|
||||
virtual void OnMouseDoubleClick(Event *e) {}
|
||||
virtual void OnMouseDown(Event *e) {}
|
||||
virtual void OnMouseUp(Event *e) {}
|
||||
virtual void OnMouseWheel(Event *e) {}
|
||||
virtual void OnMouseEnter(Event *e) {}
|
||||
virtual void OnMouseLeave(Event *e) {}
|
||||
virtual void OnMouseHover(Event *e) {}
|
||||
virtual void OnMouseDrag(Event *e) {}
|
||||
virtual void OnMouseDragStart(Event *e) {}
|
||||
virtual void OnMouseDragEnd(Event *e) {}
|
||||
virtual void OnMouseDragEnter(Event *e) {}
|
||||
virtual void OnMouseDragLeave(Event *e) {}
|
||||
virtual void OnMouseDragHover(Event *e) {}
|
||||
virtual void OnMouseDragDrop(Event *e) {}
|
||||
virtual void OnMouseDragDropEnter(Event *e) {}
|
||||
virtual void OnMouseDragDropLeave(Event *e) {}
|
||||
virtual void OnMouseDragDropHover(Event *e) {}
|
||||
virtual void OnMouseDragDropEnd(Event *e) {}
|
||||
virtual void OnMouseDragDropStart(Event *e) {}
|
||||
virtual void OnMouseDragDropCancel(Event *e) {}
|
||||
virtual void OnMouseDragDropComplete(Event *e) {}
|
||||
virtual void OnMouseDragDropAbort(Event *e) {}
|
||||
|
||||
virtual void OnKeyDown(Event *e) {}
|
||||
virtual void OnKeyUp(Event *e) {}
|
||||
virtual void OnKeyPress(Event *e) {}
|
||||
|
||||
virtual void OnFocusEnter(Event *e) {}
|
||||
virtual void OnFocusLeave(Event *e) {}
|
||||
virtual void OnFocusHover(Event *e) {}
|
||||
|
||||
virtual void OnResize(Event *e) {}
|
||||
virtual void OnMinimize(Event *e) {}
|
||||
virtual void OnMaximize(Event *e) {}
|
||||
virtual void OnMove(Event *e) {}
|
||||
virtual void OnShow(Event *e) {}
|
||||
virtual void OnHide(Event *e) {}
|
||||
virtual void OnClose(Event *e) {}
|
||||
virtual void OnDestroy(Event *e) {}
|
||||
|
||||
virtual void OnPaint(Event *e) {}
|
||||
virtual void OnPaintBackground(Event *e) {}
|
||||
virtual void OnPaintForeground(Event *e) {}
|
||||
virtual void OnPaintOverlay(Event *e) {}
|
||||
virtual void OnPaintAll(Event *e) {}
|
||||
virtual void OnPaintChildren(Event *e) {}
|
||||
virtual void OnPaintChildrenBackground(Event *e) {}
|
||||
virtual void OnPaintChildrenForeground(Event *e) {}
|
||||
virtual void OnPaintChildrenBorder(Event *e) {}
|
||||
virtual void OnPaintChildrenShadow(Event *e) {}
|
||||
virtual void OnPaintChildrenOverlay(Event *e) {}
|
||||
virtual void OnPaintChildrenAll(Event *e) {}
|
||||
*/
|
||||
|
||||
void SetPixel(ScreenBitmap *Bitmap, long X, long Y, uint32_t Color);
|
||||
void DrawOverBitmap(ScreenBitmap *DestinationBitmap,
|
||||
ScreenBitmap *SourceBitmap,
|
||||
long Top,
|
||||
long Left,
|
||||
bool IgnoreZero = true);
|
||||
void PutRect(ScreenBitmap *Bitmap, Rect rect, uint32_t Color);
|
||||
void PutBorder(ScreenBitmap *Bitmap, Rect rect, uint32_t Color);
|
||||
uint32_t BlendColors(uint32_t c1, uint32_t c2, float t);
|
||||
void PutBorderWithShadow(ScreenBitmap *Bitmap, Rect rect, uint32_t Color);
|
||||
void DrawShadow(ScreenBitmap *Bitmap, Rect rect);
|
||||
void PaintChar(Video::Font *font, ScreenBitmap *Bitmap, char c, uint32_t Color, long *CharCursorX, long *CharCursorY);
|
||||
void DrawString(ScreenBitmap *Bitmap, Rect rect, const char *Text, uint32_t Color);
|
||||
|
||||
class WidgetCollection
|
||||
{
|
||||
private:
|
||||
Memory::MemMgr *mem;
|
||||
ScreenBitmap *Buffer;
|
||||
Video::Font *CurrentFont;
|
||||
void *ParentWindow;
|
||||
bool NeedRedraw;
|
||||
|
||||
struct HandleMeta
|
||||
{
|
||||
char Type[4];
|
||||
};
|
||||
|
||||
struct LabelObject
|
||||
{
|
||||
HandleMeta Handle;
|
||||
Rect rect;
|
||||
char Text[512];
|
||||
uint32_t Color;
|
||||
long CharCursorX, CharCursorY;
|
||||
};
|
||||
|
||||
struct PanelObject
|
||||
{
|
||||
HandleMeta Handle;
|
||||
Rect rect;
|
||||
uint32_t Color;
|
||||
uint32_t BorderColor;
|
||||
uint32_t ShadowColor;
|
||||
bool Shadow;
|
||||
};
|
||||
|
||||
struct ButtonObject
|
||||
{
|
||||
HandleMeta Handle;
|
||||
Rect rect;
|
||||
char Text[512];
|
||||
uint32_t Color;
|
||||
uint32_t HoverColor;
|
||||
uint32_t PressedColor;
|
||||
uint32_t BorderColor;
|
||||
uint32_t ShadowColor;
|
||||
long CharCursorX, CharCursorY;
|
||||
bool Shadow;
|
||||
bool Hover;
|
||||
bool Pressed;
|
||||
uintptr_t OnClick;
|
||||
};
|
||||
|
||||
std::vector<LabelObject *> Labels;
|
||||
std::vector<PanelObject *> Panels;
|
||||
std::vector<ButtonObject *> Buttons;
|
||||
|
||||
public:
|
||||
void ReplaceFont(Video::Font *NewFont)
|
||||
{
|
||||
delete this->CurrentFont;
|
||||
this->CurrentFont = NewFont;
|
||||
}
|
||||
|
||||
Handle CreatePanel(Rect rect, uint32_t Color);
|
||||
Handle CreateButton(Rect rect, const char *Text, uintptr_t OnClick = (uintptr_t) nullptr);
|
||||
Handle CreateLabel(Rect rect, const char *Text);
|
||||
Handle CreateTextBox(Rect rect, const char *Text);
|
||||
Handle CreateCheckBox(Rect rect, const char *Text);
|
||||
Handle CreateRadioButton(Rect rect, const char *Text);
|
||||
Handle CreateComboBox(Rect rect, const char *Text);
|
||||
Handle CreateListBox(Rect rect, const char *Text);
|
||||
Handle CreateProgressBar(Rect rect, const char *Text);
|
||||
Handle CreateContextMenu(Rect rect, const char *Text);
|
||||
|
||||
void SetText(Handle handle, const char *Text);
|
||||
|
||||
WidgetCollection(void /* Window */ *ParentWindow);
|
||||
~WidgetCollection();
|
||||
|
||||
void OnMouseMove(Event *e);
|
||||
void OnMouseClick(Event *e);
|
||||
void OnMouseDoubleClick(Event *e);
|
||||
void OnMouseDown(Event *e);
|
||||
void OnMouseUp(Event *e);
|
||||
void OnMouseWheel(Event *e);
|
||||
void OnMouseEnter(Event *e);
|
||||
void OnMouseLeave(Event *e);
|
||||
void OnMouseHover(Event *e);
|
||||
void OnMouseDrag(Event *e);
|
||||
void OnMouseDragStart(Event *e);
|
||||
void OnMouseDragEnd(Event *e);
|
||||
|
||||
void OnKeyDown(Event *e);
|
||||
void OnKeyUp(Event *e);
|
||||
void OnKeyPress(Event *e);
|
||||
|
||||
void OnShow(Event *e);
|
||||
void OnHide(Event *e);
|
||||
void OnDestroy(Event *e);
|
||||
|
||||
void OnPaint(Event *e);
|
||||
void OnPaintBackground(Event *e);
|
||||
void OnPaintForeground(Event *e);
|
||||
};
|
||||
|
||||
class Window
|
||||
{
|
||||
private:
|
||||
Memory::MemMgr *mem;
|
||||
ScreenBitmap *Buffer;
|
||||
Rect Position;
|
||||
Rect LastPosition;
|
||||
char Title[256];
|
||||
std::vector<WidgetCollection *> Widgets;
|
||||
void *ParentGUI;
|
||||
|
||||
bool Maximized;
|
||||
bool Minimized;
|
||||
|
||||
public:
|
||||
bool IsMaximized() { return Maximized; }
|
||||
bool IsMinimized() { return Minimized; }
|
||||
ScreenBitmap *GetBuffer() { return Buffer; }
|
||||
Rect GetPosition() { return Position; }
|
||||
Rect *GetPositionPtr() { return &Position; }
|
||||
const char *GetTitle() { return (const char *)Title; }
|
||||
void SetTitle(const char *Title) { strcpy(this->Title, Title); }
|
||||
void AddWidget(WidgetCollection *widget);
|
||||
|
||||
Window(void *ParentGUI, Rect rect, const char *Title);
|
||||
~Window();
|
||||
|
||||
void OnMouseMove(Event *e);
|
||||
void OnMouseClick(Event *e);
|
||||
void OnMouseDoubleClick(Event *e);
|
||||
void OnMouseDown(Event *e);
|
||||
void OnMouseUp(Event *e);
|
||||
void OnMouseWheel(Event *e);
|
||||
void OnMouseEnter(Event *e);
|
||||
void OnMouseLeave(Event *e);
|
||||
void OnMouseHover(Event *e);
|
||||
void OnMouseDrag(Event *e);
|
||||
void OnMouseDragStart(Event *e);
|
||||
void OnMouseDragEnd(Event *e);
|
||||
|
||||
void OnKeyDown(Event *e);
|
||||
void OnKeyUp(Event *e);
|
||||
void OnKeyPress(Event *e);
|
||||
|
||||
void OnFocusEnter(Event *e);
|
||||
void OnFocusLeave(Event *e);
|
||||
void OnFocusHover(Event *e);
|
||||
|
||||
void OnResize(Event *e);
|
||||
void OnMinimize(Event *e);
|
||||
void OnMaximize(Event *e);
|
||||
void OnMove(Event *e);
|
||||
void OnShow(Event *e);
|
||||
void OnHide(Event *e);
|
||||
void OnClose(Event *e);
|
||||
void OnDestroy(Event *e);
|
||||
|
||||
void OnPaint(Event *e);
|
||||
void OnPaintBackground(Event *e);
|
||||
void OnPaintForeground(Event *e);
|
||||
void OnPaintOverlay(Event *e);
|
||||
void OnPaintAll(Event *e);
|
||||
void OnPaintChildren(Event *e);
|
||||
void OnPaintChildrenBackground(Event *e);
|
||||
void OnPaintChildrenForeground(Event *e);
|
||||
void OnPaintChildrenBorder(Event *e);
|
||||
void OnPaintChildrenShadow(Event *e);
|
||||
void OnPaintChildrenOverlay(Event *e);
|
||||
void OnPaintChildrenAll(Event *e);
|
||||
};
|
||||
|
||||
class GUI
|
||||
{
|
||||
private:
|
||||
MouseData MouseArray[256];
|
||||
Memory::MemMgr *mem;
|
||||
Video::Font *CurrentFont;
|
||||
Rect Desktop;
|
||||
ScreenBitmap *BackBuffer;
|
||||
ScreenBitmap *DesktopBuffer;
|
||||
ScreenBitmap *OverlayBuffer;
|
||||
ScreenBitmap *CursorBuffer;
|
||||
std::vector<WidgetCollection *> Widgets;
|
||||
std::vector<Window *> Windows;
|
||||
CursorType Cursor = CursorType::Arrow;
|
||||
CursorType LastCursor = CursorType::Arrow;
|
||||
bool CursorVisible = true;
|
||||
bool IsRunning = false;
|
||||
|
||||
bool DesktopBufferRepaint = true;
|
||||
bool OverlayBufferRepaint = true;
|
||||
bool OverlayFullRepaint = true;
|
||||
bool CursorBufferRepaint = true;
|
||||
|
||||
void FetchInputs();
|
||||
void PaintDesktop();
|
||||
void PaintWidgets();
|
||||
void PaintWindows();
|
||||
void PaintCursor();
|
||||
|
||||
public:
|
||||
void SetCursorType(CursorType Type = CursorType::Visible) { this->Cursor = Type; }
|
||||
void Loop();
|
||||
void AddWindow(Window *window);
|
||||
void AddWidget(WidgetCollection *widget);
|
||||
GUI();
|
||||
~GUI();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_GUI_H__
|
121
Kernel/include/hashmap.hpp
Normal file
121
Kernel/include/hashmap.hpp
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define HASHMAP_ERROR -0x8A50
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
~HashMap()
|
||||
{
|
||||
for (int i = 0; i < HashMapCapacity; i++)
|
||||
if (Nodes[i] != nullptr)
|
||||
delete Nodes[i], Nodes[i] = nullptr;
|
||||
delete[] Nodes, Nodes = nullptr;
|
||||
delete DummyNode, DummyNode = nullptr;
|
||||
}
|
||||
|
||||
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 != (K)-1)
|
||||
{
|
||||
Index++;
|
||||
Index %= HashMapCapacity;
|
||||
}
|
||||
|
||||
if (Nodes[Index] == nullptr || Nodes[Index]->Key == (K)-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 HASHMAP_ERROR;
|
||||
}
|
||||
|
||||
V Get(int Key)
|
||||
{
|
||||
int Index = HashCode(Key);
|
||||
int Iterate = 0;
|
||||
|
||||
while (Nodes[Index] != nullptr)
|
||||
{
|
||||
if (Iterate++ > HashMapCapacity)
|
||||
return HASHMAP_ERROR;
|
||||
|
||||
if (Nodes[Index]->Key == (K)Key)
|
||||
return Nodes[Index]->Value;
|
||||
Index++;
|
||||
Index %= HashMapCapacity;
|
||||
}
|
||||
return HASHMAP_ERROR;
|
||||
}
|
||||
|
||||
int Size() { return HashMapSize; }
|
||||
bool IsEmpty() { return HashMapSize == 0; }
|
||||
};
|
80
Kernel/include/intrin.hpp
Normal file
80
Kernel/include/intrin.hpp
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_INTRIN_H__
|
||||
#define __FENNIX_KERNEL_INTRIN_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <debug.h>
|
||||
|
||||
namespace FXSR
|
||||
{
|
||||
void _fxsave(void *mem_addr)
|
||||
{
|
||||
#ifdef a64
|
||||
__builtin_ia32_fxsave(mem_addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void _fxrstor(void *mem_addr)
|
||||
{
|
||||
#ifdef a64
|
||||
__builtin_ia32_fxrstor(mem_addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
void _fxsave64(void *mem_addr)
|
||||
{
|
||||
#ifdef a64
|
||||
asmv("fxsaveq (%0)"
|
||||
:
|
||||
: "r"(mem_addr)
|
||||
: "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
void _fxrstor64(void *mem_addr)
|
||||
{
|
||||
#ifdef a64
|
||||
asmv("fxrstorq (%0)"
|
||||
:
|
||||
: "r"(mem_addr)
|
||||
: "memory");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
namespace SMAP
|
||||
{
|
||||
void _clac(void)
|
||||
{
|
||||
#if defined(a86)
|
||||
asmv("clac" ::
|
||||
: "cc");
|
||||
#endif // a64 || a32
|
||||
}
|
||||
|
||||
void _stac(void)
|
||||
{
|
||||
#if defined(a86)
|
||||
asmv("stac" ::
|
||||
: "cc");
|
||||
#endif // a64 || a32
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_INTRIN_H__
|
78
Kernel/include/ints.hpp
Normal file
78
Kernel/include/ints.hpp
Normal file
@ -0,0 +1,78 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_INTERRUPTS_H__
|
||||
#define __FENNIX_KERNEL_INTERRUPTS_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <cpu.hpp>
|
||||
|
||||
namespace Interrupts
|
||||
{
|
||||
#ifdef DEBUG // For performance reasons
|
||||
#define INT_FRAMES_MAX 512
|
||||
#else
|
||||
#define INT_FRAMES_MAX 8
|
||||
#endif
|
||||
|
||||
#if defined(a64)
|
||||
/* APIC::APIC */ extern void *apic[256]; // MAX_CPU
|
||||
/* APIC::Timer */ extern void *apicTimer[256]; // MAX_CPU
|
||||
#elif defined(a32)
|
||||
/* APIC::APIC */ extern void *apic[256]; // MAX_CPU
|
||||
/* APIC::Timer */ extern void *apicTimer[256]; // MAX_CPU
|
||||
#elif defined(aa64)
|
||||
#endif
|
||||
extern void *InterruptFrames[INT_FRAMES_MAX];
|
||||
|
||||
void Initialize(int Core);
|
||||
void Enable(int Core);
|
||||
void InitializeTimer(int Core);
|
||||
void RemoveAll();
|
||||
|
||||
class Handler
|
||||
{
|
||||
private:
|
||||
int InterruptNumber;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Set a new interrupt number.
|
||||
* @param InterruptNumber The interrupt number. NOT the IRQ number! (IRQ0 != 32)
|
||||
*/
|
||||
void SetInterruptNumber(int InterruptNumber) { this->InterruptNumber = InterruptNumber; }
|
||||
int GetInterruptNumber() { return this->InterruptNumber; }
|
||||
|
||||
/**
|
||||
* @brief Create a new interrupt handler.
|
||||
* @param InterruptNumber The interrupt number. NOT the IRQ number! (IRQ0 != 32)
|
||||
*/
|
||||
Handler(int InterruptNumber);
|
||||
~Handler();
|
||||
|
||||
public:
|
||||
#if defined(a64)
|
||||
virtual void OnInterruptReceived(CPU::x64::TrapFrame *Frame);
|
||||
#elif defined(a32)
|
||||
virtual void OnInterruptReceived(CPU::x32::TrapFrame *Frame);
|
||||
#elif defined(aa64)
|
||||
virtual void OnInterruptReceived(CPU::aarch64::TrapFrame *Frame);
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_INTERRUPTS_H__
|
237
Kernel/include/io.h
Normal file
237
Kernel/include/io.h
Normal file
@ -0,0 +1,237 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_IO_H__
|
||||
#define __FENNIX_KERNEL_IO_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#if defined(a86)
|
||||
|
||||
#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 *)(uintptr_t)Address;
|
||||
asmv("" ::
|
||||
: "memory");
|
||||
return Result;
|
||||
}
|
||||
|
||||
static inline uint16_t mmioin16(uint64_t Address)
|
||||
{
|
||||
asmv("" ::
|
||||
: "memory");
|
||||
uint16_t Result = *(volatile uint16_t *)(uintptr_t)Address;
|
||||
asmv("" ::
|
||||
: "memory");
|
||||
return Result;
|
||||
}
|
||||
|
||||
static inline uint32_t mmioin32(uint64_t Address)
|
||||
{
|
||||
asmv("" ::
|
||||
: "memory");
|
||||
uint32_t Result = *(volatile uint32_t *)(uintptr_t)Address;
|
||||
asmv("" ::
|
||||
: "memory");
|
||||
return Result;
|
||||
}
|
||||
|
||||
static inline uint64_t mmioin64(uint64_t Address)
|
||||
{
|
||||
asmv("" ::
|
||||
: "memory");
|
||||
uint64_t Result = *(volatile uint64_t *)(uintptr_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(a86)
|
||||
|
||||
#endif // !__FENNIX_KERNEL_IO_H__
|
92
Kernel/include/ipc.hpp
Normal file
92
Kernel/include/ipc.hpp
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_IPC_H__
|
||||
#define __FENNIX_KERNEL_IPC_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <filesystem.hpp>
|
||||
#include <memory.hpp>
|
||||
#include <lock.hpp>
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
|
||||
namespace InterProcessCommunication
|
||||
{
|
||||
typedef int IPCID;
|
||||
|
||||
enum IPCType
|
||||
{
|
||||
IPCNone,
|
||||
IPCMessagePassing,
|
||||
IPCPort,
|
||||
IPCSharedMemory,
|
||||
IPCPipe,
|
||||
IPCSocket
|
||||
};
|
||||
|
||||
enum IPCErrorCode
|
||||
{
|
||||
IPCError = -1,
|
||||
IPCSuccess,
|
||||
IPCNotListening,
|
||||
IPCTimeout,
|
||||
IPCInvalidCommand,
|
||||
IPCAlreadyAllocated,
|
||||
IPCNotAllocated,
|
||||
IPCIDInUse,
|
||||
IPCIDNotRegistered,
|
||||
IPCIDNotFound
|
||||
};
|
||||
|
||||
struct IPCHandle
|
||||
{
|
||||
IPCID ID;
|
||||
VirtualFileSystem::Node *Node;
|
||||
void *Buffer;
|
||||
long Length;
|
||||
std::atomic_bool Listening;
|
||||
};
|
||||
|
||||
class IPC
|
||||
{
|
||||
private:
|
||||
NewLock(IPCLock);
|
||||
IPCID NextID = 0;
|
||||
std::vector<IPCHandle *> Handles;
|
||||
Memory::MemMgr *mem;
|
||||
VirtualFileSystem::Node *IPCNode;
|
||||
void *Process;
|
||||
|
||||
public:
|
||||
IPCHandle *Create(IPCType Type, char UniqueToken[16]);
|
||||
IPCErrorCode Destroy(IPCID ID);
|
||||
IPCErrorCode Allocate(IPCID ID, long Size);
|
||||
IPCErrorCode Deallocate(IPCID ID);
|
||||
IPCErrorCode Read(IPCID ID, void *Buffer, long Size);
|
||||
IPCErrorCode Write(IPCID ID, void *Buffer, long Size);
|
||||
IPCErrorCode Listen(IPCID ID, bool Listen);
|
||||
IPCErrorCode Wait(IPCID ID);
|
||||
IPCHandle *SearchByToken(char UniqueToken[16]);
|
||||
int HandleSyscall(long Command, long Type, int ID, int Flags, void *Buffer, size_t Size);
|
||||
|
||||
IPC(void *Process);
|
||||
~IPC();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_IPC_H__
|
40
Kernel/include/kconfig.hpp
Normal file
40
Kernel/include/kconfig.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_KERNEL_CONFIG_H__
|
||||
#define __FENNIX_KERNEL_KERNEL_CONFIG_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <memory.hpp>
|
||||
|
||||
struct KernelConfig
|
||||
{
|
||||
Memory::MemoryAllocatorType AllocatorType;
|
||||
bool SchedulerType;
|
||||
char DriverDirectory[256];
|
||||
char InitPath[256];
|
||||
bool InterruptsOnCrash;
|
||||
int Cores;
|
||||
int IOAPICInterruptCore;
|
||||
bool UnlockDeadLock;
|
||||
bool SIMD;
|
||||
bool BootAnimation;
|
||||
};
|
||||
|
||||
void ParseConfig(char *ConfigString, KernelConfig *ModConfig);
|
||||
|
||||
#endif // !__FENNIX_KERNEL_KERNEL_CONFIG_H__
|
159
Kernel/include/lock.hpp
Normal file
159
Kernel/include/lock.hpp
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_LOCK_H__
|
||||
#define __FENNIX_KERNEL_LOCK_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <cpu.hpp>
|
||||
#include <atomic>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
/* Enabled ONLY on crash. */
|
||||
extern bool ForceUnlock;
|
||||
|
||||
/**
|
||||
* @brief Get how many locks are currently in use.
|
||||
*
|
||||
* @return size_t
|
||||
*/
|
||||
size_t GetLocksCount();
|
||||
|
||||
/** @brief Please use this macro to create a new lock. */
|
||||
class LockClass
|
||||
{
|
||||
struct SpinLockData
|
||||
{
|
||||
std::atomic_uint64_t LockData = 0x0;
|
||||
std::atomic<const char *> CurrentHolder = "(nul)";
|
||||
std::atomic<const char *> AttemptingToGet = "(nul)";
|
||||
std::atomic_uintptr_t StackPointerHolder = 0;
|
||||
std::atomic_uintptr_t StackPointerAttempt = 0;
|
||||
std::atomic_size_t Count = 0;
|
||||
std::atomic_long Core = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
SpinLockData LockData;
|
||||
std::atomic_bool IsLocked = false;
|
||||
std::atomic_ulong DeadLocks = 0;
|
||||
|
||||
void DeadLock(SpinLockData Lock);
|
||||
void TimeoutDeadLock(SpinLockData Lock, uint64_t Timeout);
|
||||
|
||||
public:
|
||||
SpinLockData *GetLockData() { return &LockData; }
|
||||
int Lock(const char *FunctionName);
|
||||
int Unlock();
|
||||
|
||||
int TimeoutLock(const char *FunctionName, uint64_t Timeout);
|
||||
};
|
||||
|
||||
/** @brief Please use this macro to create a new smart lock. */
|
||||
class SmartLockClass
|
||||
{
|
||||
private:
|
||||
LockClass *LockPointer = nullptr;
|
||||
|
||||
public:
|
||||
SmartLockClass(LockClass &Lock, const char *FunctionName)
|
||||
{
|
||||
this->LockPointer = &Lock;
|
||||
this->LockPointer->Lock(FunctionName);
|
||||
}
|
||||
~SmartLockClass() { this->LockPointer->Unlock(); }
|
||||
};
|
||||
|
||||
class SmartTimeoutLockClass
|
||||
{
|
||||
private:
|
||||
LockClass *LockPointer = nullptr;
|
||||
|
||||
public:
|
||||
SmartTimeoutLockClass(LockClass &Lock, const char *FunctionName, uint64_t Timeout)
|
||||
{
|
||||
this->LockPointer = &Lock;
|
||||
this->LockPointer->TimeoutLock(FunctionName, Timeout);
|
||||
}
|
||||
~SmartTimeoutLockClass() { this->LockPointer->Unlock(); }
|
||||
};
|
||||
|
||||
/** @brief Please use this macro to create a new smart critical section lock. */
|
||||
class SmartLockCriticalSectionClass
|
||||
{
|
||||
private:
|
||||
LockClass *LockPointer = nullptr;
|
||||
bool InterruptsEnabled = false;
|
||||
|
||||
public:
|
||||
SmartLockCriticalSectionClass(LockClass &Lock, const char *FunctionName)
|
||||
{
|
||||
if (CPU::Interrupts(CPU::Check))
|
||||
InterruptsEnabled = true;
|
||||
CPU::Interrupts(CPU::Disable);
|
||||
this->LockPointer = &Lock;
|
||||
this->LockPointer->Lock(FunctionName);
|
||||
}
|
||||
~SmartLockCriticalSectionClass()
|
||||
{
|
||||
this->LockPointer->Unlock();
|
||||
if (InterruptsEnabled)
|
||||
CPU::Interrupts(CPU::Enable);
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief Please use this macro to create a new critical section. */
|
||||
class SmartCriticalSectionClass
|
||||
{
|
||||
private:
|
||||
bool InterruptsEnabled = false;
|
||||
|
||||
public:
|
||||
bool IsInterruptsEnabled() { return InterruptsEnabled; }
|
||||
|
||||
SmartCriticalSectionClass()
|
||||
{
|
||||
if (CPU::Interrupts(CPU::Check))
|
||||
InterruptsEnabled = true;
|
||||
CPU::Interrupts(CPU::Disable);
|
||||
}
|
||||
~SmartCriticalSectionClass()
|
||||
{
|
||||
if (InterruptsEnabled)
|
||||
CPU::Interrupts(CPU::Enable);
|
||||
}
|
||||
};
|
||||
|
||||
/** @brief Create a new lock (can be used with SmartCriticalSection). */
|
||||
#define NewLock(Name) LockClass Name
|
||||
|
||||
/** @brief Simple lock that is automatically released when the scope ends. */
|
||||
#define SmartLock(LockClassName) SmartLockClass CONCAT(lock##_, __COUNTER__)(LockClassName, __FUNCTION__)
|
||||
|
||||
/** @brief Simple lock with timeout that is automatically released when the scope ends. */
|
||||
#define SmartTimeoutLock(LockClassName, Timeout) SmartTimeoutLockClass CONCAT(lock##_, __COUNTER__)(LockClassName, __FUNCTION__, Timeout)
|
||||
|
||||
/** @brief Simple critical section that is automatically released when the scope ends and interrupts are restored if they were enabled. */
|
||||
#define SmartCriticalSection(LockClassName) SmartLockCriticalSectionClass CONCAT(lock##_, __COUNTER__)(LockClassName, __FUNCTION__)
|
||||
|
||||
/** @brief Automatically disable interrupts and restore them when the scope ends. */
|
||||
#define CriticalSection SmartCriticalSectionClass
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // !__FENNIX_KERNEL_LOCK_H__
|
54
Kernel/include/md5.h
Normal file
54
Kernel/include/md5.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_MD5_H__
|
||||
#define __FENNIX_KERNEL_MD5_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
/*
|
||||
https://github.com/Zunawe/md5-c
|
||||
*/
|
||||
|
||||
START_EXTERNC
|
||||
|
||||
typedef struct
|
||||
{
|
||||
size_t size; // Size of input in bytes
|
||||
uint32_t buffer[4]; // Current accumulation of hash
|
||||
uint8_t input[64]; // Input to be used in the next step
|
||||
uint8_t digest[16]; // Result of algorithm
|
||||
} MD5Context;
|
||||
|
||||
void md5Init(MD5Context *ctx);
|
||||
void md5Update(MD5Context *ctx, uint8_t *input, size_t input_len);
|
||||
void md5Finalize(MD5Context *ctx);
|
||||
void md5Step(uint32_t *buffer, uint32_t *input);
|
||||
|
||||
uint8_t *md5String(char *input);
|
||||
uint8_t *md5File(uint8_t *buffer, size_t input_len);
|
||||
|
||||
uint32_t F(uint32_t X, uint32_t Y, uint32_t Z);
|
||||
uint32_t G(uint32_t X, uint32_t Y, uint32_t Z);
|
||||
uint32_t H(uint32_t X, uint32_t Y, uint32_t Z);
|
||||
uint32_t I(uint32_t X, uint32_t Y, uint32_t Z);
|
||||
|
||||
uint32_t rotateLeft(uint32_t x, uint32_t n);
|
||||
|
||||
END_EXTERNC
|
||||
|
||||
#endif // !__FENNIX_KERNEL_MD5_H__
|
898
Kernel/include/memory.hpp
Normal file
898
Kernel/include/memory.hpp
Normal file
@ -0,0 +1,898 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_INTERNAL_MEMORY_H__
|
||||
#define __FENNIX_KERNEL_INTERNAL_MEMORY_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <filesystem.hpp>
|
||||
#include <boot/binfo.h>
|
||||
#include <bitmap.hpp>
|
||||
#include <lock.hpp>
|
||||
#include <std.hpp>
|
||||
#endif // __cplusplus
|
||||
#include <types.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
extern uintptr_t _kernel_start, _kernel_end;
|
||||
extern uintptr_t _bootstrap_start, _bootstrap_end;
|
||||
extern uintptr_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 // 4KB
|
||||
#define PAGE_SIZE_4K PAGE_SIZE // 4KB
|
||||
#define PAGE_SIZE_2M 0x200000 // 2MB
|
||||
#define PAGE_SIZE_1G 0x40000000 // 1GB
|
||||
|
||||
#define STACK_SIZE 0x4000 // 16kb
|
||||
#define USER_STACK_SIZE 0x2000 // 8kb
|
||||
|
||||
// To pages
|
||||
#define TO_PAGES(d) (((d) + PAGE_SIZE - 1) / PAGE_SIZE)
|
||||
// From pages
|
||||
#define FROM_PAGES(d) ((d)*PAGE_SIZE)
|
||||
|
||||
#if defined(a64) || defined(aa64)
|
||||
#define NORMAL_VMA_OFFSET 0xFFFF800000000000
|
||||
#define KERNEL_VMA_OFFSET 0xFFFFFFFF80000000
|
||||
#define KERNEL_HEAP_BASE 0xFFFFA00000000000
|
||||
#define USER_HEAP_BASE 0xFFFFB00000000000
|
||||
#define USER_STACK_BASE 0xFFFFEFFFFFFF0000
|
||||
#elif defined(a32)
|
||||
#define NORMAL_VMA_OFFSET 0x80000000
|
||||
#define KERNEL_VMA_OFFSET 0xC0000000
|
||||
#define KERNEL_HEAP_BASE 0xA0000000
|
||||
#define USER_HEAP_BASE 0xB0000000
|
||||
#define USER_STACK_BASE 0xEFFFFFFF
|
||||
#endif
|
||||
|
||||
namespace Memory
|
||||
{
|
||||
enum MemoryAllocatorType
|
||||
{
|
||||
None,
|
||||
Pages,
|
||||
XallocV1,
|
||||
liballoc11
|
||||
};
|
||||
|
||||
/**
|
||||
* @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
|
||||
};
|
||||
|
||||
/* 2.2 Paging in IA-32e Mode - https://composter.com.ua/documents/TLBs_Paging-Structure_Caches_and_Their_Invalidation.pdf */
|
||||
|
||||
union __packed PageTableEntry
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint64_t Present : 1; // 0
|
||||
uint64_t ReadWrite : 1; // 1
|
||||
uint64_t UserSupervisor : 1; // 2
|
||||
uint64_t WriteThrough : 1; // 3
|
||||
uint64_t CacheDisable : 1; // 4
|
||||
uint64_t Accessed : 1; // 5
|
||||
uint64_t Dirty : 1; // 6
|
||||
uint64_t PageAttributeTable : 1; // 7
|
||||
uint64_t Global : 1; // 8
|
||||
uint64_t Available0 : 3; // 9-11
|
||||
uint64_t Address : 40; // 12-51
|
||||
uint64_t Available1 : 7; // 52-58
|
||||
uint64_t ProtectionKey : 4; // 59-62
|
||||
uint64_t ExecuteDisable : 1; // 63
|
||||
};
|
||||
uint64_t raw;
|
||||
|
||||
/** @brief Set Address */
|
||||
void SetAddress(uintptr_t _Address)
|
||||
{
|
||||
#if defined(a64)
|
||||
_Address &= 0x000000FFFFFFFFFF;
|
||||
this->raw &= 0xFFF0000000000FFF;
|
||||
this->raw |= (_Address << 12);
|
||||
#elif defined(a32)
|
||||
_Address &= 0x000FFFFF;
|
||||
this->raw &= 0xFFC00003;
|
||||
this->raw |= (_Address << 12);
|
||||
#elif defined(aa64)
|
||||
_Address &= 0x000000FFFFFFFFFF;
|
||||
this->raw &= 0xFFF0000000000FFF;
|
||||
this->raw |= (_Address << 12);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @brief Get Address */
|
||||
uintptr_t GetAddress()
|
||||
{
|
||||
#if defined(a64)
|
||||
return (this->raw & 0x000FFFFFFFFFF000) >> 12;
|
||||
#elif defined(a32)
|
||||
return (this->raw & 0x003FFFFF000) >> 12;
|
||||
#elif defined(aa64)
|
||||
return (this->raw & 0x000FFFFFFFFFF000) >> 12;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
struct __packed PageTableEntryPtr
|
||||
{
|
||||
PageTableEntry Entries[512];
|
||||
};
|
||||
|
||||
union __packed PageDirectoryEntry
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint64_t Present : 1; // 0
|
||||
uint64_t ReadWrite : 1; // 1
|
||||
uint64_t UserSupervisor : 1; // 2
|
||||
uint64_t WriteThrough : 1; // 3
|
||||
uint64_t CacheDisable : 1; // 4
|
||||
uint64_t Accessed : 1; // 5
|
||||
uint64_t Available0 : 1; // 6
|
||||
uint64_t PageSize : 1; // 7
|
||||
uint64_t Available1 : 4; // 8-11
|
||||
uint64_t Address : 40; // 12-51
|
||||
uint64_t Available2 : 11; // 52-62
|
||||
uint64_t ExecuteDisable : 1; // 63
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
uint64_t Present : 1; // 0
|
||||
uint64_t ReadWrite : 1; // 1
|
||||
uint64_t UserSupervisor : 1; // 2
|
||||
uint64_t WriteThrough : 1; // 3
|
||||
uint64_t CacheDisable : 1; // 4
|
||||
uint64_t Accessed : 1; // 5
|
||||
uint64_t Dirty : 1; // 6
|
||||
uint64_t PageSize : 1; // 7
|
||||
uint64_t Global : 1; // 8
|
||||
uint64_t Available0 : 3; // 9-11
|
||||
uint64_t PageAttributeTable : 1; // 12
|
||||
uint64_t Reserved0 : 8; // 13-20
|
||||
uint64_t Address : 31; // 21-51
|
||||
uint64_t Available1 : 7; // 52-58
|
||||
uint64_t ProtectionKey : 4; // 59-62
|
||||
uint64_t ExecuteDisable : 1; // 63
|
||||
} TwoMB;
|
||||
|
||||
uint64_t raw;
|
||||
|
||||
/** @brief Set PageTableEntryPtr address */
|
||||
void SetAddress(uintptr_t _Address)
|
||||
{
|
||||
#if defined(a64)
|
||||
_Address &= 0x000000FFFFFFFFFF;
|
||||
this->raw &= 0xFFF0000000000FFF;
|
||||
this->raw |= (_Address << 12);
|
||||
#elif defined(a32)
|
||||
_Address &= 0x000FFFFF;
|
||||
this->raw &= 0xFFC00003;
|
||||
this->raw |= (_Address << 12);
|
||||
#elif defined(aa64)
|
||||
_Address &= 0x000000FFFFFFFFFF;
|
||||
this->raw &= 0xFFF0000000000FFF;
|
||||
this->raw |= (_Address << 12);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @brief Get PageTableEntryPtr address */
|
||||
uintptr_t GetAddress()
|
||||
{
|
||||
#if defined(a64)
|
||||
return (this->raw & 0x000FFFFFFFFFF000) >> 12;
|
||||
#elif defined(a32)
|
||||
return (this->raw & 0x003FFFFF000) >> 12;
|
||||
#elif defined(aa64)
|
||||
return (this->raw & 0x000FFFFFFFFFF000) >> 12;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
struct __packed PageDirectoryEntryPtr
|
||||
{
|
||||
PageDirectoryEntry Entries[512];
|
||||
};
|
||||
|
||||
union __packed PageDirectoryPointerTableEntry
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint64_t Present : 1; // 0
|
||||
uint64_t ReadWrite : 1; // 1
|
||||
uint64_t UserSupervisor : 1; // 2
|
||||
uint64_t WriteThrough : 1; // 3
|
||||
uint64_t CacheDisable : 1; // 4
|
||||
uint64_t Accessed : 1; // 5
|
||||
uint64_t Available0 : 1; // 6
|
||||
uint64_t PageSize : 1; // 7
|
||||
uint64_t Available1 : 4; // 8-11
|
||||
uint64_t Address : 40; // 12-51
|
||||
uint64_t Available2 : 11; // 52-62
|
||||
uint64_t ExecuteDisable : 1; // 63
|
||||
};
|
||||
|
||||
struct
|
||||
{
|
||||
uint64_t Present : 1; // 0
|
||||
uint64_t ReadWrite : 1; // 1
|
||||
uint64_t UserSupervisor : 1; // 2
|
||||
uint64_t WriteThrough : 1; // 3
|
||||
uint64_t CacheDisable : 1; // 4
|
||||
uint64_t Accessed : 1; // 5
|
||||
uint64_t Dirty : 1; // 6
|
||||
uint64_t PageSize : 1; // 7
|
||||
uint64_t Global : 1; // 8
|
||||
uint64_t Available0 : 3; // 9-11
|
||||
uint64_t PageAttributeTable : 1; // 12
|
||||
uint64_t Reserved0 : 17; // 13-29
|
||||
uint64_t Address : 22; // 30-51
|
||||
uint64_t Available1 : 7; // 52-58
|
||||
uint64_t ProtectionKey : 4; // 59-62
|
||||
uint64_t ExecuteDisable : 1; // 63
|
||||
} OneGB;
|
||||
|
||||
uint64_t raw;
|
||||
|
||||
/** @brief Set PageDirectoryEntryPtr address */
|
||||
void SetAddress(uintptr_t _Address)
|
||||
{
|
||||
#if defined(a64)
|
||||
_Address &= 0x000000FFFFFFFFFF;
|
||||
this->raw &= 0xFFF0000000000FFF;
|
||||
this->raw |= (_Address << 12);
|
||||
#elif defined(a32)
|
||||
_Address &= 0x000FFFFF;
|
||||
this->raw &= 0xFFC00003;
|
||||
this->raw |= (_Address << 12);
|
||||
#elif defined(aa64)
|
||||
_Address &= 0x000000FFFFFFFFFF;
|
||||
this->raw &= 0xFFF0000000000FFF;
|
||||
this->raw |= (_Address << 12);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @brief Get PageDirectoryEntryPtr address */
|
||||
uintptr_t GetAddress()
|
||||
{
|
||||
#if defined(a64)
|
||||
return (this->raw & 0x000FFFFFFFFFF000) >> 12;
|
||||
#elif defined(a32)
|
||||
return (this->raw & 0x003FFFFF000) >> 12;
|
||||
#elif defined(aa64)
|
||||
return (this->raw & 0x000FFFFFFFFFF000) >> 12;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
struct __packed PageDirectoryPointerTableEntryPtr
|
||||
{
|
||||
PageDirectoryPointerTableEntry Entries[512];
|
||||
};
|
||||
|
||||
union __packed PageMapLevel4
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint64_t Present : 1; // 0
|
||||
uint64_t ReadWrite : 1; // 1
|
||||
uint64_t UserSupervisor : 1; // 2
|
||||
uint64_t WriteThrough : 1; // 3
|
||||
uint64_t CacheDisable : 1; // 4
|
||||
uint64_t Accessed : 1; // 5
|
||||
uint64_t Available0 : 1; // 6
|
||||
uint64_t Reserved0 : 1; // 7
|
||||
uint64_t Available1 : 4; // 8-11
|
||||
uint64_t Address : 40; // 12-51
|
||||
uint64_t Available2 : 11; // 52-62
|
||||
uint64_t ExecuteDisable : 1; // 63
|
||||
};
|
||||
uint64_t raw;
|
||||
|
||||
/** @brief Set PageDirectoryPointerTableEntryPtr address */
|
||||
void SetAddress(uintptr_t _Address)
|
||||
{
|
||||
#if defined(a64)
|
||||
_Address &= 0x000000FFFFFFFFFF;
|
||||
this->raw &= 0xFFF0000000000FFF;
|
||||
this->raw |= (_Address << 12);
|
||||
#elif defined(a32)
|
||||
_Address &= 0x000FFFFF;
|
||||
this->raw &= 0xFFC00003;
|
||||
this->raw |= (_Address << 12);
|
||||
#elif defined(aa64)
|
||||
_Address &= 0x000000FFFFFFFFFF;
|
||||
this->raw &= 0xFFF0000000000FFF;
|
||||
this->raw |= (_Address << 12);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @brief Get PageDirectoryPointerTableEntryPtr address */
|
||||
uintptr_t GetAddress()
|
||||
{
|
||||
#if defined(a64)
|
||||
return (this->raw & 0x000FFFFFFFFFF000) >> 12;
|
||||
#elif defined(a32)
|
||||
return (this->raw & 0x003FFFFF000) >> 12;
|
||||
#elif defined(aa64)
|
||||
return (this->raw & 0x000FFFFFFFFFF000) >> 12;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
struct PageTable4
|
||||
{
|
||||
PageMapLevel4 Entries[512];
|
||||
|
||||
/**
|
||||
* @brief Update CR3 with this PageTable4
|
||||
*/
|
||||
void Update()
|
||||
{
|
||||
#if defined(a86)
|
||||
asmv("mov %0, %%cr3" ::"r"(this));
|
||||
#elif defined(aa64)
|
||||
asmv("msr ttbr0_el1, %0" ::"r"(this));
|
||||
#endif
|
||||
}
|
||||
} __aligned(0x1000);
|
||||
|
||||
struct __packed PageMapLevel5
|
||||
{
|
||||
/* FIXME: NOT IMPLEMENTED! */
|
||||
};
|
||||
|
||||
struct PageTable5
|
||||
{
|
||||
PageMapLevel5 Entries[512];
|
||||
} __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;
|
||||
|
||||
public:
|
||||
Bitmap GetPageBitmap() { return PageBitmap; }
|
||||
|
||||
/**
|
||||
* @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, size_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, size_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, size_t PageCount);
|
||||
|
||||
void ReservePage(void *Address);
|
||||
void ReservePages(void *Address, size_t PageCount);
|
||||
void UnreservePage(void *Address);
|
||||
void UnreservePages(void *Address, size_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(size_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, size_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);
|
||||
PageTable4 *Table = nullptr;
|
||||
|
||||
public:
|
||||
enum MapType
|
||||
{
|
||||
NoMapType,
|
||||
FourKB,
|
||||
TwoMB,
|
||||
OneGB
|
||||
};
|
||||
|
||||
class PageMapIndexer
|
||||
{
|
||||
public:
|
||||
uintptr_t PMLIndex = 0;
|
||||
uintptr_t PDPTEIndex = 0;
|
||||
uintptr_t PDEIndex = 0;
|
||||
uintptr_t PTEIndex = 0;
|
||||
PageMapIndexer(uintptr_t VirtualAddress);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Check if page has the specified flag.
|
||||
*
|
||||
* @param VirtualAddress Virtual address of the page
|
||||
* @param Flag Flag to check
|
||||
* @param Type Type of the page. Check MapType enum.
|
||||
* @return true if page has the specified flag.
|
||||
* @return false if page is has the specified flag.
|
||||
*/
|
||||
bool Check(void *VirtualAddress, PTFlag Flag = PTFlag::P, MapType Type = MapType::FourKB);
|
||||
|
||||
/**
|
||||
* @brief Get physical address of the page.
|
||||
* @param VirtualAddress Virtual address of the page.
|
||||
* @return Physical address of the page.
|
||||
*/
|
||||
void *GetPhysical(void *VirtualAddress);
|
||||
|
||||
/**
|
||||
* @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.
|
||||
* @param Type Type of the page. Check MapType enum.
|
||||
*/
|
||||
void Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flag = PTFlag::P, MapType Type = MapType::FourKB);
|
||||
|
||||
/**
|
||||
* @brief Map multiple pages.
|
||||
*
|
||||
* @param VirtualAddress First virtual address of the page.
|
||||
* @param PhysicalAddress First physical address of the page.
|
||||
* @param Length Length to map.
|
||||
* @param Flags Flags of the page. Check PTFlag enum.
|
||||
* @param Type Type of the page. Check MapType enum.
|
||||
*/
|
||||
__always_inline inline void Map(void *VirtualAddress, void *PhysicalAddress, size_t Length, uint64_t Flags, MapType Type = MapType::FourKB)
|
||||
{
|
||||
int PageSize = PAGE_SIZE_4K;
|
||||
|
||||
if (Type == MapType::TwoMB)
|
||||
PageSize = PAGE_SIZE_2M;
|
||||
else if (Type == MapType::OneGB)
|
||||
PageSize = PAGE_SIZE_1G;
|
||||
|
||||
for (uintptr_t i = 0; i < Length; i += PageSize)
|
||||
this->Map((void *)((uintptr_t)VirtualAddress + i), (void *)((uintptr_t)PhysicalAddress + i), Flags, Type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Map multiple pages efficiently.
|
||||
*
|
||||
* This function will detect the best page size to map the pages.
|
||||
*
|
||||
* @note This function will not check if PSE or 1GB pages are enabled or supported.
|
||||
*
|
||||
* @param VirtualAddress First virtual address of the page.
|
||||
* @param PhysicalAddress First physical address of the page.
|
||||
* @param Length Length of the pages.
|
||||
* @param Flags Flags of the page. Check PTFlag enum.
|
||||
* @param Fit If true, the function will try to fit the pages in the smallest page size.
|
||||
* @param FailOnModulo If true, the function will return NoMapType if the length is not a multiple of the page size.
|
||||
* @return The best page size to map the pages.
|
||||
*/
|
||||
__always_inline inline MapType OptimizedMap(void *VirtualAddress, void *PhysicalAddress, size_t Length, uint64_t Flags, bool Fit = false, bool FailOnModulo = false)
|
||||
{
|
||||
if (unlikely(Fit))
|
||||
{
|
||||
while (Length >= PAGE_SIZE_1G)
|
||||
{
|
||||
this->Map(VirtualAddress, PhysicalAddress, Length, Flags, Virtual::MapType::OneGB);
|
||||
VirtualAddress = (void *)((uintptr_t)VirtualAddress + PAGE_SIZE_1G);
|
||||
PhysicalAddress = (void *)((uintptr_t)PhysicalAddress + PAGE_SIZE_1G);
|
||||
Length -= PAGE_SIZE_1G;
|
||||
}
|
||||
|
||||
while (Length >= PAGE_SIZE_2M)
|
||||
{
|
||||
this->Map(VirtualAddress, PhysicalAddress, Length, Flags, Virtual::MapType::TwoMB);
|
||||
VirtualAddress = (void *)((uintptr_t)VirtualAddress + PAGE_SIZE_2M);
|
||||
PhysicalAddress = (void *)((uintptr_t)PhysicalAddress + PAGE_SIZE_2M);
|
||||
Length -= PAGE_SIZE_2M;
|
||||
}
|
||||
|
||||
while (Length >= PAGE_SIZE_4K)
|
||||
{
|
||||
this->Map(VirtualAddress, PhysicalAddress, Length, Flags, Virtual::MapType::FourKB);
|
||||
VirtualAddress = (void *)((uintptr_t)VirtualAddress + PAGE_SIZE_4K);
|
||||
PhysicalAddress = (void *)((uintptr_t)PhysicalAddress + PAGE_SIZE_4K);
|
||||
Length -= PAGE_SIZE_4K;
|
||||
}
|
||||
|
||||
return Virtual::MapType::FourKB;
|
||||
}
|
||||
|
||||
Virtual::MapType Type = Virtual::MapType::FourKB;
|
||||
|
||||
if (Length >= PAGE_SIZE_1G)
|
||||
{
|
||||
Type = Virtual::MapType::OneGB;
|
||||
if (Length % PAGE_SIZE_1G != 0)
|
||||
{
|
||||
warn("Length is not a multiple of 1GB.");
|
||||
if (FailOnModulo)
|
||||
return Virtual::MapType::NoMapType;
|
||||
}
|
||||
}
|
||||
else if (Length >= PAGE_SIZE_2M)
|
||||
{
|
||||
Type = Virtual::MapType::TwoMB;
|
||||
if (Length % PAGE_SIZE_2M != 0)
|
||||
{
|
||||
warn("Length is not a multiple of 2MB.");
|
||||
if (FailOnModulo)
|
||||
return Virtual::MapType::NoMapType;
|
||||
}
|
||||
}
|
||||
|
||||
this->Map(VirtualAddress, PhysicalAddress, Length, Flags, Type);
|
||||
return Type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unmap page.
|
||||
*
|
||||
* @param VirtualAddress Virtual address of the page.
|
||||
* @param Type Type of the page. Check MapType enum.
|
||||
*/
|
||||
void Unmap(void *VirtualAddress, MapType Type = MapType::FourKB);
|
||||
|
||||
/**
|
||||
* @brief Unmap multiple pages.
|
||||
*
|
||||
* @param VirtualAddress First virtual address of the page.
|
||||
* @param Length Length to map.
|
||||
* @param Type Type of the page. Check MapType enum.
|
||||
*/
|
||||
__always_inline inline void Unmap(void *VirtualAddress, size_t Length, MapType Type = MapType::FourKB)
|
||||
{
|
||||
int PageSize = PAGE_SIZE_4K;
|
||||
|
||||
if (Type == MapType::TwoMB)
|
||||
PageSize = PAGE_SIZE_2M;
|
||||
else if (Type == MapType::OneGB)
|
||||
PageSize = PAGE_SIZE_1G;
|
||||
|
||||
for (uintptr_t i = 0; i < Length; i += PageSize)
|
||||
this->Unmap((void *)((uintptr_t)VirtualAddress + i), Type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remap page.
|
||||
*
|
||||
* @param VirtualAddress Virtual address of the page.
|
||||
* @param PhysicalAddress Physical address of the page.
|
||||
* @param Flags Flags of the page. Check PTFlag enum.
|
||||
* @param Type Type of the page. Check MapType enum.
|
||||
*/
|
||||
__always_inline inline void Remap(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags, MapType Type = MapType::FourKB)
|
||||
{
|
||||
this->Unmap(VirtualAddress, Type);
|
||||
this->Map(VirtualAddress, PhysicalAddress, Flags, Type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Construct a new Virtual object
|
||||
*
|
||||
* @param Table Page table. If null, it will use the current page table.
|
||||
*/
|
||||
Virtual(PageTable4 *Table = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Destroy the Virtual object
|
||||
*
|
||||
*/
|
||||
~Virtual();
|
||||
};
|
||||
|
||||
class StackGuard
|
||||
{
|
||||
private:
|
||||
void *StackBottom = nullptr;
|
||||
void *StackTop = nullptr;
|
||||
void *StackPhyiscalBottom = nullptr;
|
||||
void *StackPhyiscalTop = nullptr;
|
||||
uint64_t Size = 0;
|
||||
bool UserMode = false;
|
||||
PageTable4 *Table = nullptr;
|
||||
|
||||
public:
|
||||
/** @brief For general info */
|
||||
void *GetStackBottom() { return StackBottom; }
|
||||
/** @brief For RSP */
|
||||
void *GetStackTop() { return StackTop; }
|
||||
/** @brief For general info */
|
||||
void *GetStackPhysicalBottom() { return StackPhyiscalBottom; }
|
||||
/** @brief For general info */
|
||||
void *GetStackPhysicalTop() { return StackPhyiscalTop; }
|
||||
/** @brief Called by exception handler */
|
||||
bool Expand(uintptr_t FaultAddress);
|
||||
/**
|
||||
* @brief Construct a new Stack Guard object
|
||||
* @param User Stack for user mode?
|
||||
*/
|
||||
StackGuard(bool User, PageTable4 *Table);
|
||||
/**
|
||||
* @brief Destroy the Stack Guard object
|
||||
*/
|
||||
~StackGuard();
|
||||
};
|
||||
|
||||
class MemMgr
|
||||
{
|
||||
public:
|
||||
struct AllocatedPages
|
||||
{
|
||||
void *Address;
|
||||
size_t PageCount;
|
||||
};
|
||||
|
||||
std::vector<AllocatedPages> GetAllocatedPagesList() { return AllocatedPagesList; }
|
||||
uint64_t GetAllocatedMemorySize();
|
||||
|
||||
bool Add(void *Address, size_t Count);
|
||||
|
||||
void *RequestPages(size_t Count, bool User = false);
|
||||
void FreePages(void *Address, size_t Count);
|
||||
|
||||
void DetachAddress(void *Address);
|
||||
|
||||
MemMgr(PageTable4 *PageTable = nullptr, VirtualFileSystem::Node *Directory = nullptr);
|
||||
~MemMgr();
|
||||
|
||||
private:
|
||||
Bitmap PageBitmap;
|
||||
PageTable4 *PageTable;
|
||||
VirtualFileSystem::Node *Directory;
|
||||
|
||||
std::vector<AllocatedPages> AllocatedPagesList;
|
||||
};
|
||||
}
|
||||
|
||||
void InitializeMemoryManagement(BootInfo *Info);
|
||||
|
||||
void *operator new(size_t Size);
|
||||
void *operator new[](size_t Size);
|
||||
void *operator new(size_t Size, std::align_val_t Alignment);
|
||||
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);
|
||||
|
||||
extern Memory::Physical KernelAllocator;
|
||||
extern Memory::PageTable4 *KernelPageTable;
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
EXTERNC void *malloc(size_t Size);
|
||||
EXTERNC void *calloc(size_t n, size_t Size);
|
||||
EXTERNC void *realloc(void *Address, size_t Size);
|
||||
EXTERNC void free(void *Address);
|
||||
|
||||
#define kmalloc(Size) malloc(Size)
|
||||
#define kcalloc(n, Size) calloc(n, Size)
|
||||
#define krealloc(Address, Size) realloc(Address, Size)
|
||||
#define kfree(Address) free(Address)
|
||||
|
||||
#endif // !__FENNIX_KERNEL_INTERNAL_MEMORY_H__
|
248
Kernel/include/msexec.h
Normal file
248
Kernel/include/msexec.h
Normal file
@ -0,0 +1,248 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_MSEXEC_H__
|
||||
#define __FENNIX_KERNEL_MSEXEC_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
// some of the code is from: https://github.com/dotnet/llilc/blob/main/include/clr/ntimage.h
|
||||
|
||||
#define near /* __near */
|
||||
#define far /* __far */
|
||||
#define NEAR near
|
||||
#define FAR far
|
||||
#define CONST const
|
||||
|
||||
typedef char CHAR;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef wchar_t WCHAR;
|
||||
typedef unsigned short USHORT;
|
||||
typedef long LONG;
|
||||
|
||||
typedef unsigned long DWORD;
|
||||
typedef int BOOL;
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short WORD;
|
||||
typedef float FLOAT;
|
||||
typedef FLOAT *PFLOAT;
|
||||
typedef BOOL near *PBOOL;
|
||||
typedef BOOL far *LPBOOL;
|
||||
typedef BYTE near *PBYTE;
|
||||
typedef BYTE far *LPBYTE;
|
||||
typedef int near *PINT;
|
||||
typedef int far *LPINT;
|
||||
typedef WORD near *PWORD;
|
||||
typedef WORD far *LPWORD;
|
||||
typedef long far *LPLONG;
|
||||
typedef DWORD near *PDWORD;
|
||||
typedef DWORD far *LPDWORD;
|
||||
typedef void far *LPVOID;
|
||||
typedef CONST void far *LPCVOID;
|
||||
|
||||
typedef int INT;
|
||||
typedef unsigned int UINT;
|
||||
typedef unsigned int *PUINT;
|
||||
|
||||
typedef short SHORT;
|
||||
typedef DWORD ULONG;
|
||||
typedef double DOUBLE;
|
||||
|
||||
#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */
|
||||
#define IMAGE_OS2_SIGNATURE 0x454E /* NE */
|
||||
#define IMAGE_OS2_SIGNATURE_LE 0x454C /* LE */
|
||||
#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */
|
||||
#define IMAGE_EDOS_SIGNATURE 0x44454550 /* PEED */
|
||||
|
||||
#define IMAGE_SIZEOF_FILE_HEADER 20
|
||||
|
||||
#define IMAGE_FILE_MACHINE_UNKNOWN 0
|
||||
#define IMAGE_FILE_MACHINE_I860 0x14d
|
||||
#define IMAGE_FILE_MACHINE_I386 0x14c
|
||||
#define IMAGE_FILE_MACHINE_R3000 0x162
|
||||
#define IMAGE_FILE_MACHINE_R4000 0x166
|
||||
#define IMAGE_FILE_MACHINE_R10000 0x0168
|
||||
#define IMAGE_FILE_MACHINE_ALPHA 0x184
|
||||
#define IMAGE_FILE_MACHINE_POWERPC 0x01F0
|
||||
#define IMAGE_FILE_MACHINE_POWERPCBE 0x01F2
|
||||
#define IMAGE_FILE_MACHINE_SH3 0x01a2
|
||||
#define IMAGE_FILE_MACHINE_SH3E 0x01a4
|
||||
#define IMAGE_FILE_MACHINE_SH4 0x01a6
|
||||
#define IMAGE_FILE_MACHINE_ARM 0x01c0
|
||||
#define IMAGE_FILE_MACHINE_THUMB 0x01c2
|
||||
#define IMAGE_FILE_MACHINE_IA64 0x0200
|
||||
#define IMAGE_FILE_MACHINE_MIPS16 0x0266
|
||||
#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366
|
||||
#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466
|
||||
#define IMAGE_FILE_MACHINE_ALPHA64 0x0284
|
||||
#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64
|
||||
#define IMAGE_FILE_MACHINE_AMD64 0x8664
|
||||
#define IMAGE_FILE_MACHINE_CEF 0xC0EF
|
||||
|
||||
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
|
||||
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0
|
||||
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1
|
||||
#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2
|
||||
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
|
||||
#define IMAGE_DIRECTORY_ENTRY_SECURITY 4
|
||||
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5
|
||||
#define IMAGE_DIRECTORY_ENTRY_DEBUG 6
|
||||
#define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7
|
||||
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8
|
||||
#define IMAGE_DIRECTORY_ENTRY_TLS 9
|
||||
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
|
||||
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11
|
||||
#define IMAGE_DIRECTORY_ENTRY_IAT 12
|
||||
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13
|
||||
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14
|
||||
|
||||
typedef struct _IMAGE_DOS_HEADER // DOS .EXE header
|
||||
{
|
||||
USHORT e_magic; // Magic number
|
||||
USHORT e_cblp; // Bytes on last page of file
|
||||
USHORT e_cp; // Pages in file
|
||||
USHORT e_crlc; // Relocations
|
||||
USHORT e_cparhdr; // Size of header in paragraphs
|
||||
USHORT e_minalloc; // Minimum extra paragraphs needed
|
||||
USHORT e_maxalloc; // Maximum extra paragraphs needed
|
||||
USHORT e_ss; // Initial (relative) SS value
|
||||
USHORT e_sp; // Initial SP value
|
||||
USHORT e_csum; // Checksum
|
||||
USHORT e_ip; // Initial IP value
|
||||
USHORT e_cs; // Initial (relative) CS value
|
||||
USHORT e_lfarlc; // File address of relocation table
|
||||
USHORT e_ovno; // Overlay number
|
||||
USHORT e_res[4]; // Reserved words
|
||||
USHORT e_oemid; // OEM identifier (for e_oeminfo)
|
||||
USHORT e_oeminfo; // OEM information; e_oemid specific
|
||||
USHORT e_res2[10]; // Reserved words
|
||||
USHORT e_lfanew; // File address of new exe header
|
||||
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
|
||||
|
||||
typedef struct _IMAGE_OS2_HEADER // OS/2 .EXE header
|
||||
{
|
||||
USHORT ne_magic; // Magic number
|
||||
UCHAR ne_ver; // Version number
|
||||
UCHAR ne_rev; // Revision number
|
||||
USHORT ne_enttab; // Offset of Entry Table
|
||||
USHORT ne_cbenttab; // Number of bytes in Entry Table
|
||||
UINT ne_crc; // Checksum of whole file
|
||||
USHORT ne_flags; // Flag word
|
||||
USHORT ne_autodata; // Automatic data segment number
|
||||
USHORT ne_heap; // Initial heap allocation
|
||||
USHORT ne_stack; // Initial stack allocation
|
||||
UINT ne_csip; // Initial CS:IP setting
|
||||
UINT ne_sssp; // Initial SS:SP setting
|
||||
USHORT ne_cseg; // Count of file segments
|
||||
USHORT ne_cmod; // Entries in Module Reference Table
|
||||
USHORT ne_cbnrestab; // Size of non-resident name table
|
||||
USHORT ne_segtab; // Offset of Segment Table
|
||||
USHORT ne_rsrctab; // Offset of Resource Table
|
||||
USHORT ne_restab; // Offset of resident name table
|
||||
USHORT ne_modtab; // Offset of Module Reference Table
|
||||
USHORT ne_imptab; // Offset of Imported Names Table
|
||||
UINT ne_nrestab; // Offset of Non-resident Names Table
|
||||
USHORT ne_cmovent; // Count of movable entries
|
||||
USHORT ne_align; // Segment alignment shift count
|
||||
USHORT ne_cres; // Count of resource segments
|
||||
UCHAR ne_exetyp; // Target Operating system
|
||||
UCHAR ne_flagsothers; // Other .EXE flags
|
||||
USHORT ne_pretthunks; // offset to return thunks
|
||||
USHORT ne_psegrefbytes; // offset to segment ref. bytes
|
||||
USHORT ne_swaparea; // Minimum code swap area size
|
||||
USHORT ne_expver; // Expected Windows version number
|
||||
} IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER;
|
||||
|
||||
typedef struct _IMAGE_SECTION_HEADER
|
||||
{
|
||||
#define IMAGE_SIZEOF_SHORT_NAME 8
|
||||
uint8_t Name[IMAGE_SIZEOF_SHORT_NAME];
|
||||
union
|
||||
{
|
||||
uint32_t PhysicalAddress;
|
||||
uint32_t VirtualSize;
|
||||
} Misc;
|
||||
uint32_t VirtualAddress;
|
||||
uint32_t SizeOfRawData;
|
||||
uint32_t PointerToRawData;
|
||||
uint32_t PointerToRelocations;
|
||||
uint32_t PointerToLinenumbers;
|
||||
uint16_t NumberOfRelocations;
|
||||
uint16_t NumberOfLinenumbers;
|
||||
uint32_t Characteristics;
|
||||
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
|
||||
|
||||
typedef struct _IMAGE_FILE_HEADER
|
||||
{
|
||||
uint16_t Machine;
|
||||
uint16_t NumberOfSections;
|
||||
uint32_t TimeDateStamp;
|
||||
uint32_t PointerToSymbolTable;
|
||||
uint32_t NumberOfSymbols;
|
||||
uint16_t SizeOfOptionalHeader;
|
||||
uint16_t Characteristics;
|
||||
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
|
||||
|
||||
typedef struct _IMAGE_DATA_DIRECTORY
|
||||
{
|
||||
uint32_t VirtualAddress;
|
||||
uint32_t Size;
|
||||
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
|
||||
|
||||
typedef struct _IMAGE_OPTIONAL_HEADER
|
||||
{
|
||||
uint16_t Magic;
|
||||
uint8_t MajorLinkerVersion;
|
||||
uint8_t MinorLinkerVersion;
|
||||
uint32_t SizeOfCode;
|
||||
uint32_t SizeOfInitializedData;
|
||||
uint32_t SizeOfUninitializedData;
|
||||
uint32_t AddressOfEntryPoint;
|
||||
uint32_t BaseOfCode;
|
||||
uint32_t BaseOfData;
|
||||
uint32_t ImageBase;
|
||||
uint32_t SectionAlignment;
|
||||
uint32_t FileAlignment;
|
||||
uint16_t MajorOperatingSystemVersion;
|
||||
uint16_t MinorOperatingSystemVersion;
|
||||
uint16_t MajorImageVersion;
|
||||
uint16_t MinorImageVersion;
|
||||
uint16_t MajorSubsystemVersion;
|
||||
uint16_t MinorSubsystemVersion;
|
||||
uint32_t Win32VersionValue;
|
||||
uint32_t SizeOfImage;
|
||||
uint32_t SizeOfHeaders;
|
||||
uint32_t CheckSum;
|
||||
uint16_t Subsystem;
|
||||
uint16_t DllCharacteristics;
|
||||
uint32_t SizeOfStackReserve;
|
||||
uint32_t SizeOfStackCommit;
|
||||
uint32_t SizeOfHeapReserve;
|
||||
uint32_t SizeOfHeapCommit;
|
||||
uint32_t LoaderFlags;
|
||||
uint32_t NumberOfRvaAndSizes;
|
||||
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
|
||||
} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
|
||||
|
||||
typedef struct _IMAGE_NT_HEADERS
|
||||
{
|
||||
uint32_t Signature;
|
||||
IMAGE_FILE_HEADER FileHeader;
|
||||
IMAGE_OPTIONAL_HEADER OptionalHeader;
|
||||
} IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS;
|
||||
|
||||
#endif // !__FENNIX_KERNEL_MSEXEC_H__
|
106
Kernel/include/net/arp.hpp
Normal file
106
Kernel/include/net/arp.hpp
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_NETWORK_ARP_H__
|
||||
#define __FENNIX_KERNEL_NETWORK_ARP_H__
|
||||
|
||||
#include <net/eth.hpp>
|
||||
#include <net/nc.hpp>
|
||||
#include <types.h>
|
||||
#include <vector>
|
||||
|
||||
namespace NetworkARP
|
||||
{
|
||||
enum ARPOperation
|
||||
{
|
||||
REQUEST = 0x1,
|
||||
REPLY = 0x2
|
||||
};
|
||||
|
||||
enum ARPHardwareType
|
||||
{
|
||||
HTYPE_ETHERNET = 1,
|
||||
HTYPE_802_3 = 6,
|
||||
HTYPE_ARCNET = 7,
|
||||
HTYPE_FRAME_RELAY = 15,
|
||||
HTYPE_ATM = 16,
|
||||
HTYPE_HDLC = 17,
|
||||
HTYPE_FIBRE_CHANNEL = 18,
|
||||
HTYPE_ATM_2 = 19,
|
||||
HTYPE_SERIAL_LINE = 20
|
||||
};
|
||||
|
||||
struct ARPHeader
|
||||
{
|
||||
uint16_t HardwareType;
|
||||
uint16_t ProtocolType;
|
||||
uint8_t HardwareSize;
|
||||
uint8_t ProtocolSize;
|
||||
uint16_t Operation;
|
||||
uint48_t SenderMAC : 48;
|
||||
uint32_t SenderIP;
|
||||
uint48_t TargetMAC : 48;
|
||||
uint32_t TargetIP;
|
||||
} __packed;
|
||||
|
||||
struct DiscoveredAddress
|
||||
{
|
||||
MediaAccessControl MAC;
|
||||
InternetProtocol IP;
|
||||
};
|
||||
|
||||
class ARP : public NetworkEthernet::EthernetEvents
|
||||
{
|
||||
private:
|
||||
NetworkEthernet::Ethernet *Ethernet;
|
||||
|
||||
enum DAType
|
||||
{
|
||||
DA_ADD = 1,
|
||||
DA_DEL = 2,
|
||||
DA_SEARCH = 3,
|
||||
DA_UPDATE = 4
|
||||
};
|
||||
|
||||
std::vector<NetworkARP::DiscoveredAddress *> DiscoveredAddresses;
|
||||
DiscoveredAddress *ManageDiscoveredAddresses(DAType Type, InternetProtocol IP, MediaAccessControl MAC);
|
||||
DiscoveredAddress *Search(InternetProtocol TargetIP);
|
||||
DiscoveredAddress *Update(InternetProtocol TargetIP, MediaAccessControl TargetMAC);
|
||||
bool OnEthernetPacketReceived(uint8_t *Data, uint64_t Length);
|
||||
|
||||
public:
|
||||
ARP(NetworkEthernet::Ethernet *Ethernet);
|
||||
~ARP();
|
||||
|
||||
/**
|
||||
* @brief Resolve an IP address to a MAC address.
|
||||
*
|
||||
* @param IP The IP address to resolve. (Little-endian)
|
||||
* @return uint48_t The MAC address of the IP address.
|
||||
*/
|
||||
uint48_t Resolve(InternetProtocol IP);
|
||||
|
||||
/**
|
||||
* @brief Broadcast an ARP packet.
|
||||
*
|
||||
* @param IP The IP address to broadcast.
|
||||
*/
|
||||
void Broadcast(InternetProtocol IP);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_NETWORK_ARP_H__
|
182
Kernel/include/net/dhcp.hpp
Normal file
182
Kernel/include/net/dhcp.hpp
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_DHCP_H__
|
||||
#define __FENNIX_KERNEL_DHCP_H__
|
||||
|
||||
#include <net/ipv4.hpp>
|
||||
#include <net/udp.hpp>
|
||||
#include <net/nc.hpp>
|
||||
#include <types.h>
|
||||
|
||||
namespace NetworkDHCP
|
||||
{
|
||||
struct DHCPHeader
|
||||
{
|
||||
uint8_t Opcode;
|
||||
uint8_t HardwareType;
|
||||
uint8_t HardwareAddressLength;
|
||||
uint8_t Hops;
|
||||
uint32_t TransactionID;
|
||||
uint16_t Seconds;
|
||||
uint16_t Flags;
|
||||
uint32_t ClientIP;
|
||||
uint32_t YourIP;
|
||||
uint32_t ServerIP;
|
||||
uint32_t GatewayIP;
|
||||
uint8_t ClientHardwareAddress[16];
|
||||
uint8_t ServerHostName[64];
|
||||
uint8_t BootFileName[128];
|
||||
uint8_t Options[64];
|
||||
} __packed;
|
||||
|
||||
enum DHCPOperation
|
||||
{
|
||||
DHCP_OP_BOOTREQUEST = 1,
|
||||
DHCP_OP_BOOTREPLY = 2
|
||||
};
|
||||
|
||||
/* TODO: Complete list from https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol#Options */
|
||||
enum DHCPOption
|
||||
{
|
||||
DHCP_OPTION_PAD = 0,
|
||||
DHCP_OPTION_SUBNETMASK = 1,
|
||||
DHCP_OPTION_TIME_OFFSET = 2,
|
||||
DHCP_OPTION_ROUTER = 3,
|
||||
DHCP_OPTION_TIME_SERVER = 4,
|
||||
DHCP_OPTION_NAME_SERVER = 5,
|
||||
DHCP_OPTION_DOMAIN_NAME_SERVER = 6,
|
||||
DHCP_OPTION_LOG_SERVER = 7,
|
||||
DHCP_OPTION_COOKIE_SERVER = 8,
|
||||
DHCP_OPTION_LPR_SERVER = 9,
|
||||
DHCP_OPTION_IMPRESS_SERVER = 10,
|
||||
DHCP_OPTION_RESOURCE_LOCATION_SERVER = 11,
|
||||
DHCP_OPTION_HOST_NAME = 12,
|
||||
DHCP_OPTION_BOOT_FILE_SIZE = 13,
|
||||
DHCP_OPTION_MERIT_DUMP_FILE = 14,
|
||||
DHCP_OPTION_DOMAIN_NAME = 15,
|
||||
DHCP_OPTION_SWAP_SERVER = 16,
|
||||
DHCP_OPTION_ROOT_PATH = 17,
|
||||
DHCP_OPTION_EXTENSION_PATH = 18,
|
||||
|
||||
DHCP_OPTION_IP_FORWARDING = 19,
|
||||
DHCP_OPTION_NON_LOCAL_SOURCE_ROUTING = 20,
|
||||
DHCP_OPTION_POLICY_FILTER = 21,
|
||||
DHCP_OPTION_MAX_DATAGRAM_REASSEMBLY_SIZE = 22,
|
||||
DHCP_OPTION_DEFAULT_IP_TTL = 23,
|
||||
DHCP_OPTION_PATH_MTU_AGING_TIMEOUT = 24,
|
||||
DHCP_OPTION_PATH_MTU_PLATEAU_TABLE = 25,
|
||||
|
||||
DHCP_OPTION_INTERFACE_MTU = 26,
|
||||
DHCP_OPTION_ALL_SUBNETS_ARE_LOCAL = 27,
|
||||
DHCP_OPTION_BROADCAST_ADDRESS = 28,
|
||||
DHCP_OPTION_PERFORM_MASK_DISCOVERY = 29,
|
||||
DHCP_OPTION_MASK_SUPPLIER = 30,
|
||||
DHCP_OPTION_ROUTER_DISCOVERY = 31,
|
||||
DHCP_OPTION_ROUTER_SOLICITATION_ADDRESS = 32,
|
||||
DHCP_OPTION_STATIC_ROUTE = 33,
|
||||
|
||||
DHCP_OPTION_TRAILER_ENCAPSULATION = 34,
|
||||
DHCP_OPTION_ARP_CACHE_TIMEOUT = 35,
|
||||
DHCP_OPTION_ETHERNET_ENCAPSULATION = 36,
|
||||
|
||||
DHCP_OPTION_DEFAULT_TCP_TTL = 37,
|
||||
DHCP_OPTION_TCP_KEEPALIVE_INTERVAL = 38,
|
||||
DHCP_OPTION_TCP_KEEPALIVE_GARBAGE = 39,
|
||||
|
||||
DHCP_OPTION_NIS_DOMAIN = 40,
|
||||
DHCP_OPTION_NIS_SERVERS = 41,
|
||||
DHCP_OPTION_NTP_SERVERS = 42,
|
||||
DHCP_OPTION_VENDOR_SPECIFIC = 43,
|
||||
DHCP_OPTION_NETBIOS_NAME_SERVERS = 44,
|
||||
DHCP_OPTION_NETBIOS_DD_SERVER = 45,
|
||||
DHCP_OPTION_NETBIOS_NODE_TYPE = 46,
|
||||
DHCP_OPTION_NETBIOS_SCOPE = 47,
|
||||
DHCP_OPTION_X_FONT_SERVERS = 48,
|
||||
DHCP_OPTION_X_DISPLAY_MANAGER = 49,
|
||||
|
||||
DHCP_OPTION_REQUESTED_IP = 50,
|
||||
DHCP_OPTION_IP_LEASE_TIME = 51,
|
||||
DHCP_OPTION_OPTION_OVERLOAD = 52,
|
||||
DHCP_OPTION_MESSAGE_TYPE = 53,
|
||||
DHCP_OPTION_SERVER_IDENTIFIER = 54,
|
||||
DHCP_OPTION_PARAMETER_REQUEST_LIST = 55,
|
||||
DHCP_OPTION_MESSAGE = 56,
|
||||
DHCP_OPTION_MAX_MESSAGE_SIZE = 57,
|
||||
DHCP_OPTION_T1_TIMEOUT = 58,
|
||||
DHCP_OPTION_T2_TIMEOUT = 59,
|
||||
DHCP_OPTION_VENDOR_CLASS_IDENTIFIER = 60,
|
||||
DHCP_OPTION_CLIENT_IDENTIFIER = 61,
|
||||
|
||||
DHCP_OPTION_NETWORK_TIME_SERVER = 62,
|
||||
|
||||
DHCP_OPTION_END = 255
|
||||
};
|
||||
|
||||
enum DHCPMessageType
|
||||
{
|
||||
DHCP_MESSAGE_TYPE_DISCOVER = 1,
|
||||
DHCP_MESSAGE_TYPE_OFFER = 2,
|
||||
DHCP_MESSAGE_TYPE_REQUEST = 3,
|
||||
DHCP_MESSAGE_TYPE_DECLINE = 4,
|
||||
DHCP_MESSAGE_TYPE_ACK = 5,
|
||||
DHCP_MESSAGE_TYPE_NAK = 6,
|
||||
DHCP_MESSAGE_TYPE_RELEASE = 7,
|
||||
DHCP_MESSAGE_TYPE_INFORM = 8,
|
||||
DHCP_MESSAGE_TYPE_FORCERENEW = 9,
|
||||
DHCP_MESSAGE_TYPE_LEASEQUERY = 10,
|
||||
DHCP_MESSAGE_TYPE_LEASEUNASSIGNED = 11,
|
||||
DHCP_MESSAGE_TYPE_LEASEUNKNOWN = 12,
|
||||
DHCP_MESSAGE_TYPE_LEASEACTIVE = 13,
|
||||
DHCP_MESSAGE_TYPE_BULKLEASEQUERY = 14,
|
||||
DHCP_MESSAGE_TYPE_LEASEQUERYDONE = 15,
|
||||
DHCP_MESSAGE_TYPE_ACTIVELEASEQUERY = 16,
|
||||
DHCP_MESSAGE_TYPE_LEASEQUERYSTATUS = 17,
|
||||
DHCP_MESSAGE_TYPE_DHCPTLS = 18
|
||||
};
|
||||
|
||||
#define DHCP_TRANSACTION_ID 0xFE2EC005
|
||||
|
||||
class DHCP : public NetworkUDP::UDPEvents
|
||||
{
|
||||
private:
|
||||
NetworkUDP::Socket *UDPSocket;
|
||||
NetworkInterfaceManager::DeviceInterface *Interface;
|
||||
bool Received = false;
|
||||
|
||||
void CreatePacket(DHCPHeader *Packet, uint8_t MessageType, uint32_t RequestIP);
|
||||
void *GetOption(DHCPHeader *Packet, uint8_t Type);
|
||||
void OnUDPPacketReceived(NetworkUDP::Socket *Socket, uint8_t *Data, uint64_t Length);
|
||||
|
||||
public:
|
||||
/** @brief IP address (Little-endian) */
|
||||
InternetProtocol IP = {};
|
||||
/** @brief Gateway address (Little-endian) */
|
||||
InternetProtocol Gateway = {};
|
||||
/** @brief Subnet mask (Little-endian) */
|
||||
InternetProtocol SubNetworkMask = {};
|
||||
/** @brief DNS server address (Little-endian) */
|
||||
InternetProtocol DomainNameSystem = {};
|
||||
|
||||
DHCP(NetworkUDP::Socket *Socket, NetworkInterfaceManager::DeviceInterface *Interface);
|
||||
~DHCP();
|
||||
void Request();
|
||||
void Request(InternetProtocol IP);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_DHCP_H__
|
37
Kernel/include/net/dns.hpp
Normal file
37
Kernel/include/net/dns.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_DNS_H__
|
||||
#define __FENNIX_KERNEL_DNS_H__
|
||||
|
||||
#include <net/udp.hpp>
|
||||
#include <types.h>
|
||||
|
||||
namespace NetworkDNS
|
||||
{
|
||||
class DNS : public NetworkUDP::UDPEvents
|
||||
{
|
||||
private:
|
||||
NetworkUDP::Socket *UDPSocket;
|
||||
|
||||
public:
|
||||
DNS(NetworkUDP::Socket *Socket);
|
||||
~DNS();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_DNS_H__
|
108
Kernel/include/net/eth.hpp
Normal file
108
Kernel/include/net/eth.hpp
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_NETWORK_ETHERNET_H__
|
||||
#define __FENNIX_KERNEL_NETWORK_ETHERNET_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <net/nc.hpp>
|
||||
|
||||
namespace NetworkEthernet
|
||||
{
|
||||
enum FrameType
|
||||
{
|
||||
TYPE_IPV4 = 0x0800,
|
||||
TYPE_ARP = 0x0806,
|
||||
TYPE_RARP = 0x8035,
|
||||
TYPE_IPV6 = 0x86DD
|
||||
};
|
||||
|
||||
struct EthernetHeader
|
||||
{
|
||||
uint48_t DestinationMAC : 48;
|
||||
uint48_t SourceMAC : 48;
|
||||
uint16_t Type;
|
||||
} __packed;
|
||||
|
||||
struct EthernetPacket
|
||||
{
|
||||
EthernetHeader Header;
|
||||
uint8_t Data[];
|
||||
};
|
||||
|
||||
class EthernetEvents
|
||||
{
|
||||
private:
|
||||
FrameType FType;
|
||||
|
||||
protected:
|
||||
EthernetEvents(FrameType Type);
|
||||
~EthernetEvents();
|
||||
|
||||
public:
|
||||
FrameType GetFrameType() { return FType; }
|
||||
virtual void OnEthernetPacketSent(EthernetPacket *Packet)
|
||||
{
|
||||
UNUSED(Packet);
|
||||
netdbg("Event not handled. [%p]", Packet);
|
||||
}
|
||||
|
||||
virtual bool OnEthernetPacketReceived(uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
UNUSED(Data);
|
||||
UNUSED(Length);
|
||||
netdbg("Event not handled. [%p, %d]", Data, Length);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class Ethernet : public NetworkInterfaceManager::Events
|
||||
{
|
||||
private:
|
||||
NetworkInterfaceManager::DeviceInterface *Interface;
|
||||
void Receive(uint8_t *Data, uint64_t Length);
|
||||
void OnInterfaceReceived(NetworkInterfaceManager::DeviceInterface *Interface, uint8_t *Data, uint64_t Length);
|
||||
|
||||
public:
|
||||
/** @brief Get driver interface
|
||||
* @return Driver interface
|
||||
*/
|
||||
NetworkInterfaceManager::DeviceInterface *GetInterface()
|
||||
{
|
||||
netdbg("Interface: %#lx (MAC: %s; IPv4: %s; IPv6: %s)", this->Interface,
|
||||
this->Interface->MAC.ToString(),
|
||||
this->Interface->IP.v4.ToStringLittleEndian(),
|
||||
this->Interface->IP.v6.ToStringLittleEndian());
|
||||
return this->Interface;
|
||||
}
|
||||
|
||||
Ethernet(NetworkInterfaceManager::DeviceInterface *Interface);
|
||||
~Ethernet();
|
||||
|
||||
/**
|
||||
* @brief Send an Ethernet packet.
|
||||
*
|
||||
* @param MAC The MAC address of the destination. (Big-endian)
|
||||
* @param Type The type of the packet.
|
||||
* @param Data The data to send.
|
||||
* @param Length The length of the data.
|
||||
*/
|
||||
void Send(MediaAccessControl MAC, FrameType Type, uint8_t *Data, uint64_t Length);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_NETWORK_ETHERNET_H__
|
71
Kernel/include/net/icmpv4.hpp
Normal file
71
Kernel/include/net/icmpv4.hpp
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_ICMPv4_H__
|
||||
#define __FENNIX_KERNEL_ICMPv4_H__
|
||||
|
||||
#include <net/nc.hpp>
|
||||
#include <types.h>
|
||||
|
||||
namespace NetworkICMPv4
|
||||
{
|
||||
enum ICMPv4Type
|
||||
{
|
||||
TYPE_ECHO_REPLY = 0,
|
||||
TYPE_DESTINATION_UNREACHABLE = 3,
|
||||
TYPE_SOURCE_QUENCH = 4,
|
||||
TYPE_REDIRECT = 5,
|
||||
TYPE_ECHO = 8,
|
||||
TYPE_ROUTER_ADVERTISEMENT = 9,
|
||||
TYPE_ROUTER_SELECTION = 10,
|
||||
TYPE_TIME_EXCEEDED = 11,
|
||||
TYPE_PARAMETER_PROBLEM = 12,
|
||||
TYPE_TIMESTAMP = 13,
|
||||
TYPE_TIMESTAMP_REPLY = 14
|
||||
};
|
||||
|
||||
struct ICMPHeader
|
||||
{
|
||||
uint8_t Type;
|
||||
uint8_t Code;
|
||||
uint16_t Checksum;
|
||||
uint16_t Identifier;
|
||||
uint16_t SequenceNumber;
|
||||
};
|
||||
|
||||
struct ICMPPacket
|
||||
{
|
||||
ICMPHeader Header;
|
||||
uint8_t Data[];
|
||||
};
|
||||
|
||||
class ICMPv4
|
||||
{
|
||||
private:
|
||||
NetworkInterfaceManager::DeviceInterface *Interface;
|
||||
|
||||
public:
|
||||
NetworkInterfaceManager::DeviceInterface *GetInterface() { return this->Interface; }
|
||||
|
||||
ICMPv4(NetworkInterfaceManager::DeviceInterface *Interface);
|
||||
~ICMPv4();
|
||||
void Send(/* ???? */);
|
||||
void Receive(ICMPPacket *Packet);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_ICMPv4_H__
|
56
Kernel/include/net/icmpv6.hpp
Normal file
56
Kernel/include/net/icmpv6.hpp
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_ICMPv6_H__
|
||||
#define __FENNIX_KERNEL_ICMPv6_H__
|
||||
|
||||
#include <net/nc.hpp>
|
||||
#include <types.h>
|
||||
|
||||
namespace NetworkICMPv6
|
||||
{
|
||||
struct ICMPHeader
|
||||
{
|
||||
uint8_t Type;
|
||||
uint8_t Code;
|
||||
uint16_t Checksum;
|
||||
uint16_t Identifier;
|
||||
uint16_t SequenceNumber;
|
||||
};
|
||||
|
||||
struct ICMPPacket
|
||||
{
|
||||
ICMPHeader Header;
|
||||
uint8_t Data[];
|
||||
};
|
||||
|
||||
class ICMPv6
|
||||
{
|
||||
private:
|
||||
NetworkInterfaceManager::DeviceInterface *Interface;
|
||||
|
||||
public:
|
||||
NetworkInterfaceManager::DeviceInterface *GetInterface() { return this->Interface; }
|
||||
|
||||
ICMPv6(NetworkInterfaceManager::DeviceInterface *Interface);
|
||||
~ICMPv6();
|
||||
void Send(uint8_t *Data, uint64_t Length);
|
||||
void Receive(uint8_t *Data);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_ICMPv6_H__
|
137
Kernel/include/net/ipv4.hpp
Normal file
137
Kernel/include/net/ipv4.hpp
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_IPv4_H__
|
||||
#define __FENNIX_KERNEL_IPv4_H__
|
||||
|
||||
#include <net/ipv4.hpp>
|
||||
#include <net/arp.hpp>
|
||||
#include <net/nc.hpp>
|
||||
#include <types.h>
|
||||
|
||||
namespace NetworkIPv4
|
||||
{
|
||||
struct IPv4Header
|
||||
{
|
||||
uint8_t IHL : 4;
|
||||
uint8_t Version : 4;
|
||||
uint8_t TypeOfService;
|
||||
uint16_t TotalLength;
|
||||
uint16_t Identification;
|
||||
uint8_t Flags;
|
||||
uint8_t FragmentOffset;
|
||||
uint8_t TimeToLive;
|
||||
uint8_t Protocol;
|
||||
uint16_t HeaderChecksum;
|
||||
uint32_t SourceIP;
|
||||
uint32_t DestinationIP;
|
||||
|
||||
/* On wikipedia page we have this: https://en.wikipedia.org/wiki/File:IPv4_Packet-en.svg
|
||||
but only the code above works... */
|
||||
// uint8_t Version : 4;
|
||||
// uint8_t IHL : 4;
|
||||
// uint16_t TypeOfService : 8;
|
||||
// uint16_t TotalLength : 12;
|
||||
// uint16_t Identification : 16;
|
||||
// uint16_t Flags : 3;
|
||||
// uint16_t FragmentOffset : 13;
|
||||
// uint8_t TimeToLive : 8;
|
||||
// uint8_t Protocol : 8;
|
||||
// uint16_t HeaderChecksum;
|
||||
// uint32_t SourceIP;
|
||||
// uint32_t DestinationIP;
|
||||
};
|
||||
|
||||
struct IPv4Packet
|
||||
{
|
||||
IPv4Header Header;
|
||||
uint8_t Data[];
|
||||
};
|
||||
|
||||
enum IPv4Protocols
|
||||
{
|
||||
PROTOCOL_ICMP = 1,
|
||||
PROTOCOL_IGMP = 2,
|
||||
PROTOCOL_TCP = 6,
|
||||
PROTOCOL_UDP = 17,
|
||||
PROTOCOL_IPV6 = 41,
|
||||
PROTOCOL_ROUTING = 43,
|
||||
PROTOCOL_FRAGMENT = 44,
|
||||
PROTOCOL_ESP = 50,
|
||||
PROTOCOL_AH = 51,
|
||||
PROTOCOL_ICMPV6 = 58,
|
||||
PROTOCOL_NONE = 59,
|
||||
PROTOCOL_DSTOPTS = 60,
|
||||
PROTOCOL_ND = 77,
|
||||
PROTOCOL_ICLFXBM = 78,
|
||||
PROTOCOL_PIM = 103,
|
||||
PROTOCOL_COMP = 108,
|
||||
PROTOCOL_SCTP = 132,
|
||||
PROTOCOL_UDPLITE = 136,
|
||||
PROTOCOL_RAW = 255
|
||||
};
|
||||
|
||||
class IPv4 : public NetworkEthernet::EthernetEvents
|
||||
{
|
||||
private:
|
||||
NetworkARP::ARP *ARP;
|
||||
NetworkEthernet::Ethernet *Ethernet;
|
||||
|
||||
virtual bool OnEthernetPacketReceived(uint8_t *Data, uint64_t Length);
|
||||
|
||||
public:
|
||||
InternetProtocol GatewayIP;
|
||||
InternetProtocol SubNetworkMaskIP;
|
||||
IPv4(NetworkARP::ARP *ARP, NetworkEthernet::Ethernet *Ethernet);
|
||||
~IPv4();
|
||||
|
||||
/**
|
||||
* @brief Send an IPv4 packet.
|
||||
*
|
||||
* @param Data The data to send.
|
||||
* @param Length The length of the data.
|
||||
* @param Protocol The protocol of the packet.
|
||||
* @param DestinationIP The IP address of the destination. (Big-endian)
|
||||
*/
|
||||
void Send(uint8_t *Data, uint64_t Length, uint8_t Protocol, InternetProtocol DestinationIP);
|
||||
};
|
||||
|
||||
class IPv4Events
|
||||
{
|
||||
private:
|
||||
uint8_t Protocol;
|
||||
|
||||
protected:
|
||||
IPv4Events(IPv4Protocols Protocol);
|
||||
~IPv4Events();
|
||||
|
||||
public:
|
||||
uint8_t GetProtocol() { return Protocol; }
|
||||
|
||||
virtual bool OnIPv4PacketReceived(InternetProtocol SourceIP, InternetProtocol DestinationIP, uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
UNUSED(SourceIP);
|
||||
UNUSED(DestinationIP);
|
||||
UNUSED(Data);
|
||||
UNUSED(Length);
|
||||
warn("Not implemented.");
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_IPv4_H__
|
44
Kernel/include/net/ipv6.hpp
Normal file
44
Kernel/include/net/ipv6.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_IPv6_H__
|
||||
#define __FENNIX_KERNEL_IPv6_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
namespace NetworkIPv6
|
||||
{
|
||||
struct IPv6Header
|
||||
{
|
||||
uint32_t Version;
|
||||
uint8_t TrafficClass;
|
||||
uint16_t FlowLabel;
|
||||
uint16_t PayloadLength;
|
||||
uint8_t NextHeader;
|
||||
uint8_t HopLimit;
|
||||
uint32_t SourceIP;
|
||||
uint32_t DestinationIP;
|
||||
};
|
||||
|
||||
struct IPv6Packet
|
||||
{
|
||||
IPv6Header Header;
|
||||
uint8_t Data[];
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_IPv6_H__
|
116
Kernel/include/net/nc.hpp
Normal file
116
Kernel/include/net/nc.hpp
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_NETWORK_CONTROLLER_H__
|
||||
#define __FENNIX_KERNEL_NETWORK_CONTROLLER_H__
|
||||
|
||||
#include <net/net.hpp>
|
||||
#include <memory.hpp>
|
||||
#include <task.hpp>
|
||||
#include <types.h>
|
||||
#include <debug.h>
|
||||
#include <vector>
|
||||
|
||||
namespace NetworkInterfaceManager
|
||||
{
|
||||
struct DeviceInterface
|
||||
{
|
||||
/** @brief Device interface name */
|
||||
char Name[128];
|
||||
|
||||
/** @brief Device interface index */
|
||||
uint64_t ID;
|
||||
|
||||
/** @brief Device interface MAC address (Big-endian) */
|
||||
MediaAccessControl MAC;
|
||||
|
||||
/** @brief Device interface IP address (Big-endian) */
|
||||
InternetProtocol IP;
|
||||
|
||||
/** @brief Reserved */
|
||||
unsigned long DriverID;
|
||||
};
|
||||
|
||||
class Events
|
||||
{
|
||||
protected:
|
||||
Events(DeviceInterface *Interface);
|
||||
~Events();
|
||||
|
||||
public:
|
||||
virtual void OnInterfaceAdded(DeviceInterface *Interface)
|
||||
{
|
||||
UNUSED(Interface);
|
||||
netdbg("Event for %s not handled.", Interface->Name);
|
||||
}
|
||||
|
||||
virtual void OnInterfaceRemoved(DeviceInterface *Interface)
|
||||
{
|
||||
UNUSED(Interface);
|
||||
netdbg("Event for %s not handled.", Interface->Name);
|
||||
}
|
||||
|
||||
virtual void OnInterfaceChanged(DeviceInterface *Interface)
|
||||
{
|
||||
UNUSED(Interface);
|
||||
netdbg("Event for %s not handled.", Interface->Name);
|
||||
}
|
||||
|
||||
virtual void OnInterfaceReceived(DeviceInterface *Interface, uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
UNUSED(Interface);
|
||||
UNUSED(Data);
|
||||
UNUSED(Length);
|
||||
netdbg("Event for %s not handled.", Interface->Name);
|
||||
}
|
||||
|
||||
virtual void OnInterfaceSent(DeviceInterface *Interface, uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
UNUSED(Interface);
|
||||
UNUSED(Data);
|
||||
UNUSED(Length);
|
||||
netdbg("Event for %s not handled.", Interface->Name);
|
||||
}
|
||||
};
|
||||
|
||||
class NetworkInterface
|
||||
{
|
||||
private:
|
||||
Memory::MemMgr *mem;
|
||||
int CardIDs = 0;
|
||||
std::vector<DeviceInterface *> Interfaces;
|
||||
|
||||
Tasking::TCB *NetSvcThread;
|
||||
void StopNetworkStack();
|
||||
void FetchNetworkCards(unsigned long DriverUID);
|
||||
|
||||
public:
|
||||
NetworkInterface();
|
||||
~NetworkInterface();
|
||||
|
||||
void StartService();
|
||||
|
||||
void Send(DeviceInterface *Interface, uint8_t *Data, uint64_t Length);
|
||||
void Receive(DeviceInterface *Interface, uint8_t *Data, uint64_t Length);
|
||||
|
||||
void DrvSend(unsigned int DriverID, unsigned char *Data, unsigned short Size);
|
||||
void DrvReceive(unsigned int DriverID, unsigned char *Data, unsigned short Size);
|
||||
void StartNetworkStack();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_NETWORK_CONTROLLER_H__
|
232
Kernel/include/net/net.hpp
Normal file
232
Kernel/include/net/net.hpp
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_NETWORK_H__
|
||||
#define __FENNIX_KERNEL_NETWORK_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <printf.h>
|
||||
|
||||
// #define DEBUG_NETWORK 1
|
||||
|
||||
#ifdef DEBUG_NETWORK
|
||||
#define netdbg(m, ...) debug(m, ##__VA_ARGS__)
|
||||
void DbgNetwork();
|
||||
void DbgDumpData(const char *Description, void *Address, unsigned long Length);
|
||||
#else
|
||||
#define netdbg(m, ...)
|
||||
static inline void DbgNetwork() { return; }
|
||||
static inline void DbgDumpData(const char *Description, void *Address, unsigned long Length)
|
||||
{
|
||||
UNUSED(Description);
|
||||
UNUSED(Address);
|
||||
UNUSED(Length);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
enum Endianness
|
||||
{
|
||||
LITTLE_ENDIAN,
|
||||
BIG_ENDIAN
|
||||
};
|
||||
|
||||
struct MediaAccessControl
|
||||
{
|
||||
uint8_t Address[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
|
||||
Endianness Endianess = LITTLE_ENDIAN;
|
||||
|
||||
inline bool operator==(const MediaAccessControl &lhs) const
|
||||
{
|
||||
return lhs.Address[0] == this->Address[0] &&
|
||||
lhs.Address[1] == this->Address[1] &&
|
||||
lhs.Address[2] == this->Address[2] &&
|
||||
lhs.Address[3] == this->Address[3] &&
|
||||
lhs.Address[4] == this->Address[4] &&
|
||||
lhs.Address[5] == this->Address[5];
|
||||
}
|
||||
|
||||
inline bool operator==(const uint48_t &lhs) const
|
||||
{
|
||||
MediaAccessControl MAC;
|
||||
MAC.Address[0] = (uint8_t)((lhs >> 40) & 0xFF);
|
||||
MAC.Address[1] = (uint8_t)((lhs >> 32) & 0xFF);
|
||||
MAC.Address[2] = (uint8_t)((lhs >> 24) & 0xFF);
|
||||
MAC.Address[3] = (uint8_t)((lhs >> 16) & 0xFF);
|
||||
MAC.Address[4] = (uint8_t)((lhs >> 8) & 0xFF);
|
||||
MAC.Address[5] = (uint8_t)(lhs & 0xFF);
|
||||
return MAC.Address[0] == this->Address[0] &&
|
||||
MAC.Address[1] == this->Address[1] &&
|
||||
MAC.Address[2] == this->Address[2] &&
|
||||
MAC.Address[3] == this->Address[3] &&
|
||||
MAC.Address[4] == this->Address[4] &&
|
||||
MAC.Address[5] == this->Address[5];
|
||||
}
|
||||
|
||||
inline bool operator!=(const MediaAccessControl &lhs) const { return !(*this == lhs); }
|
||||
inline bool operator!=(const uint48_t &lhs) const { return !(*this == lhs); }
|
||||
|
||||
inline uint48_t ToHex()
|
||||
{
|
||||
return ((uint48_t)this->Address[0] << 40) |
|
||||
((uint48_t)this->Address[1] << 32) |
|
||||
((uint48_t)this->Address[2] << 24) |
|
||||
((uint48_t)this->Address[3] << 16) |
|
||||
((uint48_t)this->Address[4] << 8) |
|
||||
((uint48_t)this->Address[5]);
|
||||
}
|
||||
|
||||
inline MediaAccessControl FromHex(uint48_t Hex)
|
||||
{
|
||||
this->Address[0] = (uint8_t)((Hex >> 40) & 0xFF);
|
||||
this->Address[1] = (uint8_t)((Hex >> 32) & 0xFF);
|
||||
this->Address[2] = (uint8_t)((Hex >> 24) & 0xFF);
|
||||
this->Address[3] = (uint8_t)((Hex >> 16) & 0xFF);
|
||||
this->Address[4] = (uint8_t)((Hex >> 8) & 0xFF);
|
||||
this->Address[5] = (uint8_t)(Hex & 0xFF);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool Valid()
|
||||
{
|
||||
// TODO: More complex MAC validation
|
||||
return (this->Address[0] != 0 ||
|
||||
this->Address[1] != 0 ||
|
||||
this->Address[2] != 0 ||
|
||||
this->Address[3] != 0 ||
|
||||
this->Address[4] != 0 ||
|
||||
this->Address[5] != 0) &&
|
||||
(this->Address[0] != 0xFF ||
|
||||
this->Address[1] != 0xFF ||
|
||||
this->Address[2] != 0xFF ||
|
||||
this->Address[3] != 0xFF ||
|
||||
this->Address[4] != 0xFF ||
|
||||
this->Address[5] != 0xFF);
|
||||
}
|
||||
|
||||
char *ToString()
|
||||
{
|
||||
static char Buffer[18];
|
||||
sprintf(Buffer, "%02X:%02X:%02X:%02X:%02X:%02X", this->Address[0], this->Address[1], this->Address[2], this->Address[3], this->Address[4], this->Address[5]);
|
||||
return Buffer;
|
||||
}
|
||||
};
|
||||
|
||||
/* There's a confusion between LSB and MSB. Not sure if "ToStringLittleEndian" and "ToStringBigEndian" are implemented correctly.
|
||||
Because x86 is a LSB architecture, I'm assuming that the "ToStringLittleEndian" is correct? */
|
||||
struct InternetProtocol
|
||||
{
|
||||
struct Version4
|
||||
{
|
||||
uint8_t Address[4] = {255, 255, 255, 255};
|
||||
Endianness Endianess = LITTLE_ENDIAN;
|
||||
|
||||
inline bool operator==(const InternetProtocol::Version4 &lhs) const
|
||||
{
|
||||
return lhs.Address[0] == this->Address[0] &&
|
||||
lhs.Address[1] == this->Address[1] &&
|
||||
lhs.Address[2] == this->Address[2] &&
|
||||
lhs.Address[3] == this->Address[3];
|
||||
}
|
||||
|
||||
inline bool operator==(const uint32_t &lhs) const
|
||||
{
|
||||
InternetProtocol::Version4 IP;
|
||||
IP.Address[0] = (uint8_t)((lhs >> 24) & 0xFF);
|
||||
IP.Address[1] = (uint8_t)((lhs >> 16) & 0xFF);
|
||||
IP.Address[2] = (uint8_t)((lhs >> 8) & 0xFF);
|
||||
IP.Address[3] = (uint8_t)(lhs & 0xFF);
|
||||
|
||||
return IP.Address[0] == this->Address[0] &&
|
||||
IP.Address[1] == this->Address[1] &&
|
||||
IP.Address[2] == this->Address[2] &&
|
||||
IP.Address[3] == this->Address[3];
|
||||
}
|
||||
|
||||
inline bool operator!=(const InternetProtocol::Version4 &lhs) const { return !(*this == lhs); }
|
||||
inline bool operator!=(const uint32_t &lhs) const { return !(*this == lhs); }
|
||||
|
||||
inline uint32_t ToHex()
|
||||
{
|
||||
return ((uint32_t)this->Address[0] << 24) |
|
||||
((uint32_t)this->Address[1] << 16) |
|
||||
((uint32_t)this->Address[2] << 8) |
|
||||
((uint32_t)this->Address[3]);
|
||||
}
|
||||
|
||||
inline InternetProtocol::Version4 FromHex(uint32_t Hex)
|
||||
{
|
||||
this->Address[0] = (uint8_t)((Hex >> 24) & 0xFF);
|
||||
this->Address[1] = (uint8_t)((Hex >> 16) & 0xFF);
|
||||
this->Address[2] = (uint8_t)((Hex >> 8) & 0xFF);
|
||||
this->Address[3] = (uint8_t)(Hex & 0xFF);
|
||||
return *this;
|
||||
}
|
||||
|
||||
char *ToStringLittleEndian()
|
||||
{
|
||||
static char Buffer[16];
|
||||
sprintf(Buffer, "%d.%d.%d.%d", this->Address[0], this->Address[1], this->Address[2], this->Address[3]);
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
char *ToStringBigEndian()
|
||||
{
|
||||
static char Buffer[16];
|
||||
sprintf(Buffer, "%d.%d.%d.%d", this->Address[3], this->Address[2], this->Address[1], this->Address[0]);
|
||||
return Buffer;
|
||||
}
|
||||
} v4;
|
||||
|
||||
struct Version6
|
||||
{
|
||||
uint16_t Address[8] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
|
||||
Endianness Endianess = LITTLE_ENDIAN;
|
||||
|
||||
inline bool operator==(const InternetProtocol::Version6 &lhs) const
|
||||
{
|
||||
return lhs.Address[0] == this->Address[0] &&
|
||||
lhs.Address[1] == this->Address[1] &&
|
||||
lhs.Address[2] == this->Address[2] &&
|
||||
lhs.Address[3] == this->Address[3] &&
|
||||
lhs.Address[4] == this->Address[4] &&
|
||||
lhs.Address[5] == this->Address[5] &&
|
||||
lhs.Address[6] == this->Address[6] &&
|
||||
lhs.Address[7] == this->Address[7];
|
||||
}
|
||||
|
||||
inline bool operator!=(const InternetProtocol::Version6 &lhs) const { return !(*this == lhs); }
|
||||
|
||||
char *ToStringLittleEndian()
|
||||
{
|
||||
static char Buffer[40];
|
||||
sprintf(Buffer, "%04X:%04X:%04X:%04X:%04X:%04X:%04X:%04X", this->Address[0], this->Address[1], this->Address[2], this->Address[3], this->Address[4], this->Address[5], this->Address[6], this->Address[7]);
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
char *ToStringBigEndian()
|
||||
{
|
||||
static char Buffer[40];
|
||||
sprintf(Buffer, "%04X:%04X:%04X:%04X:%04X:%04X:%04X:%04X", this->Address[7], this->Address[6], this->Address[5], this->Address[4], this->Address[3], this->Address[2], this->Address[1], this->Address[0]);
|
||||
return Buffer;
|
||||
}
|
||||
} v6;
|
||||
};
|
||||
|
||||
uint16_t CalculateChecksum(uint16_t *Data, uint64_t Length);
|
||||
|
||||
#endif // !__FENNIX_KERNEL_NETWORK_H__
|
166
Kernel/include/net/ntp.hpp
Normal file
166
Kernel/include/net/ntp.hpp
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_NTP_H__
|
||||
#define __FENNIX_KERNEL_NTP_H__
|
||||
|
||||
#include <net/udp.hpp>
|
||||
#include <types.h>
|
||||
|
||||
namespace NetworkNTP
|
||||
{
|
||||
struct NTPHeader
|
||||
{
|
||||
/** @brief Leap indicator
|
||||
* 00 - no warning
|
||||
* 01 - last minute has 61 seconds
|
||||
* 10 - last minute has 59 seconds
|
||||
* 11 - alarm condition (clock not synchronized)
|
||||
*/
|
||||
uint8_t LeapIndicator : 2;
|
||||
/** @brief Version number of the protocol
|
||||
* 3 - IPv4 only
|
||||
* 4 - IPv4, IPv6 and OSI
|
||||
* 5 - IPv4, IPv6 and OSI
|
||||
* 6 - IPv4, IPv6 and OSI
|
||||
* 7 - IPv4, IPv6 and OSI
|
||||
*/
|
||||
uint8_t VersionNumber : 3;
|
||||
/** @brief Mode
|
||||
* 0 - reserved
|
||||
* 1 - symmetric active
|
||||
* 2 - symmetric passive
|
||||
* 3 - client
|
||||
* 4 - server
|
||||
* 5 - broadcast
|
||||
* 6 - reserved for NTP control message
|
||||
* 7 - reserved for private use
|
||||
*/
|
||||
uint8_t Mode : 3;
|
||||
/** @brief Stratum
|
||||
* 0 - unspecified or unavailable
|
||||
* 1 - primary reference (e.g. radio clock)
|
||||
* 2-15 - secondary reference (via NTP or SNTP)
|
||||
* 16 - unsynchronized
|
||||
* 17-255 - reserved
|
||||
*/
|
||||
uint8_t Stratum;
|
||||
/** @brief Polling interval
|
||||
* 4 - 16 seconds
|
||||
* 5 - 32 seconds
|
||||
* 6 - 64 seconds
|
||||
* 7 - 128 seconds
|
||||
* 8 - 256 seconds
|
||||
* 9 - 512 seconds
|
||||
* 10 - 1024 seconds
|
||||
* 11 - 2048 seconds
|
||||
* 12 - 4096 seconds
|
||||
* 13 - 8192 seconds
|
||||
* 14 - 16384 seconds
|
||||
* 15 - 32768 seconds
|
||||
*/
|
||||
uint8_t Poll;
|
||||
/** @brief Precision
|
||||
* -6 - 0.015625 seconds
|
||||
* -5 - 0.03125 seconds
|
||||
* -4 - 0.0625 seconds
|
||||
* -3 - 0.125 seconds
|
||||
* -2 - 0.25 seconds
|
||||
* -1 - 0.5 seconds
|
||||
* 0 - 1 second
|
||||
* 1 - 2 seconds
|
||||
* 2 - 4 seconds
|
||||
* 3 - 8 seconds
|
||||
* 4 - 16 seconds
|
||||
* 5 - 32 seconds
|
||||
* 6 - 64 seconds
|
||||
* 7 - 128 seconds
|
||||
*/
|
||||
uint8_t Precision;
|
||||
/** @brief Root delay
|
||||
* Total round trip delay to the primary reference source
|
||||
*/
|
||||
uint32_t RootDelay;
|
||||
/** @brief Root dispersion
|
||||
* Nominal error relative to the primary reference source
|
||||
*/
|
||||
uint32_t RootDispersion;
|
||||
/** @brief Reference identifier
|
||||
* 0x00000000 - unspecified
|
||||
* 0x00000001 - radio clock
|
||||
* 0x00000002 - atomic clock
|
||||
* 0x00000003 - GPS receiver
|
||||
* 0x00000004 - local oscillator
|
||||
* 0x00000005 - LORAN-C receiver
|
||||
* 0x00000006 - microprocessor
|
||||
* 0x00000007 - internet
|
||||
* 0x00000008 - FLL
|
||||
* 0x00000009 - other
|
||||
* 0x0000000A - WWV
|
||||
* 0x0000000B - WWVB
|
||||
* 0x0000000C - WWVH
|
||||
* 0x0000000D - NIST dialup
|
||||
* 0x0000000E - telephone
|
||||
* 0x0000000F - reserved
|
||||
*/
|
||||
uint32_t ReferenceIdentifier;
|
||||
/** @brief Reference timestamp
|
||||
* The time at which the clock was last set or corrected
|
||||
*/
|
||||
uint32_t ReferenceTimestamp[2];
|
||||
/** @brief Originate timestamp
|
||||
* The time at which the request departed the client for the server
|
||||
*/
|
||||
uint32_t OriginateTimestamp[2];
|
||||
/** @brief Receive timestamp
|
||||
* The time at which the request arrived at the server
|
||||
*/
|
||||
uint32_t ReceiveTimestamp[2];
|
||||
/** @brief Transmit timestamp
|
||||
* The time at which the reply departed the server for the client
|
||||
*/
|
||||
uint32_t TransmitTimestamp[2];
|
||||
/** @brief Message authentication code
|
||||
* Key identifier
|
||||
* @note Only when the NTP authentication scheme is used
|
||||
*/
|
||||
// uint32_t MessageAuthenticationCode;
|
||||
} __packed;
|
||||
|
||||
class NTP : public NetworkUDP::UDPEvents
|
||||
{
|
||||
private:
|
||||
NetworkUDP::Socket *UDPSocket;
|
||||
bool TimeReceived = false;
|
||||
NTPHeader NTPPacket;
|
||||
|
||||
virtual void OnUDPPacketReceived(NetworkUDP::Socket *Socket, uint8_t *Data, uint64_t Length);
|
||||
|
||||
public:
|
||||
NTP(NetworkUDP::Socket *Socket);
|
||||
~NTP();
|
||||
|
||||
/**
|
||||
* @brief Get the time from the NTP server
|
||||
*
|
||||
* @return Unix Timestamp
|
||||
*/
|
||||
int ReadTime();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_NTP_H__
|
27
Kernel/include/net/tcp.hpp
Normal file
27
Kernel/include/net/tcp.hpp
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_TCP_H__
|
||||
#define __FENNIX_KERNEL_TCP_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
namespace NetworkTCP
|
||||
{
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_TCP_H__
|
97
Kernel/include/net/udp.hpp
Normal file
97
Kernel/include/net/udp.hpp
Normal file
@ -0,0 +1,97 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_UDP_H__
|
||||
#define __FENNIX_KERNEL_UDP_H__
|
||||
|
||||
#include <net/ipv4.hpp>
|
||||
#include <net/udp.hpp>
|
||||
#include <net/nc.hpp>
|
||||
#include <types.h>
|
||||
|
||||
namespace NetworkUDP
|
||||
{
|
||||
struct UDPHeader
|
||||
{
|
||||
uint16_t SourcePort;
|
||||
uint16_t DestinationPort;
|
||||
uint16_t Length;
|
||||
uint16_t Checksum;
|
||||
} __packed;
|
||||
|
||||
struct UDPPacket
|
||||
{
|
||||
UDPHeader Header;
|
||||
uint8_t Data[];
|
||||
};
|
||||
|
||||
class Socket;
|
||||
|
||||
class UDPEvents
|
||||
{
|
||||
protected:
|
||||
UDPEvents();
|
||||
~UDPEvents();
|
||||
|
||||
public:
|
||||
virtual void OnUDPPacketReceived(Socket *Socket, uint8_t *Data, uint64_t Length)
|
||||
{
|
||||
UNUSED(Socket);
|
||||
UNUSED(Data);
|
||||
UNUSED(Length);
|
||||
warn("Not implemented.");
|
||||
}
|
||||
};
|
||||
|
||||
class UDP : public NetworkIPv4::IPv4Events
|
||||
{
|
||||
private:
|
||||
NetworkIPv4::IPv4 *ipv4;
|
||||
NetworkInterfaceManager::DeviceInterface *Interface;
|
||||
|
||||
public:
|
||||
NetworkInterfaceManager::DeviceInterface *GetInterface() { return this->Interface; }
|
||||
|
||||
UDP(NetworkIPv4::IPv4 *ipv4, NetworkInterfaceManager::DeviceInterface *Interface);
|
||||
~UDP();
|
||||
|
||||
virtual Socket *Connect(InternetProtocol IP, uint16_t Port);
|
||||
virtual Socket *Listen(uint16_t Port);
|
||||
virtual void Disconnect(Socket *Socket);
|
||||
virtual void Send(Socket *Socket, uint8_t *Data, uint64_t Length);
|
||||
virtual void Bind(Socket *Socket, UDPEvents *EventHandler);
|
||||
|
||||
virtual bool OnIPv4PacketReceived(InternetProtocol SourceIP, InternetProtocol DestinationIP, uint8_t *Data, uint64_t Length);
|
||||
};
|
||||
|
||||
class Socket
|
||||
{
|
||||
public:
|
||||
InternetProtocol LocalIP;
|
||||
uint16_t LocalPort = 0;
|
||||
InternetProtocol RemoteIP;
|
||||
uint16_t RemotePort = 0;
|
||||
bool Listening = false;
|
||||
UDPEvents *EventHandler = nullptr;
|
||||
UDP *SocketUDP = nullptr;
|
||||
|
||||
Socket(UDP *_UDP);
|
||||
~Socket();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_UDP_H__
|
240
Kernel/include/pci.hpp
Normal file
240
Kernel/include/pci.hpp
Normal file
@ -0,0 +1,240 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_PCI_H__
|
||||
#define __FENNIX_KERNEL_PCI_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <debug.h>
|
||||
#include <vector>
|
||||
|
||||
namespace PCI
|
||||
{
|
||||
namespace Descriptors
|
||||
{
|
||||
enum PCIVendors
|
||||
{
|
||||
SymbiosLogic = 0x1000,
|
||||
RedHat = 0x1AF4,
|
||||
REDHat2 = 0x1B36,
|
||||
Realtek = 0x10EC,
|
||||
VirtualBox = 0x80EE,
|
||||
Ensoniq = 0x1274,
|
||||
QEMU = 0x1234,
|
||||
VMware = 0x15AD,
|
||||
IntelCorporation = 0x8086,
|
||||
AdvancedMicroDevices = 0x1022,
|
||||
NVIDIACorporation = 0x10DE
|
||||
};
|
||||
|
||||
const char *const DeviceClasses[]{
|
||||
"Unclassified",
|
||||
"Mass Storage Controller",
|
||||
"Network Controller",
|
||||
"Display Controller",
|
||||
"Multimedia Controller",
|
||||
"Memory Controller",
|
||||
"Bridge Device",
|
||||
"Simple Communication Controller",
|
||||
"Base System Peripheral",
|
||||
"Input Device Controller",
|
||||
"Docking Station",
|
||||
"Processor",
|
||||
"Serial Bus Controller",
|
||||
"Wireless Controller",
|
||||
"Intelligent Controller",
|
||||
"Satellite Communication Controller",
|
||||
"Encryption Controller",
|
||||
"Signal Processing Controller",
|
||||
"Processing Accelerator",
|
||||
"Non Essential Instrumentation"};
|
||||
|
||||
const char *MassStorageControllerSubclassName(uint8_t SubclassCode);
|
||||
const char *NetworkControllerSubclassName(uint8_t SubclassCode);
|
||||
const char *DisplayControllerSubclassName(uint8_t SubclassCode);
|
||||
const char *CommunicationControllerSubclassName(uint8_t SubclassCode);
|
||||
const char *BaseSystemPeripheralSubclassName(uint8_t SubclassCode);
|
||||
const char *SerialBusControllerSubclassName(uint8_t SubclassCode);
|
||||
const char *BridgeDeviceSubclassName(uint8_t SubclassCode);
|
||||
const char *WirelessControllerSubclassName(uint8_t SubclassCode);
|
||||
const char *GetVendorName(uint32_t VendorID);
|
||||
const char *GetDeviceName(uint32_t VendorID, uint32_t DeviceID);
|
||||
const char *GetSubclassName(uint8_t ClassCode, uint8_t SubclassCode);
|
||||
const char *GetProgIFName(uint8_t ClassCode, uint8_t SubclassCode, uint8_t ProgIF);
|
||||
}
|
||||
|
||||
/* https://sites.uclouvain.be/SystInfo/usr/include/linux/pci_regs.h.html */
|
||||
enum PCICommands
|
||||
{
|
||||
/** @brief Enable response in I/O space */
|
||||
PCI_COMMAND_IO = 0x1,
|
||||
/** @brief Enable response in Memory space */
|
||||
PCI_COMMAND_MEMORY = 0x2,
|
||||
/** @brief Enable bus mastering */
|
||||
PCI_COMMAND_MASTER = 0x4,
|
||||
/** @brief Enable response to special cycles */
|
||||
PCI_COMMAND_SPECIAL = 0x8,
|
||||
/** @brief Use memory write and invalidate */
|
||||
PCI_COMMAND_INVALIDATE = 0x10,
|
||||
/** @brief Enable palette snooping */
|
||||
PCI_COMMAND_VGA_PALETTE = 0x20,
|
||||
/** @brief Enable parity checking */
|
||||
PCI_COMMAND_PARITY = 0x40,
|
||||
/** @brief Enable address/data stepping */
|
||||
PCI_COMMAND_WAIT = 0x80,
|
||||
/** @brief Enable SERR */
|
||||
PCI_COMMAND_SERR = 0x100,
|
||||
/** @brief Enable back-to-back writes */
|
||||
PCI_COMMAND_FAST_BACK = 0x200,
|
||||
/** @brief INTx Emulation Disable */
|
||||
PCI_COMMAND_INTX_DISABLE = 0x400
|
||||
};
|
||||
|
||||
struct PCIDeviceHeader
|
||||
{
|
||||
uint16_t VendorID;
|
||||
uint16_t DeviceID;
|
||||
uint16_t Command;
|
||||
uint16_t Status;
|
||||
uint8_t RevisionID;
|
||||
uint8_t ProgIF;
|
||||
uint8_t Subclass;
|
||||
uint8_t Class;
|
||||
uint8_t CacheLineSize;
|
||||
uint8_t LatencyTimer;
|
||||
uint8_t HeaderType;
|
||||
uint8_t BIST;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief PCI Header Type 0
|
||||
*
|
||||
*/
|
||||
struct PCIHeader0
|
||||
{
|
||||
PCIDeviceHeader Header;
|
||||
uint32_t BAR0;
|
||||
uint32_t BAR1;
|
||||
uint32_t BAR2;
|
||||
uint32_t BAR3;
|
||||
uint32_t BAR4;
|
||||
uint32_t BAR5;
|
||||
uint32_t CardbusCISPointer;
|
||||
uint16_t SubsystemVendorID;
|
||||
uint16_t SubsystemID;
|
||||
uint32_t ExpansionROMBaseAddress;
|
||||
uint8_t CapabilitiesPointer;
|
||||
uint8_t Reserved0;
|
||||
uint16_t Reserved1;
|
||||
uint32_t Reserved2;
|
||||
uint8_t InterruptLine;
|
||||
uint8_t InterruptPin;
|
||||
uint8_t MinGrant;
|
||||
uint8_t MaxLatency;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief PCI Header Type 1 (PCI-to-PCI Bridge)
|
||||
*/
|
||||
struct PCIHeader1
|
||||
{
|
||||
PCIDeviceHeader Header;
|
||||
uint32_t BAR0;
|
||||
uint32_t BAR1;
|
||||
uint8_t PrimaryBusNumber;
|
||||
uint8_t SecondaryBusNumber;
|
||||
uint8_t SubordinateBusNumber;
|
||||
uint8_t SecondaryLatencyTimer;
|
||||
uint8_t IOBase;
|
||||
uint8_t IOLimit;
|
||||
uint16_t SecondaryStatus;
|
||||
uint16_t MemoryBase;
|
||||
uint16_t MemoryLimit;
|
||||
uint16_t PrefetchableMemoryBase;
|
||||
uint16_t PrefetchableMemoryLimit;
|
||||
uint32_t PrefetchableMemoryBaseUpper32;
|
||||
uint32_t PrefetchableMemoryLimitUpper32;
|
||||
uint16_t IOBaseUpper16;
|
||||
uint16_t IOLimitUpper16;
|
||||
uint8_t CapabilitiesPointer;
|
||||
uint8_t Reserved0;
|
||||
uint16_t Reserved1;
|
||||
uint32_t ExpansionROMBaseAddress;
|
||||
uint8_t InterruptLine;
|
||||
uint8_t InterruptPin;
|
||||
uint16_t BridgeControl;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief PCI Header Type 2 (PCI-to-CardBus Bridge)
|
||||
*/
|
||||
struct PCIHeader2
|
||||
{
|
||||
PCIDeviceHeader Header;
|
||||
uint32_t CardbusSocketRegistersBaseAddress;
|
||||
uint8_t CapabilitiesPointer;
|
||||
uint8_t Reserved0;
|
||||
uint16_t SecondaryStatus;
|
||||
uint8_t PCIbusNumber;
|
||||
uint8_t CardbusBusNumber;
|
||||
uint8_t SubordinateBusNumber;
|
||||
uint8_t CardbusLatencyTimer;
|
||||
uint32_t MemoryBase0;
|
||||
uint32_t MemoryLimit0;
|
||||
uint32_t MemoryBase1;
|
||||
uint32_t MemoryLimit1;
|
||||
uint32_t IOBase0;
|
||||
uint32_t IOLimit0;
|
||||
uint32_t IOBase1;
|
||||
uint32_t IOLimit1;
|
||||
uint8_t InterruptLine;
|
||||
uint8_t InterruptPin;
|
||||
uint16_t BridgeControl;
|
||||
uint16_t SubsystemVendorID;
|
||||
uint16_t SubsystemID;
|
||||
uint32_t LegacyBaseAddress;
|
||||
};
|
||||
|
||||
struct DeviceConfig
|
||||
{
|
||||
uintptr_t BaseAddress;
|
||||
uint16_t PCISegGroup;
|
||||
uint8_t StartBus;
|
||||
uint8_t EndBus;
|
||||
uint32_t Reserved;
|
||||
} __packed;
|
||||
|
||||
class PCI
|
||||
{
|
||||
private:
|
||||
std::vector<PCIDeviceHeader *> Devices;
|
||||
|
||||
public:
|
||||
std::vector<PCIDeviceHeader *> &GetDevices() { return Devices; }
|
||||
void EnumerateFunction(uintptr_t DeviceAddress, uint64_t Function);
|
||||
void EnumerateDevice(uintptr_t BusAddress, uint64_t Device);
|
||||
void EnumerateBus(uintptr_t BaseAddress, uint64_t Bus);
|
||||
std::vector<PCIDeviceHeader *> FindPCIDevice(uint8_t Class, uint8_t Subclass, uint8_t ProgIF);
|
||||
std::vector<PCIDeviceHeader *> FindPCIDevice(int VendorID, int DeviceID);
|
||||
|
||||
PCI();
|
||||
~PCI();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_PCI_H__
|
70
Kernel/include/power.hpp
Normal file
70
Kernel/include/power.hpp
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_POWER_H__
|
||||
#define __FENNIX_KERNEL_POWER_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
namespace Power
|
||||
{
|
||||
class Power
|
||||
{
|
||||
private:
|
||||
void *acpi = nullptr;
|
||||
void *dsdt = nullptr;
|
||||
void *madt = nullptr;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Get Advanced Configuration and Power Interface. (Available only on x32 and x64)
|
||||
*
|
||||
* @return void* (ACPI::ACPI *)
|
||||
*/
|
||||
void *GetACPI() { return this->acpi; }
|
||||
|
||||
/**
|
||||
* @brief Get Differentiated System Description Table. (Available only on x32 and x64)
|
||||
*
|
||||
* @return void* (ACPI::DSDT *)
|
||||
*/
|
||||
void *GetDSDT() { return this->dsdt; }
|
||||
|
||||
/**
|
||||
* @brief Get Multiple APIC Description Table. (Available only on x32 and x64)
|
||||
*
|
||||
* @return void* (ACPI::MADT *)
|
||||
*/
|
||||
void *GetMADT() { return this->madt; }
|
||||
|
||||
/**
|
||||
* @brief Reboot the system.
|
||||
*/
|
||||
void Reboot();
|
||||
|
||||
/**
|
||||
* @brief Shutdown the system.
|
||||
*/
|
||||
void Shutdown();
|
||||
|
||||
void InitDSDT();
|
||||
Power();
|
||||
~Power();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_POWER_H__
|
194
Kernel/include/printf.h
Normal file
194
Kernel/include/printf.h
Normal file
@ -0,0 +1,194 @@
|
||||
/**
|
||||
* @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 <types.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_
|
31
Kernel/include/rand.hpp
Normal file
31
Kernel/include/rand.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_RANDOM_H__
|
||||
#define __FENNIX_KERNEL_RANDOM_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
namespace Random
|
||||
{
|
||||
uint16_t rand16();
|
||||
uint32_t rand32();
|
||||
uint64_t rand64();
|
||||
void ChangeSeed(uint64_t CustomSeed);
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_RANDOM_H__
|
41
Kernel/include/recovery.hpp
Normal file
41
Kernel/include/recovery.hpp
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_RECOVERY_H__
|
||||
#define __FENNIX_KERNEL_RECOVERY_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <memory.hpp>
|
||||
#include <task.hpp>
|
||||
|
||||
namespace Recovery
|
||||
{
|
||||
class KernelRecovery
|
||||
{
|
||||
private:
|
||||
Memory::MemMgr *mem;
|
||||
Tasking::TCB *guiThread;
|
||||
Tasking::TCB *recoveryThread;
|
||||
|
||||
public:
|
||||
void RecoveryThread();
|
||||
KernelRecovery();
|
||||
~KernelRecovery();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_RECOVERY_H__
|
19
Kernel/include/smart_ptr.hpp
Normal file
19
Kernel/include/smart_ptr.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <std/smart_ptr.hpp>
|
81
Kernel/include/smp.hpp
Normal file
81
Kernel/include/smp.hpp
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_SMP_H__
|
||||
#define __FENNIX_KERNEL_SMP_H__
|
||||
|
||||
#include <task.hpp>
|
||||
#include <types.h>
|
||||
#include <atomic>
|
||||
|
||||
/** @brief Maximum supported number of CPU cores by the kernel */
|
||||
#define MAX_CPU 256
|
||||
#define CPU_DATA_CHECKSUM 0xC0FFEE
|
||||
|
||||
struct CPUArchData
|
||||
{
|
||||
#if defined(a64)
|
||||
CPU::x64::FXState *FPU;
|
||||
/* TODO */
|
||||
#elif defined(a32)
|
||||
#elif defined(aa64)
|
||||
#endif
|
||||
};
|
||||
|
||||
struct CPUData
|
||||
{
|
||||
/** @brief Used by syscall handler */
|
||||
uint8_t *SystemCallStack; /* gs+0x0 */
|
||||
|
||||
/** @brief Used by syscall handler */
|
||||
uintptr_t TempStack; /* gs+0x8 */
|
||||
|
||||
/** @brief Used by CPU */
|
||||
uintptr_t Stack; /* gs+0x10 */
|
||||
|
||||
/** @brief CPU ID. */
|
||||
int ID;
|
||||
|
||||
/** @brief Local CPU error code. */
|
||||
long ErrorCode;
|
||||
|
||||
/** @brief Current running process */
|
||||
std::atomic<Tasking::PCB *> CurrentProcess;
|
||||
|
||||
/** @brief Current running thread */
|
||||
std::atomic<Tasking::TCB *> CurrentThread;
|
||||
|
||||
/** @brief Architecture-specific data. */
|
||||
CPUArchData Data;
|
||||
|
||||
/** @brief Checksum. Used to verify the integrity of the data. Must be equal to CPU_DATA_CHECKSUM (0xC0FFEE). */
|
||||
int Checksum;
|
||||
|
||||
/** @brief Is CPU online? */
|
||||
bool IsActive;
|
||||
} __aligned(16);
|
||||
|
||||
CPUData *GetCurrentCPU();
|
||||
CPUData *GetCPU(long ID);
|
||||
|
||||
namespace SMP
|
||||
{
|
||||
extern int CPUCores;
|
||||
void Initialize(void *madt);
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_SMP_H__
|
9370
Kernel/include/stb/image.h
Normal file
9370
Kernel/include/stb/image.h
Normal file
File diff suppressed because it is too large
Load Diff
2946
Kernel/include/stb/image_resize.h
Normal file
2946
Kernel/include/stb/image_resize.h
Normal file
File diff suppressed because it is too large
Load Diff
43
Kernel/include/symbols.hpp
Normal file
43
Kernel/include/symbols.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <types.h>
|
||||
|
||||
namespace SymbolResolver
|
||||
{
|
||||
class Symbols
|
||||
{
|
||||
private:
|
||||
struct SymbolTable
|
||||
{
|
||||
uintptr_t Address;
|
||||
char *FunctionName;
|
||||
};
|
||||
|
||||
SymbolTable SymTable[0x10000];
|
||||
uintptr_t TotalEntries = 0;
|
||||
|
||||
public:
|
||||
Symbols(uintptr_t ImageAddress);
|
||||
~Symbols();
|
||||
const char *GetSymbolFromAddress(uintptr_t Address);
|
||||
void AddSymbol(uintptr_t Address, const char *Name);
|
||||
};
|
||||
}
|
||||
|
||||
extern SymbolResolver::Symbols *SymTbl;
|
44
Kernel/include/syscalls.hpp
Normal file
44
Kernel/include/syscalls.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_SYSCALLS_H__
|
||||
#define __FENNIX_KERNEL_SYSCALLS_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
typedef struct SyscallsFrame
|
||||
{
|
||||
#if defined(a64)
|
||||
uint64_t r15, r14, r13, r12, r11, r10, r9, r8;
|
||||
uint64_t rbp, rdi, rsi, rdx, rcx, rbx, rax;
|
||||
uint64_t InterruptNumber, ErrorCode, rip, cs, rflags, rsp, ss;
|
||||
#elif defined(a32)
|
||||
uint32_t ebp, edi, esi, edx, ecx, ebx, eax;
|
||||
uint32_t InterruptNumber, ErrorCode, eip, cs, eflags, esp, ss;
|
||||
#elif defined(aa64)
|
||||
#endif
|
||||
} SyscallsFrame;
|
||||
|
||||
uintptr_t HandleNativeSyscalls(SyscallsFrame *Frame);
|
||||
uintptr_t HandleLinuxSyscalls(SyscallsFrame *Frame);
|
||||
|
||||
/**
|
||||
* @brief Initialize syscalls for the current CPU. (Function is available on x32, x64 & aarch64)
|
||||
*/
|
||||
void InitializeSystemCalls();
|
||||
|
||||
#endif // !__FENNIX_KERNEL_SYSCALLS_H__
|
32
Kernel/include/targp.h
Normal file
32
Kernel/include/targp.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TinyArgumentParser_H__
|
||||
#define TinyArgumentParser_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void targp_parse(const char *cmd, char **argv, int *argc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // !TinyArgumentParser_H__
|
356
Kernel/include/task.hpp
Normal file
356
Kernel/include/task.hpp
Normal file
@ -0,0 +1,356 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_TASKING_H__
|
||||
#define __FENNIX_KERNEL_TASKING_H__
|
||||
|
||||
#include <types.h>
|
||||
|
||||
#include <filesystem.hpp>
|
||||
#include <symbols.hpp>
|
||||
#include <memory.hpp>
|
||||
#include <ints.hpp>
|
||||
#include <ipc.hpp>
|
||||
#include <debug.h>
|
||||
#include <vector>
|
||||
#include <atomic>
|
||||
#include <abi.h>
|
||||
|
||||
namespace Tasking
|
||||
{
|
||||
typedef unsigned long IP;
|
||||
typedef __UINTPTR_TYPE__ IPOffset;
|
||||
typedef unsigned long UPID;
|
||||
typedef unsigned long UTID;
|
||||
typedef __UINTPTR_TYPE__ Token;
|
||||
|
||||
enum TaskArchitecture
|
||||
{
|
||||
UnknownArchitecture,
|
||||
x32,
|
||||
x64,
|
||||
ARM32,
|
||||
ARM64
|
||||
};
|
||||
|
||||
enum TaskCompatibility
|
||||
{
|
||||
UnknownPlatform,
|
||||
Native,
|
||||
Linux,
|
||||
Windows
|
||||
};
|
||||
|
||||
enum TaskTrustLevel
|
||||
{
|
||||
UnknownElevation,
|
||||
Kernel,
|
||||
System,
|
||||
User
|
||||
};
|
||||
|
||||
enum TaskStatus
|
||||
{
|
||||
UnknownStatus,
|
||||
Ready,
|
||||
Running,
|
||||
Sleeping,
|
||||
Waiting,
|
||||
Stopped,
|
||||
Terminated
|
||||
};
|
||||
|
||||
enum TaskPriority
|
||||
{
|
||||
UnknownPriority = 0,
|
||||
Idle = 1,
|
||||
Low = 2,
|
||||
Normal = 5,
|
||||
High = 8,
|
||||
Critical = 10
|
||||
};
|
||||
|
||||
struct TaskSecurity
|
||||
{
|
||||
TaskTrustLevel TrustLevel;
|
||||
Token UniqueToken;
|
||||
bool IsCritical;
|
||||
bool IsDebugEnabled;
|
||||
bool IsKernelDebugEnabled;
|
||||
};
|
||||
|
||||
struct TaskInfo
|
||||
{
|
||||
uint64_t OldUserTime = 0;
|
||||
uint64_t OldKernelTime = 0;
|
||||
|
||||
uint64_t SleepUntil = 0;
|
||||
uint64_t KernelTime = 0, UserTime = 0, SpawnTime = 0, LastUpdateTime = 0;
|
||||
uint64_t Year, Month, Day, Hour, Minute, Second;
|
||||
bool Affinity[256]; // MAX_CPU
|
||||
TaskPriority Priority;
|
||||
TaskArchitecture Architecture;
|
||||
TaskCompatibility Compatibility;
|
||||
};
|
||||
|
||||
struct TCB
|
||||
{
|
||||
UTID ID;
|
||||
char Name[256];
|
||||
struct PCB *Parent;
|
||||
IP EntryPoint;
|
||||
IPOffset Offset;
|
||||
int ExitCode;
|
||||
Memory::StackGuard *Stack;
|
||||
Memory::MemMgr *Memory;
|
||||
TaskStatus Status;
|
||||
#if defined(a64)
|
||||
CPU::x64::TrapFrame Registers;
|
||||
uint64_t GSBase, FSBase;
|
||||
#elif defined(a32)
|
||||
CPU::x32::TrapFrame Registers; // TODO
|
||||
uint64_t GSBase, FSBase;
|
||||
#elif defined(aa64)
|
||||
uint64_t Registers; // TODO
|
||||
#endif
|
||||
uintptr_t IPHistory[128];
|
||||
TaskSecurity Security;
|
||||
TaskInfo Info;
|
||||
CPU::x64::FXState *FPU;
|
||||
|
||||
void Rename(const char *name)
|
||||
{
|
||||
CriticalSection cs;
|
||||
if (strlen(name) > 256 || strlen(name) == 0)
|
||||
{
|
||||
debug("Invalid thread name");
|
||||
return;
|
||||
}
|
||||
|
||||
trace("Renaming thread %s to %s", Name, name);
|
||||
strncpy(Name, name, 256);
|
||||
}
|
||||
|
||||
void SetPriority(TaskPriority priority)
|
||||
{
|
||||
CriticalSection cs;
|
||||
trace("Setting priority of thread %s to %d", Name, priority);
|
||||
Info.Priority = priority;
|
||||
}
|
||||
|
||||
int GetExitCode() { return ExitCode; }
|
||||
|
||||
void SetCritical(bool Critical)
|
||||
{
|
||||
CriticalSection cs;
|
||||
trace("Setting criticality of thread %s to %s", Name, Critical ? "true" : "false");
|
||||
Security.IsCritical = Critical;
|
||||
}
|
||||
|
||||
void SetDebugMode(bool Enable)
|
||||
{
|
||||
CriticalSection cs;
|
||||
trace("Setting debug mode of thread %s to %s", Name, Enable ? "true" : "false");
|
||||
Security.IsDebugEnabled = Enable;
|
||||
}
|
||||
|
||||
void SetKernelDebugMode(bool Enable)
|
||||
{
|
||||
CriticalSection cs;
|
||||
trace("Setting kernel debug mode of thread %s to %s", Name, Enable ? "true" : "false");
|
||||
Security.IsKernelDebugEnabled = Enable;
|
||||
}
|
||||
};
|
||||
|
||||
struct PCB
|
||||
{
|
||||
UPID ID;
|
||||
char Name[256];
|
||||
PCB *Parent;
|
||||
int ExitCode;
|
||||
TaskStatus Status;
|
||||
TaskSecurity Security;
|
||||
TaskInfo Info;
|
||||
std::vector<TCB *> Threads;
|
||||
std::vector<PCB *> Children;
|
||||
InterProcessCommunication::IPC *IPC;
|
||||
Memory::PageTable4 *PageTable;
|
||||
SymbolResolver::Symbols *ELFSymbolTable;
|
||||
VirtualFileSystem::Node *ProcessDirectory;
|
||||
VirtualFileSystem::Node *memDirectory;
|
||||
};
|
||||
|
||||
/** @brief Token Trust Level */
|
||||
enum TTL
|
||||
{
|
||||
UnknownTrustLevel = 0b0001,
|
||||
Untrusted = 0b0010,
|
||||
Trusted = 0b0100,
|
||||
TrustedByKernel = 0b1000,
|
||||
FullTrust = Trusted | TrustedByKernel
|
||||
};
|
||||
|
||||
class Security
|
||||
{
|
||||
private:
|
||||
struct TokenData
|
||||
{
|
||||
Token token;
|
||||
int TrustLevel;
|
||||
uint64_t OwnerID;
|
||||
bool Process;
|
||||
};
|
||||
|
||||
std::vector<TokenData> Tokens;
|
||||
|
||||
public:
|
||||
Token CreateToken();
|
||||
bool TrustToken(Token token, TTL TrustLevel);
|
||||
bool AddTrustLevel(Token token, TTL TrustLevel);
|
||||
bool RemoveTrustLevel(Token token, TTL TrustLevel);
|
||||
bool UntrustToken(Token token);
|
||||
bool DestroyToken(Token token);
|
||||
bool IsTokenTrusted(Token token, TTL TrustLevel);
|
||||
bool IsTokenTrusted(Token token, int TrustLevel);
|
||||
int GetTokenTrustLevel(Token token);
|
||||
Security();
|
||||
~Security();
|
||||
};
|
||||
|
||||
class Task : public Interrupts::Handler
|
||||
{
|
||||
private:
|
||||
Security SecurityManager;
|
||||
UPID NextPID = 0;
|
||||
UTID NextTID = 0;
|
||||
|
||||
std::vector<PCB *> ProcessList;
|
||||
PCB *IdleProcess = nullptr;
|
||||
TCB *IdleThread = nullptr;
|
||||
TCB *CleanupThread = nullptr;
|
||||
std::atomic_uint64_t SchedulerTicks = 0;
|
||||
std::atomic_uint64_t LastTaskTicks = 0;
|
||||
bool StopScheduler = false;
|
||||
bool InvalidPCB(PCB *pcb);
|
||||
bool InvalidTCB(TCB *tcb);
|
||||
|
||||
void RemoveThread(TCB *tcb);
|
||||
void RemoveProcess(PCB *pcb);
|
||||
|
||||
void UpdateUsage(TaskInfo *Info, TaskSecurity *Security, int Core);
|
||||
|
||||
bool FindNewProcess(void *CPUDataPointer);
|
||||
bool GetNextAvailableThread(void *CPUDataPointer);
|
||||
bool GetNextAvailableProcess(void *CPUDataPointer);
|
||||
bool SchedulerSearchProcessThread(void *CPUDataPointer);
|
||||
void UpdateProcessStatus();
|
||||
void WakeUpThreads();
|
||||
|
||||
#if defined(a64)
|
||||
void Schedule(CPU::x64::TrapFrame *Frame);
|
||||
void OnInterruptReceived(CPU::x64::TrapFrame *Frame);
|
||||
#elif defined(a32)
|
||||
void Schedule(void *Frame);
|
||||
void OnInterruptReceived(CPU::x32::TrapFrame *Frame);
|
||||
#elif defined(aa64)
|
||||
void Schedule(CPU::aarch64::TrapFrame *Frame);
|
||||
void OnInterruptReceived(CPU::aarch64::TrapFrame *Frame);
|
||||
#endif
|
||||
|
||||
public:
|
||||
void SetCleanupThread(TCB *Thread) { CleanupThread = Thread; }
|
||||
uint64_t GetSchedulerTicks() { return SchedulerTicks.load(); }
|
||||
uint64_t GetLastTaskTicks() { return LastTaskTicks.load(); }
|
||||
std::vector<PCB *> GetProcessList() { return ProcessList; }
|
||||
Security *GetSecurityManager() { return &SecurityManager; }
|
||||
void CleanupProcessesThread();
|
||||
void Panic() { StopScheduler = true; }
|
||||
void Schedule();
|
||||
void SignalShutdown();
|
||||
void RevertProcessCreation(PCB *Process);
|
||||
void RevertThreadCreation(TCB *Thread);
|
||||
|
||||
void KillThread(TCB *tcb, int Code)
|
||||
{
|
||||
tcb->Status = TaskStatus::Terminated;
|
||||
tcb->ExitCode = Code;
|
||||
}
|
||||
|
||||
void KillProcess(PCB *pcb, int Code)
|
||||
{
|
||||
pcb->Status = TaskStatus::Terminated;
|
||||
pcb->ExitCode = Code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the Current Process object
|
||||
* @return PCB*
|
||||
*/
|
||||
PCB *GetCurrentProcess();
|
||||
|
||||
/**
|
||||
* @brief Get the Current Thread object
|
||||
* @return TCB*
|
||||
*/
|
||||
TCB *GetCurrentThread();
|
||||
|
||||
PCB *GetProcessByID(UPID ID);
|
||||
|
||||
TCB *GetThreadByID(UTID ID);
|
||||
|
||||
/** @brief Wait for process to terminate */
|
||||
void WaitForProcess(PCB *pcb);
|
||||
|
||||
/** @brief Wait for thread to terminate */
|
||||
void WaitForThread(TCB *tcb);
|
||||
|
||||
void WaitForProcessStatus(PCB *pcb, TaskStatus Status);
|
||||
void WaitForThreadStatus(TCB *tcb, TaskStatus Status);
|
||||
|
||||
/**
|
||||
* @brief Sleep for a given amount of milliseconds
|
||||
*
|
||||
* @param Milliseconds Amount of milliseconds to sleep
|
||||
*/
|
||||
void Sleep(uint64_t Milliseconds);
|
||||
|
||||
PCB *CreateProcess(PCB *Parent,
|
||||
const char *Name,
|
||||
TaskTrustLevel TrustLevel,
|
||||
void *Image = nullptr,
|
||||
bool DoNotCreatePageTable = false);
|
||||
|
||||
TCB *CreateThread(PCB *Parent,
|
||||
IP EntryPoint,
|
||||
const char **argv = nullptr,
|
||||
const char **envp = nullptr,
|
||||
const std::vector<AuxiliaryVector> &auxv = std::vector<AuxiliaryVector>(),
|
||||
IPOffset Offset = 0,
|
||||
TaskArchitecture Architecture = TaskArchitecture::x64,
|
||||
TaskCompatibility Compatibility = TaskCompatibility::Native);
|
||||
|
||||
Task(const IP EntryPoint);
|
||||
~Task();
|
||||
};
|
||||
}
|
||||
|
||||
#define PEXIT(Code) TaskManager->GetCurrentProcess()->ExitCode = Code
|
||||
#define TEXIT(Code) TaskManager->GetCurrentThread()->ExitCode = Code
|
||||
|
||||
extern "C" void TaskingScheduler_OneShot(int TimeSlice);
|
||||
|
||||
#endif // !__FENNIX_KERNEL_TASKING_H__
|
202
Kernel/include/time.hpp
Normal file
202
Kernel/include/time.hpp
Normal file
@ -0,0 +1,202 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_TIME_H__
|
||||
#define __FENNIX_KERNEL_TIME_H__
|
||||
|
||||
#include <types.h>
|
||||
#include <debug.h>
|
||||
|
||||
namespace Time
|
||||
{
|
||||
struct Clock
|
||||
{
|
||||
int Year, Month, Day, Hour, Minute, Second;
|
||||
uint64_t Counter;
|
||||
};
|
||||
|
||||
Clock ReadClock();
|
||||
Clock ConvertFromUnix(int Timestamp);
|
||||
|
||||
enum Units
|
||||
{
|
||||
Femtoseconds,
|
||||
Picoseconds,
|
||||
Nanoseconds,
|
||||
Microseconds,
|
||||
Milliseconds,
|
||||
Seconds,
|
||||
Minutes,
|
||||
Hours,
|
||||
Days,
|
||||
Months,
|
||||
Years
|
||||
};
|
||||
|
||||
class HighPrecisionEventTimer
|
||||
{
|
||||
private:
|
||||
struct HPET
|
||||
{
|
||||
uint64_t GeneralCapabilities;
|
||||
uint64_t Reserved0;
|
||||
uint64_t GeneralConfiguration;
|
||||
uint64_t Reserved1;
|
||||
uint64_t GeneralIntStatus;
|
||||
uint64_t Reserved2;
|
||||
uint64_t Reserved3[24];
|
||||
uint64_t MainCounterValue;
|
||||
uint64_t Reserved4;
|
||||
};
|
||||
|
||||
uint32_t clk = 0;
|
||||
HPET *hpet = nullptr;
|
||||
uint64_t ClassCreationTime = 0;
|
||||
|
||||
inline uint64_t ConvertUnit(Units Unit)
|
||||
{
|
||||
switch (Unit)
|
||||
{
|
||||
case Femtoseconds:
|
||||
return 1;
|
||||
case Picoseconds:
|
||||
return 1000;
|
||||
case Nanoseconds:
|
||||
return 1000000;
|
||||
case Microseconds:
|
||||
return 1000000000;
|
||||
case Milliseconds:
|
||||
return 1000000000000;
|
||||
case Seconds:
|
||||
return 1000000000000000;
|
||||
case Minutes:
|
||||
return 1000000000000000000;
|
||||
// case Hours:
|
||||
// return 1000000000000000000000;
|
||||
// case Days:
|
||||
// return 1000000000000000000000000;
|
||||
// case Months:
|
||||
// return 1000000000000000000000000000;
|
||||
// case Years:
|
||||
// return 1000000000000000000000000000000;
|
||||
default:
|
||||
error("Invalid time unit %d", Unit);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
bool Sleep(uint64_t Duration, Units Unit);
|
||||
uint64_t GetCounter();
|
||||
uint64_t CalculateTarget(uint64_t Target, Units Unit);
|
||||
uint64_t GetNanosecondsSinceClassCreation();
|
||||
|
||||
HighPrecisionEventTimer(void *hpet);
|
||||
~HighPrecisionEventTimer();
|
||||
};
|
||||
|
||||
class TimeStampCounter
|
||||
{
|
||||
private:
|
||||
uint64_t clk = 0;
|
||||
uint64_t ClassCreationTime = 0;
|
||||
|
||||
inline uint64_t ConvertUnit(Units Unit)
|
||||
{
|
||||
switch (Unit)
|
||||
{
|
||||
case Femtoseconds:
|
||||
return 1;
|
||||
case Picoseconds:
|
||||
return 1000;
|
||||
case Nanoseconds:
|
||||
return 1000000;
|
||||
case Microseconds:
|
||||
return 1000000000;
|
||||
case Milliseconds:
|
||||
return 1000000000000;
|
||||
case Seconds:
|
||||
return 1000000000000000;
|
||||
case Minutes:
|
||||
return 1000000000000000000;
|
||||
// case Hours:
|
||||
// return 1000000000000000000000;
|
||||
// case Days:
|
||||
// return 1000000000000000000000000;
|
||||
// case Months:
|
||||
// return 1000000000000000000000000000;
|
||||
// case Years:
|
||||
// return 1000000000000000000000000000000;
|
||||
default:
|
||||
error("Invalid time unit %d", Unit);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
bool Sleep(uint64_t Duration, Units Unit);
|
||||
uint64_t GetCounter();
|
||||
uint64_t CalculateTarget(uint64_t Target, Units Unit);
|
||||
uint64_t GetNanosecondsSinceClassCreation();
|
||||
|
||||
TimeStampCounter();
|
||||
~TimeStampCounter();
|
||||
};
|
||||
|
||||
class time
|
||||
{
|
||||
public:
|
||||
enum TimeActiveTimer
|
||||
{
|
||||
NONE = 0b0,
|
||||
RTC = 0b1,
|
||||
PIT = 0b10,
|
||||
HPET = 0b100,
|
||||
ACPI = 0b1000,
|
||||
APIC = 0b10000,
|
||||
TSC = 0b100000
|
||||
};
|
||||
|
||||
private:
|
||||
int SupportedTimers = 0;
|
||||
TimeActiveTimer ActiveTimer = NONE;
|
||||
|
||||
HighPrecisionEventTimer *hpet;
|
||||
TimeStampCounter *tsc;
|
||||
|
||||
public:
|
||||
int GetSupportedTimers() { return SupportedTimers; }
|
||||
TimeActiveTimer GetActiveTimer() { return ActiveTimer; }
|
||||
bool ChangeActiveTimer(TimeActiveTimer Timer)
|
||||
{
|
||||
if (!(SupportedTimers & Timer))
|
||||
return false;
|
||||
ActiveTimer = Timer;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Sleep(uint64_t Duration, Units Unit);
|
||||
uint64_t GetCounter();
|
||||
uint64_t CalculateTarget(uint64_t Target, Units Unit);
|
||||
uint64_t GetNanosecondsSinceClassCreation();
|
||||
void FindTimers(void *acpi);
|
||||
time();
|
||||
~time();
|
||||
};
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_TIME_H__
|
372
Kernel/include/types.h
Normal file
372
Kernel/include/types.h
Normal file
@ -0,0 +1,372 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __FENNIX_KERNEL_TYPES_H__
|
||||
#define __FENNIX_KERNEL_TYPES_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define EXTERNC extern "C"
|
||||
#define START_EXTERNC \
|
||||
EXTERNC \
|
||||
{
|
||||
#define END_EXTERNC \
|
||||
}
|
||||
#else // __cplusplus
|
||||
#define EXTERNC
|
||||
#define START_EXTERNC
|
||||
#define END_EXTERNC
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define NULL 0
|
||||
#else // __cplusplus
|
||||
#define NULL ((void *)0)
|
||||
#define bool _Bool
|
||||
#endif // __cplusplus
|
||||
|
||||
#define asm __asm__
|
||||
#define asmv __asm__ volatile
|
||||
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#define inf_loop while (1)
|
||||
#define ilp inf_loop; /* Used for debugging */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define foreach for
|
||||
#define in :
|
||||
|
||||
#define r_cst(t, v) reinterpret_cast<t>(v)
|
||||
#define c_cst(t, v) const_cast<t>(v)
|
||||
#define s_cst(t, v) static_cast<t>(v)
|
||||
#define d_cst(t, v) dynamic_cast<t>(v)
|
||||
#endif // __cplusplus
|
||||
|
||||
#define UNUSED(x) (void)(x)
|
||||
#define CONCAT(x, y) x##y
|
||||
|
||||
#ifndef __cplusplus /* This conflicts with std */
|
||||
#define toupper(c) ((c)-0x20 * (((c) >= 'a') && ((c) <= 'z')))
|
||||
#define tolower(c) ((c) + 0x20 * (((c) >= 'A') && ((c) <= 'Z')))
|
||||
#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))(((uintptr_t)(x) + ((align)-1)) & (~((align)-1))))
|
||||
#define ALIGN_DOWN(x, align) ((__typeof__(x))((x) & (~((align)-1))))
|
||||
|
||||
#define offsetof(type, member) __builtin_offsetof(type, member)
|
||||
|
||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
#define VPOKE(type, address) (*((volatile type *)(address)))
|
||||
#define POKE(type, address) (*((type *)(address)))
|
||||
|
||||
#ifndef __cplusplus
|
||||
|
||||
#ifdef __STDC__
|
||||
#ifdef __STDC_VERSION__
|
||||
#if (__STDC_VERSION__ >= 201710L)
|
||||
#define C_LANGUAGE_STANDARD 2018
|
||||
#elif (__STDC_VERSION__ >= 201112L)
|
||||
#define C_LANGUAGE_STANDARD 2011
|
||||
#elif (__STDC_VERSION__ >= 199901L)
|
||||
#define C_LANGUAGE_STANDARD 1999
|
||||
#elif (__STDC_VERSION__ >= 199409L)
|
||||
#define C_LANGUAGE_STANDARD 1995
|
||||
#endif
|
||||
#else
|
||||
#define C_LANGUAGE_STANDARD 1990
|
||||
#endif
|
||||
#else
|
||||
#define C_LANGUAGE_STANDARD 1972
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifdef __STDC__
|
||||
#ifdef __cplusplus
|
||||
#if (__cplusplus >= 202100L)
|
||||
#define CPP_LANGUAGE_STANDARD 2023
|
||||
#elif (__cplusplus >= 202002L)
|
||||
#define CPP_LANGUAGE_STANDARD 2020
|
||||
#elif (__cplusplus >= 201703L)
|
||||
#define CPP_LANGUAGE_STANDARD 2017
|
||||
#elif (__cplusplus >= 201402L)
|
||||
#define CPP_LANGUAGE_STANDARD 2014
|
||||
#elif (__cplusplus >= 201103L)
|
||||
#define CPP_LANGUAGE_STANDARD 2011
|
||||
#elif (__cplusplus >= 199711L)
|
||||
#define CPP_LANGUAGE_STANDARD 1998
|
||||
#endif
|
||||
#else
|
||||
#define CPP_LANGUAGE_STANDARD __cplusplus
|
||||
#endif
|
||||
#else
|
||||
#define CPP_LANGUAGE_STANDARD __cplusplus
|
||||
#endif
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifndef __SIG_ATOMIC_TYPE__
|
||||
#define __SIG_ATOMIC_TYPE__ int
|
||||
#endif
|
||||
|
||||
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;
|
||||
#ifndef __cplusplus
|
||||
typedef __WCHAR_TYPE__ wchar_t;
|
||||
#endif
|
||||
typedef __WINT_TYPE__ wint_t;
|
||||
typedef __SIG_ATOMIC_TYPE__ sig_atomic_t;
|
||||
// TODO: ssize_t
|
||||
typedef intptr_t ssize_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__
|
||||
|
||||
#if defined(a64)
|
||||
#define BREAK __asm__ __volatile__("int $0x3" \
|
||||
: \
|
||||
: \
|
||||
: "memory");
|
||||
#elif defined(a32)
|
||||
#define BREAK __asm__ __volatile__("int $0x3" \
|
||||
: \
|
||||
: \
|
||||
: "memory");
|
||||
#elif defined(aa64)
|
||||
#define BREAK __asm__ __volatile__("brk #0" \
|
||||
: \
|
||||
: \
|
||||
: "memory");
|
||||
#endif
|
||||
|
||||
#ifdef __INT48_TYPE__
|
||||
typedef __INT48_TYPE__ int48_t;
|
||||
typedef __UINT48_TYPE__ uint48_t;
|
||||
typedef int48_t int_least48_t;
|
||||
typedef uint48_t uint_least48_t;
|
||||
typedef int48_t int_fast48_t;
|
||||
typedef uint48_t uint_fast48_t;
|
||||
#else // __INT48_TYPE__
|
||||
typedef __INT64_TYPE__ int48_t;
|
||||
typedef __UINT64_TYPE__ uint48_t;
|
||||
typedef int48_t int_least48_t;
|
||||
typedef uint48_t uint_least48_t;
|
||||
typedef int48_t int_fast48_t;
|
||||
typedef uint48_t uint_fast48_t;
|
||||
#endif // __INT48_TYPE__
|
||||
|
||||
#define b4(x) ((x & 0x0F) << 4 | (x & 0xF0) >> 4)
|
||||
#define b8(x) ((x)&0xFF)
|
||||
#define b16(x) __builtin_bswap16(x)
|
||||
#define b32(x) __builtin_bswap32(x)
|
||||
#define b48(x) (((((x)&0x0000000000ff) << 40) | \
|
||||
(((x)&0x00000000ff00) << 24) | \
|
||||
(((x)&0x000000ff0000) << 8) | \
|
||||
(((x)&0x0000ff000000) >> 8) | \
|
||||
(((x)&0x00ff00000000) >> 24) | \
|
||||
(((x)&0xff0000000000) >> 40)))
|
||||
#define b64(x) __builtin_bswap64(x)
|
||||
|
||||
/* https://gcc.gnu.org/onlinedocs/gcc-9.5.0/gnat_ugn/Optimization-Levels.html */
|
||||
|
||||
/** @brief No optimization (the default); generates unoptimized code but has the fastest compilation time. */
|
||||
#define O0 __attribute__((optimize("O0")))
|
||||
/** @brief Moderate optimization; optimizes reasonably well but does not degrade compilation time significantly. */
|
||||
#define O1 __attribute__((optimize("O1")))
|
||||
/** @brief Full optimization; generates highly optimized code and has the slowest compilation time. */
|
||||
#define O2 __attribute__((optimize("O2")))
|
||||
/** @brief Full optimization as in -O2; also uses more aggressive automatic inlining of subprograms within a unit (Inlining of Subprograms) and attempts to vectorize loops. */
|
||||
#define O3 __attribute__((optimize("O3")))
|
||||
/** @brief Optimize space usage (code and data) of resulting program. */
|
||||
#define Os __attribute__((optimize("Os")))
|
||||
/** @brief Disregard strict standards compliance. -Ofast enables all -O3 optimizations. It also enables optimizations that are not valid for all standard-compliant programs. */
|
||||
#define Ofast __attribute__((optimize("Ofast")))
|
||||
|
||||
#define __unused __attribute__((unused))
|
||||
#define __packed __attribute__((packed))
|
||||
#define __naked __attribute__((naked))
|
||||
#define __aligned(x) __attribute__((aligned(x)))
|
||||
#define __section(x) __attribute__((section(x)))
|
||||
#define __noreturn __attribute__((noreturn))
|
||||
#define __weak __attribute__((weak))
|
||||
#define __alias(x) __attribute__((alias(x)))
|
||||
#define __always_inline __attribute__((always_inline))
|
||||
#define __noinline __attribute__((noinline))
|
||||
#define __pure __attribute__((pure))
|
||||
#define __const __attribute__((const))
|
||||
#define __malloc __attribute__((malloc))
|
||||
#define __returns_twice __attribute__((returns_twice))
|
||||
#define __used __attribute__((used))
|
||||
#define __deprecated __attribute__((deprecated))
|
||||
#define __deprecated_msg(x) __attribute__((deprecated(x)))
|
||||
#define __weakref(x) __attribute__((weakref(x)))
|
||||
#define __weakrefalias(x) __attribute__((weakref(#x)))
|
||||
#define __visibility(x) __attribute__((visibility(x)))
|
||||
#define __constructor __attribute__((constructor))
|
||||
#define __destructor __attribute__((destructor))
|
||||
#define __cleanup(x) __attribute__((cleanup(x)))
|
||||
#define __fallthrough __attribute__((fallthrough))
|
||||
#define __nonnull(x) __attribute__((nonnull x))
|
||||
#define __nonnull_all __attribute__((nonnull))
|
||||
#define __returns_nonnull __attribute__((returns_nonnull))
|
||||
#define __sentinel __attribute__((sentinel))
|
||||
#define __sentinel_all __attribute__((sentinel(0)))
|
||||
#define __format(x, y, z) __attribute__((format(x, y, z)))
|
||||
#define __format_arg(x) __attribute__((format_arg(x)))
|
||||
#define __nonnull_params(x) __attribute__((nonnull x))
|
||||
#define __nonnull_all __attribute__((nonnull))
|
||||
#define __warn_unused_result __attribute__((warn_unused_result))
|
||||
#define __no_stack_protector __attribute__((no_stack_protector))
|
||||
#define __no_instrument_function __attribute__((no_instrument_function))
|
||||
#define __no_debug __attribute__((no_debug))
|
||||
#define __target(x) __attribute__((target(x)))
|
||||
#define __min_vector_width(x) __attribute__((min_vector_width(x)))
|
||||
|
||||
// sanitizer
|
||||
#define __no_sanitize_address __attribute__((no_sanitize_address))
|
||||
#define __no_sanitize_undefined __attribute__((no_sanitize_undefined))
|
||||
#define __no_address_safety_analysis __attribute__((no_address_safety_analysis))
|
||||
#define __no_sanitize_thread __attribute__((no_sanitize_thread))
|
||||
|
||||
#define __synchronize __sync_synchronize()
|
||||
#define __sync __synchronize
|
||||
|
||||
#define likely(x) __builtin_expect(!!(x), 1)
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
|
||||
#define SafeFunction __no_stack_protector __no_sanitize_address __no_sanitize_undefined __no_address_safety_analysis __no_sanitize_thread
|
||||
|
||||
#define NIF __no_instrument_function
|
||||
|
||||
#define int1 \
|
||||
__asm__ __volatile__("int $0x1" \
|
||||
: \
|
||||
: \
|
||||
: "memory")
|
||||
|
||||
#define int3 \
|
||||
__asm__ __volatile__("int3" \
|
||||
: \
|
||||
: \
|
||||
: "memory")
|
||||
|
||||
#endif // !__FENNIX_KERNEL_TYPES_H__
|
88
Kernel/include/uart.hpp
Normal file
88
Kernel/include/uart.hpp
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
This file is part of Fennix Kernel.
|
||||
|
||||
Fennix Kernel is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
Fennix Kernel is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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
|
||||
*/
|
||||
SafeFunction NIF SerialPorts GetRegisteredPort() { return this->Port; }
|
||||
|
||||
/**
|
||||
* @brief Called when a character is sent.
|
||||
* @param Char the sent character.
|
||||
*/
|
||||
|
||||
virtual void OnSent(uint8_t Char) { UNUSED(Char); }
|
||||
/**
|
||||
* @brief Called when a character is received.
|
||||
* @param Char the received character.
|
||||
*/
|
||||
virtual void OnReceived(uint8_t Char) { UNUSED(Char); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // !__FENNIX_KERNEL_UART_H__
|
Reference in New Issue
Block a user