Fix 32-bit compilation

This commit is contained in:
Alex 2023-08-23 16:59:21 +03:00
parent 8898791257
commit bef0897442
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
58 changed files with 4419 additions and 3418 deletions

View File

@ -1,7 +1,7 @@
/* Based on this tutorial:
https://github.com/s-matyukevich/raspberry-pi-os */
.section ".text.boot"
.section ".text.boot", "a"
.extern _bss_start
.extern _bss_end

View File

@ -18,7 +18,7 @@
.intel_syntax noprefix
.code32
.section .multiboot
.section .multiboot, "a"
.align 4
MULTIBOOT_HEADER:

View File

@ -16,7 +16,7 @@
*/
.code32
.section .bootstrap.text
.section .bootstrap.text, "a"
.global Multiboot1_start
Multiboot1_start:

View File

@ -18,7 +18,7 @@
.intel_syntax noprefix
.code32
.section .bootstrap.text
.section .bootstrap.text, "a"
.global DetectCPUID
DetectCPUID:

View File

@ -16,7 +16,7 @@
*/
.code32
.section .bootstrap.text
.section .bootstrap.text, "a"
.align 32
.global gdtr

View File

@ -16,7 +16,7 @@
*/
.code64
.section .bootstrap.data
.section .bootstrap.data, "a"
/* Access bits */
A = 0x1

View File

@ -19,7 +19,7 @@
.extern Multiboot2_start
/* https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html */
.section .multiboot2
.section .multiboot2, "a"
.align 0x1000
MULTIBOOT2_HEADER_START:
.long 0xE85250D6

View File

@ -18,13 +18,13 @@
PAGE_TABLE_SIZE = 0x4
.code32
.section .bootstrap.data
.section .bootstrap.data, "a"
.align 0x1000
.global BootPageTable
BootPageTable:
.space 0x10000 /* 0x4000 bytes will be used in UpdatePageTable */
.section .bootstrap.text
.section .bootstrap.text, "a"
.global UpdatePageTable
UpdatePageTable:
mov $(BootPageTable + 0x0000), %edi /* First PML4E */

View File

@ -30,14 +30,14 @@ KERNEL_STACK_SIZE = 0x4000 /* 16KB */
.extern GDT64.Code
.extern GDT64.Data
.section .bootstrap.data
.section .bootstrap.data, "a"
MB_HeaderMagic:
.quad 0
MB_HeaderInfo:
.quad 0
.section .bootstrap.text
.section .bootstrap.text, "a"
.global Multiboot2_start
Multiboot2_start:
@ -113,7 +113,7 @@ HigherHalfStart:
hlt
jmp .Hang
.section .bootstrap.bss
.section .bootstrap.bss, "a"
.align 16
KernelStack:
.space KERNEL_STACK_SIZE

View File

@ -21,7 +21,7 @@
.extern Multiboot2_start
.code32
.section .bootstrap.text
.section .bootstrap.text, "a"
.global _start
_start:

View File

@ -24,7 +24,7 @@ TRAMPOLINE_IDT = 0x590
TRAMPOLINE_CORE = 0x600
TRAMPOLINE_START = 0x2000
.section .text
.section .text, "a"
/* ========== 16-bit ========== */

View File

@ -0,0 +1,158 @@
/*
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/>.
*/
#include "acpi.hpp"
#include <debug.h>
#include <io.h>
#include "../../kernel.h"
namespace ACPI
{
__no_sanitize("alignment") void *ACPI::FindTable(ACPI::ACPIHeader *ACPIHeader, char *Signature)
{
for (uint64_t t = 0; t < ((ACPIHeader->Length - sizeof(ACPI::ACPIHeader)) / (XSDTSupported ? 8 : 4)); t++)
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
// TODO: Should I be concerned about unaligned memory access?
ACPI::ACPIHeader *SDTHdr = nullptr;
if (XSDTSupported)
SDTHdr = (ACPI::ACPIHeader *)(*(uint64_t *)((uint64_t)ACPIHeader + sizeof(ACPI::ACPIHeader) + (t * 8)));
else
SDTHdr = (ACPI::ACPIHeader *)(*(uint32_t *)((uint64_t)ACPIHeader + sizeof(ACPI::ACPIHeader) + (t * 4)));
#pragma GCC diagnostic pop
for (int i = 0; i < 4; i++)
{
if (SDTHdr->Signature[i] != Signature[i])
break;
if (i == 3)
{
trace("%s found at address %p", Signature, (uintptr_t)SDTHdr);
return SDTHdr;
}
}
}
// warn("%s not found!", Signature);
return nullptr;
}
void ACPI::SearchTables(ACPIHeader *Header)
{
if (!Header)
return;
HPET = (HPETHeader *)FindTable(Header, (char *)"HPET");
FADT = (FADTHeader *)FindTable(Header, (char *)"FACP");
MCFG = (MCFGHeader *)FindTable(Header, (char *)"MCFG");
BGRT = (BGRTHeader *)FindTable(Header, (char *)"BGRT");
SRAT = (SRATHeader *)FindTable(Header, (char *)"SRAT");
TPM2 = (TPM2Header *)FindTable(Header, (char *)"TPM2");
TCPA = (TCPAHeader *)FindTable(Header, (char *)"TCPA");
WAET = (WAETHeader *)FindTable(Header, (char *)"WAET");
MADT = (MADTHeader *)FindTable(Header, (char *)"APIC");
HEST = (HESTHeader *)FindTable(Header, (char *)"HEST");
FindTable(Header, (char *)"BERT");
FindTable(Header, (char *)"CPEP");
FindTable(Header, (char *)"DSDT");
FindTable(Header, (char *)"ECDT");
FindTable(Header, (char *)"EINJ");
FindTable(Header, (char *)"ERST");
FindTable(Header, (char *)"FACS");
FindTable(Header, (char *)"MSCT");
FindTable(Header, (char *)"MPST");
FindTable(Header, (char *)"OEMx");
FindTable(Header, (char *)"PMTT");
FindTable(Header, (char *)"PSDT");
FindTable(Header, (char *)"RASF");
FindTable(Header, (char *)"RSDT");
FindTable(Header, (char *)"SBST");
FindTable(Header, (char *)"SLIT");
FindTable(Header, (char *)"SSDT");
FindTable(Header, (char *)"XSDT");
FindTable(Header, (char *)"DRTM");
FindTable(Header, (char *)"FPDT");
FindTable(Header, (char *)"GTDT");
FindTable(Header, (char *)"PCCT");
FindTable(Header, (char *)"S3PT");
FindTable(Header, (char *)"MATR");
FindTable(Header, (char *)"MSDM");
FindTable(Header, (char *)"WPBT");
FindTable(Header, (char *)"OSDT");
FindTable(Header, (char *)"RSDP");
FindTable(Header, (char *)"NFIT");
FindTable(Header, (char *)"ASF!");
FindTable(Header, (char *)"BOOT");
FindTable(Header, (char *)"CSRT");
FindTable(Header, (char *)"DBG2");
FindTable(Header, (char *)"DBGP");
FindTable(Header, (char *)"DMAR");
FindTable(Header, (char *)"IBFT");
FindTable(Header, (char *)"IORT");
FindTable(Header, (char *)"IVRS");
FindTable(Header, (char *)"LPIT");
FindTable(Header, (char *)"MCHI");
FindTable(Header, (char *)"MTMR");
FindTable(Header, (char *)"SLIC");
FindTable(Header, (char *)"SPCR");
FindTable(Header, (char *)"SPMI");
FindTable(Header, (char *)"UEFI");
FindTable(Header, (char *)"VRTC");
FindTable(Header, (char *)"WDAT");
FindTable(Header, (char *)"WDDT");
FindTable(Header, (char *)"WDRT");
FindTable(Header, (char *)"ATKG");
FindTable(Header, (char *)"GSCI");
FindTable(Header, (char *)"IEIT");
FindTable(Header, (char *)"HMAT");
FindTable(Header, (char *)"CEDT");
FindTable(Header, (char *)"AEST");
}
ACPI::ACPI()
{
trace("Initializing ACPI");
if (bInfo.RSDP->Revision >= 2 && bInfo.RSDP->XSDTAddress)
{
debug("XSDT supported");
XSDTSupported = true;
XSDT = (ACPIHeader *)(bInfo.RSDP->XSDTAddress);
}
else
{
debug("RSDT supported");
XSDT = (ACPIHeader *)(uintptr_t)bInfo.RSDP->RSDTAddress;
}
this->SearchTables(XSDT);
if (FADT)
{
outb(s_cst(uint16_t, FADT->SMI_CommandPort), FADT->AcpiEnable);
while (!(inw(s_cst(uint16_t, FADT->PM1aControlBlock)) & 1))
;
}
}
ACPI::~ACPI()
{
}
}

View File

@ -18,7 +18,7 @@
.intel_syntax noprefix
.code32
.section .multiboot
.section .multiboot, "a"
.align 4
MULTIBOOT_HEADER:

View File

@ -16,7 +16,7 @@
*/
.code32
.section .bootstrap.text
.section .bootstrap.text, "a"
.global Multiboot1_start
Multiboot1_start:

View File

@ -18,7 +18,7 @@
.intel_syntax noprefix
.code32
.section .bootstrap.text
.section .bootstrap.text, "a"
.global DetectCPUID
DetectCPUID:

View File

@ -18,7 +18,7 @@
.intel_syntax noprefix
.code32
.section .bootstrap.text
.section .bootstrap.text, "a"
.align 32
.global gdtr

View File

@ -21,7 +21,7 @@
.extern Multiboot2_start
/* https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html */
.section .multiboot2
.section .multiboot2, "a"
.align 0x1000
MULTIBOOT2_HEADER_START:
.long 0xE85250D6

View File

@ -19,7 +19,7 @@
KERNEL_VIRTUAL_BASE = 0xC0000000 /* 3GB */
KERNEL_PAGE_NUMBER = 768 /* KERNEL_VIRTUAL_BASE >> 22 */
.section .bootstrap.data
.section .bootstrap.data, "a"
.align 0x1000
.global BootPageTable
BootPageTable:

View File

@ -24,14 +24,14 @@ KERNEL_STACK_SIZE = 0x4000 /* 16KB */
.extern LoadGDT32
.extern BootPageTable
.section .bootstrap.data
.section .bootstrap.data, "a"
MB_HeaderMagic:
.quad 0
MB_HeaderInfo:
.quad 0
.section .bootstrap.text
.section .bootstrap.text, "a"
.global Multiboot2_start
Multiboot2_start:
@ -73,7 +73,7 @@ Multiboot2_start:
hlt
jmp .Hang
.section .bootstrap.bss
.section .bootstrap.bss, "a"
.align 16
KernelStack:
.space KERNEL_STACK_SIZE

