Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] arm64 PR #72

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,9 @@ qemu-riscv: fullbuild-plus-full-initrd
qemu-system-$(shell scripts/target-triplet-to-arch.sh $(HOST)) -kernel kernel/vmonyx -m 512M -machine virt \
-serial stdio -s -initrd initrd.tar -smp 4

qemu-arm64: fullbuild-plus-initrd
qemu-arm64: fullbuild-plus-full-initrd
qemu-system-$(shell scripts/target-triplet-to-arch.sh $(HOST)) -kernel kernel/vmonyx -m 512M -machine virt \
-monitor stdio -cpu cortex-a53 -d int -s -no-shutdown -no-reboot -initrd initrd.tar
-cpu cortex-a53 -s -no-shutdown -no-reboot -initrd initrd.tar -serial stdio

qemu: iso
qemu-system-$(shell scripts/target-triplet-to-arch.sh $(HOST)) \
Expand Down
4 changes: 1 addition & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

## A POSIX-like operating system

Onyx is a POSIX-like operating system.

Right now, the only supported architectures are x86_64 and riscv64.
Onyx is a POSIX-like operating system that supports x86_64, arm64 and riscv64.

It's designed to comply to the POSIX standard, implement some of the standard Unix API's while learning from the mistakes the past POSIX OSes made. It follows the System V ABI.

Expand Down
4 changes: 3 additions & 1 deletion kernel/arch/arm64/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
arm64-y:= image.o fpu.o copy_user.o stubs.o vdso_helper.o mmu.o early_mmu.o virt-uart.o entry.o traps.o interrupts.o
arm64-y:= image.o fpu.o copy_user.o stubs.o vdso_helper.o mmu.o early_mmu.o virt-uart.o \
entry.o traps.o interrupts.o irq.o syscall.o usercopy.o scheduler.o timer.o gic.o \
process.o panic.o signal.o

obj-y+= $(patsubst %, arch/arm64/%, $(arm64-y))

Expand Down
125 changes: 101 additions & 24 deletions kernel/arch/arm64/copy_user.S
Original file line number Diff line number Diff line change
@@ -1,27 +1,104 @@
/*
* Copyright (c) 2022 Pedro Falcato
* This file is part of Onyx, and is released under the terms of the MIT License
* check LICENSE at the root directory for more information
*/

/* TODO: Stubs */
.global copy_to_user
.global copy_from_user
.global user_memset
.global get_user64
.global get_user32
.global strlen_user
.type get_user64, @function
.type copy_to_user,@function
.type copy_from_user,@function
.type strlen_user,@function
.type user_memset,@function
.type get_user32,@function
copy_from_user:
strlen_user:
get_user64:
get_user32:
user_memset:
copy_to_user:
* Copyright (c) 2023 Pedro Falcato
* This file is part of Onyx, and is released under the terms of the MIT License
* check LICENSE at the root directory for more information
*
* SPDX-License-Identifier: MIT
*/

/* ssize_t copy_to_user_internal(void *user, const void *data, size_t size); */
.global copy_to_user_internal
.type copy_to_user_internal,@function
copy_to_user_internal:
mov x3, x0
mov x0, xzr
/* x2 = limit, x3 = user, x1 = data, x0 = 0 */
cbz x2, 3f
add x2, x3, x2
1:
ldrb w4, [x1], #1
2:
strb w4, [x3], #1
cmp x2, x3
bne 1b
3:
ret
4:
mov x0, -14
ret

.pushsection .ehtable
.dword 2b
.dword 4b
.popsection


/* ssize_t copy_from_user_internal(void *data, const void *usr, size_t size); */
.global copy_from_user_internal
.type copy_from_user_internal,@function
copy_from_user_internal:
mov x3, x0
mov x0, xzr
/* x2 = limit, x3 = user, x1 = data, x0 = 0 */
cbz x2, 3f
add x2, x3, x2
1:
ldrb w4, [x1], #1
strb w4, [x3], #1
cmp x2, x3
bne 1b
3:
ret
4:
mov x0, -14
ret

.pushsection .ehtable
.dword 1b
.dword 4b
.popsection

/* ssize_t user_memset_internal(void *data, int val, size_t len); */
.global user_memset_internal
.type user_memset_internal,@function
user_memset_internal:
and w1, w1, 0xff
cbz x2, 3f
add x2, x0, x2
1:
strb w1, [x0], #1
cmp x2, x0
bne 1b
3:
mov x0, xzr
ret
4:
mov x0, -14
ret

.pushsection .ehtable
.dword 1b
.dword 4b
.popsection

/* ssize_t strlen_user_internal(const char *user); */
.global strlen_user_internal
.type strlen_user_internal,@function
strlen_user_internal:
mov x1, x0
mov x0, xzr
1:
ldrb w2, [x1], #1
cbz w2, 2f
add x0, x0, 1
b 1b
2:
ret
4:
mov x0, -14
ret

.pushsection .ehtable
.dword 1b
.dword 4b
.popsection
16 changes: 12 additions & 4 deletions kernel/arch/arm64/entry.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 Pedro Falcato
* Copyright (c) 2022 - 2023 Pedro Falcato
* This file is part of Onyx, and is released under the terms of the MIT License
* check LICENSE at the root directory for more information
*
Expand All @@ -23,9 +23,8 @@
extern char percpu_base;

void time_init();
void riscv_cpu_init();
void plic_init();
void arm64_setup_trap_handling();
void arm64_timer_init();

