exo2: Initial work on the exosphere rewrite.

exo2: Implement uncompressor stub and boot code up to Main().

exo2: implement some more init (uart/gic)

exo2: implement more of init

exo2: improve reg api, add keyslot flag setters

exo2: implement se aes decryption/enc

exo2: fix bugs in loader stub/mmu mappings

exo2: start skeletoning bootconfig/global context types

arch: fix makefile flags

exo2: implement through master key derivation

exo2: implement device master keygen

exo2: more init through start of SetupSocSecurity

exo2: implement pmc secure scratch management

se: implement sticky bit validation

libexosphere: fix building for arm32

libexo: fix makefile flags

libexo: support building for arm64/arm

sc7fw: skeleton binary

sc7fw: skeleton a little more

sc7fw: implement all non-dram functionality

exo2: fix DivideUp error

sc7fw: implement more dram code, fix reg library errors

sc7fw: complete sc7fw impl.

exo2: skeleton the rest of SetupSocSecurity

exo2: implement fiq interrupt handler

exo2: implement all exception handlers

exo2: skeleton the entire smc api, implement the svc invoker

exo2: implement rest of SetupSocSecurity

exo2: correct slave security errors

exo2: fix register definition

exo2: minor fixes
This commit is contained in:
Michael Scire
2020-05-04 23:33:16 -07:00
committed by SciresM
parent 71e0102f7a
commit f66b41c027
192 changed files with 15093 additions and 24 deletions

View File