View File

@ -21,7 +21,7 @@
.extern Multiboot2_start
.code32
.section .bootstrap.text
.section .bootstrap.text, "a"
.global _start
_start:

View File

@ -0,0 +1,255 @@
/*
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/>.
*/
#include "acpi.hpp"
#include <time.hpp>
#include <debug.h>
#include <smp.hpp>
#include <io.h>
#include "cpu/apic.hpp"
#include "../../kernel.h"
#define ACPI_TIMER 0x0001
#define ACPI_BUSMASTER 0x0010
#define ACPI_GLOBAL 0x0020
#define ACPI_POWER_BUTTON 0x0100
#define ACPI_SLEEP_BUTTON 0x0200
#define ACPI_RTC_ALARM 0x0400
#define ACPI_PCIE_WAKE 0x4000
#define ACPI_WAKE 0x8000
namespace ACPI
{
__always_inline inline bool IsCanonical(uint64_t Address)
{
return ((Address <= 0x00007FFFFFFFFFFF) || ((Address >= 0xFFFF800000000000) && (Address <= 0xFFFFFFFFFFFFFFFF)));
}
#define ACPI_ENABLED 0x0001
#define ACPI_SLEEP 0x2000
#define ACPI_GAS_MMIO 0
#define ACPI_GAS_IO 1
#define ACPI_GAS_PCI 2
void DSDT::OnInterruptReceived(CPU::x32::TrapFrame *Frame)
{
debug("SCI Handle Triggered");
uint16_t Event = 0;
{
uint16_t a = 0, b = 0;
if (acpi->FADT->PM1aEventBlock)
{
a = inw(s_cst(uint16_t, acpi->FADT->PM1aEventBlock));
outw(s_cst(uint16_t, acpi->FADT->PM1aEventBlock), a);
}
if (acpi->FADT->PM1bEventBlock)
{
b = inw(s_cst(uint16_t, acpi->FADT->PM1bEventBlock));
outw(s_cst(uint16_t, acpi->FADT->PM1bEventBlock), b);
}
Event = a | b;
}
debug("SCI Event: %#lx", Event);
if (Event & ACPI_BUSMASTER)
{
fixme("ACPI Busmaster");
}
else if (Event & ACPI_GLOBAL)
{
fixme("ACPI Global");
}
else if (Event & ACPI_POWER_BUTTON)
{
if (TaskManager && !TaskManager->IsPanic())
{
TaskManager->CreateThread(TaskManager->CreateProcess(nullptr,
"Shutdown",
Tasking::TaskExecutionMode::Kernel),
Tasking::IP(KST_Shutdown));
}
else
KernelShutdownThread(false);
}
else if (Event & ACPI_SLEEP_BUTTON)
{
fixme("ACPI Sleep Button");
}
else if (Event & ACPI_RTC_ALARM)
{
fixme("ACPI RTC Alarm");
}
else if (Event & ACPI_PCIE_WAKE)
{
fixme("ACPI PCIe Wake");
}
else if (Event & ACPI_WAKE)
{
fixme("ACPI Wake");
}
else if (Event & ACPI_TIMER)
{
fixme("ACPI Timer");
}
else
{
error("ACPI unknown event %#lx on CPU %d", Event, GetCurrentCPU()->ID);
CPU::Stop();
}
UNUSED(Frame);
}
void DSDT::Shutdown()
{
trace("Shutting down...");
if (SCI_EN == 1)
{
outw(s_cst(uint16_t, acpi->FADT->PM1aControlBlock),
s_cst(uint16_t,
(inw(s_cst(uint16_t,
acpi->FADT->PM1aControlBlock)) &
0xE3FF) |
((SLP_TYPa << 10) | ACPI_SLEEP)));
if (acpi->FADT->PM1bControlBlock)
outw(s_cst(uint16_t, acpi->FADT->PM1bControlBlock),
s_cst(uint16_t,
(inw(
s_cst(uint16_t, acpi->FADT->PM1bControlBlock)) &
0xE3FF) |
((SLP_TYPb << 10) | ACPI_SLEEP)));
outw(s_cst(uint16_t, PM1a_CNT), SLP_TYPa | SLP_EN);
if (PM1b_CNT)
outw(s_cst(uint16_t, PM1b_CNT), SLP_TYPb | SLP_EN);
}
}
void DSDT::Reboot()
{
trace("Rebooting...");
switch (acpi->FADT->ResetReg.AddressSpace)
{
case ACPI_GAS_MMIO:
{
*(uint8_t *)(acpi->FADT->ResetReg.Address) = acpi->FADT->ResetValue;
break;
}
case ACPI_GAS_IO:
{
outb(s_cst(uint16_t, acpi->FADT->ResetReg.Address), acpi->FADT->ResetValue);
break;
}
case ACPI_GAS_PCI:
{
fixme("ACPI_GAS_PCI not supported.");
/*
seg - 0
bus - 0
dev - (FADT->ResetReg.Address >> 32) & 0xFFFF
function - (FADT->ResetReg.Address >> 16) & 0xFFFF
offset - FADT->ResetReg.Address & 0xFFFF
value - FADT->ResetValue
*/
break;
}
default:
{
error("Unknown reset register address space: %d", acpi->FADT->ResetReg.AddressSpace);
break;
}
}
}
DSDT::DSDT(ACPI *acpi) : Interrupts::Handler(acpi->FADT->SCI_Interrupt)
{
this->acpi = acpi;
uint64_t Address = ((IsCanonical(acpi->FADT->X_Dsdt) && acpi->XSDTSupported) ? acpi->FADT->X_Dsdt : acpi->FADT->Dsdt);
uint8_t *S5Address = (uint8_t *)(Address) + 36;
ACPI::ACPI::ACPIHeader *Header = (ACPI::ACPI::ACPIHeader *)Address;
size_t Length = Header->Length;
while (Length-- > 0)
{
if (!memcmp(S5Address, "_S5_", 4))
break;
S5Address++;
}
if (Length <= 0)
{
warn("_S5 not present in ACPI");
return;
}
if ((*(S5Address - 1) == 0x08 || (*(S5Address - 2) == 0x08 && *(S5Address - 1) == '\\')) && *(S5Address + 4) == 0x12)
{
S5Address += 5;
S5Address += ((*S5Address & 0xC0) >> 6) + 2;
if (*S5Address == 0x0A)
S5Address++;
SLP_TYPa = s_cst(uint16_t, *(S5Address) << 10);
S5Address++;
if (*S5Address == 0x0A)
S5Address++;
SLP_TYPb = s_cst(uint16_t, *(S5Address) << 10);
SMI_CMD = acpi->FADT->SMI_CommandPort;
ACPI_ENABLE = acpi->FADT->AcpiEnable;
ACPI_DISABLE = acpi->FADT->AcpiDisable;
PM1a_CNT = acpi->FADT->PM1aControlBlock;
PM1b_CNT = acpi->FADT->PM1bControlBlock;
PM1_CNT_LEN = acpi->FADT->PM1ControlLength;
SLP_EN = 1 << 13;
SCI_EN = 1;
trace("ACPI Shutdown is supported");
ACPIShutdownSupported = true;
uint16_t value = ACPI_POWER_BUTTON | ACPI_SLEEP_BUTTON | ACPI_WAKE;
{
uint16_t a = s_cst(uint16_t, acpi->FADT->PM1aEventBlock + (acpi->FADT->PM1EventLength / 2));
uint16_t b = s_cst(uint16_t, acpi->FADT->PM1bEventBlock + (acpi->FADT->PM1EventLength / 2));
debug("SCI Event: %#lx [a:%#x b:%#x]", value, a, b);
if (acpi->FADT->PM1aEventBlock)
outw(a, value);
if (acpi->FADT->PM1bEventBlock)
outw(b, value);
}
{
uint16_t a = 0, b = 0;
if (acpi->FADT->PM1aEventBlock)
{
a = inw(s_cst(uint16_t, acpi->FADT->PM1aEventBlock));
outw(s_cst(uint16_t, acpi->FADT->PM1aEventBlock), a);
}
if (acpi->FADT->PM1bEventBlock)
{
b = inw(s_cst(uint16_t, acpi->FADT->PM1bEventBlock));
outw(s_cst(uint16_t, acpi->FADT->PM1bEventBlock), b);
}
}
((APIC::APIC *)Interrupts::apic[0])->RedirectIRQ(0, acpi->FADT->SCI_Interrupt, 1);
return;
}
warn("Failed to parse _S5 in ACPI");
SCI_EN = 0;
}
DSDT::~DSDT()
{
}
}

View File

