mirror of
https://github.com/EnderIce2/Fennix.git
synced 2025-05-28 15:34:31 +00:00
kernel: add arm architecture support
Some checks failed
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 5m35s
Build OS / Analyze (${{ matrix.language }}) (manual, c-cpp) (push) Has been cancelled
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Build OS / Build amd64 (push) Has been cancelled
Build OS / Build i386 (push) Has been cancelled
Build OS / Build aarch64 (push) Has been cancelled
Build OS / Build arm (push) Has been cancelled
Some checks failed
Build OS / Deploy Documentation to GitHub Pages (push) Failing after 5m35s
Build OS / Analyze (${{ matrix.language }}) (manual, c-cpp) (push) Has been cancelled
Build OS / Build Cross-Compiler & Toolchain (push) Has been cancelled
Build OS / Build amd64 (push) Has been cancelled
Build OS / Build i386 (push) Has been cancelled
Build OS / Build aarch64 (push) Has been cancelled
Build OS / Build arm (push) Has been cancelled
Signed-off-by: EnderIce2 <enderice2@protonmail.com>
This commit is contained in:
parent
e6933acfb0
commit
fbe9fbfbd1
27
Kernel/.vscode/c_cpp_properties.json
vendored
27
Kernel/.vscode/c_cpp_properties.json
vendored
@ -137,6 +137,33 @@
|
|||||||
"-nostdinc++"
|
"-nostdinc++"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Fennix Arm (Linux, GCC, debug)",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/include",
|
||||||
|
"${workspaceFolder}/include/**",
|
||||||
|
"${workspaceFolder}/include_std",
|
||||||
|
"${workspaceFolder}/include_std/**",
|
||||||
|
"${workspaceFolder}/arch/aarch64/include"
|
||||||
|
],
|
||||||
|
"forcedInclude": [
|
||||||
|
"${workspaceFolder}/.vscode/preinclude.h"
|
||||||
|
],
|
||||||
|
"defines": [
|
||||||
|
"DEBUG=\"1\""
|
||||||
|
],
|
||||||
|
"compilerPath": "${workspaceFolder}/../tools/cross/bin/arm-fennix-gcc",
|
||||||
|
"cStandard": "c17",
|
||||||
|
"cppStandard": "c++20",
|
||||||
|
"intelliSenseMode": "linux-gcc-arm",
|
||||||
|
"configurationProvider": "ms-vscode.makefile-tools",
|
||||||
|
"compilerArgs": [
|
||||||
|
// VSCode flags
|
||||||
|
"-ffreestanding",
|
||||||
|
"-nostdinc",
|
||||||
|
"-nostdinc++"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Fennix Aarch64 (Linux, GCC, debug)",
|
"name": "Fennix Aarch64 (Linux, GCC, debug)",
|
||||||
"includePath": [
|
"includePath": [
|
||||||
|
@ -53,6 +53,10 @@ LDFLAGS += -Tarch/amd64/linker.ld
|
|||||||
else ifeq ($(OSARCH), i386)
|
else ifeq ($(OSARCH), i386)
|
||||||
CFLAGS += -march=pentium -m32 -mno-red-zone
|
CFLAGS += -march=pentium -m32 -mno-red-zone
|
||||||
LDFLAGS += -Tarch/i386/linker.ld
|
LDFLAGS += -Tarch/i386/linker.ld
|
||||||
|
else ifeq ($(OSARCH), arm)
|
||||||
|
CFLAGS += -march=armv7-a -mfloat-abi=hard -mfpu=vfpv3-d16
|
||||||
|
LDFLAGS += -Tarch/arm/linker.ld
|
||||||
|
WARNCFLAG += -w
|
||||||
else ifeq ($(OSARCH), aarch64)
|
else ifeq ($(OSARCH), aarch64)
|
||||||
CFLAGS += -march=armv9.4-a -mtune=cortex-a72 -mlittle-endian -mcmodel=large
|
CFLAGS += -march=armv9.4-a -mtune=cortex-a72 -mlittle-endian -mcmodel=large
|
||||||
LDFLAGS += -Tarch/aarch64/linker.ld
|
LDFLAGS += -Tarch/aarch64/linker.ld
|
||||||
@ -67,6 +71,9 @@ ifeq ($(DEBUG), 1)
|
|||||||
ifeq ($(OSARCH), amd64)
|
ifeq ($(OSARCH), amd64)
|
||||||
CFLAGS += -fverbose-asm
|
CFLAGS += -fverbose-asm
|
||||||
endif # amd64
|
endif # amd64
|
||||||
|
ifeq ($(OSARCH), arm)
|
||||||
|
CFLAGS += -fstack-check -fverbose-asm
|
||||||
|
endif # arm
|
||||||
ifeq ($(OSARCH), aarch64)
|
ifeq ($(OSARCH), aarch64)
|
||||||
CFLAGS += -fstack-check -fverbose-asm
|
CFLAGS += -fstack-check -fverbose-asm
|
||||||
endif # aarch64
|
endif # aarch64
|
||||||
@ -119,6 +126,8 @@ ifeq ($(OSARCH), amd64)
|
|||||||
$(__CONF_OBJCOPY) -O elf64-x86-64 -I binary $< $@
|
$(__CONF_OBJCOPY) -O elf64-x86-64 -I binary $< $@
|
||||||
else ifeq ($(OSARCH), i386)
|
else ifeq ($(OSARCH), i386)
|
||||||
$(__CONF_OBJCOPY) -O elf32-i386 -I binary $< $@
|
$(__CONF_OBJCOPY) -O elf32-i386 -I binary $< $@
|
||||||
|
else ifeq ($(OSARCH), arm)
|
||||||
|
$(__CONF_OBJCOPY) -O elf32-littlearm -I binary $< $@
|
||||||
else ifeq ($(OSARCH), aarch64)
|
else ifeq ($(OSARCH), aarch64)
|
||||||
$(__CONF_OBJCOPY) -O elf64-littleaarch64 -I binary $< $@
|
$(__CONF_OBJCOPY) -O elf64-littleaarch64 -I binary $< $@
|
||||||
endif
|
endif
|
||||||
@ -129,6 +138,8 @@ ifeq ($(OSARCH), amd64)
|
|||||||
$(__CONF_OBJCOPY) -O elf64-x86-64 -I binary $< $@
|
$(__CONF_OBJCOPY) -O elf64-x86-64 -I binary $< $@
|
||||||
else ifeq ($(OSARCH), i386)
|
else ifeq ($(OSARCH), i386)
|
||||||
$(__CONF_OBJCOPY) -O elf32-i386 -I binary $< $@
|
$(__CONF_OBJCOPY) -O elf32-i386 -I binary $< $@
|
||||||
|
else ifeq ($(OSARCH), arm)
|
||||||
|
$(__CONF_OBJCOPY) -O elf32-littlearm -I binary $< $@
|
||||||
else ifeq ($(OSARCH), aarch64)
|
else ifeq ($(OSARCH), aarch64)
|
||||||
$(__CONF_OBJCOPY) -O elf64-littlearch64 -I binary $< $@
|
$(__CONF_OBJCOPY) -O elf64-littlearch64 -I binary $< $@
|
||||||
endif
|
endif
|
||||||
|
40
Kernel/arch/arm/aeabi.c
Normal file
40
Kernel/arch/arm/aeabi.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Fennix Kernel.
|
||||||
|
|
||||||
|
Fennix Kernel is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
Fennix Kernel is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned __aeabi_uidiv(unsigned a, unsigned b) { return a / b; }
|
||||||
|
unsigned __aeabi_idiv(unsigned a, unsigned b) { return a / b; }
|
||||||
|
unsigned __aeabi_l2d(unsigned a) { return a; }
|
||||||
|
unsigned __aeabi_d2lz(unsigned a) { return a; }
|
||||||
|
|
||||||
|
unsigned __aeabi_ldivmod(unsigned a, unsigned b, unsigned *r) { *r = a % b; return a / b; }
|
||||||
|
|
||||||
|
unsigned __aeabi_uldivmod(unsigned a, unsigned b, unsigned *r) { *r = a % b; return a / b; }
|
||||||
|
|
||||||
|
unsigned __aeabi_uidivmod(unsigned a, unsigned b, unsigned *r) { *r = a % b; return a / b; }
|
||||||
|
|
||||||
|
|
||||||
|
unsigned __aeabi_idivmod(unsigned a, unsigned b, unsigned *r) { *r = a % b; return a / b; }
|
||||||
|
|
||||||
|
|
||||||
|
unsigned __aeabi_unwind_cpp_pr1(void) { return 0; }
|
||||||
|
unsigned __aeabi_atexit(void) { return 0; }
|
||||||
|
unsigned __cxa_end_cleanup(void) { return 0; }
|
||||||
|
unsigned __aeabi_unwind_cpp_pr0(void) { return 0; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
18
Kernel/arch/arm/bootstrap/boot.S
Normal file
18
Kernel/arch/arm/bootstrap/boot.S
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/* Based on this tutorial:
|
||||||
|
https://github.com/s-matyukevich/raspberry-pi-os */
|
||||||
|
|
||||||
|
.section ".text.boot", "a"
|
||||||
|
|
||||||
|
.extern _bss_start
|
||||||
|
.extern _bss_end
|
||||||
|
|
||||||
|
.global _start
|
||||||
|
_start:
|
||||||
|
b CPU_Loop
|
||||||
|
|
||||||
|
Halt:
|
||||||
|
wfe
|
||||||
|
b Halt
|
||||||
|
|
||||||
|
CPU_Loop:
|
||||||
|
b CPU_Loop
|
46
Kernel/arch/arm/core/panic/ui.cpp
Normal file
46
Kernel/arch/arm/core/panic/ui.cpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
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 <display.hpp>
|
||||||
|
#include <bitmap.hpp>
|
||||||
|
#include <convert.h>
|
||||||
|
#include <printf.h>
|
||||||
|
#include <lock.hpp>
|
||||||
|
#include <rand.hpp>
|
||||||
|
#include <uart.hpp>
|
||||||
|
#include <debug.h>
|
||||||
|
#include <smp.hpp>
|
||||||
|
#include <cpu.hpp>
|
||||||
|
#include <io.h>
|
||||||
|
|
||||||
|
#if defined(__amd64__)
|
||||||
|
#include "../../arch/amd64/cpu/gdt.hpp"
|
||||||
|
#include "../arch/amd64/cpu/apic.hpp"
|
||||||
|
#elif defined(__i386__)
|
||||||
|
#include "../../arch/i386/cpu/gdt.hpp"
|
||||||
|
#include "../arch/i386/cpu/apic.hpp"
|
||||||
|
#elif defined(__aarch64__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../../../../kernel.h"
|
||||||
|
|
||||||
|
extern void ExPrint(const char *Format, ...);
|
||||||
|
|
||||||
|
arch nsa void DisplayDetailsScreen(CPU::ExceptionFrame *Frame)
|
||||||
|
{
|
||||||
|
ExPrint("\nException Frame:\n");
|
||||||
|
}
|
59
Kernel/arch/arm/cpu/smp.cpp
Normal file
59
Kernel/arch/arm/cpu/smp.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
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 <smp.hpp>
|
||||||
|
|
||||||
|
#include <ints.hpp>
|
||||||
|
#include <memory.hpp>
|
||||||
|
#include <cpu.hpp>
|
||||||
|
|
||||||
|
#include "../../../kernel.h"
|
||||||
|
|
||||||
|
volatile bool CPUEnabled = false;
|
||||||
|
|
||||||
|
#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
|
||||||
|
static __aligned(0x1000) CPUData CPUs[MAX_CPU] = {0};
|
||||||
|
|
||||||
|
CPUData *GetCPU(uint64_t id) { return &CPUs[id]; }
|
||||||
|
|
||||||
|
CPUData *GetCurrentCPU()
|
||||||
|
{
|
||||||
|
uint64_t ret = 0;
|
||||||
|
|
||||||
|
if (!CPUs[ret].IsActive)
|
||||||
|
{
|
||||||
|
error("CPU %d is not active!", ret);
|
||||||
|
return &CPUs[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CPUs[ret].Checksum != CPU_DATA_CHECKSUM)
|
||||||
|
{
|
||||||
|
error("CPU %d data is corrupted!", ret);
|
||||||
|
return &CPUs[0];
|
||||||
|
}
|
||||||
|
return &CPUs[ret];
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace SMP
|
||||||
|
{
|
||||||
|
int CPUCores = 0;
|
||||||
|
|
||||||
|
void Initialize(void *madt)
|
||||||
|
{
|
||||||
|
fixme("SMP::Initialize() is not implemented!");
|
||||||
|
}
|
||||||
|
}
|
27
Kernel/arch/arm/entry.cpp
Normal file
27
Kernel/arch/arm/entry.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Fennix Kernel.
|
||||||
|
|
||||||
|
Fennix Kernel is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
Fennix Kernel is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <types.h>
|
||||||
|
|
||||||
|
#include <debug.h>
|
||||||
|
#include <cpu.hpp>
|
||||||
|
|
||||||
|
EXTERNC void arm64Entry(uint64_t dtb_ptr32, uint64_t x1, uint64_t x2, uint64_t x3)
|
||||||
|
{
|
||||||
|
trace("Hello, World!");
|
||||||
|
CPU::Halt(true);
|
||||||
|
}
|
0
Kernel/arch/arm/include/.gitkeep
Normal file
0
Kernel/arch/arm/include/.gitkeep
Normal file
89
Kernel/arch/arm/linker.ld
Normal file
89
Kernel/arch/arm/linker.ld
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ENTRY(_start)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
_bootstrap_start = .;
|
||||||
|
.text.boot :
|
||||||
|
{
|
||||||
|
*(.text.boot)
|
||||||
|
. += CONSTANT(MAXPAGESIZE);
|
||||||
|
_bss_start = .;
|
||||||
|
*(.text.bss)
|
||||||
|
_bss_end = .;
|
||||||
|
}
|
||||||
|
_bootstrap_end = .;
|
||||||
|
|
||||||
|
_kernel_start = .;
|
||||||
|
_kernel_text_start = .;
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
KEEP(*(.text.boot))
|
||||||
|
*(.text .text.*)
|
||||||
|
}
|
||||||
|
. = ALIGN(4096);
|
||||||
|
_kernel_text_end = .;
|
||||||
|
|
||||||
|
_kernel_data_start = .;
|
||||||
|
.data :
|
||||||
|
{
|
||||||
|
*(.data .data.*)
|
||||||
|
}
|
||||||
|
. = ALIGN(4096);
|
||||||
|
_kernel_data_end = .;
|
||||||
|
|
||||||
|
_kernel_rodata_start = .;
|
||||||
|
.rodata :
|
||||||
|
{
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
}
|
||||||
|
. = ALIGN(4096);
|
||||||
|
|
||||||
|
.init_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN(__init_array_start = .);
|
||||||
|
KEEP(*(.init_array .ctors))
|
||||||
|
KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fini_array :
|
||||||
|
{
|
||||||
|
PROVIDE_HIDDEN(__fini_array_start = .);
|
||||||
|
KEEP(*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
|
||||||
|
KEEP(*(.fini_array .dtors))
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
}
|
||||||
|
_kernel_rodata_end = .;
|
||||||
|
|
||||||
|
_kernel_bss_start = .;
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
*(.bss .bss.*)
|
||||||
|
}
|
||||||
|
. = ALIGN(4096);
|
||||||
|
_kernel_bss_end = .;
|
||||||
|
_kernel_end = .;
|
||||||
|
_bss_size = _kernel_end - _kernel_rodata_end;
|
||||||
|
|
||||||
|
/DISCARD/ :
|
||||||
|
{
|
||||||
|
*(.comment*)
|
||||||
|
}
|
||||||
|
}
|
97
Kernel/arch/arm/madt.cpp
Normal file
97
Kernel/arch/arm/madt.cpp
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
This file is part of Fennix Kernel.
|
||||||
|
|
||||||
|
Fennix Kernel is free software: you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License as
|
||||||
|
published by the Free Software Foundation, either version 3 of
|
||||||
|
the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
Fennix Kernel is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fennix Kernel. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "acpi.hpp"
|
||||||
|
|
||||||
|
#include <memory.hpp>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#include "../../kernel.h"
|
||||||
|
|
||||||
|
namespace ACPI
|
||||||
|
{
|
||||||
|
MADT::MADT(ACPI::MADTHeader *madt)
|
||||||
|
{
|
||||||
|
trace("Initializing MADT");
|
||||||
|
if (!madt)
|
||||||
|
{
|
||||||
|
error("MADT is NULL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 %d (APIC %d) found.", lapic.back()->ACPIProcessorId, lapic.back()->APICId);
|
||||||
|
CPUCores++;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
ioapic.push_back((MADTIOApic *)ptr);
|
||||||
|
KPrint("I/O APIC %d (Address %#lx) 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:%#lx, BUS:%#lx, GSI:%#lx, %s/%s) found.",
|
||||||
|
iso.back()->IRQSource, iso.back()->BuSSource, iso.back()->GSI,
|
||||||
|
iso.back()->Flags & 0x00000004 ? "Active High" : "Active Low",
|
||||||
|
iso.back()->Flags & 0x00000100 ? "Edge Triggered" : "Level Triggered");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
{
|
||||||
|
nmi.push_back((MADTNmi *)ptr);
|
||||||
|
KPrint("NMI %#lx (lint:%#lx) found.", nmi.back()->processor, nmi.back()->lint);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 5:
|
||||||
|
{
|
||||||
|
LAPICAddress = (LAPIC *)ptr;
|
||||||
|
KPrint("APIC found at %#lx", LAPICAddress);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
KPrint("Unknown MADT entry %#lx", *(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()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
69
Kernel/arch/arm/memory/vmm.cpp
Normal file
69
Kernel/arch/arm/memory/vmm.cpp
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
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 <memory.hpp>
|
||||||
|
|
||||||
|
#include <convert.h>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
namespace Memory
|
||||||
|
{
|
||||||
|
bool Virtual::Check(void *VirtualAddress, PTFlag Flag, MapType Type)
|
||||||
|
{
|
||||||
|
#warning "arm not implemented"
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *Virtual::GetPhysical(void *VirtualAddress)
|
||||||
|
{
|
||||||
|
#warning "arm not implemented"
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Virtual::MapType Virtual::GetMapType(void *VirtualAddress)
|
||||||
|
{
|
||||||
|
#warning "arm not implemented"
|
||||||
|
return MapType::NoMapType;
|
||||||
|
}
|
||||||
|
|
||||||
|
PageDirectoryEntry *Virtual::GetPDE(void *VirtualAddress, MapType Type)
|
||||||
|
{
|
||||||
|
#warning "arm not implemented"
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PageTableEntry *Virtual::GetPTE(void *VirtualAddress, MapType Type)
|
||||||
|
{
|
||||||
|
#warning "arm not implemented"
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Virtual::Map(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags, MapType Type)
|
||||||
|
{
|
||||||
|
#warning "arm not implemented"
|
||||||
|
}
|
||||||
|
|
||||||
|
void Virtual::Unmap(void *VirtualAddress, MapType Type)
|
||||||
|
{
|
||||||
|
#warning "arm not implemented"
|
||||||
|
}
|
||||||
|
|
||||||
|
void Virtual::Remap(void *VirtualAddress, void *PhysicalAddress, uint64_t Flags, MapType Type)
|
||||||
|
{
|
||||||
|
#warning "arm not implemented"
|
||||||
|
}
|
||||||
|
}
|
30
Kernel/arch/arm/syscalls.cpp
Normal file
30
Kernel/arch/arm/syscalls.cpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
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 <syscalls.hpp>
|
||||||
|
|
||||||
|
#include <cpu.hpp>
|
||||||
|
|
||||||
|
extern "C" __used __no_stack_protector void SystemCallHandlerStub()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" uint64_t SystemCallsHandler(SyscallsFrame *regs);
|
||||||
|
|
||||||
|
void InitializeSystemCalls()
|
||||||
|
{
|
||||||
|
}
|
38
Kernel/arch/arm/tasking/signal.cpp
Normal file
38
Kernel/arch/arm/tasking/signal.cpp
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
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 <signal.hpp>
|
||||||
|
#include <dumper.hpp>
|
||||||
|
#include <task.hpp>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
/* subsystem/linux/syscall.cpp */
|
||||||
|
extern int ConvertSignalToLinux(signal_t sig);
|
||||||
|
|
||||||
|
namespace Tasking
|
||||||
|
{
|
||||||
|
bool Signal::HandleSignal(CPU::SchedulerFrame *tf, void *thread)
|
||||||
|
{
|
||||||
|
#warning "arm not implemented"
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Signal::RestoreHandleSignal(SyscallsFrame *sf, void *thread)
|
||||||
|
{
|
||||||
|
#warning "arm not implemented"
|
||||||
|
}
|
||||||
|
}
|
28
Kernel/arch/arm/tasking/signal_trampoline.s
Normal file
28
Kernel/arch/arm/tasking/signal_trampoline.s
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.global _sig_native_trampoline_start
|
||||||
|
_sig_native_trampoline_start:
|
||||||
|
|
||||||
|
.global _sig_native_trampoline_end
|
||||||
|
_sig_native_trampoline_end:
|
||||||
|
|
||||||
|
.global _sig_linux_trampoline_start
|
||||||
|
_sig_linux_trampoline_start:
|
||||||
|
|
||||||
|
.global _sig_linux_trampoline_end
|
||||||
|
_sig_linux_trampoline_end:
|
@ -551,9 +551,9 @@ struct heap_t
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Keep in sync with heap_t inside rpmalloc_compat.cpp */
|
/* Keep in sync with heap_t inside rpmalloc_compat.cpp */
|
||||||
#ifndef __i386__
|
#if !defined(__i386__) && !defined(__arm__)
|
||||||
static_assert(sizeof(heap_t) == 56408, "heap_t size mismatch");
|
static_assert(sizeof(heap_t) == 56408, "heap_t size mismatch");
|
||||||
#endif // __i386__
|
#endif // __i386__ || __arm__
|
||||||
|
|
||||||
// Size class for defining a block size bucket
|
// Size class for defining a block size bucket
|
||||||
struct size_class_t
|
struct size_class_t
|
||||||
@ -3105,7 +3105,11 @@ rpcalloc(size_t num, size_t size)
|
|||||||
{
|
{
|
||||||
size_t total;
|
size_t total;
|
||||||
#if ENABLE_VALIDATE_ARGS
|
#if ENABLE_VALIDATE_ARGS
|
||||||
|
#ifdef __arm__
|
||||||
|
int err = __builtin_umull_overflow(num, size, (unsigned long *)&total);
|
||||||
|
#else
|
||||||
int err = __builtin_umull_overflow(num, size, &total);
|
int err = __builtin_umull_overflow(num, size, &total);
|
||||||
|
#endif
|
||||||
assert(!err && (total < MAX_ALLOC_SIZE));
|
assert(!err && (total < MAX_ALLOC_SIZE));
|
||||||
#else
|
#else
|
||||||
total = num * size;
|
total = num * size;
|
||||||
@ -3150,7 +3154,11 @@ rpaligned_calloc(size_t alignment, size_t num, size_t size)
|
|||||||
{
|
{
|
||||||
size_t total;
|
size_t total;
|
||||||
#if ENABLE_VALIDATE_ARGS
|
#if ENABLE_VALIDATE_ARGS
|
||||||
|
#ifdef __arm__
|
||||||
|
int err = __builtin_umull_overflow(num, size, (unsigned long *)&total);
|
||||||
|
#else
|
||||||
int err = __builtin_umull_overflow(num, size, &total);
|
int err = __builtin_umull_overflow(num, size, &total);
|
||||||
|
#endif
|
||||||
assert(!err && (total < MAX_ALLOC_SIZE));
|
assert(!err && (total < MAX_ALLOC_SIZE));
|
||||||
#else
|
#else
|
||||||
total = num * size;
|
total = num * size;
|
||||||
|
@ -93,7 +93,7 @@ namespace Memory
|
|||||||
#if defined(__amd64__) || defined(__aarch64__)
|
#if defined(__amd64__) || defined(__aarch64__)
|
||||||
Elf64_Xword SymbolSize = 0;
|
Elf64_Xword SymbolSize = 0;
|
||||||
Elf64_Xword StringSize = 0;
|
Elf64_Xword StringSize = 0;
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__) || defined(__arm__)
|
||||||
Elf32_Word SymbolSize = 0;
|
Elf32_Word SymbolSize = 0;
|
||||||
Elf32_Word StringSize = 0;
|
Elf32_Word StringSize = 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -304,12 +304,19 @@ nsa void DisplayMainScreen(CPU::ExceptionFrame *Frame)
|
|||||||
"stub",
|
"stub",
|
||||||
"stub",
|
"stub",
|
||||||
#warning "aarch64 not implemented"
|
#warning "aarch64 not implemented"
|
||||||
|
#elif defined(__arm__)
|
||||||
|
"stub",
|
||||||
|
"stub",
|
||||||
|
#warning "arm not implemented"
|
||||||
#endif
|
#endif
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
Frame->InterruptNumber);
|
Frame->InterruptNumber);
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
0);
|
0);
|
||||||
#warning "aarch64 not implemented"
|
#warning "aarch64 not implemented"
|
||||||
|
#elif defined(__arm__)
|
||||||
|
0);
|
||||||
|
#warning "arm not implemented"
|
||||||
#endif
|
#endif
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
ExPrint("Cause: %s\n", x86Exceptions[Frame->InterruptNumber].Cause);
|
ExPrint("Cause: %s\n", x86Exceptions[Frame->InterruptNumber].Cause);
|
||||||
@ -320,6 +327,8 @@ nsa void DisplayMainScreen(CPU::ExceptionFrame *Frame)
|
|||||||
Frame->rip);
|
Frame->rip);
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__)
|
||||||
Frame->eip);
|
Frame->eip);
|
||||||
|
#elif defined(__arm__)
|
||||||
|
0);
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
0);
|
0);
|
||||||
#warning "aarch64 not implemented"
|
#warning "aarch64 not implemented"
|
||||||
|
@ -104,7 +104,7 @@ namespace SymbolResolver
|
|||||||
#if defined(__amd64__) || defined(__aarch64__)
|
#if defined(__amd64__) || defined(__aarch64__)
|
||||||
Elf64_Xword SymbolSize = 0;
|
Elf64_Xword SymbolSize = 0;
|
||||||
// Elf64_Xword StringSize = 0;
|
// Elf64_Xword StringSize = 0;
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__) || defined(__arm__)
|
||||||
Elf32_Word SymbolSize = 0;
|
Elf32_Word SymbolSize = 0;
|
||||||
// Elf32_Word StringSize = 0;
|
// Elf32_Word StringSize = 0;
|
||||||
#endif
|
#endif
|
||||||
@ -220,7 +220,7 @@ namespace SymbolResolver
|
|||||||
|
|
||||||
#if defined(__amd64__) || defined(__aarch64__)
|
#if defined(__amd64__) || defined(__aarch64__)
|
||||||
Elf64_Ehdr *Header = (Elf64_Ehdr *)ImageAddress;
|
Elf64_Ehdr *Header = (Elf64_Ehdr *)ImageAddress;
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__) || defined(__arm__)
|
||||||
Elf32_Ehdr *Header = (Elf32_Ehdr *)ImageAddress;
|
Elf32_Ehdr *Header = (Elf32_Ehdr *)ImageAddress;
|
||||||
#endif
|
#endif
|
||||||
if (Header->e_ident[0] != 0x7F &&
|
if (Header->e_ident[0] != 0x7F &&
|
||||||
|
@ -80,9 +80,11 @@ typedef struct
|
|||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
typedef Elf64_auxv_t Elf_auxv_t;
|
typedef Elf64_auxv_t Elf_auxv_t;
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__)
|
||||||
typedef Elf64_auxv_t Elf_auxv_t;
|
typedef Elf32_auxv_t Elf_auxv_t;
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
typedef Elf64_auxv_t Elf_auxv_t;
|
typedef Elf64_auxv_t Elf_auxv_t;
|
||||||
|
#elif defined(__arm__)
|
||||||
|
typedef Elf32_auxv_t Elf_auxv_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -90,8 +90,8 @@ extern "C"
|
|||||||
long unsigned strlen_sse4_1(const char s[]);
|
long unsigned strlen_sse4_1(const char s[]);
|
||||||
long unsigned strlen_sse4_2(const char s[]);
|
long unsigned strlen_sse4_2(const char s[]);
|
||||||
|
|
||||||
long unsigned strlen(const char s[]);
|
size_t strlen(const char s[]);
|
||||||
int strncmp(const char *s1, const char *s2, unsigned long n);
|
int strncmp(const char *s1, const char *s2, size_t n);
|
||||||
char *strcat_unsafe(char *destination, const char *source);
|
char *strcat_unsafe(char *destination, const char *source);
|
||||||
char *strcpy_unsafe(char *destination, const char *source);
|
char *strcpy_unsafe(char *destination, const char *source);
|
||||||
char *strncpy(char *destination, const char *source, unsigned long num);
|
char *strncpy(char *destination, const char *source, unsigned long num);
|
||||||
|
@ -1072,6 +1072,72 @@ namespace CPU
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace arm
|
||||||
|
{
|
||||||
|
struct TrapFrame
|
||||||
|
{
|
||||||
|
uint32_t R0; /* Register R0 (argument / scratch) */
|
||||||
|
uint32_t R1; /* Register R1 (argument / scratch) */
|
||||||
|
uint32_t R2; /* Register R2 (argument / scratch) */
|
||||||
|
uint32_t R3; /* Register R3 (argument / scratch) */
|
||||||
|
uint32_t R4; /* Register R4 (callee-saved) */
|
||||||
|
uint32_t R5; /* Register R5 (callee-saved) */
|
||||||
|
uint32_t R6; /* Register R6 (callee-saved) */
|
||||||
|
uint32_t R7; /* Register R7 (callee-saved) */
|
||||||
|
uint32_t R8; /* Register R8 (callee-saved) */
|
||||||
|
uint32_t R9; /* Register R9 (platform-specific) */
|
||||||
|
uint32_t R10; /* Register R10 (callee-saved) */
|
||||||
|
uint32_t FP; /* Frame Pointer (R11) */
|
||||||
|
uint32_t IP; /* Intra-Procedure Scratch (R12) */
|
||||||
|
uint32_t SP; /* Stack Pointer (R13) */
|
||||||
|
uint32_t LR; /* Link Register (R14) */
|
||||||
|
uint32_t PC; /* Program Counter (R15) */
|
||||||
|
uint32_t CPSR; /* Current Program Status Register */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SchedulerFrame
|
||||||
|
{
|
||||||
|
uint32_t R0; /* Register R0 (argument / scratch) */
|
||||||
|
uint32_t R1; /* Register R1 (argument / scratch) */
|
||||||
|
uint32_t R2; /* Register R2 (argument / scratch) */
|
||||||
|
uint32_t R3; /* Register R3 (argument / scratch) */
|
||||||
|
uint32_t R4; /* Register R4 (callee-saved) */
|
||||||
|
uint32_t R5; /* Register R5 (callee-saved) */
|
||||||
|
uint32_t R6; /* Register R6 (callee-saved) */
|
||||||
|
uint32_t R7; /* Register R7 (callee-saved) */
|
||||||
|
uint32_t R8; /* Register R8 (callee-saved) */
|
||||||
|
uint32_t R9; /* Register R9 (platform-specific) */
|
||||||
|
uint32_t R10; /* Register R10 (callee-saved) */
|
||||||
|
uint32_t FP; /* Frame Pointer (R11) */
|
||||||
|
uint32_t IP; /* Intra-Procedure Scratch (R12) */
|
||||||
|
uint32_t SP; /* Stack Pointer (R13) */
|
||||||
|
uint32_t LR; /* Link Register (R14) */
|
||||||
|
uint32_t PC; /* Program Counter (R15) */
|
||||||
|
uint32_t CPSR; /* Current Program Status Register */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ExceptionFrame
|
||||||
|
{
|
||||||
|
uint32_t R0; /* Register R0 (argument / scratch) */
|
||||||
|
uint32_t R1; /* Register R1 (argument / scratch) */
|
||||||
|
uint32_t R2; /* Register R2 (argument / scratch) */
|
||||||
|
uint32_t R3; /* Register R3 (argument / scratch) */
|
||||||
|
uint32_t R4; /* Register R4 (callee-saved) */
|
||||||
|
uint32_t R5; /* Register R5 (callee-saved) */
|
||||||
|
uint32_t R6; /* Register R6 (callee-saved) */
|
||||||
|
uint32_t R7; /* Register R7 (callee-saved) */
|
||||||
|
uint32_t R8; /* Register R8 (callee-saved) */
|
||||||
|
uint32_t R9; /* Register R9 (platform-specific) */
|
||||||
|
uint32_t R10; /* Register R10 (callee-saved) */
|
||||||
|
uint32_t FP; /* Frame Pointer (R11) */
|
||||||
|
uint32_t IP; /* Intra-Procedure Scratch (R12) */
|
||||||
|
uint32_t SP; /* Stack Pointer (R13) */
|
||||||
|
uint32_t LR; /* Link Register (R14) */
|
||||||
|
uint32_t PC; /* Program Counter (R15) */
|
||||||
|
uint32_t CPSR; /* Current Program Status Register */
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
namespace aarch64
|
namespace aarch64
|
||||||
{
|
{
|
||||||
struct TrapFrame
|
struct TrapFrame
|
||||||
@ -1123,6 +1189,15 @@ namespace CPU
|
|||||||
typedef x32::TrapFrame TrapFrame;
|
typedef x32::TrapFrame TrapFrame;
|
||||||
typedef x32::SchedulerFrame SchedulerFrame;
|
typedef x32::SchedulerFrame SchedulerFrame;
|
||||||
typedef x32::ExceptionFrame ExceptionFrame;
|
typedef x32::ExceptionFrame ExceptionFrame;
|
||||||
|
#elif defined(__arm__)
|
||||||
|
/**
|
||||||
|
* CPU trap frame for the current architecture
|
||||||
|
*
|
||||||
|
* @note This is for arm
|
||||||
|
*/
|
||||||
|
typedef arm::TrapFrame TrapFrame;
|
||||||
|
typedef arm::SchedulerFrame SchedulerFrame;
|
||||||
|
typedef arm::ExceptionFrame ExceptionFrame;
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
/**
|
/**
|
||||||
* CPU trap frame for the current architecture
|
* CPU trap frame for the current architecture
|
||||||
|
@ -962,7 +962,7 @@ typedef Elf64_Rel Elf_Rel;
|
|||||||
typedef Elf64_Sym Elf_Sym;
|
typedef Elf64_Sym Elf_Sym;
|
||||||
typedef Elf64_Dyn Elf_Dyn;
|
typedef Elf64_Dyn Elf_Dyn;
|
||||||
typedef Elf64_Rela Elf_Rela;
|
typedef Elf64_Rela Elf_Rela;
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__) || defined(__arm__)
|
||||||
typedef Elf32_Addr Elf_Addr;
|
typedef Elf32_Addr Elf_Addr;
|
||||||
typedef Elf32_Half Elf_Half;
|
typedef Elf32_Half Elf_Half;
|
||||||
typedef Elf32_Off Elf_Off;
|
typedef Elf32_Off Elf_Off;
|
||||||
|
@ -59,7 +59,7 @@
|
|||||||
|
|
||||||
#define USER_STACK_END 0xFFFFEFFF00000000 /* 256 MiB */
|
#define USER_STACK_END 0xFFFFEFFF00000000 /* 256 MiB */
|
||||||
#define USER_STACK_BASE 0xFFFFEFFFFFFF0000
|
#define USER_STACK_BASE 0xFFFFEFFFFFFF0000
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__) || defined(__arm__)
|
||||||
#define KERNEL_VMA_OFFSET 0xC0000000
|
#define KERNEL_VMA_OFFSET 0xC0000000
|
||||||
|
|
||||||
#define USER_ALLOC_BASE 0x80000000
|
#define USER_ALLOC_BASE 0x80000000
|
||||||
|
@ -67,6 +67,14 @@ typedef struct SyscallsFrame
|
|||||||
uint64_t ExceptionSyndromeRegister;
|
uint64_t ExceptionSyndromeRegister;
|
||||||
uint64_t FaultAddressRegister;
|
uint64_t FaultAddressRegister;
|
||||||
uint64_t SavedProgramStatusRegister;
|
uint64_t SavedProgramStatusRegister;
|
||||||
|
#elif defined(__arm__)
|
||||||
|
uint32_t ReturnAddress; /* r0 */
|
||||||
|
uint32_t x[14];
|
||||||
|
uint32_t StackPointer;
|
||||||
|
uint32_t ExceptionLinkRegister;
|
||||||
|
uint32_t ExceptionSyndromeRegister;
|
||||||
|
uint32_t FaultAddressRegister;
|
||||||
|
uint32_t SavedProgramStatusRegister;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uintptr_t ReturnValue() const
|
uintptr_t ReturnValue() const
|
||||||
|
@ -553,6 +553,8 @@ namespace Tasking
|
|||||||
return x64;
|
return x64;
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__)
|
||||||
return x32;
|
return x32;
|
||||||
|
#elif defined(__arm__)
|
||||||
|
return ARM32;
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
return ARM64;
|
return ARM64;
|
||||||
#endif
|
#endif
|
||||||
|
@ -171,7 +171,7 @@ typedef uint32_t uid_t;
|
|||||||
typedef uint32_t gid_t;
|
typedef uint32_t gid_t;
|
||||||
typedef int64_t clock_t;
|
typedef int64_t clock_t;
|
||||||
typedef int32_t pid_t;
|
typedef int32_t pid_t;
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__) || defined(__arm__)
|
||||||
typedef int32_t off_t;
|
typedef int32_t off_t;
|
||||||
typedef long long off64_t;
|
typedef long long off64_t;
|
||||||
typedef uint32_t mode_t;
|
typedef uint32_t mode_t;
|
||||||
|
@ -27,6 +27,10 @@
|
|||||||
#define DBL_MANT_DIG 24
|
#define DBL_MANT_DIG 24
|
||||||
#define DBL_MAX_10_EXP 38
|
#define DBL_MAX_10_EXP 38
|
||||||
#define DBL_MAX 3.4028234663852886e+38
|
#define DBL_MAX 3.4028234663852886e+38
|
||||||
|
#elif __arm__
|
||||||
|
#define DBL_MANT_DIG __DBL_MANT_DIG__
|
||||||
|
#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__
|
||||||
|
#define DBL_MAX __DBL_MAX__
|
||||||
#elif __aarch64__
|
#elif __aarch64__
|
||||||
#define DBL_MANT_DIG __DBL_MANT_DIG__
|
#define DBL_MANT_DIG __DBL_MANT_DIG__
|
||||||
#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__
|
#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__
|
||||||
|
@ -45,6 +45,10 @@ namespace std
|
|||||||
static_assert(sizeof(uintptr_t) == sizeof(uint32_t));
|
static_assert(sizeof(uintptr_t) == sizeof(uint32_t));
|
||||||
const uint32_t FNV_OFFSET_BASIS = 2166136261u;
|
const uint32_t FNV_OFFSET_BASIS = 2166136261u;
|
||||||
const uint32_t FNV_PRIME = 16777619u;
|
const uint32_t FNV_PRIME = 16777619u;
|
||||||
|
#elif defined(__arm__)
|
||||||
|
static_assert(sizeof(uintptr_t) == sizeof(uint32_t));
|
||||||
|
const uint32_t FNV_OFFSET_BASIS = 2166136261u;
|
||||||
|
const uint32_t FNV_PRIME = 16777619u;
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
static_assert(sizeof(uintptr_t) == sizeof(uint64_t));
|
static_assert(sizeof(uintptr_t) == sizeof(uint64_t));
|
||||||
const uint64_t FNV_OFFSET_BASIS = 14695981039346656037ull;
|
const uint64_t FNV_OFFSET_BASIS = 14695981039346656037ull;
|
||||||
|
@ -79,13 +79,13 @@ namespace std
|
|||||||
|
|
||||||
[[nodiscard]] void *operator new(std::size_t count);
|
[[nodiscard]] void *operator new(std::size_t count);
|
||||||
[[nodiscard]] void *operator new[](std::size_t count);
|
[[nodiscard]] void *operator new[](std::size_t count);
|
||||||
// [[nodiscard]] void *operator new(std::size_t count, std::align_val_t al);
|
[[nodiscard]] void *operator new(std::size_t count, std::align_val_t al);
|
||||||
// [[nodiscard]] void *operator new[](std::size_t count, std::align_val_t al);
|
[[nodiscard]] void *operator new[](std::size_t count, std::align_val_t al);
|
||||||
|
|
||||||
// [[nodiscard]] void *operator new(std::size_t count, const std::nothrow_t &tag) noexcept;
|
[[nodiscard]] void *operator new(std::size_t count, const std::nothrow_t &tag) noexcept;
|
||||||
// [[nodiscard]] void *operator new[](std::size_t count, const std::nothrow_t &tag) noexcept;
|
[[nodiscard]] void *operator new[](std::size_t count, const std::nothrow_t &tag) noexcept;
|
||||||
// [[nodiscard]] void *operator new(std::size_t count, std::align_val_t al, const std::nothrow_t &) noexcept;
|
[[nodiscard]] void *operator new(std::size_t count, std::align_val_t al, const std::nothrow_t &) noexcept;
|
||||||
// [[nodiscard]] void *operator new[](std::size_t count, std::align_val_t al, const std::nothrow_t &) noexcept;
|
[[nodiscard]] void *operator new[](std::size_t count, std::align_val_t al, const std::nothrow_t &) noexcept;
|
||||||
|
|
||||||
[[nodiscard]] void *operator new(std::size_t count, void *ptr) noexcept;
|
[[nodiscard]] void *operator new(std::size_t count, void *ptr) noexcept;
|
||||||
[[nodiscard]] void *operator new[](std::size_t count, void *ptr) noexcept;
|
[[nodiscard]] void *operator new[](std::size_t count, void *ptr) noexcept;
|
||||||
|
@ -62,7 +62,7 @@ EXTERNC int strncmp(const char *s1, const char *s2, size_t n)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXTERNC long unsigned strlen(const char s[])
|
EXTERNC size_t strlen(const char s[])
|
||||||
{
|
{
|
||||||
if (Config.SIMD)
|
if (Config.SIMD)
|
||||||
{
|
{
|
||||||
|
@ -192,7 +192,9 @@ extern "C" __noreturn void __cxa_throw(void *thrown_object,
|
|||||||
Exception->terminateHandler = &terminate_header_stub;
|
Exception->terminateHandler = &terminate_header_stub;
|
||||||
Exception->unwindHeader.exception_cleanup = &exception_cleanup_stub;
|
Exception->unwindHeader.exception_cleanup = &exception_cleanup_stub;
|
||||||
INIT_EXCEPTION_CLASS(&Exception->unwindHeader.exception_class);
|
INIT_EXCEPTION_CLASS(&Exception->unwindHeader.exception_class);
|
||||||
|
#ifndef __arm__
|
||||||
Exception->adjustedPtr = thrown_object;
|
Exception->adjustedPtr = thrown_object;
|
||||||
|
#endif
|
||||||
|
|
||||||
_Unwind_RaiseException(&Exception->unwindHeader);
|
_Unwind_RaiseException(&Exception->unwindHeader);
|
||||||
__cxa_begin_catch(&Exception->unwindHeader);
|
__cxa_begin_catch(&Exception->unwindHeader);
|
||||||
|
@ -134,7 +134,7 @@ void md5Finalize(MD5Context *ctx)
|
|||||||
(uint32_t)(ctx->input[(j * 4)]);
|
(uint32_t)(ctx->input[(j * 4)]);
|
||||||
}
|
}
|
||||||
input[14] = (uint32_t)(ctx->size * 8);
|
input[14] = (uint32_t)(ctx->size * 8);
|
||||||
#ifdef __i386__
|
#if defined(__i386__) || defined(__arm__)
|
||||||
input[15] = (uint32_t)((uint64_t)(((uint64_t)ctx->size >> 32) | ((uint64_t)ctx->size << 32)) >> 32);
|
input[15] = (uint32_t)((uint64_t)(((uint64_t)ctx->size >> 32) | ((uint64_t)ctx->size << 32)) >> 32);
|
||||||
#else
|
#else
|
||||||
input[15] = (uint32_t)((ctx->size * 8) >> 32);
|
input[15] = (uint32_t)((ctx->size * 8) >> 32);
|
||||||
|
@ -42,8 +42,37 @@ void *operator new[](std::size_t count)
|
|||||||
throw std::bad_alloc{};
|
throw std::bad_alloc{};
|
||||||
}
|
}
|
||||||
|
|
||||||
// void *operator new(std::size_t count, std::align_val_t al)
|
void *operator new(std::size_t count, std::align_val_t al)
|
||||||
// void *operator new[](std::size_t count, std::align_val_t al)
|
{
|
||||||
|
if (count == 0)
|
||||||
|
++count;
|
||||||
|
|
||||||
|
std::size_t alignment = static_cast<std::size_t>(al);
|
||||||
|
void *ptr = kmalloc(count + alignment - 1 + sizeof(void *));
|
||||||
|
if (!ptr)
|
||||||
|
throw std::bad_alloc{};
|
||||||
|
|
||||||
|
void *aligned_ptr = reinterpret_cast<void *>(
|
||||||
|
(reinterpret_cast<std::size_t>(ptr) + sizeof(void *) + alignment - 1) & ~(alignment - 1));
|
||||||
|
reinterpret_cast<void **>(aligned_ptr)[-1] = ptr;
|
||||||
|
return aligned_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *operator new[](std::size_t count, std::align_val_t al)
|
||||||
|
{
|
||||||
|
if (count == 0)
|
||||||
|
++count;
|
||||||
|
|
||||||
|
std::size_t alignment = static_cast<std::size_t>(al);
|
||||||
|
void *ptr = kmalloc(count + alignment - 1 + sizeof(void *));
|
||||||
|
if (!ptr)
|
||||||
|
throw std::bad_alloc{};
|
||||||
|
|
||||||
|
void *aligned_ptr = reinterpret_cast<void *>(
|
||||||
|
(reinterpret_cast<std::size_t>(ptr) + sizeof(void *) + alignment - 1) & ~(alignment - 1));
|
||||||
|
reinterpret_cast<void **>(aligned_ptr)[-1] = ptr;
|
||||||
|
return aligned_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
// void *operator new(std::size_t count, const std::nothrow_t &tag)
|
// void *operator new(std::size_t count, const std::nothrow_t &tag)
|
||||||
// void *operator new[](std::size_t count, const std::nothrow_t &tag)
|
// void *operator new[](std::size_t count, const std::nothrow_t &tag)
|
||||||
@ -62,8 +91,24 @@ void operator delete(void *ptr) noexcept { kfree(ptr); }
|
|||||||
|
|
||||||
void operator delete[](void *ptr) noexcept { kfree(ptr); }
|
void operator delete[](void *ptr) noexcept { kfree(ptr); }
|
||||||
|
|
||||||
// void operator delete(void *ptr, std::align_val_t al) noexcept
|
void operator delete(void *ptr, std::align_val_t al) noexcept
|
||||||
// void operator delete[](void *ptr, std::align_val_t al) noexcept
|
{
|
||||||
|
if (!ptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
void *original_ptr = reinterpret_cast<void **>(ptr)[-1];
|
||||||
|
kfree(original_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete[](void *ptr, std::align_val_t al) noexcept
|
||||||
|
{
|
||||||
|
if (!ptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
void *original_ptr = reinterpret_cast<void **>(ptr)[-1];
|
||||||
|
kfree(original_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
void operator delete(void *ptr, std::size_t) noexcept { kfree(ptr); }
|
void operator delete(void *ptr, std::size_t) noexcept { kfree(ptr); }
|
||||||
|
|
||||||
void operator delete[](void *ptr, std::size_t sz) noexcept { kfree(ptr); }
|
void operator delete[](void *ptr, std::size_t sz) noexcept { kfree(ptr); }
|
||||||
|
@ -334,6 +334,24 @@ struct linux_kstat
|
|||||||
__kernel_ulong_t st_ctime_nsec;
|
__kernel_ulong_t st_ctime_nsec;
|
||||||
#undef __unused
|
#undef __unused
|
||||||
__kernel_long_t __unused[3];
|
__kernel_long_t __unused[3];
|
||||||
|
#elif defined(__arm__)
|
||||||
|
__kernel_ulong_t st_dev;
|
||||||
|
__kernel_ulong_t st_ino;
|
||||||
|
__kernel_ulong_t st_nlink;
|
||||||
|
unsigned int st_mode;
|
||||||
|
unsigned int st_uid;
|
||||||
|
unsigned int st_gid;
|
||||||
|
unsigned int __pad0;
|
||||||
|
__kernel_ulong_t st_rdev;
|
||||||
|
__kernel_long_t st_size;
|
||||||
|
__kernel_long_t st_blksize;
|
||||||
|
__kernel_long_t st_blocks;
|
||||||
|
__kernel_ulong_t st_atime;
|
||||||
|
__kernel_ulong_t st_atime_nsec;
|
||||||
|
__kernel_ulong_t st_mtime;
|
||||||
|
__kernel_ulong_t st_mtime_nsec;
|
||||||
|
__kernel_ulong_t st_ctime;
|
||||||
|
__kernel_ulong_t st_ctime_nsec;
|
||||||
#else
|
#else
|
||||||
#error "Unsupported architecture"
|
#error "Unsupported architecture"
|
||||||
#endif
|
#endif
|
||||||
@ -371,7 +389,7 @@ struct __old_kernel_stat
|
|||||||
unsigned short st_uid;
|
unsigned short st_uid;
|
||||||
unsigned short st_gid;
|
unsigned short st_gid;
|
||||||
unsigned short st_rdev;
|
unsigned short st_rdev;
|
||||||
#ifdef __i386__
|
#if defined(__i386__) || defined(__arm__)
|
||||||
unsigned long st_size;
|
unsigned long st_size;
|
||||||
unsigned long st_atime;
|
unsigned long st_atime;
|
||||||
unsigned long st_mtime;
|
unsigned long st_mtime;
|
||||||
|
18
Makefile
18
Makefile
@ -66,6 +66,15 @@ QEMUFLAGS += -M q35 \
|
|||||||
-device intel-hda \
|
-device intel-hda \
|
||||||
-device ich9-intel-hda \
|
-device ich9-intel-hda \
|
||||||
-acpitable file=tools/acpi/SSDT1.dat
|
-acpitable file=tools/acpi/SSDT1.dat
|
||||||
|
else ifeq ($(OSARCH), arm)
|
||||||
|
QEMUFLAGS += -M raspi2b \
|
||||||
|
-monitor pty \
|
||||||
|
-cpu cortex-a15 \
|
||||||
|
-serial file:serial.log \
|
||||||
|
-serial file:COM2.dmp \
|
||||||
|
-serial file:COM3.dmp \
|
||||||
|
-serial stdio \
|
||||||
|
-kernel $(OSNAME).img
|
||||||
else ifeq ($(OSARCH), aarch64)
|
else ifeq ($(OSARCH), aarch64)
|
||||||
QEMUFLAGS += -M raspi3b \
|
QEMUFLAGS += -M raspi3b \
|
||||||
-monitor pty \
|
-monitor pty \
|
||||||
@ -160,7 +169,7 @@ ifeq ($(BOOTLOADER), grub)
|
|||||||
cp tools/grub.cfg iso_tmp_data/boot/grub/
|
cp tools/grub.cfg iso_tmp_data/boot/grub/
|
||||||
grub-mkrescue -o $(OSNAME).iso iso_tmp_data
|
grub-mkrescue -o $(OSNAME).iso iso_tmp_data
|
||||||
endif
|
endif
|
||||||
ifeq ($(OSARCH), aarch64)
|
ifneq ($(filter aarch64 arm,$(OSARCH)),)
|
||||||
$(__CONF_OBJCOPY) Kernel/fennix.elf -O binary $(OSNAME).img
|
$(__CONF_OBJCOPY) Kernel/fennix.elf -O binary $(OSNAME).img
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -179,6 +188,10 @@ ifeq ($(OSARCH), i386)
|
|||||||
QEMU_SMP = -smp $(shell nproc)
|
QEMU_SMP = -smp $(shell nproc)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(OSARCH), arm)
|
||||||
|
QEMU_SMP = -smp 4
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(OSARCH), aarch64)
|
ifeq ($(OSARCH), aarch64)
|
||||||
QEMU_SMP = -smp 4
|
QEMU_SMP = -smp 4
|
||||||
endif
|
endif
|
||||||
@ -189,6 +202,9 @@ QEMUMEMORY = -m 4G
|
|||||||
else ifeq ($(OSARCH), i386)
|
else ifeq ($(OSARCH), i386)
|
||||||
QEMUHWACCELERATION = -machine q35 -enable-kvm
|
QEMUHWACCELERATION = -machine q35 -enable-kvm
|
||||||
QEMUMEMORY = -m 4G
|
QEMUMEMORY = -m 4G
|
||||||
|
else ifeq ($(OSARCH), arm)
|
||||||
|
QEMUHWACCELERATION =
|
||||||
|
QEMUMEMORY = -m 1G
|
||||||
else ifeq ($(OSARCH), aarch64)
|
else ifeq ($(OSARCH), aarch64)
|
||||||
QEMUHWACCELERATION =
|
QEMUHWACCELERATION =
|
||||||
QEMUMEMORY = -m 1G
|
QEMUMEMORY = -m 1G
|
||||||
|
21
Userspace/.vscode/c_cpp_properties.json
vendored
21
Userspace/.vscode/c_cpp_properties.json
vendored
@ -82,6 +82,27 @@
|
|||||||
"-nostdinc++"
|
"-nostdinc++"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Fennix Arm (Linux, GCC, debug)",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/libc/include/**",
|
||||||
|
"${workspaceFolder}/libs/include/**"
|
||||||
|
],
|
||||||
|
"defines": [
|
||||||
|
"__debug_vscode__",
|
||||||
|
"DEBUG=\"1\""
|
||||||
|
],
|
||||||
|
"compilerPath": "${workspaceFolder}/../tools/cross/bin/arm-fennix-gcc",
|
||||||
|
"cStandard": "c17",
|
||||||
|
"cppStandard": "c++20",
|
||||||
|
"intelliSenseMode": "linux-gcc-arm",
|
||||||
|
"configurationProvider": "ms-vscode.makefile-tools",
|
||||||
|
"compilerArgs": [
|
||||||
|
"-ffreestanding",
|
||||||
|
"-nostdinc",
|
||||||
|
"-nostdinc++"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Fennix Aarch64 (Linux, GCC, debug)",
|
"name": "Fennix Aarch64 (Linux, GCC, debug)",
|
||||||
"includePath": [
|
"includePath": [
|
||||||
|
@ -50,7 +50,7 @@ extern "C"
|
|||||||
#define P_tmpdir "/tmp/"
|
#define P_tmpdir "/tmp/"
|
||||||
|
|
||||||
typedef long fpos_t;
|
typedef long fpos_t;
|
||||||
typedef unsigned long size_t;
|
typedef __SIZE_TYPE__ size_t;
|
||||||
|
|
||||||
struct _IO_FILE
|
struct _IO_FILE
|
||||||
{
|
{
|
||||||
|
@ -46,7 +46,7 @@ extern "C"
|
|||||||
long rem;
|
long rem;
|
||||||
} ldiv_t;
|
} ldiv_t;
|
||||||
|
|
||||||
typedef unsigned long size_t;
|
typedef __SIZE_TYPE__ size_t;
|
||||||
// typedef __WCHAR_TYPE__ wchar_t;
|
// typedef __WCHAR_TYPE__ wchar_t;
|
||||||
|
|
||||||
long a64l(const char *);
|
long a64l(const char *);
|
||||||
|
@ -108,7 +108,7 @@ extern "C"
|
|||||||
char __data;
|
char __data;
|
||||||
} pthread_barrier_t;
|
} pthread_barrier_t;
|
||||||
|
|
||||||
typedef unsigned long size_t;
|
typedef __SIZE_TYPE__ size_t;
|
||||||
typedef long ssize_t;
|
typedef long ssize_t;
|
||||||
|
|
||||||
typedef long suseconds_t;
|
typedef long suseconds_t;
|
||||||
|
@ -189,6 +189,15 @@ enum RelocationTypes
|
|||||||
R_AARCH64_RELATIVE = 1027,
|
R_AARCH64_RELATIVE = 1027,
|
||||||
R_AARCH64_TLS_DTPMOD64 = 1028,
|
R_AARCH64_TLS_DTPMOD64 = 1028,
|
||||||
|
|
||||||
|
R_ARM_NONE = 0,
|
||||||
|
R_ARM_COPY = 1024,
|
||||||
|
R_ARM_GLOB_DAT = 1025,
|
||||||
|
R_ARM_JUMP_SLOT = 1026,
|
||||||
|
R_ARM_RELATIVE = 1027,
|
||||||
|
R_ARM_TLS_DTPMOD32 = 1028,
|
||||||
|
R_ARM_TLS_DTPOFF32 = 1029,
|
||||||
|
R_ARM_TLS_TPOFF32 = 1030,
|
||||||
|
|
||||||
#if defined(__x86_64__)
|
#if defined(__x86_64__)
|
||||||
R_NONE = R_X86_64_NONE,
|
R_NONE = R_X86_64_NONE,
|
||||||
R_COPY = R_X86_64_COPY,
|
R_COPY = R_X86_64_COPY,
|
||||||
@ -216,6 +225,15 @@ enum RelocationTypes
|
|||||||
R_DTPMOD64 = R_AARCH64_TLS_DTPMOD64,
|
R_DTPMOD64 = R_AARCH64_TLS_DTPMOD64,
|
||||||
R_DTPOFF64 = R_AARCH64_NONE,
|
R_DTPOFF64 = R_AARCH64_NONE,
|
||||||
R_TPOFF64 = R_AARCH64_NONE,
|
R_TPOFF64 = R_AARCH64_NONE,
|
||||||
|
#elif defined(__arm__)
|
||||||
|
R_NONE = R_ARM_NONE,
|
||||||
|
R_COPY = R_ARM_COPY,
|
||||||
|
R_GLOB_DAT = R_ARM_GLOB_DAT,
|
||||||
|
R_JMP_SLOT = R_ARM_JUMP_SLOT,
|
||||||
|
R_RELATIVE = R_ARM_RELATIVE,
|
||||||
|
R_DTPMOD64 = R_ARM_TLS_DTPMOD32,
|
||||||
|
R_DTPOFF64 = R_ARM_TLS_DTPOFF32,
|
||||||
|
R_TPOFF64 = R_ARM_TLS_TPOFF32,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1002,7 +1020,7 @@ typedef Elf64_Rela Elf_Rela;
|
|||||||
#define ELF_ST_BIND(info) ELF64_ST_BIND(info)
|
#define ELF_ST_BIND(info) ELF64_ST_BIND(info)
|
||||||
#define ELF_ST_TYPE(info) ELF64_ST_TYPE(info)
|
#define ELF_ST_TYPE(info) ELF64_ST_TYPE(info)
|
||||||
#define ELF_ST_INFO(bind, type) ELF64_ST_INFO(bind, type)
|
#define ELF_ST_INFO(bind, type) ELF64_ST_INFO(bind, type)
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__) || defined(__arm__)
|
||||||
typedef Elf32_Addr Elf_Addr;
|
typedef Elf32_Addr Elf_Addr;
|
||||||
typedef Elf32_Half Elf_Half;
|
typedef Elf32_Half Elf_Half;
|
||||||
typedef Elf32_Off Elf_Off;
|
typedef Elf32_Off Elf_Off;
|
||||||
|
@ -128,6 +128,8 @@ __attribute__((naked, used, no_stack_protector)) void _start()
|
|||||||
"call _exit\n"); /* Call _exit */
|
"call _exit\n"); /* Call _exit */
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__)
|
||||||
#warning "i386 _start not implemented"
|
#warning "i386 _start not implemented"
|
||||||
|
#elif defined(__arm__)
|
||||||
|
#warning "arm _start not implemented"
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
#warning "aarch64 _start not implemented"
|
#warning "aarch64 _start not implemented"
|
||||||
#else
|
#else
|
||||||
|
@ -68,6 +68,8 @@ __attribute__((naked, used, no_stack_protector, section(".text"))) void _start()
|
|||||||
"call _exit\n");
|
"call _exit\n");
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__)
|
||||||
#warning "i386 _start not implemented"
|
#warning "i386 _start not implemented"
|
||||||
|
#elif defined(__arm__)
|
||||||
|
#warning "arm _start not implemented"
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
#warning "aarch64 _start not implemented"
|
#warning "aarch64 _start not implemented"
|
||||||
#else
|
#else
|
||||||
|
@ -68,6 +68,8 @@ __attribute__((naked, used, no_stack_protector, section(".text"))) void _start()
|
|||||||
"call _exit\n");
|
"call _exit\n");
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__)
|
||||||
#warning "i386 _start not implemented"
|
#warning "i386 _start not implemented"
|
||||||
|
#elif defined(__arm__)
|
||||||
|
#warning "arm _start not implemented"
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
#warning "aarch64 _start not implemented"
|
#warning "aarch64 _start not implemented"
|
||||||
#else
|
#else
|
||||||
|
@ -19,3 +19,176 @@ double __trunctfdf2(long double a)
|
|||||||
{
|
{
|
||||||
return (double)a;
|
return (double)a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __aeabi_dcmple(long double a, long double b)
|
||||||
|
{
|
||||||
|
return a <= b;
|
||||||
|
}
|
||||||
|
|
||||||
|
long long __aeabi_d2lz(double a)
|
||||||
|
{
|
||||||
|
return (long long)a;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __aeabi_dcmplt(long double a, long double b)
|
||||||
|
{
|
||||||
|
return a < b;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
double d;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
__UINT64_TYPE__ mantissa : 52;
|
||||||
|
__UINT64_TYPE__ exponent : 11;
|
||||||
|
__UINT64_TYPE__ sign : 1;
|
||||||
|
} parts;
|
||||||
|
} aeabi_double_t;
|
||||||
|
|
||||||
|
aeabi_double_t __aeabi_ddiv(aeabi_double_t a, aeabi_double_t b)
|
||||||
|
{
|
||||||
|
aeabi_double_t result;
|
||||||
|
result.d = a.d / b.d;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
aeabi_double_t __aeabi_dmul(aeabi_double_t a, aeabi_double_t b)
|
||||||
|
{
|
||||||
|
aeabi_double_t result;
|
||||||
|
result.d = a.d * b.d;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
aeabi_double_t __aeabi_dadd(aeabi_double_t a, aeabi_double_t b)
|
||||||
|
{
|
||||||
|
aeabi_double_t result;
|
||||||
|
result.d = a.d + b.d;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __aeabi_dcmpgt(aeabi_double_t a, aeabi_double_t b)
|
||||||
|
{
|
||||||
|
return a.d > b.d;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __aeabi_dcmpge(aeabi_double_t a, aeabi_double_t b)
|
||||||
|
{
|
||||||
|
return a.d >= b.d;
|
||||||
|
}
|
||||||
|
|
||||||
|
aeabi_double_t __aeabi_dsub(aeabi_double_t a, aeabi_double_t b)
|
||||||
|
{
|
||||||
|
aeabi_double_t result;
|
||||||
|
result.d = a.d - b.d;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
aeabi_double_t __aeabi_i2d(int a)
|
||||||
|
{
|
||||||
|
aeabi_double_t result;
|
||||||
|
result.d = (double)a;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
aeabi_double_t __aeabi_l2d(long long a)
|
||||||
|
{
|
||||||
|
aeabi_double_t result;
|
||||||
|
result.d = (double)a;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __aeabi_dcmpeq(aeabi_double_t a, aeabi_double_t b)
|
||||||
|
{
|
||||||
|
return a.d == b.d;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __aeabi_d2iz(aeabi_double_t a)
|
||||||
|
{
|
||||||
|
return (int)a.d;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ldivmod_result
|
||||||
|
{
|
||||||
|
long quot;
|
||||||
|
long rem;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ldivmod_result __aeabi_ldivmod(long numerator, long denominator)
|
||||||
|
{
|
||||||
|
struct ldivmod_result result;
|
||||||
|
result.quot = numerator / denominator;
|
||||||
|
result.rem = numerator % denominator;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
signed __aeabi_idiv(signed numerator, signed denominator)
|
||||||
|
{
|
||||||
|
return numerator / denominator;
|
||||||
|
}
|
||||||
|
|
||||||
|
signed __aeabi_idivmod(signed numerator, signed denominator)
|
||||||
|
{
|
||||||
|
signed quotient = numerator / denominator;
|
||||||
|
signed remainder = numerator % denominator;
|
||||||
|
return (quotient << 16) | remainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator)
|
||||||
|
{
|
||||||
|
return numerator / denominator;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned __aeabi_uidivmod(unsigned numerator, unsigned denominator)
|
||||||
|
{
|
||||||
|
unsigned quotient = numerator / denominator;
|
||||||
|
unsigned remainder = numerator % denominator;
|
||||||
|
return (quotient << 16) | remainder;
|
||||||
|
}
|
||||||
|
|
||||||
|
__UINT64_TYPE__ __udivmoddi4(__UINT64_TYPE__ numerator, __UINT64_TYPE__ denominator, __UINT64_TYPE__ *remainder)
|
||||||
|
{
|
||||||
|
__UINT64_TYPE__ quotient = 0;
|
||||||
|
__UINT64_TYPE__ bit = 1;
|
||||||
|
|
||||||
|
if (denominator == 0)
|
||||||
|
{
|
||||||
|
*remainder = numerator;
|
||||||
|
return ~0ULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (denominator < numerator && (denominator & (1ULL << 63)) == 0)
|
||||||
|
{
|
||||||
|
denominator <<= 1;
|
||||||
|
bit <<= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (bit)
|
||||||
|
{
|
||||||
|
if (numerator >= denominator)
|
||||||
|
{
|
||||||
|
numerator -= denominator;
|
||||||
|
quotient |= bit;
|
||||||
|
}
|
||||||
|
denominator >>= 1;
|
||||||
|
bit >>= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remainder)
|
||||||
|
*remainder = numerator;
|
||||||
|
|
||||||
|
return quotient;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct udivmod_result
|
||||||
|
{
|
||||||
|
__UINT64_TYPE__ quot;
|
||||||
|
__UINT64_TYPE__ rem;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct udivmod_result __aeabi_uldivmod(__UINT64_TYPE__ numerator, __UINT64_TYPE__ denominator)
|
||||||
|
{
|
||||||
|
struct udivmod_result result;
|
||||||
|
result.quot = __udivmoddi4(numerator, denominator, &result.rem);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user