From b7e9fc1513f2c4e3d28dc18d8daf345a1e767d75 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 24 Jan 2020 00:47:43 -0800 Subject: [PATCH] kern: finish implementing assembly init routines --- config/common.mk | 8 ++--- libmesosphere/include/mesosphere.hpp | 1 + .../arch/arm64/init/kern_k_init_arguments.hpp | 34 +++++++++++++++++++ .../arm64/init/kern_k_init_page_table.hpp | 27 +++++++++++++++ .../mesosphere/arch/arm64/kern_cpu.hpp | 13 +++++++ .../init/kern_init_arguments_select.hpp | 29 ++++++++++++++++ 6 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_arguments.hpp create mode 100644 libmesosphere/include/mesosphere/init/kern_init_arguments_select.hpp diff --git a/config/common.mk b/config/common.mk index 937e10d2..db207459 100644 --- a/config/common.mk +++ b/config/common.mk @@ -76,14 +76,14 @@ TARGET := $(notdir $(CURDIR)) BUILD := build DATA := data INCLUDES := include -SOURCES ?= $(foreach d,$(filter-out source/arch source/board,$(wildcard source)),$(call DIR_WILDCARD,$d) $d) +SOURCES ?= source $(foreach d,$(filter-out source/arch source/board source,$(wildcard source)),$(call DIR_WILDCARD,$d) $d) ifneq ($(strip $(wildcard source/$(ATMOSPHERE_ARCH_DIR)/.*)),) -SOURCES += $(call DIR_WILDCARD,source/$(ATMOSPHERE_ARCH_DIR)) +SOURCES += source/$(ATMOSPHERE_ARCH_DIR) $(call DIR_WILDCARD,source/$(ATMOSPHERE_ARCH_DIR)) endif ifneq ($(strip $(wildcard source/$(ATMOSPHERE_BOARD_DIR)/.*)),) -SOURCES += $(call DIR_WILDCARD,source/$(ATMOSPHERE_BOARD_DIR)) +SOURCES += source/$(ATMOSPHERE_BOARD_DIR $(call DIR_WILDCARD,source/$(ATMOSPHERE_BOARD_DIR)) endif ifneq ($(strip $(wildcard source/$(ATMOSPHERE_OS_DIR)/.*)),) -SOURCES += $(call DIR_WILDCARD,source/$(ATMOSPHERE_OS_DIR)) +SOURCES += source/$(ATMOSPHERE_OS_DIR $(call DIR_WILDCARD,source/$(ATMOSPHERE_OS_DIR)) endif diff --git a/libmesosphere/include/mesosphere.hpp b/libmesosphere/include/mesosphere.hpp index 135b6b5a..3371f426 100644 --- a/libmesosphere/include/mesosphere.hpp +++ b/libmesosphere/include/mesosphere.hpp @@ -32,6 +32,7 @@ #include "mesosphere/init/kern_init_elf.hpp" #include "mesosphere/init/kern_init_layout.hpp" #include "mesosphere/init/kern_init_page_table_select.hpp" +#include "mesosphere/init/kern_init_arguments_select.hpp" /* Core functionality. */ #include "mesosphere/kern_select_interrupts.hpp" diff --git a/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_arguments.hpp b/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_arguments.hpp new file mode 100644 index 00000000..cdddbc13 --- /dev/null +++ b/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_arguments.hpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 this program. If not, see . + */ +#pragma once + +namespace ams::kern::init { + + struct KInitArguments { + u64 ttbr0; + u64 ttbr1; + u64 tcr; + u64 mair; + u64 cpuactlr; + u64 cpuectlr; + u64 sctlr; + u64 sp; + u64 entrypoint; + u64 argument; + u64 setup_function; + }; + +} \ No newline at end of file diff --git a/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp b/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp index 96d7296b..58a0c153 100644 --- a/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp +++ b/libmesosphere/include/mesosphere/arch/arm64/init/kern_k_init_page_table.hpp @@ -495,4 +495,31 @@ namespace ams::kern::init { }; + class KInitialPageAllocator : public KInitialPageTable::IPageAllocator { + private: + uintptr_t next_address; + public: + constexpr ALWAYS_INLINE KInitialPageAllocator() : next_address(Null) { /* ... */ } + + ALWAYS_INLINE void Initialize(uintptr_t address) { + this->next_address = address; + } + + ALWAYS_INLINE uintptr_t GetFinalState() { + const uintptr_t final_address = this->next_address; + this->next_address = Null; + return final_address; + } + public: + virtual KPhysicalAddress Allocate() override { + MESOSPHERE_ABORT_UNLESS(this->next_address != Null); + const uintptr_t allocated = this->next_address; + this->next_address += PageSize; + std::memset(reinterpret_cast(allocated), 0, PageSize); + return allocated; + } + + /* No need to override free. The default does nothing, and so would we. */ + }; + } diff --git a/libmesosphere/include/mesosphere/arch/arm64/kern_cpu.hpp b/libmesosphere/include/mesosphere/arch/arm64/kern_cpu.hpp index 1e1610c9..86412c3a 100644 --- a/libmesosphere/include/mesosphere/arch/arm64/kern_cpu.hpp +++ b/libmesosphere/include/mesosphere/arch/arm64/kern_cpu.hpp @@ -19,6 +19,19 @@ namespace ams::kern::arm64::cpu { +#if defined(ATMOSPHERE_CPU_ARM_CORTEX_A57) || defined(ATMOSPHERE_CPU_ARM_CORTEX_A53) + constexpr inline size_t InstructionCacheLineSize = 0x40; + constexpr inline size_t DataCacheLineSize = 0x40; +#else + #error "Unknown CPU for cache line sizes" +#endif + +#if defined(ATMOSPHERE_BOARD_NINTENDO_SWITCH) + static constexpr size_t NumCores = 4; +#else + #error "Unknown Board for cpu::NumCores" +#endif + /* Helpers for managing memory state. */ ALWAYS_INLINE void DataSynchronizationBarrier() { __asm__ __volatile__("dsb sy" ::: "memory"); diff --git a/libmesosphere/include/mesosphere/init/kern_init_arguments_select.hpp b/libmesosphere/include/mesosphere/init/kern_init_arguments_select.hpp new file mode 100644 index 00000000..6c124528 --- /dev/null +++ b/libmesosphere/include/mesosphere/init/kern_init_arguments_select.hpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018-2019 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 this program. If not, see . + */ +#pragma once +#include + +#ifdef ATMOSPHERE_ARCH_ARM64 + #include "../arch/arm64/init/kern_k_init_arguments.hpp" +#else + #error "Unknown architecture for KInitArguments" +#endif + +namespace ams::kern::init { + + KPhysicalAddress GetInitArgumentsAddress(s32 core_id); + +}