@ -76,7 +76,7 @@ namespace Memory
{
// 0x1000 aligned
uintptr_t Address = (uintptr_t)VirtualAddress;
Address &= 0xFFFFFFFFFFFFF000;
Address &= 0xFFFFF000;
PageMapIndexer Index = PageMapIndexer(Address);
@ -101,7 +101,7 @@ namespace Memory
PageDirectoryEntry *Virtual::GetPDE(void *VirtualAddress, MapType Type)
{
uintptr_t Address = (uintptr_t)VirtualAddress;
Address &= 0xFFFFFFFFFFFFF000;
Address &= 0xFFFFF000;
PageMapIndexer Index = PageMapIndexer(Address);
PageDirectoryEntry *PDE = &this->Table->Entries[Index.PDEIndex];
@ -113,7 +113,7 @@ namespace Memory
PageTableEntry *Virtual::GetPTE(void *VirtualAddress, MapType Type)
{
uintptr_t Address = (uintptr_t)VirtualAddress;
Address &= 0xFFFFFFFFFFFFF000;
Address &= 0xFFFFF000;
PageMapIndexer Index = PageMapIndexer(Address);
PageDirectoryEntry *PDE = &this->Table->Entries[Index.PDEIndex];

View 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/>.
*/
#include "acpi.hpp"
#include <memory.hpp>
#include <debug.h>
#include "../../kernel.h"
namespace ACPI
{
MADT::MADT(ACPI::MADTHeader *madt)
{
trace("Initializing MADT");
CPUCores = 0;
LAPICAddress = (LAPIC *)(uintptr_t)madt->LocalControllerAddress;
for (uint8_t *ptr = (uint8_t *)(madt->Entries);
(uintptr_t)(ptr) < (uintptr_t)(madt) + madt->Header.Length;
ptr += *(ptr + 1))
{
switch (*(ptr))
{
case 0:
{
if (ptr[4] & 1)
{
lapic.push_back((LocalAPIC *)ptr);
KPrint("Local APIC \e8888FF%d\eCCCCCC (APIC \e8888FF%d\eCCCCCC) found.", lapic.back()->ACPIProcessorId, lapic.back()->APICId);
CPUCores++;
}
break;
}
case 1:
{
ioapic.push_back((MADTIOApic *)ptr);
KPrint("I/O APIC \e8888FF%d\eCCCCCC (Address \e8888FF%#lx\eCCCCCC) found.", ioapic.back()->APICID, ioapic.back()->Address);
Memory::Virtual(KernelPageTable).Map((void *)(uintptr_t)ioapic.back()->Address, (void *)(uintptr_t)ioapic.back()->Address, Memory::PTFlag::RW | Memory::PTFlag::PCD); // Make sure that the address is mapped.
break;
}
case 2:
{
iso.push_back((MADTIso *)ptr);
KPrint("ISO (IRQ:\e8888FF%#lx\eCCCCCC, BUS:\e8888FF%#lx\eCCCCCC, GSI:\e8888FF%#lx\eCCCCCC, %s\eCCCCCC/%s\eCCCCCC) found.",
iso.back()->IRQSource, iso.back()->BuSSource, iso.back()->GSI,
iso.back()->Flags & 0x00000004 ? "\e1770FFActive High" : "\e475EFFActive Low",
iso.back()->Flags & 0x00000100 ? "\e00962DEdge Triggered" : "\e008F58Level Triggered");
break;
}
case 4:
{
nmi.push_back((MADTNmi *)ptr);
KPrint("NMI \e8888FF%#lx\eCCCCCC (lint:\e8888FF%#lx\eCCCCCC) found.", nmi.back()->processor, nmi.back()->lint);
break;
}
case 5:
{
LAPICAddress = (LAPIC *)ptr;
KPrint("APIC found at \e8888FF%#lx\eCCCCCC", LAPICAddress);
break;
}
default:
{
KPrint("Unknown MADT entry \e8888FF%#lx\eCCCCCC", *(ptr));
break;
}
}
Memory::Virtual(KernelPageTable).Map((void *)LAPICAddress, (void *)LAPICAddress, Memory::PTFlag::RW | Memory::PTFlag::PCD); // I should map more than one page?
}
CPUCores--; // We start at 0 (BSP) and end at 11 (APs), so we have 12 cores.
KPrint("Total CPU cores: %d", CPUCores + 1);
}
MADT::~MADT()
{
}
}

View File

@ -0,0 +1,411 @@
/*
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/>.
*/
#include "apic.hpp"
#include <memory.hpp>
#include <uart.hpp>
#include <lock.hpp>
#include <cpu.hpp>
#include <smp.hpp>
#include <io.h>
#include "../../../kernel.h"
#include "../acpi.hpp"
NewLock(APICLock);
using namespace CPU::x32;
using namespace CPU::x86;
/*
In constructor APIC::APIC::APIC(int):
warning: left shift count >= width of type
| APICBaseAddress = BaseStruct.ApicBaseLo << 12u | BaseStruct.ApicBaseHi << 32u;
| ~~~~~~~~~~~~~~~~~~~~~~^~~~~~
*/
#pragma GCC diagnostic ignored "-Wshift-count-overflow"
namespace APIC
{
// headache
// https://www.amd.com/system/files/TechDocs/24593.pdf
// https://www.naic.edu/~phil/software/intel/318148.pdf
uint32_t APIC::Read(uint32_t Register)
{
#ifdef DEBUG
if (Register != APIC_ICRLO &&
Register != APIC_ICRHI &&
Register != APIC_ID)
debug("APIC::Read(%#lx) [x2=%d]", Register, x2APICSupported ? 1 : 0);
#endif
if (x2APICSupported)
{
if (Register != APIC_ICRHI)
return s_cst(uint32_t, rdmsr((Register >> 4) + 0x800));
else
return s_cst(uint32_t, rdmsr(0x30 + 0x800));
}
else
{
CPU::MemBar::Barrier();
uint32_t ret = *((volatile uint32_t *)((uintptr_t)APICBaseAddress + Register));
CPU::MemBar::Barrier();
return ret;
}
}
void APIC::Write(uint32_t Register, uint32_t Value)
{
#ifdef DEBUG
if (Register != APIC_EOI &&
Register != APIC_TDCR &&
Register != APIC_TIMER &&
Register != APIC_TICR &&
Register != APIC_ICRLO &&
Register != APIC_ICRHI)
debug("APIC::Write(%#lx, %#lx) [x2=%d]", Register, Value, x2APICSupported ? 1 : 0);
#endif
if (x2APICSupported)
{
if (Register != APIC_ICRHI)
wrmsr((Register >> 4) + 0x800, Value);
else
wrmsr(MSR_X2APIC_ICR, Value);
}
else
{
CPU::MemBar::Barrier();
*((volatile uint32_t *)(((uintptr_t)APICBaseAddress) + Register)) = Value;
CPU::MemBar::Barrier();
}
}
void APIC::IOWrite(uint64_t Base, uint32_t Register, uint32_t Value)
{
debug("APIC::IOWrite(%#lx, %#lx, %#lx)", Base, Register, Value);
CPU::MemBar::Barrier();
*((volatile uint32_t *)(((uintptr_t)Base))) = Register;
CPU::MemBar::Barrier();
*((volatile uint32_t *)(((uintptr_t)Base + 16))) = Value;
CPU::MemBar::Barrier();
}
uint32_t APIC::IORead(uint64_t Base, uint32_t Register)
{
debug("APIC::IORead(%#lx, %#lx)", Base, Register);
CPU::MemBar::Barrier();
*((volatile uint32_t *)(((uintptr_t)Base))) = Register;
CPU::MemBar::Barrier();
uint32_t ret = *((volatile uint32_t *)(((uintptr_t)Base + 16)));
CPU::MemBar::Barrier();
return ret;
}
void APIC::EOI() { this->Write(APIC_EOI, 0); }
void APIC::WaitForIPI()
{
InterruptCommandRegisterLow icr = {.raw = 0};
do
{
icr.raw = this->Read(APIC_ICRLO);
CPU::Pause();
} while (icr.DeliveryStatus != Idle);
}
void APIC::IPI(uint8_t CPU, InterruptCommandRegisterLow icr)
{
SmartCriticalSection(APICLock);
if (x2APICSupported)
{
wrmsr(MSR_X2APIC_ICR, s_cst(uint32_t, icr.raw));
this->WaitForIPI();
}
else
{
this->Write(APIC_ICRHI, (CPU << 24));
this->Write(APIC_ICRLO, s_cst(uint32_t, icr.raw));
this->WaitForIPI();
}
}
void APIC::SendInitIPI(uint8_t CPU)
{
SmartCriticalSection(APICLock);
if (x2APICSupported)
{
InterruptCommandRegisterLow icr = {.raw = 0};
icr.DeliveryMode = INIT;
icr.Level = Assert;
wrmsr(MSR_X2APIC_ICR, s_cst(uint32_t, icr.raw));
this->WaitForIPI();
}
else
{
InterruptCommandRegisterLow icr = {.raw = 0};
icr.DeliveryMode = INIT;
icr.Level = Assert;
this->Write(APIC_ICRHI, (CPU << 24));
this->Write(APIC_ICRLO, s_cst(uint32_t, icr.raw));
this->WaitForIPI();
}
}
void APIC::SendStartupIPI(uint8_t CPU, uint64_t StartupAddress)
{
SmartCriticalSection(APICLock);
if (x2APICSupported)
{
InterruptCommandRegisterLow icr = {.raw = 0};
icr.Vector = s_cst(uint8_t, StartupAddress >> 12);
icr.DeliveryMode = Startup;
icr.Level = Assert;
wrmsr(MSR_X2APIC_ICR, s_cst(uint32_t, icr.raw));
this->WaitForIPI();
}
else
{
InterruptCommandRegisterLow icr = {.raw = 0};
icr.Vector = s_cst(uint8_t, StartupAddress >> 12);
icr.DeliveryMode = Startup;
icr.Level = Assert;
this->Write(APIC_ICRHI, (CPU << 24));
this->Write(APIC_ICRLO, s_cst(uint32_t, icr.raw));
this->WaitForIPI();
}
}
uint32_t APIC::IOGetMaxRedirect(uint32_t APICID)
{
uint32_t TableAddress = (this->IORead((((ACPI::MADT *)PowerManager->GetMADT())->ioapic[APICID]->Address), GetIOAPICVersion));
return ((IOAPICVersion *)&TableAddress)->MaximumRedirectionEntry;
}
void APIC::RawRedirectIRQ(uint16_t Vector, uint32_t GSI, uint16_t Flags, int CPU, int Status)
{
uint64_t Value = Vector;
int64_t IOAPICTarget = -1;
for (uint64_t i = 0; ((ACPI::MADT *)PowerManager->GetMADT())->ioapic[std::size_t(i)] != 0; i++)
if (((ACPI::MADT *)PowerManager->GetMADT())->ioapic[std::size_t(i)]->GSIBase <= GSI)
if (((ACPI::MADT *)PowerManager->GetMADT())->ioapic[std::size_t(i)]->GSIBase + IOGetMaxRedirect(s_cst(uint32_t, i)) > GSI)
{
IOAPICTarget = i;
break;
}
if (IOAPICTarget == -1)
{
error("No ISO table found for I/O APIC");
return;
}
// TODO: IOAPICRedirectEntry Entry = {.raw = 0};
if (Flags & ActiveHighLow)
Value |= (1 << 13);
if (Flags & EdgeLevel)
Value |= (1 << 15);
if (!Status)
Value |= (1 << 16);
Value |= (((uintptr_t)CPU) << 56);
uint32_t IORegister = (GSI - ((ACPI::MADT *)PowerManager->GetMADT())->ioapic[std::size_t(IOAPICTarget)]->GSIBase) * 2 + 16;
this->IOWrite(((ACPI::MADT *)PowerManager->GetMADT())->ioapic[std::size_t(IOAPICTarget)]->Address,
IORegister, (uint32_t)Value);
this->IOWrite(((ACPI::MADT *)PowerManager->GetMADT())->ioapic[std::size_t(IOAPICTarget)]->Address,
IORegister + 1, (uint32_t)(Value >> 32));
}
void APIC::RedirectIRQ(int CPU, uint16_t IRQ, int Status)
{
for (uint64_t i = 0; i < ((ACPI::MADT *)PowerManager->GetMADT())->iso.size(); i++)
if (((ACPI::MADT *)PowerManager->GetMADT())->iso[std::size_t(i)]->IRQSource == IRQ)
{
debug("[ISO %d] Mapping to source IRQ%#d GSI:%#lx on CPU %d",
i, ((ACPI::MADT *)PowerManager->GetMADT())->iso[std::size_t(i)]->IRQSource,
((ACPI::MADT *)PowerManager->GetMADT())->iso[std::size_t(i)]->GSI,
CPU);
this->RawRedirectIRQ(((ACPI::MADT *)PowerManager->GetMADT())->iso[std::size_t(i)]->IRQSource + 0x20,
((ACPI::MADT *)PowerManager->GetMADT())->iso[std::size_t(i)]->GSI,
((ACPI::MADT *)PowerManager->GetMADT())->iso[std::size_t(i)]->Flags,
CPU, Status);
return;
}
debug("Mapping IRQ%d on CPU %d", IRQ, CPU);
this->RawRedirectIRQ(IRQ + 0x20, IRQ, 0, CPU, Status);
}
void APIC::RedirectIRQs(int CPU)
{
SmartCriticalSection(APICLock);
debug("Redirecting IRQs...");
for (uint8_t i = 0; i < 16; i++)
this->RedirectIRQ(CPU, i, 1);
debug("Redirecting IRQs completed.");
}
APIC::APIC(int Core)
{
SmartCriticalSection(APICLock);
APIC_BASE BaseStruct = {.raw = rdmsr(MSR_APIC_BASE)};
uint64_t BaseLow = BaseStruct.ApicBaseLo;
uint64_t BaseHigh = BaseStruct.ApicBaseHi;
this->APICBaseAddress = BaseLow << 12u | BaseHigh << 32u;
trace("APIC Address: %#lx", this->APICBaseAddress);
Memory::Virtual().Map((void *)this->APICBaseAddress, (void *)this->APICBaseAddress, Memory::PTFlag::RW | Memory::PTFlag::PCD);
bool x2APICSupported = false;
if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0)
{
CPU::x86::AMD::CPUID0x00000001 cpuid;
cpuid.Get();
if (cpuid.ECX.x2APIC)
{
// x2APICSupported = cpuid.ECX.x2APIC;
fixme("x2APIC is supported");
}
}
else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0)
{
CPU::x86::Intel::CPUID0x00000001 cpuid;
cpuid.Get();
if (cpuid.ECX.x2APIC)
{
// x2APICSupported = cpuid.ECX.x2APIC;
fixme("x2APIC is supported");
}
}
if (x2APICSupported)
{
this->x2APICSupported = true;
wrmsr(MSR_APIC_BASE, (rdmsr(MSR_APIC_BASE) | (1 << 11)) & ~(1 << 10));
BaseStruct.EN = 1;
wrmsr(MSR_APIC_BASE, BaseStruct.raw);
}
else
{
BaseStruct.EN = 1;
wrmsr(MSR_APIC_BASE, BaseStruct.raw);
}
this->Write(APIC_TPR, 0x0);
// this->Write(APIC_SVR, this->Read(APIC_SVR) | 0x100); // 0x1FF or 0x100 ? on https://wiki.osdev.org/APIC is 0x100
if (!this->x2APICSupported)
{
this->Write(APIC_DFR, 0xF0000000);
this->Write(APIC_LDR, this->Read(APIC_ID));
}
ACPI::MADT *madt = (ACPI::MADT *)PowerManager->GetMADT();
for (size_t i = 0; i < madt->nmi.size(); i++)
{
if (madt->nmi[std::size_t(i)]->processor != 0xFF && Core != madt->nmi[std::size_t(i)]->processor)
return;
uint32_t nmi = 0x402;
if (madt->nmi[std::size_t(i)]->flags & 2)
nmi |= 1 << 13;
if (madt->nmi[std::size_t(i)]->flags & 8)
nmi |= 1 << 15;
if (madt->nmi[std::size_t(i)]->lint == 0)
this->Write(APIC_LINT0, nmi);
else if (madt->nmi[std::size_t(i)]->lint == 1)
this->Write(APIC_LINT1, nmi);
}
// Setup the spurrious interrupt vector
Spurious Spurious = {.raw = this->Read(APIC_SVR)};
Spurious.Vector = IRQ223; // TODO: Should I map the IRQ to something?
Spurious.Software = 1;
this->Write(APIC_SVR, s_cst(uint32_t, Spurious.raw));
static int once = 0;
if (!once++)
{
// Disable PIT
outb(0x43, 0x28);
outb(0x40, 0x0);
// Disable PIC
outb(0x21, 0xFF);
outb(0xA1, 0xFF);
}
}
APIC::~APIC() {}
void Timer::OnInterruptReceived(TrapFrame *Frame) { UNUSED(Frame); }
void Timer::OneShot(uint32_t Vector, uint64_t Miliseconds)
{
SmartCriticalSection(APICLock);
LVTTimer timer = {.raw = 0};
timer.Vector = s_cst(uint8_t, Vector);
timer.TimerMode = 0;
if (strcmp(CPU::Hypervisor(), x86_CPUID_VENDOR_TCG) != 0)
this->lapic->Write(APIC_TDCR, DivideBy128);
else
this->lapic->Write(APIC_TDCR, DivideBy16);
this->lapic->Write(APIC_TICR, s_cst(uint32_t, Ticks * Miliseconds));
this->lapic->Write(APIC_TIMER, s_cst(uint32_t, timer.raw));
}
Timer::Timer(APIC *apic) : Interrupts::Handler(0) /* IRQ0 */
{
SmartCriticalSection(APICLock);
this->lapic = apic;
LVTTimerDivide Divider = DivideBy16;
trace("Initializing APIC timer on CPU %d", GetCurrentCPU()->ID);
this->lapic->Write(APIC_TDCR, Divider);
this->lapic->Write(APIC_TICR, 0xFFFFFFFF);
TimeManager->Sleep(1, Time::Units::Milliseconds);
// Mask the timer
this->lapic->Write(APIC_TIMER, 0x10000 /* LVTTimer.Mask flag */);
Ticks = 0xFFFFFFFF - this->lapic->Read(APIC_TCCR);
// Config for IRQ0 timer
LVTTimer timer = {.raw = 0};
timer.Vector = IRQ0;
timer.Mask = Unmasked;
timer.TimerMode = LVTTimerMode::OneShot;
// Initialize APIC timer
this->lapic->Write(APIC_TDCR, Divider);
this->lapic->Write(APIC_TICR, s_cst(uint32_t, Ticks));
this->lapic->Write(APIC_TIMER, s_cst(uint32_t, timer.raw));
trace("%d APIC Timer %d ticks in.", GetCurrentCPU()->ID, Ticks);
KPrint("APIC Timer: \e8888FF%ld\eCCCCCC ticks.", Ticks);
}
Timer::~Timer()
{
}
}

View File

@ -228,7 +228,14 @@ namespace GlobalDescriptorTable
gdt[Core].Entries->TaskStateSegment.BaseLow = Base & 0xFFFF;
gdt[Core].Entries->TaskStateSegment.BaseMiddle = uint8_t((Base >> 16) & 0xFF);
gdt[Core].Entries->TaskStateSegment.BaseHigh = uint8_t((Base >> 24) & 0xFF);
#pragma diagnostic push
#pragma GCC diagnostic ignored "-Wshift-count-overflow"
gdt[Core].Entries->TaskStateSegment.BaseUpper = s_cst(uint32_t, (Base >> 32) & 0xFFFFFFFF);
#pragma diagnostic pop
gdt[Core].Entries->TaskStateSegment.Access = {.A = 1, .RW = 0, .DC = 0, .E = 1, .S = 0, .DPL = 0, .P = 1};
gdt[Core].Entries->TaskStateSegment.Granularity = (0 << 4) | ((Limit >> 16) & 0xF);

View File

@ -23,7 +23,17 @@
#include <cpu.hpp>
#include <atomic>
#include <smp.hpp>
#include <memory.hpp>
#include <ints.hpp>
#include <assert.h>
#include <cpu.hpp>
#include <atomic>
#include "../../../kernel.h"
#include "../acpi.hpp"
#include "apic.hpp"
enum SMPTrampolineAddress
{
@ -59,8 +69,19 @@ namespace SMP
{
int CPUCores = 0;
void Initialize(void *madt)
void Initialize(void *_madt)
{
ACPI::MADT *madt = (ACPI::MADT *)_madt;
int Cores = madt->CPUCores + 1;
if (Config.Cores > madt->CPUCores + 1)
KPrint("More cores requested than available. Using %d cores", madt->CPUCores + 1);
else if (Config.Cores != 0)
Cores = Config.Cores;
CPUCores = Cores;
fixme("SMP::Initialize() is not implemented!");
}
}

View File

@ -330,7 +330,7 @@ namespace APIC
void SendInitIPI(uint8_t CPU);
void SendStartupIPI(uint8_t CPU, uint64_t StartupAddress);
uint32_t IOGetMaxRedirect(uint32_t APICID);
void RawRedirectIRQ(uint8_t Vector, uint32_t GSI, uint16_t Flags, int CPU, int Status);
void RawRedirectIRQ(uint16_t Vector, uint32_t GSI, uint16_t Flags, int CPU, int Status);
void RedirectIRQ(int CPU, uint16_t IRQ, int Status);
APIC(int Core);
~APIC();

View File

@ -35,74 +35,92 @@
NewLock(DriverDisplayPrintLock);
void DriverDebugPrint(char *String, unsigned long DriverUID) { trace("[%ld] %s", DriverUID, String); }
void DriverDebugPrint(char *String, __UINT64_TYPE__ DriverUID)
{
trace("[%ld] %s", DriverUID, String);
}
void DriverDisplayPrint(char *String)
{
SmartLock(DriverDisplayPrintLock);
for (unsigned long i = 0; i < strlen(String); i++)
for (__UINT64_TYPE__ i = 0; i < strlen(String); i++)
Display->Print(String[i], 0, true);
}
void *RequestPage(unsigned long Size)
void *RequestPage(__UINT64_TYPE__ Size)
{
void *ret = KernelAllocator.RequestPages(Size + 1);
drvdbg("Allocated %ld pages (%#lx-%#lx)", Size, (unsigned long)ret, (unsigned long)ret + FROM_PAGES(Size));
void *ret = KernelAllocator.RequestPages(size_t(Size + 1));
drvdbg("Allocated %ld pages (%#lx-%#lx)",
Size, (__UINT64_TYPE__)ret,
(__UINT64_TYPE__)ret + FROM_PAGES(Size));
return ret;
}
void FreePage(void *Page, unsigned long Size)
void FreePage(void *Page, __UINT64_TYPE__ Size)
{
drvdbg("Freeing %ld pages (%#lx-%#lx)", Size, (unsigned long)Page, (unsigned long)Page + FROM_PAGES(Size));
KernelAllocator.FreePages(Page, Size + 1);
drvdbg("Freeing %ld pages (%#lx-%#lx)",
Size, (__UINT64_TYPE__)Page,
(__UINT64_TYPE__)Page + FROM_PAGES(Size));
KernelAllocator.FreePages(Page, size_t(Size + 1));
}
void MapMemory(void *VirtualAddress, void *PhysicalAddress, unsigned long Flags)
void MapMemory(void *VirtualAddress, void *PhysicalAddress, __UINT64_TYPE__ Flags)
{
SmartLock(DriverDisplayPrintLock);
drvdbg("Mapping %#lx to %#lx with flags %#lx...", (unsigned long)VirtualAddress, (unsigned long)PhysicalAddress, Flags);
drvdbg("Mapping %#lx to %#lx with flags %#lx...",
(__UINT64_TYPE__)VirtualAddress,
(__UINT64_TYPE__)PhysicalAddress, Flags);
Memory::Virtual(KernelPageTable).Map(VirtualAddress, PhysicalAddress, Flags);
}
void UnmapMemory(void *VirtualAddress)
{
SmartLock(DriverDisplayPrintLock);
drvdbg("Unmapping %#lx...", (unsigned long)VirtualAddress);
drvdbg("Unmapping %#lx...",
(__UINT64_TYPE__)VirtualAddress);
Memory::Virtual(KernelPageTable).Unmap(VirtualAddress);
}
void *Drivermemcpy(void *Destination, void *Source, unsigned long Size)
void *Drivermemcpy(void *Destination, void *Source, __UINT64_TYPE__ Size)
{
SmartLock(DriverDisplayPrintLock);
drvdbg("Copying %ld bytes from %#lx-%#lx to %#lx-%#lx...", Size,
(unsigned long)Source, (unsigned long)Source + Size,
(unsigned long)Destination, (unsigned long)Destination + Size);
return memcpy(Destination, Source, Size);
(__UINT64_TYPE__)Source, (__UINT64_TYPE__)Source + Size,
(__UINT64_TYPE__)Destination, (__UINT64_TYPE__)Destination + Size);
return memcpy(Destination, Source, size_t(Size));
}
void *Drivermemset(void *Destination, int Value, unsigned long Size)
void *Drivermemset(void *Destination, int Value, __UINT64_TYPE__ Size)
{
SmartLock(DriverDisplayPrintLock);
drvdbg("Setting value %#x at %#lx-%#lx (%ld bytes)...", Value,
(unsigned long)Destination, (unsigned long)Destination + Size,
Size);
return memset(Destination, Value, Size);
(__UINT64_TYPE__)Destination,
(__UINT64_TYPE__)Destination + Size, Size);
return memset(Destination, Value, size_t(Size));
}
void DriverNetSend(unsigned int DriverID, unsigned char *Data, unsigned short Size)
void DriverNetSend(__UINT32_TYPE__ DriverID,
__UINT8_TYPE__ *Data,
__UINT16_TYPE__ Size)
{
// This is useless I guess...
if (NIManager)
NIManager->DrvSend(DriverID, Data, Size);
}
void DriverNetReceive(unsigned int DriverID, unsigned char *Data, unsigned short Size)
void DriverNetReceive(__UINT32_TYPE__ DriverID,
__UINT8_TYPE__ *Data,
__UINT16_TYPE__ Size)
{
if (NIManager)
NIManager->DrvReceive(DriverID, Data, Size);
}
void DriverAHCIDiskRead(unsigned int DriverID, unsigned long Sector, unsigned char *Data, unsigned int SectorCount, unsigned char Port)
void DriverAHCIDiskRead(__UINT32_TYPE__ DriverID,
__UINT64_TYPE__ Sector,
__UINT8_TYPE__ *Data,
__UINT32_TYPE__ SectorCount,
__UINT8_TYPE__ Port)
{
DumpData("DriverDiskRead", Data, SectorCount * 512);
UNUSED(DriverID);
@ -110,41 +128,50 @@ void DriverAHCIDiskRead(unsigned int DriverID, unsigned long Sector, unsigned ch
UNUSED(Port);
}
void DriverAHCIDiskWrite(unsigned int DriverID, unsigned long Sector, unsigned char *Data, unsigned int SectorCount, unsigned char Port)
void DriverAHCIDiskWrite(__UINT32_TYPE__ DriverID,
__UINT64_TYPE__ Sector,
__UINT8_TYPE__ *Data,
__UINT32_TYPE__ SectorCount,
__UINT8_TYPE__ Port)
{
DumpData("DriverDiskWrite", Data, SectorCount * 512);
DumpData("DriverDiskWrite",
Data, SectorCount * 512);
UNUSED(DriverID);
UNUSED(Sector);
UNUSED(Port);
}
char *DriverPCIGetDeviceName(unsigned int VendorID, unsigned int DeviceID)
char *DriverPCIGetDeviceName(__UINT32_TYPE__ VendorID,
__UINT32_TYPE__ DeviceID)
{
UNUSED(VendorID);
UNUSED(DeviceID);
return (char *)"Unknown";
}
unsigned int DriverGetWidth()
__UINT32_TYPE__ DriverGetWidth()
{
/* TODO: We won't rely only on display buffers, what about graphics drivers and changing resolutions? */
/* TODO: We won't rely only on display buffers,
what about graphics drivers and changing resolutions? */
return Display->GetBuffer(0)->Width;
}
unsigned int DriverGetHeight()
__UINT32_TYPE__ DriverGetHeight()
{
/* TODO: We won't rely only on display buffers, what about graphics drivers and changing resolutions? */
/* TODO: We won't rely only on display buffers,
what about graphics drivers and changing resolutions? */
return Display->GetBuffer(0)->Height;
}
void DriverSleep(unsigned long Milliseconds)
void DriverSleep(__UINT64_TYPE__ Milliseconds)
{
SmartLock(DriverDisplayPrintLock);
drvdbg("Sleeping for %ld milliseconds...", Milliseconds);
if (TaskManager)
TaskManager->Sleep(Milliseconds);
else
TimeManager->Sleep(Milliseconds, Time::Units::Milliseconds);
TimeManager->Sleep(size_t(Milliseconds),
Time::Units::Milliseconds);
}
int Driversprintf(char *Buffer, const char *Format, ...)

View File

@ -30,6 +30,8 @@
#elif defined(a32)
#include "../Architecture/i386/cpu/gdt.hpp"
#include "../Architecture/i386/cpu/idt.hpp"
#include "../Architecture/i386/acpi.hpp"
#include "../Architecture/i386/cpu/apic.hpp"
#elif defined(aa64)
#endif
@ -47,11 +49,9 @@ namespace Interrupts
};
std::vector<Event> RegisteredEvents;
#if defined(a64)
#if defined(a86)
/* APIC::APIC */ void *apic[MAX_CPU];
/* APIC::Timer */ void *apicTimer[MAX_CPU];
#elif defined(a32)
/* APIC::APIC */ void *apic[MAX_CPU];
#elif defined(aa64)
#endif
void *InterruptFrames[INT_FRAMES_MAX];
@ -89,10 +89,12 @@ namespace Interrupts
CoreData->Stack = (uintptr_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE + 1)) + STACK_SIZE;
if (CoreData->Checksum != CPU_DATA_CHECKSUM)
{
KPrint("CPU %d checksum mismatch! %x != %x", Core, CoreData->Checksum, CPU_DATA_CHECKSUM);
KPrint("CPU %d checksum mismatch! %x != %x",
Core, CoreData->Checksum, CPU_DATA_CHECKSUM);
CPU::Stop();
}
debug("Stack for core %d is %#lx (Address: %#lx)", Core, CoreData->Stack, CoreData->Stack - STACK_SIZE);
debug("Stack for core %d is %#lx (Address: %#lx)",
Core, CoreData->Stack, CoreData->Stack - STACK_SIZE);
#elif defined(aa64)
warn("aarch64 is not supported yet");
#endif
@ -100,7 +102,7 @@ namespace Interrupts
void Enable(int Core)
{
#if defined(a64)
#if defined(a86)
if (((ACPI::MADT *)PowerManager->GetMADT())->LAPICAddress != nullptr)
{
// TODO: This function is called by SMP too. Do not initialize timers that doesn't support multiple cores.
@ -113,8 +115,6 @@ namespace Interrupts
error("LAPIC not found");
// TODO: PIC
}
#elif defined(a32)
warn("i386 is not supported yet");
#elif defined(aa64)
warn("aarch64 is not supported yet");
#endif
@ -123,15 +123,13 @@ namespace Interrupts
void InitializeTimer(int Core)
{
// TODO: This function is called by SMP too. Do not initialize timers that doesn't support multiple cores.
#if defined(a64)
#if defined(a86)
if (apic[Core] != nullptr)
apicTimer[Core] = new APIC::Timer((APIC::APIC *)apic[Core]);
else
{
fixme("apic not found");
}
#elif defined(a32)
warn("i386 is not supported yet");
#elif defined(aa64)
warn("aarch64 is not supported yet");
#endif

View File

@ -21,6 +21,7 @@
#if defined(a64)
#include "../Architecture/amd64/acpi.hpp"
#elif defined(a32)
#include "../Architecture/i386/acpi.hpp"
#elif defined(aa64)
#endif
@ -883,10 +884,10 @@ namespace PCI
}
}
void PCI::EnumerateFunction(uintptr_t DeviceAddress, uintptr_t Function)
void PCI::EnumerateFunction(uint64_t DeviceAddress, uintptr_t Function)
{
uintptr_t Offset = Function << 12;
uintptr_t FunctionAddress = DeviceAddress + Offset;
uint64_t FunctionAddress = DeviceAddress + Offset;
Memory::Virtual(KernelPageTable).Map((void *)FunctionAddress, (void *)FunctionAddress, Memory::PTFlag::RW);
PCIDeviceHeader *PCIDeviceHdr = (PCIDeviceHeader *)FunctionAddress;
if (PCIDeviceHdr->DeviceID == 0)
@ -899,10 +900,10 @@ namespace PCI
#endif
}
void PCI::EnumerateDevice(uintptr_t BusAddress, uintptr_t Device)
void PCI::EnumerateDevice(uint64_t BusAddress, uintptr_t Device)
{
uintptr_t Offset = Device << 15;
uintptr_t DeviceAddress = BusAddress + Offset;
uint64_t DeviceAddress = BusAddress + Offset;
Memory::Virtual(KernelPageTable).Map((void *)DeviceAddress, (void *)DeviceAddress, Memory::PTFlag::RW);
PCIDeviceHeader *PCIDeviceHdr = (PCIDeviceHeader *)DeviceAddress;
if (PCIDeviceHdr->DeviceID == 0)
@ -913,10 +914,10 @@ namespace PCI
EnumerateFunction(DeviceAddress, Function);
}
void PCI::EnumerateBus(uintptr_t BaseAddress, uintptr_t Bus)
void PCI::EnumerateBus(uint64_t BaseAddress, uintptr_t Bus)
{
uintptr_t Offset = Bus << 20;
uintptr_t BusAddress = BaseAddress + Offset;
uint64_t BusAddress = BaseAddress + Offset;
Memory::Virtual(KernelPageTable).Map((void *)BusAddress, (void *)BusAddress, Memory::PTFlag::RW);
PCIDeviceHeader *PCIDeviceHdr = (PCIDeviceHeader *)BusAddress;
if (Bus != 0) // TODO: VirtualBox workaround (UNTESTED ON REAL HARDWARE!)
@ -955,20 +956,18 @@ namespace PCI
PCI::PCI()
{
#if defined(a64)
#if defined(a86)
int Entries = s_cst(int, ((((ACPI::ACPI *)PowerManager->GetACPI())->MCFG->Header.Length) - sizeof(ACPI::ACPI::MCFGHeader)) / sizeof(DeviceConfig));
Memory::Virtual vmm = Memory::Virtual(KernelPageTable);
for (int t = 0; t < Entries; t++)
{
DeviceConfig *NewDeviceConfig = (DeviceConfig *)((uintptr_t)((ACPI::ACPI *)PowerManager->GetACPI())->MCFG + sizeof(ACPI::ACPI::MCFGHeader) + (sizeof(DeviceConfig) * t));
vmm.Map((void *)NewDeviceConfig->BaseAddress, (void *)NewDeviceConfig->BaseAddress, Memory::PTFlag::RW);
debug("PCI Entry %d Address:%#llx BUS:%#llx-%#llx", t, NewDeviceConfig->BaseAddress,
debug("PCI Entry %d Address:%p BUS:%#x-%#x", t, NewDeviceConfig->BaseAddress,
NewDeviceConfig->StartBus, NewDeviceConfig->EndBus);
for (uintptr_t Bus = NewDeviceConfig->StartBus; Bus < NewDeviceConfig->EndBus; Bus++)
EnumerateBus(NewDeviceConfig->BaseAddress, Bus);
}
#elif defined(a32)
error("PCI not implemented on i386");
#elif defined(aa64)
error("PCI not implemented on aarch64");
#endif

View File

@ -19,13 +19,16 @@
#include <memory.hpp>
#include <debug.h>
#include <io.h>
#include "../kernel.h"
#if defined(a64)
#include <io.h>
#include "../Architecture/amd64/acpi.hpp"
#elif defined(a32)
#include "../Architecture/i386/acpi.hpp"
#elif defined(aa64)
#endif
namespace Power
{
@ -86,45 +89,3 @@ namespace Power
trace("Power manager initialized");
}
}
#elif defined(a32)
namespace Power
{
void Power::Reboot()
{
warn("Reboot not implemented for i386");
}
void Power::Shutdown()
{
warn("Shutdown not implemented for i386");
}
Power::Power()
{
error("Power not implemented for i386");
}
}
#elif defined(aa64)
namespace Power
{
void Power::Reboot()
{
warn("Reboot not implemented for aarch64");
}
void Power::Shutdown()
{
warn("Shutdown not implemented for aarch64");
}
Power::Power()
{
error("Power not implemented for aarch64");
}
}
#endif

View File

@ -53,10 +53,6 @@ namespace SymbolResolver
__unused uint64_t Shndx,
uintptr_t Sections)
{
#ifdef a32
fixme("Function not working on 32-bit");
return;
#endif
char *sections = reinterpret_cast<char *>(Sections);
Elf_Sym *Symbols = nullptr;

158
DAPI.hpp
View File

@ -84,32 +84,32 @@ struct KernelAPI
struct KAPIInfo
{
unsigned long Offset;
unsigned int DriverUID;
__UINT64_TYPE__ Offset;
__UINT32_TYPE__ DriverUID;
char KernelDebug;
} Info;
struct KAPIMemory
{
unsigned long PageSize;
void *(*RequestPage)(unsigned long Size);
void (*FreePage)(void *Page, unsigned long Size);
void (*Map)(void *VirtualAddress, void *PhysicalAddress, unsigned long Flags);
__UINT64_TYPE__ PageSize;
void *(*RequestPage)(__UINT64_TYPE__ Size);
void (*FreePage)(void *Page, __UINT64_TYPE__ Size);
void (*Map)(void *VirtualAddress, void *PhysicalAddress, __UINT64_TYPE__ Flags);
void (*Unmap)(void *VirtualAddress);
} Memory;
struct KAPIPCI
{
char *(*GetDeviceName)(unsigned int VendorID, unsigned int DeviceID);
char *(*GetDeviceName)(__UINT32_TYPE__ VendorID, __UINT32_TYPE__ DeviceID);
} PCI;
struct KAPIUtilities
{
void (*DebugPrint)(char *String, unsigned long DriverUID);
void (*DebugPrint)(char *String, __UINT64_TYPE__ DriverUID);
void (*DisplayPrint)(char *Value);
void *(*memcpy)(void *Destination, void *Source, unsigned long Size);
void *(*memset)(void *Destination, int Value, unsigned long Size);
void (*Sleep)(unsigned long Milliseconds);
void *(*memcpy)(void *Destination, void *Source, __UINT64_TYPE__ Size);
void *(*memset)(void *Destination, int Value, __UINT64_TYPE__ Size);
void (*Sleep)(__UINT64_TYPE__ Milliseconds);
int (*sprintf)(char *Buffer, const char *Format, ...);
} Util;
@ -118,8 +118,8 @@ struct KernelAPI
/** Connects to the network manager */
struct
{
void (*SendPacket)(unsigned int DriverID, unsigned char *Data, unsigned short Size);
void (*ReceivePacket)(unsigned int DriverID, unsigned char *Data, unsigned short Size);
void (*SendPacket)(__UINT32_TYPE__ DriverID, __UINT8_TYPE__ *Data, __UINT16_TYPE__ Size);
void (*ReceivePacket)(__UINT32_TYPE__ DriverID, __UINT8_TYPE__ *Data, __UINT16_TYPE__ Size);
} Network;
/** Connects to the disk manager */
@ -127,16 +127,16 @@ struct KernelAPI
{
struct
{
void (*ReadSector)(unsigned int DriverID, unsigned long Sector, unsigned char *Data, unsigned int SectorCount, unsigned char Port);
void (*WriteSector)(unsigned int DriverID, unsigned long Sector, unsigned char *Data, unsigned int SectorCount, unsigned char Port);
void (*ReadSector)(__UINT32_TYPE__ DriverID, __UINT64_TYPE__ Sector, __UINT8_TYPE__ *Data, __UINT32_TYPE__ SectorCount, __UINT8_TYPE__ Port);
void (*WriteSector)(__UINT32_TYPE__ DriverID, __UINT64_TYPE__ Sector, __UINT8_TYPE__ *Data, __UINT32_TYPE__ SectorCount, __UINT8_TYPE__ Port);
} AHCI;
} Disk;
} Command;
struct KAPIDisplay
{
unsigned int (*GetWidth)(void);
unsigned int (*GetHeight)(void);
__UINT32_TYPE__ (*GetWidth)(void);
__UINT32_TYPE__ (*GetHeight)(void);
/* TODO: Add more */
} Display;
} __attribute__((packed));
@ -230,21 +230,21 @@ union KernelCallback
{
CallbackReason Reason;
void *RawPtr;
unsigned long RawData;
__UINT64_TYPE__ RawData;
/** When the kernel wants to send a packet. */
struct
{
struct
{
unsigned char *Data;
unsigned long Length;
__UINT8_TYPE__ *Data;
__UINT64_TYPE__ Length;
} Send;
struct
{
char Name[128];
unsigned long MAC;
__UINT64_TYPE__ MAC;
} Fetch;
} NetworkCallback;
@ -253,16 +253,16 @@ union KernelCallback
{
struct
{
unsigned long Sector;
unsigned long SectorCount;
unsigned char Port;
unsigned char *Buffer;
__UINT64_TYPE__ Sector;
__UINT64_TYPE__ SectorCount;
__UINT8_TYPE__ Port;
__UINT8_TYPE__ *Buffer;
bool Write;
} RW;
struct
{
unsigned char Ports;
__UINT8_TYPE__ Ports;
int BytesPerSector;
} Fetch;
} DiskCallback;
@ -272,9 +272,9 @@ union KernelCallback
{
struct
{
unsigned long X;
unsigned long Y;
unsigned long Z;
__UINT64_TYPE__ X;
__UINT64_TYPE__ Y;
__UINT64_TYPE__ Z;
struct
{
bool Left;
@ -290,7 +290,7 @@ union KernelCallback
*
* @note This is a scancode, not a character.
*/
unsigned char Key;
__UINT8_TYPE__ Key;
} Keyboard;
} InputCallback;
@ -308,7 +308,7 @@ union KernelCallback
*
* 0 - 100
*/
unsigned char Volume;
__UINT8_TYPE__ Volume;
/**
* Adjust the encoding.
@ -349,7 +349,7 @@ union KernelCallback
*
* ... - More
*/
unsigned short Encoding;
__UINT16_TYPE__ Encoding;
/**
* Adjust the sample rate.
@ -364,7 +364,7 @@ union KernelCallback
* 7 - 88200 Hz
* 8 - 96000 Hz
*/
unsigned char SampleRate;
__UINT8_TYPE__ SampleRate;
/**
* Adjust the channels.
@ -372,30 +372,30 @@ union KernelCallback
* 0 - Mono
* 1 - Stereo
*/
unsigned char Channels;
__UINT8_TYPE__ Channels;
} Adjust;
struct
{
unsigned char *Data;
unsigned long Length;
__UINT8_TYPE__ *Data;
__UINT64_TYPE__ Length;
} Send;
struct
{
unsigned char Volume;
unsigned short Encoding;
unsigned char SampleRate;
unsigned char Channels;
__UINT8_TYPE__ Volume;
__UINT16_TYPE__ Encoding;
__UINT8_TYPE__ SampleRate;
__UINT8_TYPE__ Channels;
} Fetch;
} AudioCallback;
struct
{
unsigned char Vector;
__UINT8_TYPE__ Vector;
} InterruptInfo;
};
unsigned long raw;
__UINT64_TYPE__ raw;
} __attribute__((packed));
union CPURegisters
@ -403,51 +403,51 @@ union CPURegisters
struct
{
#if defined(__x86_64__) || defined(__amd64__)
unsigned long r15;
unsigned long r14;
unsigned long r13;
unsigned long r12;
unsigned long r11;
unsigned long r10;
unsigned long r9;
unsigned long r8;
__UINT64_TYPE__ r15;
__UINT64_TYPE__ r14;
__UINT64_TYPE__ r13;
__UINT64_TYPE__ r12;
__UINT64_TYPE__ r11;
__UINT64_TYPE__ r10;
__UINT64_TYPE__ r9;
__UINT64_TYPE__ r8;
unsigned long rbp;
unsigned long rdi;
unsigned long rsi;
unsigned long rdx;
unsigned long rcx;
unsigned long rbx;
unsigned long rax;
__UINT64_TYPE__ rbp;
__UINT64_TYPE__ rdi;
__UINT64_TYPE__ rsi;
__UINT64_TYPE__ rdx;
__UINT64_TYPE__ rcx;
__UINT64_TYPE__ rbx;
__UINT64_TYPE__ rax;
unsigned long InterruptNumber;
unsigned long ErrorCode;
unsigned long rip;
unsigned long cs;
unsigned long rflags;
unsigned long rsp;
unsigned long ss;
__UINT64_TYPE__ InterruptNumber;
__UINT64_TYPE__ ErrorCode;
__UINT64_TYPE__ rip;
__UINT64_TYPE__ cs;
__UINT64_TYPE__ rflags;
__UINT64_TYPE__ rsp;
__UINT64_TYPE__ ss;
#elif defined(__i386__)
unsigned int ebp;
unsigned int edi;
unsigned int esi;
unsigned int edx;
unsigned int ecx;
unsigned int ebx;
unsigned int eax;
__UINT32_TYPE__ ebp;
__UINT32_TYPE__ edi;
__UINT32_TYPE__ esi;
__UINT32_TYPE__ edx;
__UINT32_TYPE__ ecx;
__UINT32_TYPE__ ebx;
__UINT32_TYPE__ eax;
unsigned int InterruptNumber;
unsigned int ErrorCode;
unsigned int eip;
unsigned int cs;
unsigned int eflags;
unsigned int esp;
unsigned int ss;
__UINT32_TYPE__ InterruptNumber;
__UINT32_TYPE__ ErrorCode;
__UINT32_TYPE__ eip;
__UINT32_TYPE__ cs;
__UINT32_TYPE__ eflags;
__UINT32_TYPE__ esp;
__UINT32_TYPE__ ss;
#else
#warning "Unsupported architecture"
#endif
};
unsigned long raw;
__UINT64_TYPE__ raw;
} __attribute__((packed));
#endif // !__FENNIX_DRIVER_API_H__