extern "C" void kernel_entry(void *fdt)
{
Expand All @@ -42,7 +41,6 @@ extern "C" void kernel_entry(void *fdt)
vm_update_addresses(arch_high_half);

paging_protect_kernel();
platform_serial_write("Done MMU protection\n", sizeof("Done MMU protection\n"));

vm_late_init();

Expand All @@ -53,4 +51,14 @@ extern "C" void kernel_entry(void *fdt)
console_init();

device_tree::enumerate();

smp::set_number_of_cpus(1);
smp::set_online(0);
}

void init_arch_vdso()
{
vdso_init();
}

INIT_LEVEL_EARLY_CORE_KERNEL_ENTRY(init_arch_vdso);
103 changes: 96 additions & 7 deletions kernel/arch/arm64/fpu.cpp
Original file line number Diff line number Diff line change
@@ -1,32 +1,121 @@
/*
* Copyright (c) 2022 Pedro Falcato
* Copyright (c) 2022 - 2023 Pedro Falcato
* This file is part of Onyx, and is released under the terms of the MIT License
* check LICENSE at the root directory for more information
*
* SPDX-License-Identifier: MIT
*/

#include <onyx/arm64/fpu.h>
#include <onyx/fpu.h>
#include <onyx/init.h>
#include <onyx/mm/slab.h>
#include <onyx/types.h>

// FIXME: STUB
void setup_fpu_area(unsigned char *address)
{
}

void save_fpu(void *address)
{
__asm__ __volatile__("stp q0, q1, [%0, #16 * 0]\n\t"
"stp q2, q3, [%0, #16 * 2]\n\t"
"stp q4, q5, [%0, #16 * 4]\n\t"
"stp q6, q7, [%0, #16 * 6]\n\t"
"stp q8, q9, [%0, #16 * 8]\n\t"
"stp q10, q11, [%0, #16 * 10]\n\t"
"stp q12, q13, [%0, #16 * 12]\n\t"
"stp q14, q15, [%0, #16 * 14]\n\t"
"stp q16, q17, [%0, #16 * 16]\n\t"
"stp q18, q19, [%0, #16 * 18]\n\t"
"stp q20, q21, [%0, #16 * 20]\n\t"
"stp q22, q23, [%0, #16 * 22]\n\t"
"stp q24, q25, [%0, #16 * 24]\n\t"
"stp q26, q27, [%0, #16 * 26]\n\t"
"stp q28, q29, [%0, #16 * 28]\n\t"
"stp q30, q31, [%0, #16 * 30]\n\t"
"mrs x1, fpsr\n\t"
"str w1, [%0, #16 * 32]\n\t"
"mrs x1, fpcr\n\t"
"str w1, [%0, #16 * 32 + 4]\n" ::"r"(address)
: "x1", "memory");
}

void restore_fpu(void *address)
{
__asm__ __volatile__("ldp q0, q1, [%0, #16 * 0]\n\t"
"ldp q2, q3, [%0, #16 * 2]\n\t"
"ldp q4, q5, [%0, #16 * 4]\n\t"
"ldp q6, q7, [%0, #16 * 6]\n\t"
"ldp q8, q9, [%0, #16 * 8]\n\t"
"ldp q10, q11, [%0, #16 * 10]\n\t"
"ldp q12, q13, [%0, #16 * 12]\n\t"
"ldp q14, q15, [%0, #16 * 14]\n\t"
"ldp q16, q17, [%0, #16 * 16]\n\t"
"ldp q18, q19, [%0, #16 * 18]\n\t"
"ldp q20, q21, [%0, #16 * 20]\n\t"
"ldp q22, q23, [%0, #16 * 22]\n\t"
"ldp q24, q25, [%0, #16 * 24]\n\t"
"ldp q26, q27, [%0, #16 * 26]\n\t"
"ldp q28, q29, [%0, #16 * 28]\n\t"
"ldp q30, q31, [%0, #16 * 30]\n\t"
"ldr w1, [%0, #16 * 32]\n\t"
"msr fpsr, x1\n\t"
"ldr w1, [%0, #16 * 32 + 4]\n"
"msr fpcr, x1\n\t" ::"r"(address)
: "x1", "memory");
}

void fpu_ptrace_getfpregs(void *fpregs, struct user_fpregs_struct *regs)
{
}
void fpu_init(void)

static slab_cache *fpu_cache = nullptr;

/**
* @brief Initialize the FPU state slab cache
*
*/
void fpu_init_cache()
{
fpu_cache = kmem_cache_create("fpu-state", sizeof(fpstate), 16, 0, nullptr);
if (!fpu_cache)
panic("Out of memory allocating fpu state");
}

/**
* @brief Allocate an FPU state object from the allocator
*
* @return Pointer to FPU state, or nullptr
*/
void *fpu_allocate_state()
{
return kmem_cache_alloc(fpu_cache, 0);
}

/**
* @brief Free FPU state object
*
* @param state Pointer to state
*/
void fpu_free_state(void *state)
{
kmem_cache_free(fpu_cache, state);
}

void fpu_init()
{
fpu_init_cache();
}
size_t fpu_get_save_size(void)

INIT_LEVEL_EARLY_PLATFORM_ENTRY(fpu_init);

size_t fpu_get_save_size()
{
return 0;
return sizeof(fpstate);
}
size_t fpu_get_save_alignment(void)

size_t fpu_get_save_alignment()
{
return 1;
return 16;
}
Loading