mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-28 07:24:37 +00:00
264 lines
6.9 KiB
C++
264 lines
6.9 KiB
C++
#ifndef __FENNIX_KERNEL_CPU_H__
|
|
#define __FENNIX_KERNEL_CPU_H__
|
|
|
|
#include <types.h>
|
|
|
|
/**
|
|
* @brief CPU related functions.
|
|
*/
|
|
namespace CPU
|
|
{
|
|
/**
|
|
* @brief Enum for CPU::Interrupts() function.
|
|
*/
|
|
enum InterruptsType
|
|
{
|
|
/**
|
|
* @brief Check if interrupts are enabled.
|
|
*/
|
|
Check,
|
|
/**
|
|
* @brief Enable interrupts.
|
|
*/
|
|
Enable,
|
|
/**
|
|
* @brief Disable interrupts.
|
|
*/
|
|
Disable
|
|
};
|
|
|
|
/**
|
|
* @brief 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 Pause the CPU
|
|
*/
|
|
void Pause();
|
|
|
|
/**
|
|
* @brief Halt the CPU
|
|
*/
|
|
void Halt();
|
|
|
|
/**
|
|
* @brief Check if interrupts are enabled
|
|
*
|
|
* @return true If InterruptsType::Check and interrupts are enabled, or if other InterruptsType were executed successfully
|
|
* @return false If InterruptsType::Check and interrupts are disabled, or if other InterruptsType failed
|
|
*/
|
|
bool Interrupts(InterruptsType Type = Check);
|
|
|
|
/**
|
|
* @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);
|
|
|
|
namespace MemBar
|
|
{
|
|
static inline void Barrier()
|
|
{
|
|
#if defined(__amd64__) || defined(__i386__)
|
|
asmv("" ::
|
|
: "memory");
|
|
#elif defined(__aarch64__)
|
|
asmv("dmb ish" ::
|
|
: "memory");
|
|
#endif
|
|
}
|
|
|
|
static inline void Fence()
|
|
{
|
|
#if defined(__amd64__) || defined(__i386__)
|
|
asmv("mfence" ::
|
|
: "memory");
|
|
#elif defined(__aarch64__)
|
|
asmv("dmb ish" ::
|
|
: "memory");
|
|
#endif
|
|
}
|
|
|
|
static inline void StoreFence()
|
|
{
|
|
#if defined(__amd64__) || defined(__i386__)
|
|
asmv("sfence" ::
|
|
: "memory");
|
|
#elif defined(__aarch64__)
|
|
asmv("dmb ishst" ::
|
|
: "memory");
|
|
#endif
|
|
}
|
|
|
|
static inline void LoadFence()
|
|
{
|
|
#if defined(__amd64__) || defined(__i386__)
|
|
asmv("lfence" ::
|
|
: "memory");
|
|
#elif defined(__aarch64__)
|
|
asmv("dmb ishld" ::
|
|
: "memory");
|
|
#endif
|
|
}
|
|
}
|
|
|
|
namespace x32
|
|
{
|
|
}
|
|
|
|
namespace x64
|
|
{
|
|
typedef union
|
|
{
|
|
struct
|
|
{
|
|
/** @brief Carry Flag */
|
|
uint64_t CF : 1;
|
|
/** @brief Reserved */
|
|
uint64_t always_one : 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 */
|
|
uint64_t ID : 1;
|
|
/** @brief Reserved */
|
|
uint64_t _reserved3 : 10;
|
|
};
|
|
uint64_t raw;
|
|
} RFLAGS;
|
|
|
|
typedef struct _TrapFrame
|
|
{
|
|
// uint64_t gs; // General-purpose Segment
|
|
// uint64_t fs; // General-purpose Segment
|
|
// uint64_t es; // Extra Segment (used for string operations)
|
|
uint64_t ds; // Data Segment
|
|
|
|
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 int_num; // Interrupt Number
|
|
uint64_t error_code; // 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;
|
|
|
|
static inline void lgdt(void *gdt)
|
|
{
|
|
#if defined(__amd64__)
|
|
asmv("lgdt (%0)"
|
|
:
|
|
: "r"(gdt));
|
|
#endif
|
|
}
|
|
|
|
static inline void lidt(void *idt)
|
|
{
|
|
#if defined(__amd64__)
|
|
asmv("lidt (%0)"
|
|
:
|
|
: "r"(idt));
|
|
#endif
|
|
}
|
|
|
|
static inline void ltr(uint16_t Segment)
|
|
{
|
|
#if defined(__amd64__)
|
|
asmv("ltr %0"
|
|
:
|
|
: "r"(Segment));
|
|
#endif
|
|
}
|
|
|
|
static inline void invlpg(void *Address)
|
|
{
|
|
#if defined(__amd64__)
|
|
asmv("invlpg (%0)"
|
|
:
|
|
: "r"(Address)
|
|
: "memory");
|
|
#endif
|
|
}
|
|
|
|
static inline void cpuid(uint32_t Function, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
|
|
{
|
|
#if defined(__amd64__)
|
|
asmv("cpuid"
|
|
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
|
|
: "a"(Function));
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif // !__FENNIX_KERNEL_CPU_H__
|