View File

@ -47,6 +47,7 @@ namespace Execute
uint64_t EntryPoint,
uint64_t BaseAddress)
{
#if defined(a64)
char *aux_platform = (char *)mm->RequestPages(1, true); /* TODO: 4KiB is too much for this */
strcpy(aux_platform, "x86_64");
@ -82,6 +83,7 @@ namespace Execute
// AT_HWCAP 16
// AT_MINSIGSTKSZ 51
// AT_SYSINFO_EHDR 33
#endif
}
void ELFObject::LoadExec_x86_32(int fd, PCB *TargetProcess)
@ -93,6 +95,7 @@ namespace Execute
void ELFObject::LoadExec_x86_64(int fd, PCB *TargetProcess)
{
#if defined(a64)
std::string InterpreterPath;
std::vector<Elf64_Phdr> PhdrINTERP = ELFGetSymbolType_x86_64(fd, PT_INTERP);
foreach (auto Interp in PhdrINTERP)
@ -121,19 +124,7 @@ namespace Execute
if (LoadInterpreter(ifd, TargetProcess))
{
/* ba deci de aici trb sa fac
sa se incarce interperter-ul
argv[1] ar trb sa fie locatia pt intrep */
// modific argv-ul
// TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME
// TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME
// TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME
// TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME
// TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME
// TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME
// TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME
/* FIXME: specify argv[1] as the location for the interpreter */
debug("Interpreter loaded successfully");
fclose(ifd);
@ -231,6 +222,7 @@ namespace Execute
this->ip = EntryPoint;
this->IsElfValid = true;
#endif
}
void ELFObject::LoadDyn_x86_32(int fd, PCB *TargetProcess)
@ -242,6 +234,7 @@ namespace Execute
void ELFObject::LoadDyn_x86_64(int fd, PCB *TargetProcess)
{
#if defined(a64)
std::string InterpreterPath;
std::vector<Elf64_Phdr> PhdrINTERP = ELFGetSymbolType_x86_64(fd, PT_INTERP);
foreach (auto Interp in PhdrINTERP)
@ -270,18 +263,7 @@ namespace Execute
if (LoadInterpreter(ifd, TargetProcess))
{
/* ba deci de aici trb sa fac
sa se incarce interperter-ul
argv[1] ar trb sa fie locatia pt intrep */
// modific argv-ul
// TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME
// TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME
// TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME
// TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME
// TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME
// TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME
// TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME TODO FIXME
/* FIXME: specify argv[1] as the location for the interpreter */
debug("Interpreter loaded successfully");
fclose(ifd);
@ -619,6 +601,7 @@ namespace Execute
this->ip = EntryPoint;
this->IsElfValid = true;
#endif
}
bool ELFObject::LoadInterpreter(int fd, PCB *TargetProcess)

View File

@ -95,6 +95,7 @@ namespace Execute
Elf64_Sym ELFLookupSymbol(int fd, const char *Name)
{
#if defined(a64)
off_t OldOffset = lseek(fd, 0, SEEK_CUR);
Elf64_Ehdr Header;
@ -152,6 +153,7 @@ namespace Execute
}
error("Symbol not found.");
lseek(fd, OldOffset, SEEK_SET);
#endif
return {};
}
@ -198,6 +200,8 @@ namespace Execute
Elf64_Shdr *Target = GetELFSection(Header, Symbol->st_shndx);
return (uintptr_t)Header + Symbol->st_value + Target->sh_offset;
}
#elif defined(a32)
return 0xdead;
#endif
}
}