@@ -0,0 +1,47 @@
/*
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
*/
#include <exosphere.hpp>
#include "secmon_loader_error.hpp"
namespace ams::diag {
NORETURN void AbortImpl(const char *file, int line, const char *func, const char *expr, u64 value, const char *format, ...) {
ams::secmon::loader::ErrorReboot();
}
NORETURN void AbortImpl(const char *file, int line, const char *func, const char *expr, u64 value) {
ams::secmon::loader::ErrorReboot();
}
NORETURN void AbortImpl() {
ams::secmon::loader::ErrorReboot();
}
}
namespace ams::secmon::loader {
NORETURN void ErrorReboot() {
/* Invalidate the security engine. */
/* TODO */
/* Reboot. */
while (true) {
wdt::Reboot();
}
}
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
*/
#include <exosphere.hpp>
#pragma once
namespace ams::secmon::loader {
NORETURN void ErrorReboot();
}

View File

@@ -0,0 +1,41 @@
/*
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
*/
#include <exosphere.hpp>
#include "secmon_loader_uncompress.hpp"
#include "program_lz4.h"
#include "boot_code_lz4.h"
namespace ams::secmon::loader {
NORETURN void UncompressAndExecute() {
/* Uncompress the program image. */
Uncompress(secmon::MemoryRegionPhysicalTzramFullProgramImage.GetPointer(), secmon::MemoryRegionPhysicalTzramFullProgramImage.GetSize(), program_lz4, program_lz4_size);
/* Copy the boot image to the end of IRAM */
u8 *relocated_boot_code = secmon::MemoryRegionPhysicalIramBootCodeImage.GetEndPointer<u8>() - boot_code_lz4_size;
std::memcpy(relocated_boot_code, boot_code_lz4, boot_code_lz4_size);
/* Uncompress the boot image. */
Uncompress(secmon::MemoryRegionPhysicalIramBootCodeImage.GetPointer(), secmon::MemoryRegionPhysicalIramBootCodeImage.GetSize(), relocated_boot_code, boot_code_lz4_size);
/* Jump to the boot image. */
reinterpret_cast<void (*)()>(secmon::MemoryRegionPhysicalIramBootCodeImage.GetAddress())();
/* We will never reach this point. */
__builtin_unreachable();
}
}

View File

@@ -0,0 +1,103 @@
/*
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
*/
#include <exosphere.hpp>
#include "secmon_loader_uncompress.hpp"
namespace ams::secmon::loader {
namespace {
class Lz4Uncompressor {
private:
const u8 *src;
size_t src_size;
size_t src_offset;
u8 *dst;
size_t dst_size;
size_t dst_offset;
public:
Lz4Uncompressor(void *dst, size_t dst_size, const void *src, size_t src_size) : src(static_cast<const u8 *>(src)), src_size(src_size), src_offset(0), dst(static_cast<u8 *>(dst)), dst_size(dst_size), dst_offset(0) {
/* ... */
}
void Uncompress() {
while (true) {
/* Read a control byte. */
u8 control = this->ReadByte();
/* Copy what it specifies we should copy. */
this->Copy(this->GetCopySize(control >> 4));
/* If we've exceeded size, we're done. */
if (this->src_offset >= this->src_size) {
break;
}
/* Read the wide copy offset. */
u16 wide_offset = this->ReadByte();
AMS_ABORT_UNLESS(this->CanRead());
wide_offset |= (this->ReadByte() << 8);
/* Determine the copy size. */
const size_t wide_copy_size = this->GetCopySize(control & 0xF);
/* Copy bytes. */
const size_t end_offset = this->dst_offset + wide_copy_size + 4;
for (size_t cur_offset = this->dst_offset; cur_offset < end_offset; this->dst_offset = (++cur_offset)) {
AMS_ABORT_UNLESS(wide_offset <= cur_offset);
this->dst[cur_offset] = this->dst[cur_offset - wide_offset];
}
}
}
private:
u8 ReadByte() {
return this->src[this->src_offset++];
}
bool CanRead() const {
return this->src_offset < this->src_size;
}
size_t GetCopySize(u8 control) {
size_t size = control;
if (control >= 0xF) {
do {
AMS_ABORT_UNLESS(this->CanRead());
control = this->ReadByte();
size += control;
} while (control == 0xFF);
}
return size;
}
void Copy(size_t size) {
__builtin_memcpy(this->dst + this->dst_offset, this->src + this->src_offset, size);
this->dst_offset += size;
this->src_offset += size;
}
};
}
void Uncompress(void *dst, size_t dst_size, const void *src, size_t src_size) {
/* Create an execute a decompressor. */
Lz4Uncompressor(dst, dst_size, src, src_size).Uncompress();
}
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
*/
#include <vapours.hpp>
#pragma once
namespace ams::secmon::loader {
void Uncompress(void *dst, size_t dst_size, const void *src, size_t src_size);
}

View File

@@ -0,0 +1,105 @@
/*
* Copyright (c) 2018-2020 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 <http://www.gnu.org/licenses/>.
*/
/* For some reason GAS doesn't know about it, even with .cpu cortex-a57 */
#define cpuactlr_el1 s3_1_c15_c2_0
#define cpuectlr_el1 s3_1_c15_c2_1
.macro RESET_CORE
mov x0, #(1 << 63)
msr cpuactlr_el1, x0 /* disable regional clock gating */
isb
mov x0, #3
msr rmr_el3, x0
isb
dsb sy
/* Nintendo forgot to copy-paste the branch instruction below. */
1:
wfi
b 1b
.endm
.macro ERRATUM_INVALIDATE_BTB_AT_BOOT
/* Nintendo copy-pasted https://github.com/ARM-software/arm-trusted-firmware/blob/master/plat/nvidia/tegra/common/aarch64/tegra_helpers.S#L312 */
/*
* Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/* The following comments are mine. */
/*
Enable invalidates of branch target buffer, then flush
the entire instruction cache at the local level, and
with the reg change, the branch target buffer, then disable
invalidates of the branch target buffer again.
*/
mrs x0, cpuactlr_el1
orr x0, x0, #1
msr cpuactlr_el1, x0
dsb sy
isb
ic iallu
dsb sy
isb
mrs x0, cpuactlr_el1
bic x0, x0, #1
msr cpuactlr_el1, x0
.rept 7
nop /* wait long enough for the write to cpuactlr_el1 to have completed */
.endr
/* if the OS lock is set, disable it and request a warm reset */
mrs x0, oslsr_el1
ands x0, x0, #2
b.eq 2f
mov x0, xzr
msr oslar_el1, x0
RESET_CORE
.rept 65
nop /* guard against speculative excecution */
.endr
2:
/* set the OS lock */
mov x0, #1
msr oslar_el1, x0
.endm
.section .crt0.text.start, "ax", %progbits
.align 6
.global _start
_start:
/* mask all interrupts */
msr daifset, #0xF
/* Fixup hardware erratum */
ERRATUM_INVALIDATE_BTB_AT_BOOT
/* Set the stack pointer to a temporary location. */
ldr x20, =0x7C010800
mov sp, x20
/* Call our init array functions. */
bl __libc_init_array
/* Uncompress the program and iram boot code images. */
b _ZN3ams6secmon6loader20UncompressAndExecuteEv