mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-28 15:34:33 +00:00
Implemented a kinda broken tty
This commit is contained in:
parent
e332fc57e0
commit
7c4d43fec3
105
arch/CPU.cpp
105
arch/CPU.cpp
@ -1,63 +1,86 @@
|
|||||||
#include <cpu.hpp>
|
#include <cpu.hpp>
|
||||||
|
#include <memory.hpp>
|
||||||
|
|
||||||
namespace CPU
|
namespace CPU
|
||||||
{
|
{
|
||||||
void Pause()
|
void Pause()
|
||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
asmv("pause");
|
asmv("pause");
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
asmv("yield");
|
asmv("yield");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Halt()
|
void Halt()
|
||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
asmv("hlt");
|
asmv("hlt");
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
asmv("wfe");
|
asmv("wfe");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Interrupts(InterruptsType Type)
|
bool Interrupts(InterruptsType Type)
|
||||||
{
|
{
|
||||||
switch (Type)
|
switch (Type)
|
||||||
{
|
{
|
||||||
case Check:
|
case Check:
|
||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
uint64_t rflags;
|
uint64_t rflags;
|
||||||
asmv("pushfq");
|
asmv("pushfq");
|
||||||
asmv("popq %0"
|
asmv("popq %0"
|
||||||
: "=r"(rflags));
|
: "=r"(rflags));
|
||||||
return rflags & (1 << 9);
|
return rflags & (1 << 9);
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
uint64_t daif;
|
uint64_t daif;
|
||||||
asmv("mrs %0, daif"
|
asmv("mrs %0, daif"
|
||||||
: "=r"(daif));
|
: "=r"(daif));
|
||||||
return !(daif & (1 << 2));
|
return !(daif & (1 << 2));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
case Enable:
|
case Enable:
|
||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
asmv("sti");
|
asmv("sti");
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
asmv("msr daifclr, #2");
|
asmv("msr daifclr, #2");
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case Disable:
|
case Disable:
|
||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
asmv("cli");
|
asmv("cli");
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
asmv("msr daifset, #2");
|
asmv("msr daifset, #2");
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *PageTable(void *PT)
|
||||||
|
{
|
||||||
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
|
if (PT)
|
||||||
|
asmv("movq %0, %%cr3"
|
||||||
|
:
|
||||||
|
: "r"(PT));
|
||||||
|
else
|
||||||
|
asmv("movq %%cr3, %0"
|
||||||
|
: "=r"(PT));
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
if (PT)
|
||||||
|
asmv("msr ttbr0_el1, %0"
|
||||||
|
:
|
||||||
|
: "r"(PT));
|
||||||
|
else
|
||||||
|
asmv("mrs %0, ttbr0_el1"
|
||||||
|
: "=r"(PT));
|
||||||
|
#endif
|
||||||
|
return PT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ void init_limine()
|
|||||||
while (1)
|
while (1)
|
||||||
asmv("hlt");
|
asmv("hlt");
|
||||||
}
|
}
|
||||||
TerminalResponse->write(TerminalResponse->terminals[0], "Please wait... ", 15);
|
TerminalResponse->write(TerminalResponse->terminals[0], "\033[37mPlease wait... ", 20);
|
||||||
|
|
||||||
struct limine_framebuffer_response *FrameBufferResponse = FramebufferRequest.response;
|
struct limine_framebuffer_response *FrameBufferResponse = FramebufferRequest.response;
|
||||||
struct limine_memmap_response *MemmapResponse = MemmapRequest.response;
|
struct limine_memmap_response *MemmapResponse = MemmapRequest.response;
|
||||||
|
@ -28,7 +28,7 @@ void tracepagetable(PageTable *pt)
|
|||||||
for (int i = 0; i < 512; i++)
|
for (int i = 0; i < 512; i++)
|
||||||
{
|
{
|
||||||
if (pt->Entries[i].Value.Present)
|
if (pt->Entries[i].Value.Present)
|
||||||
debug("Entry %d: %x %x %x %x %x %x %x %x %x %x %x %p-%#lx", i,
|
debug("Entry %03d: %x %x %x %x %x %x %x %x %x %x %x %p-%#lx", i,
|
||||||
pt->Entries[i].Value.Present, pt->Entries[i].Value.ReadWrite,
|
pt->Entries[i].Value.Present, pt->Entries[i].Value.ReadWrite,
|
||||||
pt->Entries[i].Value.UserSupervisor, pt->Entries[i].Value.WriteThrough,
|
pt->Entries[i].Value.UserSupervisor, pt->Entries[i].Value.WriteThrough,
|
||||||
pt->Entries[i].Value.CacheDisable, pt->Entries[i].Value.Accessed,
|
pt->Entries[i].Value.CacheDisable, pt->Entries[i].Value.Accessed,
|
||||||
|
@ -118,6 +118,13 @@ namespace Memory
|
|||||||
this->Unmap((void *)((uint64_t)VirtualAddress + (i * PAGE_SIZE)));
|
this->Unmap((void *)((uint64_t)VirtualAddress + (i * PAGE_SIZE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Virtual::Virtual(PageTable *Table) { this->Table = Table; }
|
Virtual::Virtual(PageTable *Table)
|
||||||
|
{
|
||||||
|
if (Table)
|
||||||
|
this->Table = Table;
|
||||||
|
else
|
||||||
|
this->Table = (PageTable *)CPU::PageTable();
|
||||||
|
}
|
||||||
|
|
||||||
Virtual::~Virtual() {}
|
Virtual::~Virtual() {}
|
||||||
}
|
}
|
||||||
|
111
core/Video/Display.cpp
Normal file
111
core/Video/Display.cpp
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
#include <display.hpp>
|
||||||
|
#include <lock.hpp>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
extern uint64_t _binary_files_ter_powerline_v12n_psf_start;
|
||||||
|
extern uint64_t _binary_files_ter_powerline_v12n_psf_end;
|
||||||
|
extern uint64_t _binary_files_ter_powerline_v12n_psf_size;
|
||||||
|
|
||||||
|
NEWLOCK(PrintLock);
|
||||||
|
|
||||||
|
namespace Video
|
||||||
|
{
|
||||||
|
char Display::Print(char Char, int Index)
|
||||||
|
{
|
||||||
|
SMARTLOCK(PrintLock);
|
||||||
|
switch (Char)
|
||||||
|
{
|
||||||
|
case '\b':
|
||||||
|
{
|
||||||
|
if (Buffers[Index]->CursorX > 0)
|
||||||
|
Buffers[Index]->CursorX -= this->GetCurrentFont()->GetInfo().Width;
|
||||||
|
return Char;
|
||||||
|
}
|
||||||
|
case '\t':
|
||||||
|
{
|
||||||
|
Buffers[Index]->CursorX = (Buffers[Index]->CursorX + 8) & ~(8 - 1);
|
||||||
|
return Char;
|
||||||
|
}
|
||||||
|
case '\r':
|
||||||
|
{
|
||||||
|
Buffers[Index]->CursorX = 0;
|
||||||
|
return Char;
|
||||||
|
}
|
||||||
|
case '\n':
|
||||||
|
{
|
||||||
|
Buffers[Index]->CursorX = 0;
|
||||||
|
Buffers[Index]->CursorY += this->GetCurrentFont()->GetInfo().Height;
|
||||||
|
return Char;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Buffers[Index]->CursorX + this->GetCurrentFont()->GetInfo().Width >= Buffers[Index]->Width)
|
||||||
|
{
|
||||||
|
Buffers[Index]->CursorX = 0;
|
||||||
|
Buffers[Index]->CursorY += this->GetCurrentFont()->GetInfo().Height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Buffers[Index]->CursorY + this->GetCurrentFont()->GetInfo().Height >= Buffers[Index]->Height)
|
||||||
|
{
|
||||||
|
Buffers[Index]->CursorY = Buffers[Index]->Height - this->GetCurrentFont()->GetInfo().Height;
|
||||||
|
this->SetBuffer(Index);
|
||||||
|
Scroll(Index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CurrentFont->GetInfo().Type == FontType::PCScreenFont2)
|
||||||
|
{
|
||||||
|
// if (CurrentFont->PSF2Font->GlyphBuffer == (uint16_t *)0x01) // HAS UNICODE TABLE
|
||||||
|
// Char = CurrentFont->PSF2Font->GlyphBuffer[Char];
|
||||||
|
int bytesperline = (CurrentFont->GetInfo().PSF2Font->Header->width + 7) / 8;
|
||||||
|
char *FontPtr = (char *)CurrentFont->GetInfo().StartAddress +
|
||||||
|
CurrentFont->GetInfo().PSF2Font->Header->headersize +
|
||||||
|
(Char > 0 && (unsigned char)Char < CurrentFont->GetInfo().PSF2Font->Header->length ? Char : 0) *
|
||||||
|
CurrentFont->GetInfo().PSF2Font->Header->charsize;
|
||||||
|
|
||||||
|
for (unsigned long Y = Buffers[Index]->CursorY; Y < Buffers[Index]->CursorY + CurrentFont->GetInfo().PSF2Font->Header->height; Y++)
|
||||||
|
{
|
||||||
|
for (unsigned long X = Buffers[Index]->CursorX; X < Buffers[Index]->CursorX + CurrentFont->GetInfo().PSF2Font->Header->width; X++)
|
||||||
|
if ((*FontPtr & (0b10000000 >> (X - Buffers[Index]->CursorX))) > 0)
|
||||||
|
*(uint32_t *)((uint64_t)Buffers[Index]->Buffer + (Y * Buffers[Index]->Width + X) * (framebuffer.BitsPerPixel / 8)) = 0xFFFFFF;
|
||||||
|
|
||||||
|
FontPtr += bytesperline;
|
||||||
|
}
|
||||||
|
Buffers[Index]->CursorX += CurrentFont->GetInfo().PSF2Font->Header->width;
|
||||||
|
return Char;
|
||||||
|
}
|
||||||
|
else if (CurrentFont->GetInfo().Type == FontType::PCScreenFont1)
|
||||||
|
{
|
||||||
|
uint32_t *PixelPtr = (uint32_t *)Buffers[Index]->Buffer;
|
||||||
|
char *FontPtr = (char *)CurrentFont->GetInfo().PSF1Font->GlyphBuffer + (Char * CurrentFont->GetInfo().PSF1Font->Header->charsize);
|
||||||
|
for (unsigned long Y = Buffers[Index]->CursorY; Y < Buffers[Index]->CursorY + 16; Y++)
|
||||||
|
{
|
||||||
|
for (unsigned long X = Buffers[Index]->CursorX; X < Buffers[Index]->CursorX + 8; X++)
|
||||||
|
if ((*FontPtr & (0b10000000 >> (X - Buffers[Index]->CursorX))) > 0)
|
||||||
|
*(unsigned int *)(PixelPtr + X + (Y * Buffers[Index]->Width)) = Buffers[Index]->Color;
|
||||||
|
FontPtr++;
|
||||||
|
}
|
||||||
|
Buffers[Index]->CursorX += 8;
|
||||||
|
return Char;
|
||||||
|
}
|
||||||
|
return Char;
|
||||||
|
}
|
||||||
|
|
||||||
|
Display::Display(BootInfo::FramebufferInfo Info, bool LoadDefaultFont)
|
||||||
|
{
|
||||||
|
framebuffer = Info;
|
||||||
|
if (LoadDefaultFont)
|
||||||
|
{
|
||||||
|
CurrentFont = new Font(&_binary_files_ter_powerline_v12n_psf_start, &_binary_files_ter_powerline_v12n_psf_end, FontType::PCScreenFont2);
|
||||||
|
FontInfo Info = CurrentFont->GetInfo();
|
||||||
|
debug("Font loaded: %dx%d %s",
|
||||||
|
Info.Width, Info.Height, Info.Type == FontType::PCScreenFont1 ? "PSF1" : "PSF2");
|
||||||
|
}
|
||||||
|
this->CreateBuffer(Info.Width, Info.Height, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Display::~Display()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
DeleteBuffer(i);
|
||||||
|
}
|
||||||
|
}
|
54
core/Video/Font.cpp
Normal file
54
core/Video/Font.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include <display.hpp>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace Video
|
||||||
|
{
|
||||||
|
Font::Font(uint64_t *Start, uint64_t *End, FontType Type)
|
||||||
|
{
|
||||||
|
trace("Initializing font with start %#llx and end %#llx Type: %d", Start, End, Type);
|
||||||
|
this->Info.StartAddress = Start;
|
||||||
|
this->Info.EndAddress = End;
|
||||||
|
this->Info.Type = Type;
|
||||||
|
if (Type == FontType::PCScreenFont2)
|
||||||
|
{
|
||||||
|
this->Info.PSF2Font = new PSF2_FONT;
|
||||||
|
|
||||||
|
uint64_t FontDataLength = End - Start;
|
||||||
|
PSF2_HEADER *font2 = (PSF2_HEADER *)KernelAllocator.RequestPages(FontDataLength / PAGE_SIZE + 1);
|
||||||
|
for (uint64_t i = 0; i < FontDataLength / PAGE_SIZE + 1; i++)
|
||||||
|
Memory::Virtual().Map((void *)(font2 + (i * PAGE_SIZE)), (void *)(font2 + (i * PAGE_SIZE)), Memory::PTFlag::RW);
|
||||||
|
memcpy((void *)font2, Start, FontDataLength);
|
||||||
|
|
||||||
|
this->Info.Width = font2->width;
|
||||||
|
this->Info.Height = font2->height;
|
||||||
|
if (font2->magic[0] != PSF2_MAGIC0 || font2->magic[1] != PSF2_MAGIC1 || font2->magic[2] != PSF2_MAGIC2 || font2->magic[3] != PSF2_MAGIC3)
|
||||||
|
error("Font2 magic mismatch.");
|
||||||
|
|
||||||
|
this->Info.PSF2Font->Header = font2;
|
||||||
|
this->Info.PSF2Font->GlyphBuffer = reinterpret_cast<void *>(reinterpret_cast<uint64_t>(Start) + sizeof(PSF2_HEADER));
|
||||||
|
}
|
||||||
|
else if (Type == FontType::PCScreenFont1)
|
||||||
|
{
|
||||||
|
this->Info.PSF1Font = new PSF1_FONT;
|
||||||
|
PSF1_HEADER *font1 = (PSF1_HEADER *)Start;
|
||||||
|
if (font1->magic[0] != PSF1_MAGIC0 || font1->magic[1] != PSF1_MAGIC1)
|
||||||
|
error("Font1 magic mismatch.");
|
||||||
|
uint32_t glyphBufferSize = font1->charsize * 256;
|
||||||
|
if (font1->mode == 1) // 512 glyph mode
|
||||||
|
glyphBufferSize = font1->charsize * 512;
|
||||||
|
void *glyphBuffer = reinterpret_cast<void *>(reinterpret_cast<uint64_t>(Start) + sizeof(PSF1_HEADER));
|
||||||
|
this->Info.PSF1Font->Header = font1;
|
||||||
|
this->Info.PSF1Font->GlyphBuffer = glyphBuffer;
|
||||||
|
UNUSED(glyphBufferSize); // TODO: Use this in the future?
|
||||||
|
|
||||||
|
// TODO: Get font size.
|
||||||
|
this->Info.Width = 16;
|
||||||
|
this->Info.Height = 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Font::~Font()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
179
include/cpu.hpp
179
include/cpu.hpp
@ -8,127 +8,134 @@
|
|||||||
*/
|
*/
|
||||||
namespace CPU
|
namespace CPU
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @brief Enum for CPU::Interrupts() function.
|
|
||||||
*/
|
|
||||||
enum InterruptsType
|
|
||||||
{
|
|
||||||
/**
|
/**
|
||||||
* @brief Check if interrupts are enabled.
|
* @brief Enum for CPU::Interrupts() function.
|
||||||
*/
|
*/
|
||||||
Check,
|
enum InterruptsType
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @brief Check if interrupts are enabled.
|
||||||
|
*/
|
||||||
|
Check,
|
||||||
|
/**
|
||||||
|
* @brief Enable interrupts.
|
||||||
|
*/
|
||||||
|
Enable,
|
||||||
|
/**
|
||||||
|
* @brief Disable interrupts.
|
||||||
|
*/
|
||||||
|
Disable
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable interrupts.
|
* @brief Pause the CPU
|
||||||
*/
|
*/
|
||||||
Enable,
|
void Pause();
|
||||||
/**
|
/**
|
||||||
* @brief Disable interrupts.
|
* @brief Halt the CPU
|
||||||
*/
|
*/
|
||||||
Disable
|
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
|
||||||
* @brief Pause the CPU
|
|
||||||
*/
|
|
||||||
void Pause();
|
|
||||||
/**
|
|
||||||
* @brief Halt the CPU
|
|
||||||
*/
|
|
||||||
void Halt();
|
|
||||||
/**
|
|
||||||
* @brief Check if interrupts are enabled
|
|
||||||
*
|
|
||||||
* @return true If InterruptsType::Check and interrupts are enabled, or if other InterruptsType were executed successfully
|
|
||||||
* @return false If InterruptsType::Check and interrupts are disabled, or if other InterruptsType failed
|
|
||||||
*/
|
|
||||||
bool Interrupts(InterruptsType Type = Check);
|
|
||||||
|
|
||||||
namespace MemBar
|
|
||||||
{
|
|
||||||
static inline void Barrier()
|
|
||||||
{
|
{
|
||||||
|
static inline void Barrier()
|
||||||
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
asmv("" ::
|
asmv("" ::
|
||||||
: "memory");
|
: "memory");
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
asmv("dmb ish" ::
|
asmv("dmb ish" ::
|
||||||
: "memory");
|
: "memory");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void Fence()
|
static inline void Fence()
|
||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
asmv("mfence" ::
|
asmv("mfence" ::
|
||||||
: "memory");
|
: "memory");
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
asmv("dmb ish" ::
|
asmv("dmb ish" ::
|
||||||
: "memory");
|
: "memory");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void StoreFence()
|
static inline void StoreFence()
|
||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
asmv("sfence" ::
|
asmv("sfence" ::
|
||||||
: "memory");
|
: "memory");
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
asmv("dmb ishst" ::
|
asmv("dmb ishst" ::
|
||||||
: "memory");
|
: "memory");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void LoadFence()
|
static inline void LoadFence()
|
||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
asmv("lfence" ::
|
asmv("lfence" ::
|
||||||
: "memory");
|
: "memory");
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
asmv("dmb ishld" ::
|
asmv("dmb ishld" ::
|
||||||
: "memory");
|
: "memory");
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace x86
|
|
||||||
{
|
|
||||||
static inline void lgdt(void *gdt)
|
|
||||||
{
|
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
|
||||||
asmv("lgdt (%0)"
|
|
||||||
:
|
|
||||||
: "r"(gdt));
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void lidt(void *idt)
|
namespace x86
|
||||||
{
|
{
|
||||||
|
static inline void lgdt(void *gdt)
|
||||||
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
asmv("lidt (%0)"
|
asmv("lgdt (%0)"
|
||||||
:
|
:
|
||||||
: "r"(idt));
|
: "r"(gdt));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ltr(uint16_t Segment)
|
static inline void lidt(void *idt)
|
||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
asmv("ltr %0"
|
asmv("lidt (%0)"
|
||||||
:
|
:
|
||||||
: "r"(Segment));
|
: "r"(idt));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void invlpg(void *Address)
|
static inline void ltr(uint16_t Segment)
|
||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
asmv("invlpg (%0)"
|
asmv("ltr %0"
|
||||||
:
|
:
|
||||||
: "r"(Address)
|
: "r"(Segment));
|
||||||
: "memory");
|
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void invlpg(void *Address)
|
||||||
|
{
|
||||||
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
|
asmv("invlpg (%0)"
|
||||||
|
:
|
||||||
|
: "r"(Address)
|
||||||
|
: "memory");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !__FENNIX_KERNEL_CPU_H__
|
#endif // !__FENNIX_KERNEL_CPU_H__
|
||||||
|
159
include/display.hpp
Normal file
159
include/display.hpp
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
#ifndef __FENNIX_KERNEL_DISPLAY_H__
|
||||||
|
#define __FENNIX_KERNEL_DISPLAY_H__
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
#include <boot/binfo.h>
|
||||||
|
#include <memory.hpp>
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
uint64_t *StartAddress;
|
||||||
|
uint64_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(uint64_t *Start, uint64_t *End, FontType Type);
|
||||||
|
~Font();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ScreenBuffer
|
||||||
|
{
|
||||||
|
void *Buffer;
|
||||||
|
uint32_t Width, Height;
|
||||||
|
uint64_t Size;
|
||||||
|
uint32_t Color;
|
||||||
|
uint32_t CursorX, CursorY;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Display
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
BootInfo::FramebufferInfo framebuffer;
|
||||||
|
Font *CurrentFont;
|
||||||
|
ScreenBuffer *Buffers[16];
|
||||||
|
|
||||||
|
public:
|
||||||
|
Font *GetCurrentFont() { return CurrentFont; }
|
||||||
|
void SetCurrentFont(Font *Font) { CurrentFont = Font; }
|
||||||
|
void CreateBuffer(uint32_t Width, uint32_t Height, int Index)
|
||||||
|
{
|
||||||
|
uint64_t Size = framebuffer.Pitch * Height;
|
||||||
|
ScreenBuffer *buffer = new ScreenBuffer;
|
||||||
|
buffer->Buffer = KernelAllocator.RequestPages(TO_PAGES(Size));
|
||||||
|
buffer->Width = Width;
|
||||||
|
buffer->Height = Height;
|
||||||
|
buffer->Size = Size;
|
||||||
|
buffer->Color = 0x000000;
|
||||||
|
buffer->CursorX = 0;
|
||||||
|
buffer->CursorY = 0;
|
||||||
|
Buffers[Index] = buffer;
|
||||||
|
__builtin_memset(buffer->Buffer, 0, Size);
|
||||||
|
}
|
||||||
|
void SetBuffer(int Index) { __builtin_memcpy(framebuffer.BaseAddress, Buffers[Index]->Buffer, Buffers[Index]->Size); }
|
||||||
|
void ClearBuffer(int Index) { __builtin_memset(Buffers[Index]->Buffer, 0, Buffers[Index]->Size); }
|
||||||
|
void DeleteBuffer(int Index)
|
||||||
|
{
|
||||||
|
if (Buffers[Index] == nullptr)
|
||||||
|
return;
|
||||||
|
KernelAllocator.FreePages(Buffers[Index]->Buffer, TO_PAGES(Buffers[Index]->Size));
|
||||||
|
delete Buffers[Index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetPixel(uint32_t X, uint32_t Y, uint32_t Color, int Index)
|
||||||
|
{
|
||||||
|
if (X >= Buffers[Index]->Width || Y >= Buffers[Index]->Height)
|
||||||
|
return;
|
||||||
|
uint32_t *Pixel = (uint32_t *)((uint64_t)Buffers[Index]->Buffer + (Y * Buffers[Index]->Width + X) * (framebuffer.BitsPerPixel / 8));
|
||||||
|
*Pixel = Color;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t GetPixel(uint32_t X, uint32_t Y, int Index)
|
||||||
|
{
|
||||||
|
if (X >= Buffers[Index]->Width || Y >= Buffers[Index]->Height)
|
||||||
|
return 0;
|
||||||
|
uint32_t *Pixel = (uint32_t *)((uint64_t)Buffers[Index]->Buffer + (Y * Buffers[Index]->Width + X) * (framebuffer.BitsPerPixel / 8));
|
||||||
|
return *Pixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scroll(int Index, int Lines)
|
||||||
|
{
|
||||||
|
if (Lines == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (Lines > 0)
|
||||||
|
{
|
||||||
|
__builtin_memmove(Buffers[Index]->Buffer,
|
||||||
|
(uint8_t *)Buffers[Index]->Buffer + (Buffers[Index]->Width * (framebuffer.BitsPerPixel / 8) * Lines),
|
||||||
|
Buffers[Index]->Size - (Buffers[Index]->Width * (framebuffer.BitsPerPixel / 8) * Lines));
|
||||||
|
|
||||||
|
__builtin_memset((uint8_t *)Buffers[Index]->Buffer + (Buffers[Index]->Size - (Buffers[Index]->Width * (framebuffer.BitsPerPixel / 8) * Lines)),
|
||||||
|
0,
|
||||||
|
Buffers[Index]->Width * (framebuffer.BitsPerPixel / 8) * Lines);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char Print(char Char, int Index);
|
||||||
|
Display(BootInfo::FramebufferInfo Info, bool LoadDefaultFont = true);
|
||||||
|
~Display();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !__FENNIX_KERNEL_DISPLAY_H__
|
@ -396,9 +396,9 @@ namespace Memory
|
|||||||
/**
|
/**
|
||||||
* @brief Construct a new Virtual object
|
* @brief Construct a new Virtual object
|
||||||
*
|
*
|
||||||
* @param Table Page table
|
* @param Table Page table. If null, it will use the current page table.
|
||||||
*/
|
*/
|
||||||
Virtual(PageTable *Table);
|
Virtual(PageTable *Table = nullptr);
|
||||||
/**
|
/**
|
||||||
* @brief Destroy the Virtual object
|
* @brief Destroy the Virtual object
|
||||||
*
|
*
|
||||||
|
@ -32,6 +32,8 @@
|
|||||||
#define in :
|
#define in :
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define UNUSED(x) (void)(x)
|
||||||
|
|
||||||
#ifndef __va_list__
|
#ifndef __va_list__
|
||||||
typedef __builtin_va_list va_list;
|
typedef __builtin_va_list va_list;
|
||||||
#endif
|
#endif
|
||||||
|
@ -911,7 +911,7 @@ static /* double */ unsigned long pow10_of_int(int floored_exp10)
|
|||||||
double_with_bit_access dwba;
|
double_with_bit_access dwba;
|
||||||
// int exp2 = bastardized_floor(floored_exp10 * 3.321928094887362 + 0.5);
|
// int exp2 = bastardized_floor(floored_exp10 * 3.321928094887362 + 0.5);
|
||||||
// const /* double */ unsigned long z = floored_exp10 * 2.302585092994046 - exp2 * 0.6931471805599453;
|
// const /* double */ unsigned long z = floored_exp10 * 2.302585092994046 - exp2 * 0.6931471805599453;
|
||||||
int exp2 = bastardized_floor(floored_exp10 * 3 + 1/* 0.5 */);
|
int exp2 = bastardized_floor(floored_exp10 * 3 + 1 /* 0.5 */);
|
||||||
const /* double */ unsigned long z = floored_exp10 * 2 - exp2 * 0;
|
const /* double */ unsigned long z = floored_exp10 * 2 - exp2 * 0;
|
||||||
const /* double */ unsigned long z2 = z * z;
|
const /* double */ unsigned long z2 = z * z;
|
||||||
dwba.U = ((double_uint_t)(exp2) + DOUBLE_BASE_EXPONENT) << DOUBLE_STORED_MANTISSA_BITS;
|
dwba.U = ((double_uint_t)(exp2) + DOUBLE_BASE_EXPONENT) << DOUBLE_STORED_MANTISSA_BITS;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user