View File

@ -252,9 +252,16 @@ EXTERNC void KPrint(const char *Format, ...)
uint64_t Nanoseconds = TimeManager->GetNanosecondsSinceClassCreation();
if (Nanoseconds != 0)
{
#if defined(a64)
printf("\eCCCCCC[\e00AEFF%lu.%07lu\eCCCCCC] ",
Nanoseconds / 10000000,
Nanoseconds % 10000000);
Nanoseconds / 10000000, Nanoseconds % 10000000);
#elif defined(a32)
printf("\eCCCCCC[\e00AEFF%llu.%07llu\eCCCCCC] ",
Nanoseconds / 10000000, Nanoseconds % 10000000);
#elif defined(aa64)
printf("\eCCCCCC[\e00AEFF%lu.%07lu\eCCCCCC] ",
Nanoseconds / 10000000, Nanoseconds % 10000000);
#endif
}
}
@ -324,10 +331,8 @@ EXTERNC NIF void Main()
KPrint("Enabling Interrupts on Bootstrap Processor");
Interrupts::Enable(0);
#if defined(a64)
#if defined(a86)
PowerManager->InitDSDT();
#elif defined(a32)
// FIXME: Add ACPI support for i386
#elif defined(aa64)
#endif

View File

@ -30,17 +30,31 @@ void cmd_top(const char *)
printf("\e9400A1PID \e9CA100Name \e00A15BState \eCCCCCCPriority Memory Usage CPU Usage\n");
foreach (auto Proc in TaskManager->GetProcessList())
{
#if defined(a64)
printf("\e9400A1%-4d \e9CA100%-20s \e00A15B%s \eCCCCCC%d %ld %ld\n",
Proc->ID, Proc->Name, Proc->Status == Running ? "Running" : "Stopped",
Proc->Info.Priority, Proc->Memory->GetAllocatedMemorySize(),
Proc->Info.UserTime + Proc->Info.KernelTime);
#elif defined(a32)
printf("\e9400A1%-4d \e9CA100%-20s \e00A15B%s \eCCCCCC%d %lld %lld\n",
Proc->ID, Proc->Name, Proc->Status == Running ? "Running" : "Stopped",
Proc->Info.Priority, Proc->Memory->GetAllocatedMemorySize(),
Proc->Info.UserTime + Proc->Info.KernelTime);
#endif
foreach (auto Thrd in Proc->Threads)
{
#if defined(a64)
printf(" \eA80011%-4d \e9CA100%-20s \e00A15B%s \eCCCCCC%d %ld %ld\n",
Thrd->ID, Thrd->Name, Thrd->Status == Running ? "Running" : "Stopped",
Thrd->Info.Priority, Thrd->Memory->GetAllocatedMemorySize(),
Thrd->Info.UserTime + Thrd->Info.KernelTime);
#elif defined(a32)
printf(" \eA80011%-4d \e9CA100%-20s \e00A15B%s \eCCCCCC%d %lld %lld\n",
Thrd->ID, Thrd->Name, Thrd->Status == Running ? "Running" : "Stopped",
Thrd->Info.Priority, Thrd->Memory->GetAllocatedMemorySize(),
Thrd->Info.UserTime + Thrd->Info.KernelTime);
#endif
}
}
}

View File

@ -27,12 +27,12 @@ void cmd_uptime(const char *)
{
if (TimeManager)
{
size_t Nanoseconds =
uint64_t Nanoseconds =
TimeManager->GetNanosecondsSinceClassCreation();
size_t Seconds = Nanoseconds / 10000000;
size_t Minutes = Seconds / 60;
size_t Hours = Minutes / 60;
size_t Days = Hours / 24;
uint64_t Seconds = Nanoseconds / 10000000;
uint64_t Minutes = Seconds / 60;
uint64_t Hours = Minutes / 60;
uint64_t Days = Hours / 24;
debug("Nanoseconds: %ld", Nanoseconds);
@ -40,9 +40,15 @@ void cmd_uptime(const char *)
Minutes %= 60;
Hours %= 24;
#if defined(a64)
printf("%ld days, %ld hours, %ld minutes, %ld %s\n",
Days, Hours, Minutes, Seconds,
Seconds == 1 ? "second" : "seconds");
#elif defined(a32)
printf("%lld days, %lld hours, %lld minutes, %lld %s\n",
Days, Hours, Minutes, Seconds,
Seconds == 1 ? "second" : "seconds");
#endif
}
else
{

View File

@ -170,8 +170,14 @@ void TaskMgr()
continue;
int Status = Proc->Status.load();
uint64_t ProcessCpuUsage = GetUsage(OldSystemTime, &Proc->Info);
#if defined(a64)
printf("\e%s-> \eAABBCC%s \e00AAAA%s %ld%% (KT: %ld UT: %ld)\n",
Statuses[Status], Proc->Name, StatusesSign[Status], ProcessCpuUsage, Proc->Info.KernelTime, Proc->Info.UserTime);
#elif defined(a32)
printf("\e%s-> \eAABBCC%s \e00AAAA%s %lld%% (KT: %lld UT: %lld)\n",
Statuses[Status], Proc->Name, StatusesSign[Status], ProcessCpuUsage, Proc->Info.KernelTime, Proc->Info.UserTime);
#elif defined(aa64)
#endif
foreach (auto Thd in Proc->Threads)
{
@ -185,7 +191,7 @@ void TaskMgr()
Thd->Info.UserTime, Thd->Registers.rip,
Thd->Parent->ELFSymbolTable ? Thd->Parent->ELFSymbolTable->GetSymbolFromAddress(Thd->Registers.rip) : "unknown");
#elif defined(a32)
printf(" \e%s-> \eAABBCC%s \e00AAAA%s %lld%% (KT: %lld UT: %lld, IP: \e24FF2B%#lx \eEDFF24%s\e00AAAA)\n\eAABBCC",
printf(" \e%s-> \eAABBCC%s \e00AAAA%s %lld%% (KT: %lld UT: %lld, IP: \e24FF2B%#x \eEDFF24%s\e00AAAA)\n\eAABBCC",
Statuses[Status], Thd->Name, StatusesSign[Status], ThreadCpuUsage, Thd->Info.KernelTime,
Thd->Info.UserTime, Thd->Registers.eip,
Thd->Parent->ELFSymbolTable ? Thd->Parent->ELFSymbolTable->GetSymbolFromAddress(Thd->Registers.eip) : "unknown");
@ -196,12 +202,14 @@ void TaskMgr()
OldSystemTime = TimeManager->GetCounter();
#if defined(a64)
register uintptr_t CurrentStackAddress asm("rsp");
printf("Sanity: %d, Stack: %#lx", sanity++, CurrentStackAddress);
#elif defined(a32)
register uintptr_t CurrentStackAddress asm("esp");
printf("Sanity: %d, Stack: %#x", sanity++, CurrentStackAddress);
#elif defined(aa64)
register uintptr_t CurrentStackAddress asm("sp");
#endif
printf("Sanity: %d, Stack: %#lx", sanity++, CurrentStackAddress);
#endif
if (sanity > 1000)
sanity = 0;
Display->SetBufferCursor(0, tmpX, tmpY);

View File

@ -72,7 +72,7 @@ namespace AdvancedHostControllerInterface
this->AHCIPortType = Type;
this->HBAPortPtr = PortPtr;
this->Buffer = static_cast<uint8_t *>(KAPI.Memory.RequestPage(1));
memset(this->Buffer, 0, KAPI.Memory.PageSize);
memset(this->Buffer, 0, size_t(KAPI.Memory.PageSize));
this->PortNumber = PortNumber;
}

View File

@ -283,7 +283,8 @@ namespace AudioCodec97
do
{
size_t Wrote = (KAPI.Memory.PageSize > Length) ? Length : KAPI.Memory.PageSize;
size_t Wrote = (KAPI.Memory.PageSize > Length) ? size_t(Length)
: size_t(KAPI.Memory.PageSize);
if (Wrote == 0)
break;

View File

@ -113,9 +113,14 @@ namespace Gigabit
RX[i]->Status = 0;
}
#pragma diagnostic push
#pragma GCC diagnostic ignored "-Wshift-count-overflow"
WriteCMD(REG::TXDESCLO, (uint32_t)(Ptr >> 32));
WriteCMD(REG::TXDESCHI, (uint32_t)(Ptr & 0xFFFFFFFF));
#pragma diagnostic pop
WriteCMD(REG::RXDESCLO, (uint32_t)Ptr);
WriteCMD(REG::RXDESCHI, 0);

View File

@ -31,6 +31,7 @@
#include "../Architecture/amd64/cpu/gdt.hpp"
#elif defined(a32)
#include "../Architecture/i386/cpu/apic.hpp"
#include "../Architecture/i386/cpu/gdt.hpp"
#elif defined(aa64)
#endif
@ -218,9 +219,9 @@ namespace Tasking
foreach (AuxiliaryVector var in auxv_array)
{
// Subtract the size of the auxillary vector
Stack64 -= sizeof(Elf64_auxv_t) / sizeof(uintptr_t);
Stack64 -= sizeof(Elf_auxv_t) / sizeof(uintptr_t);
// Store the auxillary vector
POKE(Elf64_auxv_t, Stack64) = var.archaux;
POKE(Elf_auxv_t, Stack64) = var.archaux;
// TODO: Store strings to the stack
}
@ -263,7 +264,14 @@ namespace Tasking
debug("SubtractStack: %#lx", SubtractStack);
// Set the stack pointer to the new stack
this->Registers.rsp = ((uintptr_t)this->Stack->GetStackTop() - SubtractStack);
uintptr_t StackPointerReg = ((uintptr_t)this->Stack->GetStackTop() - SubtractStack);
#if defined(a64)
this->Registers.rsp = StackPointerReg;
#elif defined(a32)
this->Registers.esp = StackPointerReg;
#elif defined(aa64)
this->Registers.sp = StackPointerReg;
#endif
if (ArgvSize > 0)
delete[] ArgvStrings;
@ -274,10 +282,22 @@ namespace Tasking
DumpData("Stack Data", (void *)((uintptr_t)this->Stack->GetStackPhysicalTop() - (uintptr_t)SubtractStack), SubtractStack);
#endif
#if defined(a64)
this->Registers.rdi = (uintptr_t)ArgvSize; // argc
this->Registers.rsi = (uintptr_t)(this->Registers.rsp + 8); // argv
this->Registers.rcx = (uintptr_t)EnvpSize; // envc
this->Registers.rdx = (uintptr_t)(this->Registers.rsp + 8 + (8 * ArgvSize) + 8); // envp
#elif defined(a32)
this->Registers.eax = (uintptr_t)ArgvSize; // argc
this->Registers.ebx = (uintptr_t)(this->Registers.esp + 4); // argv
this->Registers.ecx = (uintptr_t)EnvpSize; // envc
this->Registers.edx = (uintptr_t)(this->Registers.esp + 4 + (4 * ArgvSize) + 4); // envp
#elif defined(aa64)
this->Registers.x0 = (uintptr_t)ArgvSize; // argc
this->Registers.x1 = (uintptr_t)(this->Registers.sp + 8); // argv
this->Registers.x2 = (uintptr_t)EnvpSize; // envc
this->Registers.x3 = (uintptr_t)(this->Registers.sp + 8 + (8 * ArgvSize) + 8); // envp
#endif
}
void TCB::SetupUserStack_x86_32(const char **argv,

View File

@ -77,15 +77,17 @@ typedef struct
} a_un;
} Elf64_auxv_t;
#if defined(a64)
typedef Elf64_auxv_t Elf_auxv_t;
#elif defined(a32)
typedef Elf64_auxv_t Elf_auxv_t;
#elif defined(aa64)
typedef Elf64_auxv_t Elf_auxv_t;
#endif
typedef struct
{
#if defined(a64)
Elf64_auxv_t archaux;
#elif defined(a32)
Elf32_auxv_t archaux;
#elif defined(aa64)
Elf64_auxv_t archaux;
#endif
Elf_auxv_t archaux;
} AuxiliaryVector;
#endif // !__FENNIX_KERNEL_ABI_H__

View File

@ -210,6 +210,35 @@ namespace CPU
namespace x32
{
/**
* @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

View File

@ -213,7 +213,7 @@ namespace PCI
struct DeviceConfig
{
uintptr_t BaseAddress;
uint64_t BaseAddress;
uint16_t PCISegGroup;
uint8_t StartBus;
uint8_t EndBus;
@ -228,9 +228,9 @@ namespace PCI
public:
std::vector<PCIDeviceHeader *> &GetDevices() { return Devices; }
void MapPCIAddresses(PCIDeviceHeader *PCIDevice, Memory::PageTable *Table = nullptr);
void EnumerateFunction(uintptr_t DeviceAddress, uintptr_t Function);
void EnumerateDevice(uintptr_t BusAddress, uintptr_t Device);
void EnumerateBus(uintptr_t BaseAddress, uintptr_t Bus);
void EnumerateFunction(uint64_t DeviceAddress, uintptr_t Function);
void EnumerateDevice(uint64_t BusAddress, uintptr_t Device);
void EnumerateBus(uint64_t BaseAddress, uintptr_t Bus);
std::vector<PCIDeviceHeader *> FindPCIDevice(uint8_t Class, uint8_t Subclass, uint8_t ProgIF);
std::vector<PCIDeviceHeader *> FindPCIDevice(int VendorID, int DeviceID);

View File

@ -52,15 +52,15 @@ namespace Time
private:
struct HPET
{
uintptr_t GeneralCapabilities;
uintptr_t Reserved0;
uintptr_t GeneralConfiguration;
uintptr_t Reserved1;
uintptr_t GeneralIntStatus;
uintptr_t Reserved2;
uintptr_t Reserved3[24];
uintptr_t MainCounterValue;
uintptr_t Reserved4;
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;