mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 20:31:14 +00:00
Move source files to src/, add Makefile, fix all build and linkage errors, etc.
This commit is contained in:
parent
4c7aa566f0
commit
b0ea9c1a0b
58 changed files with 385 additions and 203 deletions
71
exosphere/Makefile
Normal file
71
exosphere/Makefile
Normal file
|
@ -0,0 +1,71 @@
|
|||
rwildcard = $(foreach d, $(wildcard $1*), $(filter $(subst *, %, $2), $d) $(call rwildcard, $d/, $2))
|
||||
|
||||
ifeq ($(strip $(DEVKITPRO)),)
|
||||
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
|
||||
endif
|
||||
|
||||
include $(DEVKITPRO)/devkitA64/base_tools
|
||||
|
||||
name := exosphere
|
||||
|
||||
dir_source := src
|
||||
dir_build := build
|
||||
dir_out := out
|
||||
dir_bpmpfw := bpmpfw
|
||||
|
||||
ARCH := -march=armv8-a -mtune=cortex-a57
|
||||
|
||||
ASFLAGS := -g $(ARCH)
|
||||
|
||||
CFLAGS = \
|
||||
$(ARCH) \
|
||||
-g \
|
||||
-O2 \
|
||||
-ffunction-sections \
|
||||
-fdata-sections \
|
||||
-fomit-frame-pointer \
|
||||
-std=gnu11 \
|
||||
-Werror \
|
||||
-Wall
|
||||
|
||||
LDFLAGS = -g $(ARCH) -nostartfiles -Wl,--nmagic,--gc-sections
|
||||
|
||||
objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
|
||||
$(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
|
||||
$(call rwildcard, $(dir_source), *.s *.c)))
|
||||
|
||||
.PHONY: all
|
||||
all: $(dir_out)/$(name).bin
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
@$(MAKE) -C $(dir_bpmpfw) clean
|
||||
@rm -rf $(dir_build)
|
||||
@rm -rf $(dir_out)
|
||||
|
||||
.PHONY: $(dir_bpmpfw)
|
||||
|
||||
$(dir_out)/$(name).bin: $(dir_build)/$(name).elf
|
||||
@mkdir -p "$(@D)"
|
||||
$(OBJCOPY) -S -O binary $< $@
|
||||
|
||||
$(dir_build)/$(name).elf: $(objects)
|
||||
$(LINK.o) -T linker.ld $(OUTPUT_OPTION) $^
|
||||
|
||||
$(dir_bpmpfw)/out/bpmpfw.bin: $(dir_bpmpfw)
|
||||
@$(MAKE) -C $<
|
||||
|
||||
$(dir_build)/bpmpfw.bin: $(dir_bpmpfw)/out/bpmpfw.bin
|
||||
@mkdir -p "$(@D)"
|
||||
@cp $< $(@D)
|
||||
|
||||
$(dir_build)/%.bin.o: $(dir_build)/%.bin
|
||||
@$(bin2o)
|
||||
|
||||
$(dir_build)/%.o: $(dir_source)/%.c $(dir_build)/bpmpfw.bin.o
|
||||
@mkdir -p "$(@D)"
|
||||
$(COMPILE.c) $(OUTPUT_OPTION) $<
|
||||
|
||||
$(dir_build)/%.o: $(dir_source)/%.s
|
||||
@mkdir -p "$(@D)"
|
||||
$(COMPILE.c) -x assembler-with-cpp $(OUTPUT_OPTION) $<
|
|
@ -6,7 +6,7 @@ endif
|
|||
|
||||
include $(DEVKITARM)/base_tools
|
||||
|
||||
name := $(shell basename $(CURDIR))
|
||||
name := bpmpfw
|
||||
|
||||
dir_source := src
|
||||
dir_build := build
|
||||
|
|
BIN
exosphere/build/bpmpfw.bin
Normal file
BIN
exosphere/build/bpmpfw.bin
Normal file
Binary file not shown.
16
exosphere/linker.ld
Normal file
16
exosphere/linker.ld
Normal file
|
@ -0,0 +1,16 @@
|
|||
ENTRY(__start_cold)
|
||||
SECTIONS
|
||||
{
|
||||
/* DUMMY LINKER SCRIPT, REPLACE ASAP */
|
||||
. = 0xF0000000;
|
||||
|
||||
__start__ = ABSOLUTE(.);
|
||||
|
||||
.text : ALIGN(4) { *(.text*); . = ALIGN(4); }
|
||||
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
||||
.data : ALIGN(4) { *(.data*); . = ALIGN(8); *(.bss* COMMON); . = ALIGN(8); }
|
||||
|
||||
. = ALIGN(4);
|
||||
|
||||
__end__ = ABSOLUTE(.);
|
||||
}
|
BIN
exosphere/out/exosphere.bin
Normal file
BIN
exosphere/out/exosphere.bin
Normal file
Binary file not shown.
40
exosphere/src/bootconfig.c
Normal file
40
exosphere/src/bootconfig.c
Normal file
|
@ -0,0 +1,40 @@
|
|||
#include "bootconfig.h"
|
||||
|
||||
void bootconfig_load_and_verify(const bootconfig_t *bootconfig) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void bootconfig_clear(void){
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* Actual configuration getters. */
|
||||
bool bootconfig_is_package2_plaintext(void) {
|
||||
return false;
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
bool bootconfig_is_package2_unsigned(void) {
|
||||
return false;
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
bool bootconfig_disable_program_verification(void) {
|
||||
return false;
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
bool bootconfig_is_debug_mode(void) {
|
||||
return false;
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
uint64_t bootconfig_get_memory_arrangement(void) {
|
||||
return 0ULL;
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
uint64_t bootconfig_get_kernel_memory_configuration(void) {
|
||||
return 0ULL;
|
||||
/* TODO */
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
void tlb_invalidate_all(void);
|
||||
void tlb_invalidate_all_inner_shareable(void);
|
||||
|
||||
void tlb_invalidate_page(const void *page);
|
||||
void tlb_invalidate_page(const volatile void *page);
|
||||
void tlb_invalidate_page_inner_shareable(const void *page);
|
||||
|
||||
void flush_dcache_all(void);
|
|
@ -2,6 +2,7 @@
|
|||
#include "mmu.h"
|
||||
#include "memory_map.h"
|
||||
|
||||
/*
|
||||
extern void (*__preinit_array_start[])(void);
|
||||
extern void (*__preinit_array_end[])(void);
|
||||
extern void (*__init_array_start[])(void);
|
||||
|
@ -11,7 +12,7 @@ extern void _init(void);
|
|||
extern uint8_t __warmboot_crt0_start__[], __warmboot_crt0_end__[], __warmboot_crt0_lma__[];
|
||||
extern uint8_t __main_start__[], __main_end__[], __main_lma__[];
|
||||
extern uint8_t __pk2ldr_start__[], __pk2ldr_end__[], __pk2ldr_lma__[];
|
||||
extern uint8_t __vectors_start__[], __vectors_end__[], __vectors_lma__[];
|
||||
extern uint8_t __vectors_start__[], __vectors_end__[], __vectors_lma__[];*/
|
||||
extern void flush_dcache_all_tzram_pa(void);
|
||||
extern void invalidate_icache_all_tzram_pa(void);
|
||||
|
||||
|
@ -44,6 +45,8 @@ static void configure_ttbls(void) {
|
|||
tzram_map_all_segments(mmu_l3_tbl);
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
static void copy_lma_to_vma(unsigned int segment_id, void *lma, size_t size, bool vma_is_pa) {
|
||||
uintptr_t vma = vma_is_pa ? tzram_get_segment_pa(segment_id) : tzram_get_segment_address(segment_id);
|
||||
uintptr_t vma_offset = (uintptr_t)lma & 0xFFF;
|
||||
|
@ -61,6 +64,7 @@ static void __libc_init_array(void) {
|
|||
for (size_t i = 0; i < __init_array_end - __init_array_start; i++)
|
||||
__init_array_start[i]();
|
||||
}
|
||||
#endif
|
||||
|
||||
uintptr_t get_coldboot_crt0_stack_address(void) {
|
||||
return tzram_get_segment_pa(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x800;
|
||||
|
@ -68,18 +72,18 @@ uintptr_t get_coldboot_crt0_stack_address(void) {
|
|||
|
||||
void coldboot_init(void) {
|
||||
/* TODO: Set NX BOOTLOADER clock time field */
|
||||
copy_lma_to_vma(TZRAM_SEGMENT_ID_WARMBOOT_CRT0_AND_MAIN, __warmboot_crt0_lma__, __warmboot_crt0_end__ - __warmboot_crt0_start__, true);
|
||||
/*copy_lma_to_vma(TZRAM_SEGMENT_ID_WARMBOOT_CRT0_AND_MAIN, __warmboot_crt0_lma__, __warmboot_crt0_end__ - __warmboot_crt0_start__, true);*/
|
||||
/* TODO: set some mmio regs, etc. */
|
||||
/* TODO: initialize DMA controllers */
|
||||
configure_ttbls();
|
||||
copy_lma_to_vma(TZRAM_SEGMENT_ID_WARMBOOT_CRT0_AND_MAIN, __main_lma__, __main_end__ - __main_start__, false);
|
||||
/*copy_lma_to_vma(TZRAM_SEGMENT_ID_WARMBOOT_CRT0_AND_MAIN, __main_lma__, __main_end__ - __main_start__, false);
|
||||
copy_lma_to_vma(TZRAM_SEGMENT_ID_PK2LDR, __pk2ldr_lma__, __pk2ldr_end__ - __pk2ldr_start__, false);
|
||||
copy_lma_to_vma(TZRAM_SEGEMENT_ID_SECMON_EVT, __vectors_lma__, __vectors_end__ - __vectors_start__, false);
|
||||
copy_lma_to_vma(TZRAM_SEGEMENT_ID_SECMON_EVT, __vectors_lma__, __vectors_end__ - __vectors_start__, false);*/
|
||||
/* TODO: set the MMU regs & tlbi & enable MMU */
|
||||
|
||||
flush_dcache_all_tzram_pa();
|
||||
invalidate_icache_all_tzram_pa();
|
||||
/* TODO: zero-initialize the cpu context */
|
||||
/* Nintendo clears the (emtpy) pk2ldr's BSS section, but we embed it 0-filled in the binary */
|
||||
__libc_init_array(); /* construct global objects */
|
||||
/*__libc_init_array(); construct global objects */
|
||||
}
|
|
@ -2,10 +2,12 @@
|
|||
#include "utils.h"
|
||||
#include "mmu.h"
|
||||
#include "memory_map.h"
|
||||
#include "cache.h"
|
||||
|
||||
/*
|
||||
extern void (*__fini_array_start[])(void);
|
||||
extern void (*__fini_array_end[])(void);
|
||||
extern void _fini(void);
|
||||
extern void _fini(void);*/
|
||||
|
||||
extern uint8_t __pk2ldr_start__[], __pk2ldr_end__[];
|
||||
|
||||
|
@ -13,21 +15,25 @@ extern void __jump_to_lower_el(uint64_t arg, uintptr_t ep, unsigned int el);
|
|||
|
||||
void coldboot_main(void);
|
||||
|
||||
#if 0
|
||||
/* Needs to be called for EL3->EL3 chainloading (and only in that case). TODO: use it */
|
||||
static void __libc_fini_array(void) __attribute__((used)) {
|
||||
__attribute__((used)) static void __libc_fini_array(void) {
|
||||
for (size_t i = __fini_array_end - __fini_array_start; i > 0; i--)
|
||||
__fini_array_start[i - 1]();
|
||||
_fini(); /* FIXME: do we have this gcc-provided symbol if we build with -nostartfiles? */
|
||||
}
|
||||
#endif
|
||||
|
||||
void coldboot_main(void) {
|
||||
#if 0
|
||||
uintptr_t *mmu_l3_table = (uintptr_t *)tzram_get_segment_address(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
|
||||
void *pk2ldr = (void *)tzram_get_segment_address(TZRAM_SEGMENT_ID_PK2LDR);
|
||||
uintptr_t pk2ldr = tzram_get_segment_address(TZRAM_SEGMENT_ID_PK2LDR);
|
||||
|
||||
/* Clear and unmap pk2ldr (which is reused as exception entry stacks) */
|
||||
memset(pk2ldr, 0, __pk2ldr_end__ - __pk2ldr_start__);
|
||||
mmu_unmap_range(mmu_l3_table, pk2ldr, __pk2ldr_end__ - __pk2ldr_start__);
|
||||
memset((void *)pk2ldr, 0, __pk2ldr_end__ - __pk2ldr_start__);
|
||||
mmu_unmap_range(3, mmu_l3_table, pk2ldr, __pk2ldr_end__ - __pk2ldr_start__);
|
||||
tlb_invalidate_all_inner_shareable();
|
||||
#endif
|
||||
|
||||
/* TODO: stuff & jump to lower EL */
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
#include "interrupt.h"
|
||||
#include "package2.h"
|
||||
#include "se.h"
|
||||
#include "fuse.h"
|
||||
#include "utils.h"
|
||||
|
||||
int g_battery_profile = 0;
|
||||
|
@ -15,6 +16,7 @@ uint32_t configitem_set(enum ConfigItem item, uint64_t value) {
|
|||
}
|
||||
|
||||
g_battery_profile = ((int)(value != 0)) & 1;
|
||||
return 0; /* FIXME: what should we return there */
|
||||
}
|
||||
|
||||
bool configitem_is_recovery_boot(void) {
|
|
@ -56,3 +56,15 @@ uint32_t cpu_on(uint32_t core, uint64_t entrypoint_addr, uint64_t context_id) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint32_t cpu_off(void) {
|
||||
return 0;
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint_addr, uint64_t context_id) {
|
||||
(void)power_state;
|
||||
(void)entrypoint_addr;
|
||||
(void)context_id;
|
||||
return 0;
|
||||
/* TODO */
|
||||
}
|
|
@ -47,8 +47,8 @@ typedef struct {
|
|||
void set_core_entrypoint_and_context_id(uint32_t core, uint64_t entrypoint_addr, uint64_t context_id);
|
||||
|
||||
uint32_t cpu_on(uint32_t core, uint64_t entrypoint_addr, uint64_t context_id);
|
||||
uint32_t cpu_off(void);
|
||||
uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint_addr, uint64_t context_id);
|
||||
uint32_t cpu_off(void); /* TODO */
|
||||
uint32_t cpu_suspend(uint64_t power_state, uint64_t entrypoint_addr, uint64_t context_id); /* TODO */
|
||||
|
||||
|
||||
#endif
|
|
@ -50,9 +50,6 @@
|
|||
.endif
|
||||
.endm
|
||||
|
||||
|
||||
|
||||
|
||||
/* Actual Vectors for Exosphere. */
|
||||
.global exosphere_vectors
|
||||
vector_base exosphere_vectors
|
||||
|
@ -69,32 +66,32 @@ vector_entry synch_sp0
|
|||
|
||||
vector_entry irq_sp0
|
||||
b unknown_exception
|
||||
check_vector irq_sp0
|
||||
check_vector_size irq_sp0
|
||||
|
||||
vector_entry fiq_sp0
|
||||
b unknown_exception
|
||||
check_vector fiq_sp0
|
||||
check_vector_size fiq_sp0
|
||||
|
||||
vector_entry serror_sp0
|
||||
b unknown_exception
|
||||
check_vector serror_sp0
|
||||
check_vector_size serror_sp0
|
||||
|
||||
/* Current EL, SPx */
|
||||
vector_entry synch_spx
|
||||
b unknown_exception
|
||||
check_vector synch_spx
|
||||
check_vector_size synch_spx
|
||||
|
||||
vector_entry irq_spx
|
||||
b unknown_exception
|
||||
check_vector irq_spx
|
||||
check_vector_size irq_spx
|
||||
|
||||
vector_entry fiq_spx
|
||||
b unknown_exception
|
||||
check_vector fiq_spx
|
||||
check_vector_size fiq_spx
|
||||
|
||||
vector_entry serror_spx
|
||||
b unknown_exception
|
||||
check_vector serror_spx
|
||||
check_vector_size serror_spx
|
||||
|
||||
/* Lower EL, A64 */
|
||||
vector_entry synch_a64
|
||||
|
@ -108,22 +105,22 @@ vector_entry synch_a64
|
|||
/* Call appropriate handler. */
|
||||
stp x29, x30, [sp, #-0x10]!
|
||||
mrs x29, mpidr_el1
|
||||
and x29, x39, #0x3
|
||||
and x29, x29, #0x3
|
||||
cmp x29, #0x3
|
||||
b.ne handle_core012_smc_exception
|
||||
bl handle_core3_smc_exception
|
||||
ldp x29, x30, [sp],#0x10
|
||||
eret
|
||||
check_vector synch_a64
|
||||
check_vector_size synch_a64
|
||||
|
||||
vector_entry irq_a64
|
||||
b unknown_exception
|
||||
check_vector irq_a64
|
||||
check_vector_size irq_a64
|
||||
|
||||
vector_entry fiq_a64
|
||||
stp x29, x30, [sp, #-0x10]!
|
||||
mrs x29, mpidr_el1
|
||||
and x29, x39, #0x3
|
||||
and x29, x29, #0x3
|
||||
cmp x29, #0x3
|
||||
b.ne unknown_exception
|
||||
stp x28, x29, [sp, #-0x10]!
|
||||
|
@ -133,7 +130,7 @@ vector_entry fiq_a64
|
|||
ldp x28, x29, [sp],#0x10
|
||||
ldp x29, x30, [sp],#0x10
|
||||
eret
|
||||
check_vector fiq_a64
|
||||
check_vector_size fiq_a64
|
||||
|
||||
vector_entry serror_a64
|
||||
b unknown_exception
|
||||
|
@ -171,18 +168,15 @@ handle_core012_smc_exception:
|
|||
ldp x6, x7, [sp],#0x10
|
||||
ldp x29, x30, [sp],#0x10
|
||||
eret
|
||||
.if (. - serror_a64) > (32 * 4)
|
||||
.error "Vector exceeds 32 instructions"
|
||||
.endif
|
||||
|
||||
/* Lower EL, A32 */
|
||||
vector_entry synch_a32
|
||||
b unknown_exception
|
||||
check_vector synch_a32
|
||||
check_vector_size synch_a32
|
||||
|
||||
vector_entry irq_a32
|
||||
b unknown_exception
|
||||
check_vector irq_a32
|
||||
check_vector_size irq_a32
|
||||
|
||||
vector_entry fiq_a32
|
||||
b fiq_a64
|
||||
|
@ -222,9 +216,6 @@ handle_fiq_exception:
|
|||
ldp x24, x25, [sp],#0x10
|
||||
ldp x29, x30, [sp],#0x10
|
||||
ret
|
||||
.if (. - fiq_a32) > (32 * 4)
|
||||
.error "Vector exceeds 32 instructions"
|
||||
.endif
|
||||
|
||||
vector_entry serror_a32
|
||||
b unknown_exception
|
||||
|
@ -260,6 +251,3 @@ handle_core3_smc_exception:
|
|||
ldp x16, x17, [sp],#0x10
|
||||
ldp x18, x19, [sp],#0x10
|
||||
ret
|
||||
.if (. - serror_a32) > (32 * 4)
|
||||
.error "Vector exceeds 32 instructions"
|
||||
.endif
|
|
@ -1,5 +1,3 @@
|
|||
#include <stbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fuse.h"
|
||||
|
@ -25,7 +23,7 @@ void fuse_init(void)
|
|||
void fuse_make_regs_visible(void)
|
||||
{
|
||||
/* TODO: Replace this with a proper CLKRST driver */
|
||||
uint32_t* misc_clk_reg = (volatile uint32_t *)mmio_get_device_address(MMIO_DEVID_CLKRST) + 0x48;
|
||||
volatile uint32_t* misc_clk_reg = (volatile uint32_t *)mmio_get_device_address(MMIO_DEVID_CLKRST) + 0x48;
|
||||
uint32_t misc_clk_val = *misc_clk_reg;
|
||||
*misc_clk_reg = (misc_clk_val | (1 << 28));
|
||||
}
|
||||
|
@ -77,7 +75,7 @@ uint32_t fuse_hw_read(uint32_t addr)
|
|||
}
|
||||
|
||||
/* Write a fuse in the hardware array */
|
||||
void fuse_hw_write(uint32_t, value, uint32_t addr)
|
||||
void fuse_hw_write(uint32_t value, uint32_t addr)
|
||||
{
|
||||
fuse_wait_idle();
|
||||
|
|
@ -174,7 +174,7 @@ typedef struct {
|
|||
void fuse_init(void);
|
||||
|
||||
uint32_t fuse_hw_read(uint32_t addr);
|
||||
void fuse_hw_write(uint32_t, value, uint32_t addr);
|
||||
void fuse_hw_write(uint32_t value, uint32_t addr);
|
||||
void fuse_hw_sense(void);
|
||||
void fuse_disable_programming(void);
|
||||
void fuse_secondary_private_key_disable(void);
|
|
@ -1,5 +1,3 @@
|
|||
#include <stbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "i2c.h"
|
||||
|
@ -135,7 +133,7 @@ bool i2c_send(unsigned int id, uint8_t device, uint8_t r, void *src, size_t src_
|
|||
uint32_t val = r;
|
||||
if (src_size <= 3) {
|
||||
memcpy(((uint8_t *)&val) + 1, src, src_size);
|
||||
return i2c_write(i2c_get_registers_from_id(id), &val, src_size + 1, device);
|
||||
return i2c_write(i2c_get_registers_from_id(id), device, &val, src_size + 1);
|
||||
} else {
|
||||
return false;
|
||||
}
|
|
@ -10,21 +10,22 @@ struct {
|
|||
void (*handler)(void);
|
||||
} g_registered_interrupts[MAX_REGISTERED_INTERRUPTS] = { {0, NULL}, {0, NULL}, {0, NULL}, {0, NULL} };
|
||||
|
||||
/* Prototypes for internal (private) functions. */
|
||||
unsigned int get_interrupt_id(void);
|
||||
|
||||
static unsigned int get_interrupt_id(void) {
|
||||
return 0;
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
/* Initializes the GIC. TODO: This must be called during wakeup. */
|
||||
void intr_initialize_gic(void) {
|
||||
/* Setup interrupts 0-0x1F as nonsecure with highest non-secure priority. */
|
||||
GICD_IGROUPR[0] = 0xFFFFFFFF;
|
||||
for (unsigned int i = 0; i < 0x20; i++) {
|
||||
GICD_IPRIORITYR[i] = GIC_PRI_HIGHEST;
|
||||
GICD_IPRIORITYR[i] = GIC_PRI_HIGHEST_NONSECURE;
|
||||
}
|
||||
|
||||
/* Setup the GICC. */
|
||||
GICC_CTLR = 0x1D9;
|
||||
GICC_PMR = GIC_PRI_HIGHEST;
|
||||
GICC_PMR = GIC_PRI_HIGHEST_NONSECURE;
|
||||
GICC_BPR = 7;
|
||||
}
|
||||
|
||||
|
@ -50,7 +51,7 @@ void intr_set_cpu_mask(unsigned int id, uint8_t mask) {
|
|||
|
||||
/* Sets an interrupt's edge/level bits in the GICD. */
|
||||
void intr_set_edge_level(unsigned int id, int edge_level) {
|
||||
GICD_ICFGR[id >> 4] = (GICD_ICFGR[id >> 4] & (~(3 << ((id & 0xF) << 1))) | (((edge_level & 1) << 1) << ((id & 0xF) << 1));
|
||||
GICD_ICFGR[id >> 4] = GICD_ICFGR[id >> 4] & ((~(3 << ((id & 0xF) << 1))) | (((edge_level & 1) << 1) << ((id & 0xF) << 1)));
|
||||
}
|
||||
|
||||
/* Sets an interrupt's enabled status in the GICD. */
|
|
@ -108,7 +108,7 @@ static const struct {
|
|||
#define WARMBOOT_RAM_SEGMENT_ID_SE_STATE 0
|
||||
#define WARMBOOT_RAM_SEGMENT_ID_TZRAM 1
|
||||
|
||||
#define TZRAM_SEGMENT_ID_WARMBOOT_CRT0_MAIN_CODE 0
|
||||
#define TZRAM_SEGMENT_ID_WARMBOOT_CRT0_AND_MAIN 0
|
||||
#define TZRAM_SEGMENT_ID_PK2LDR 1
|
||||
#define TZRAM_SEGMENT_ID_USERPAGE 2
|
||||
#define TZRAM_SEGMENT_ID_CORE012_STACK 3
|
||||
|
@ -119,12 +119,12 @@ static const struct {
|
|||
|
||||
/**********************************************************************************************/
|
||||
|
||||
static inline uintptr_t identity_map_all_mappings(uintptr_t *mmu_l1_tbl, uintptr_t *mmu_l3_tbl) {
|
||||
static inline void identity_map_all_mappings(uintptr_t *mmu_l1_tbl, uintptr_t *mmu_l3_tbl) {
|
||||
static uint64_t base_attributes = MMU_PTE_BLOCK_INNER_SHAREBLE | ATTRIB_MEMTYPE_NORMAL;
|
||||
for(size_t i = 0; i < sizeof(g_identity_mappings) / sizeof(g_identity_mappings[0]); i++) {
|
||||
uint64_t attributes = base_attributes | g_identity_mappings[i].attributes;
|
||||
if(g_identity_mappings[i].is_block_range) {
|
||||
mmu_map_block_range(mmu_l1_tbl, g_identity_mappings[i].address, g_identity_mappings[i].address,
|
||||
mmu_map_block_range(1, mmu_l1_tbl, g_identity_mappings[i].address, g_identity_mappings[i].address,
|
||||
g_identity_mappings[i].size, attributes);
|
||||
}
|
||||
else {
|
||||
|
@ -134,13 +134,13 @@ static inline uintptr_t identity_map_all_mappings(uintptr_t *mmu_l1_tbl, uintptr
|
|||
}
|
||||
}
|
||||
|
||||
static inline uintptr_t identity_unmap_all_mappings(uintptr_t *mmu_l1_tbl, uintptr_t *mmu_l3_tbl) {
|
||||
static inline void identity_unmap_all_mappings(uintptr_t *mmu_l1_tbl, uintptr_t *mmu_l3_tbl) {
|
||||
for(size_t i = 0; i < sizeof(g_identity_mappings) / sizeof(g_identity_mappings[0]); i++) {
|
||||
if(g_identity_mappings[i].is_block_range) {
|
||||
mmu_unmap_block_range(mmu_l1_tbl, g_identity_mappings[i].address, g_identity_mappings[i].size);
|
||||
mmu_unmap_range(1, mmu_l1_tbl, g_identity_mappings[i].address, g_identity_mappings[i].size);
|
||||
}
|
||||
else {
|
||||
mmu_unmap_page_range(mmu_l3_tbl, g_identity_mappings[i].address, g_identity_mappings[i].size);
|
||||
mmu_unmap_range(3, mmu_l3_tbl, g_identity_mappings[i].address, g_identity_mappings[i].size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ static inline uintptr_t lp0_get_plaintext_ram_segment_pa(unsigned int segment_id
|
|||
|
||||
#ifndef MEMORY_MAP_USE_IDENTIY_MAPPING
|
||||
static inline uintptr_t lp0_get_plaintext_ram_segment_address(unsigned int segment_id) {
|
||||
return LP0_PLAINTEXT_RAM_SEGMENT_BASE + 0x10000 * segment_id;
|
||||
return LP0_ENTRY_RAM_SEGMENT_BASE + 0x10000 * segment_id;
|
||||
}
|
||||
#else
|
||||
static inline uintptr_t lp0_get_plaintext_ram_segment_address(unsigned int segment_id) {
|
||||
|
@ -209,7 +209,7 @@ static inline uintptr_t lp0_get_plaintext_ram_segment_address(unsigned int segme
|
|||
static inline void lp0_map_all_plaintext_ram_segments(uintptr_t *mmu_l3_tbl) {
|
||||
for(size_t i = 0, offset = 0; i < sizeof(g_lp0_entry_ram_segments) / sizeof(g_lp0_entry_ram_segments[0]); i++) {
|
||||
uint64_t attributes = MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_INNER_SHAREBLE | g_lp0_entry_ram_segments[i].attributes;
|
||||
mmu_map_page_range(mmu_l3_tbl, LP0_PLAINTEXT_RAM_SEGMENT_BASE + offset, g_lp0_entry_ram_segments[i].pa,
|
||||
mmu_map_page_range(mmu_l3_tbl, LP0_ENTRY_RAM_SEGMENT_BASE + offset, g_lp0_entry_ram_segments[i].pa,
|
||||
g_lp0_entry_ram_segments[i].size, attributes);
|
||||
offset += 0x10000;
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ static inline void lp0_map_all_plaintext_ram_segments(uintptr_t *mmu_l3_tbl) {
|
|||
|
||||
static inline void lp0_unmap_all_plaintext_ram_segments(uintptr_t *mmu_l3_tbl) {
|
||||
for(size_t i = 0, offset = 0; i < sizeof(g_lp0_entry_ram_segments) / sizeof(g_lp0_entry_ram_segments[0]); i++) {
|
||||
mmu_unmap_range(3, mmu_l3_tbl, LP0_PLAINTEXT_RAM_SEGMENT_BASE + offset, g_lp0_entry_ram_segments[i].size);
|
||||
mmu_unmap_range(3, mmu_l3_tbl, LP0_ENTRY_RAM_SEGMENT_BASE + offset, g_lp0_entry_ram_segments[i].size);
|
||||
|
||||
offset += 0x10000;
|
||||
}
|
||||
|
@ -236,7 +236,7 @@ static inline uintptr_t lp0_get_ciphertext_ram_segment_address(unsigned int segm
|
|||
offset += g_warmboot_ram_segments[i].size;
|
||||
}
|
||||
|
||||
return LP0_CIPHERTEXT_RAM_SEGMENT_BASE + offset;
|
||||
return WARMBOOT_RAM_SEGMENT_BASE + offset;
|
||||
}
|
||||
#else
|
||||
static inline uintptr_t lp0_get_ciphertext_ram_segment_address(unsigned int segment_id) {
|
||||
|
@ -247,7 +247,7 @@ static inline uintptr_t lp0_get_ciphertext_ram_segment_address(unsigned int segm
|
|||
static inline void lp0_map_all_ciphertext_ram_segments(uintptr_t *mmu_l3_tbl) {
|
||||
for(size_t i = 0, offset = 0; i < sizeof(g_warmboot_ram_segments) / sizeof(g_warmboot_ram_segments[0]); i++) {
|
||||
uint64_t attributes = MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_INNER_SHAREBLE | g_warmboot_ram_segments[i].attributes;
|
||||
mmu_map_page_range(mmu_l3_tbl, LP0_CIPHERTEXT_RAM_SEGMENT_BASE + offset, g_warmboot_ram_segments[i].pa,
|
||||
mmu_map_page_range(mmu_l3_tbl, WARMBOOT_RAM_SEGMENT_BASE + offset, g_warmboot_ram_segments[i].pa,
|
||||
g_warmboot_ram_segments[i].size, attributes);
|
||||
offset += g_warmboot_ram_segments[i].size;
|
||||
}
|
||||
|
@ -255,7 +255,7 @@ static inline void lp0_map_all_ciphertext_ram_segments(uintptr_t *mmu_l3_tbl) {
|
|||
|
||||
static inline void lp0_unmap_all_ciphertext_ram_segments(uintptr_t *mmu_l3_tbl) {
|
||||
for(size_t i = 0, offset = 0; i < sizeof(g_warmboot_ram_segments) / sizeof(g_warmboot_ram_segments[0]); i++) {
|
||||
mmu_unmap_range(3, mmu_l3_tbl, LP0_CIPHERTEXT_RAM_SEGMENT_BASE + offset, g_warmboot_ram_segments[i].size);
|
||||
mmu_unmap_range(3, mmu_l3_tbl, WARMBOOT_RAM_SEGMENT_BASE + offset, g_warmboot_ram_segments[i].size);
|
||||
|
||||
offset += g_warmboot_ram_segments[i].size;
|
||||
}
|
|
@ -1,10 +1,9 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "memory_map.h"
|
||||
|
||||
#include "cpu_context.h"
|
||||
#include "package2.h"
|
||||
#include "configitem.h"
|
||||
#include "se.h"
|
||||
|
@ -22,7 +21,7 @@ static void setup_se(void) {
|
|||
se_clear_interrupts();
|
||||
|
||||
/* Perform some sanity initialization. */
|
||||
security_engine_t *p_security_engine = get_security_engine_address();
|
||||
volatile security_engine_t *p_security_engine = get_security_engine_address();
|
||||
p_security_engine->_0x4 = 0;
|
||||
p_security_engine->AES_KEY_READ_DISABLE_REG = 0;
|
||||
p_security_engine->RSA_KEY_READ_DISABLE_REG = 0;
|
|
@ -4,14 +4,15 @@
|
|||
#include "utils.h"
|
||||
#include "randomcache.h"
|
||||
#include "se.h"
|
||||
#include "cache.h"
|
||||
|
||||
/* TrustZone maintains a cache of random for the kernel. */
|
||||
/* So that requests can still be serviced even when a */
|
||||
/* usermode SMC is in progress. */
|
||||
|
||||
volatile uint8_t g_random_cache[0x400];
|
||||
volatile unsigned int g_random_cache_low = 0;
|
||||
volatile unsigned int g_random_cache_high = 0x3FF;
|
||||
static uint8_t g_random_cache[0x400];
|
||||
static unsigned int g_random_cache_low = 0;
|
||||
static unsigned int g_random_cache_high = 0x3FF;
|
||||
|
||||
|
||||
void randomcache_refill_segment(unsigned int offset, unsigned int size) {
|
|
@ -1,5 +1,3 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
@ -27,7 +25,7 @@ void ll_init(se_ll_t *ll, void *buffer, size_t size) {
|
|||
ll->num_entries = 0; /* 1 Entry. */
|
||||
|
||||
if (buffer != NULL) {
|
||||
ll->addr_info.address = get_physical_address(buffer);
|
||||
ll->addr_info.address = (uint32_t) get_physical_address(buffer);
|
||||
ll->addr_info.size = (uint32_t) size;
|
||||
} else {
|
||||
ll->addr_info.address = 0;
|
||||
|
@ -37,11 +35,6 @@ void ll_init(se_ll_t *ll, void *buffer, size_t size) {
|
|||
flush_dcache_range((uint8_t *)ll, (uint8_t *)ll + sizeof(*ll));
|
||||
}
|
||||
|
||||
/* Gets security engine pointer. */
|
||||
security_engine_t *get_security_engine_address(void) {
|
||||
return SECURITY_ENGINE;
|
||||
}
|
||||
|
||||
void set_security_engine_callback(unsigned int (*callback)(void)) {
|
||||
if (callback == NULL || g_se_callback != NULL) {
|
||||
generic_panic();
|
||||
|
@ -66,7 +59,7 @@ void se_check_for_error(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void se_trigger_intrrupt(void) {
|
||||
void se_trigger_interrupt(void) {
|
||||
intr_set_pending(INTERRUPT_ID_USER_SECURITY_ENGINE);
|
||||
}
|
||||
|
||||
|
@ -214,7 +207,7 @@ void decrypt_data_into_keyslot(unsigned int keyslot_dst, unsigned int keyslot_sr
|
|||
SECURITY_ENGINE->CRYPTO_KEYTABLE_DST_REG = keyslot_dst << 8;
|
||||
|
||||
flush_dcache_range(wrapped_key, (const uint8_t *)wrapped_key + wrapped_key_size);
|
||||
trigger_se_aes_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size);
|
||||
/* TODO: trigger_se_aes_op(OP_START, NULL, 0, wrapped_key, wrapped_key_size); */
|
||||
}
|
||||
|
||||
void se_aes_crypt_insecure_internal(unsigned int keyslot, uint32_t out_ll_paddr, uint32_t in_ll_paddr, size_t size, unsigned int crypt_config, bool encrypt, unsigned int (*callback)(void)) {
|
||||
|
@ -351,7 +344,7 @@ void se_get_exp_mod_output(void *buf, size_t size) {
|
|||
|
||||
void trigger_se_rsa_op(void *buf, size_t size) {
|
||||
se_ll_t in_ll;
|
||||
ll_init(&in_ll, buf, size);
|
||||
ll_init(&in_ll, (void *)buf, size);
|
||||
|
||||
/* Set the input LL. */
|
||||
SECURITY_ENGINE->IN_LL_ADDR_REG = get_physical_address(&in_ll);
|
||||
|
@ -369,7 +362,7 @@ void trigger_se_blocking_op(unsigned int op, void *dst, size_t dst_size, const v
|
|||
se_ll_t in_ll;
|
||||
se_ll_t out_ll;
|
||||
|
||||
ll_init(&in_ll, src, src_size);
|
||||
ll_init(&in_ll, (void *)src, src_size);
|
||||
ll_init(&out_ll, dst, dst_size);
|
||||
|
||||
/* Set the LLs. */
|
||||
|
@ -434,7 +427,7 @@ void se_aes_ctr_crypt(unsigned int keyslot, void *dst, size_t dst_size, const vo
|
|||
if (src_size < dst_size) {
|
||||
last_block_size = src_size - aligned_size;
|
||||
}
|
||||
se_perform_aes_block_operation(dst + aligned_size, last_block_size, src + aligned_size, src - aligned_size);
|
||||
se_perform_aes_block_operation(dst + aligned_size, last_block_size, (uint8_t *)src + aligned_size, src_size - aligned_size);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,8 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "memory_map.h"
|
||||
|
||||
/* Exosphere driver for the Tegra X1 security engine. */
|
||||
|
||||
#define KEYSLOT_SWITCH_PACKAGE2KEY 0x8
|
||||
|
@ -136,13 +138,16 @@ typedef struct {
|
|||
/* WIP, API subject to change. */
|
||||
|
||||
|
||||
static inline volatile security_engine_t *get_security_engine_address(void) {
|
||||
return (volatile security_engine_t *)(mmio_get_device_address(MMIO_DEVID_SE));
|
||||
}
|
||||
|
||||
/* This function MUST be registered to fire on the appropriate interrupt. */
|
||||
void se_operation_completed(void);
|
||||
|
||||
security_engine_t *get_security_engine_address(void);
|
||||
|
||||
void se_check_for_error(void);
|
||||
void se_trigger_interrupt(void);
|
||||
void se_clear_interrupts(void); /* TODO */
|
||||
|
||||
void se_verify_flags_cleared(void);
|
||||
|
|
@ -113,7 +113,7 @@ uintptr_t get_smc_core012_stack_address(void) {
|
|||
return tzram_get_segment_address(TZRAM_SEGMENT_ID_CORE012_STACK) + 0x1000;
|
||||
}
|
||||
|
||||
uintptr_t get_exception_entry_core3_stack_address(unsigned int core_id) {
|
||||
uintptr_t get_exception_entry_stack_address(unsigned int core_id) {
|
||||
/* For core3, this is also the smc stack */
|
||||
if (core_id == 3) {
|
||||
return tzram_get_segment_address(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x1000;
|
||||
|
@ -187,6 +187,7 @@ void call_smc_handler(uint32_t handler_id, smc_args_t *args) {
|
|||
|
||||
/* Call function. */
|
||||
args->X[0] = smc_handler(args);
|
||||
(void)result; /* FIXME: result unused */
|
||||
}
|
||||
|
||||
uint32_t smc_wrapper_sync(smc_args_t *args, uint32_t (*handler)(smc_args_t *)) {
|
||||
|
@ -286,6 +287,7 @@ uint32_t smc_get_result(smc_args_t *args) {
|
|||
}
|
||||
|
||||
return 0;
|
||||
(void)status; /* FIXME: status unused */
|
||||
}
|
||||
|
||||
uint32_t smc_exp_mod_get_result(void *buf, uint64_t size) {
|
||||
|
@ -454,10 +456,16 @@ uint32_t smc_read_write_register(smc_args_t *args) {
|
|||
return 2;
|
||||
}
|
||||
/* Check for PMC registers. */
|
||||
if (0x7000E400ULL <= address && address <= 0x7000EFFFULL) {
|
||||
const uint8_t pmc_whitelist[0x28] = {0xB9, 0xF9, 0x07, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x17, 0x00, 0xC4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00};
|
||||
if (0x7000E400 <= address && address <= 0x7000EFFF) {
|
||||
const uint8_t pmc_whitelist[0x28] = {
|
||||
0xB9, 0xF9, 0x07, 0x00, 0x00, 0x00, 0x80, 0x03,
|
||||
0x00, 0x00, 0x00, 0x17, 0x00, 0xC4, 0x07, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00
|
||||
};
|
||||
/* Offset = Address - PMC_BASE */
|
||||
uint32_t offset = (uint32_t)(address - 0x7000E400ULL);
|
||||
uint32_t offset = (uint32_t)(address - 0x7000E400);
|
||||
uint32_t wl_ind = (offset >> 5);
|
||||
/* If address is whitelisted, allow write. */
|
||||
if (wl_ind < sizeof(pmc_whitelist) && (pmc_whitelist[wl_ind] & (1 << ((offset >> 2) & 0x7)))) {
|
||||
|
@ -465,10 +473,25 @@ uint32_t smc_read_write_register(smc_args_t *args) {
|
|||
} else {
|
||||
return 2;
|
||||
}
|
||||
} else if (mkey_get_revision() >= MASTERKEY_REVISION_400_CURRENT && devices[MMIO_DEVID_MC].pa <= address && address < devices[MMIO_DEVID_MC].pa + devices[MMIO_DEVID_MC].size) {
|
||||
} else if (mkey_get_revision() >= MASTERKEY_REVISION_400_CURRENT && mmio_get_device_pa(MMIO_DEVID_MC) <= address &&
|
||||
address < mmio_get_device_pa(MMIO_DEVID_MC) + 0x1000) {
|
||||
/* Memory Controller RW supported only on 4.0.0+ */
|
||||
const uint8_t mc_whitelist[0x68] = {0x9F, 0x31, 0x30, 0x00, 0xF0, 0xFF, 0xF7, 0x01, 0xCD, 0xFE, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x03, 0x40, 0x73, 0x3E, 0x2F, 0x00, 0x00, 0x6E, 0x30, 0x05, 0x06, 0xB0, 0x71, 0xC8, 0x43, 0x04, 0x80, 0x1F, 0x08, 0x80, 0x03, 0x00, 0x0E, 0x00, 0x08, 0x00, 0xE0, 0x00, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xF0, 0x03, 0x03, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0x40, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xE4, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0xFE, 0x0F, 0x01, 0x00, 0x80, 0x00, 0x00, 0x08, 0x00, 0x00};
|
||||
uint32_t offset = (uint32_t)(address - 0x70019000ULL);
|
||||
const uint8_t mc_whitelist[0x68] = {
|
||||
0x9F, 0x31, 0x30, 0x00, 0xF0, 0xFF, 0xF7, 0x01,
|
||||
0xCD, 0xFE, 0xC0, 0xFE, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x40, 0x73, 0x3E, 0x2F, 0x00, 0x00, 0x6E,
|
||||
0x30, 0x05, 0x06, 0xB0, 0x71, 0xC8, 0x43, 0x04,
|
||||
0x80, 0x1F, 0x08, 0x80, 0x03, 0x00, 0x0E, 0x00,
|
||||
0x08, 0x00, 0xE0, 0x00, 0x0E, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x30, 0xF0, 0x03, 0x03, 0x30,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x31, 0x00, 0x40, 0x00, 0x00,
|
||||
0x00, 0x03, 0x00, 0x00, 0xE4, 0xFF, 0xFF, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0xFE, 0x0F,
|
||||
0x01, 0x00, 0x80, 0x00, 0x00, 0x08, 0x00, 0x00
|
||||
};
|
||||
uint32_t offset = (uint32_t)(address - 0x70019000);
|
||||
uint32_t wl_ind = (offset >> 5);
|
||||
/* If address is whitelisted, allow write. */
|
||||
if (wl_ind < sizeof(mc_whitelist) && (mc_whitelist[wl_ind] & (1 << ((offset >> 2) & 0x7)))) {
|
||||
|
@ -531,3 +554,9 @@ uint32_t smc_configure_carveout(smc_args_t *args) {
|
|||
configured_carveouts[carveout_id] = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t smc_panic(smc_args_t *args) {
|
||||
(void)args;
|
||||
return 0;
|
||||
/* TODO */
|
||||
}
|
|
@ -14,7 +14,7 @@ void set_priv_smc_in_progress(void);
|
|||
void clear_priv_smc_in_progress(void);
|
||||
|
||||
uintptr_t get_smc_core012_stack_address(void);
|
||||
uintptr_t get_exception_entry_core3_stack_address(void);
|
||||
uintptr_t get_exception_entry_stack_address(unsigned int core_id);
|
||||
|
||||
void call_smc_handler(unsigned int handler_id, smc_args_t *args);
|
||||
|
|
@ -10,16 +10,17 @@
|
|||
#include "smc_api.h"
|
||||
#include "smc_user.h"
|
||||
#include "se.h"
|
||||
#include "fuse.h"
|
||||
#include "sealedkeys.h"
|
||||
#include "userpage.h"
|
||||
#include "titlekey.h"
|
||||
|
||||
/* Globals. */
|
||||
bool g_crypt_aes_done = false;
|
||||
bool g_exp_mod_done = false;
|
||||
static bool g_crypt_aes_done = false;
|
||||
static bool g_exp_mod_done = false;
|
||||
|
||||
uint8_t g_secure_exp_mod_exponent[0x100];
|
||||
uint8_t g_rsa_oaep_exponent[0x100];
|
||||
static uint8_t g_secure_exp_mod_exponent[0x100];
|
||||
static uint8_t g_rsa_oaep_exponent[0x100];
|
||||
|
||||
|
||||
void set_exp_mod_done(bool done) {
|
||||
|
@ -606,10 +607,11 @@ uint32_t user_unwrap_aes_wrapped_titlekey(smc_args_t *args) {
|
|||
|
||||
tkey_set_master_key_rev(master_key_rev);
|
||||
|
||||
|
||||
tkey_aes_unwrap(titlekey, 0x10, aes_wrapped_titlekey, 0x10);
|
||||
seal_titlekey(sealed_titlekey, 0x10, titlekey, 0x10);
|
||||
|
||||
args->X[1] = sealed_titlekey[0];
|
||||
args->X[2] = sealed_titlekey[1];
|
||||
|
||||
return 0; /* FIXME: what should we return there */
|
||||
}
|
|
@ -1,3 +1,5 @@
|
|||
/* For some reason GAS doesn't know about it, even with .cpu cortex-a57 */
|
||||
#define cpuactlr_el1 s3_1_c15_c2_0
|
||||
.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 */
|
||||
/*
|
||||
|
@ -36,7 +38,7 @@
|
|||
/* if the OS lock is set, disable it and request a warm reset */
|
||||
mrs x0, oslsr_el1
|
||||
ands x0, x0, #2
|
||||
b.eq _set_lock_and_sp
|
||||
b.eq 2f
|
||||
mov x0, xzr
|
||||
msr oslar_el1, x0
|
||||
|
||||
|
@ -48,14 +50,14 @@
|
|||
isb
|
||||
dsb sy
|
||||
/* Nintendo forgot to copy-paste the branch instruction below. */
|
||||
_reset_wfi:
|
||||
1:
|
||||
wfi
|
||||
b _reset_wfi
|
||||
b 1b
|
||||
.rept 65
|
||||
nop /* guard against speculative excecution */
|
||||
.endr
|
||||
|
||||
_set_lock_and_sp:
|
||||
2:
|
||||
/* set the OS lock */
|
||||
mov x0, #1
|
||||
msr oslar_el1, x0
|
||||
|
@ -122,7 +124,7 @@ __set_exception_entry_stack_pointer:
|
|||
/* If SPSel == 1 on entry, make sure your function doesn't use stack variables! */
|
||||
mov x16, lr
|
||||
mrs x17, spsel
|
||||
msr x0, mpidr_el1
|
||||
mrs x0, mpidr_el1
|
||||
and w0, w0, #3
|
||||
bl get_exception_entry_stack_address /* should be optimized so it doesn't make function calls */
|
||||
msr spsel, #1
|
||||
|
@ -138,8 +140,8 @@ __jump_to_lower_el:
|
|||
/* x0: arg (context ID), x1: entrypoint, w2: exception level */
|
||||
msr elr_el3, x1
|
||||
|
||||
mov x1, #((0b1111 << 6) | 1) /* DAIF set and SP = SP_ELx*/
|
||||
orr x1, w2, lsl#2
|
||||
mov w1, #((0b1111 << 6) | 1) /* DAIF set and SP = SP_ELx*/
|
||||
orr w1, w2, w2, lsl#2
|
||||
msr spsr_el3, x1
|
||||
|
||||
bl __set_exception_entry_stack_pointer
|
|
@ -2,6 +2,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "cache.h"
|
||||
|
||||
#include "titlekey.h"
|
||||
#include "masterkey.h"
|
||||
|
@ -50,7 +51,7 @@ void calculate_mgf1_and_xor(void *masked, size_t masked_size, const void *seed,
|
|||
hash_buf[seed_size + 3] = (uint8_t)((round >> 0) & 0xFF);
|
||||
round++;
|
||||
|
||||
cache_flush(hash_buf, hash_buf + hash_buf_size);
|
||||
flush_dcache_range(hash_buf, hash_buf + hash_buf_size);
|
||||
se_calculate_sha256(cur_hash, hash_buf, hash_buf_size);
|
||||
|
||||
for (unsigned int i = 0; i < cur_size; i++) {
|
|
@ -5,10 +5,10 @@
|
|||
#include "memory_map.h"
|
||||
#include "cache.h"
|
||||
|
||||
static uintptr_t g_user_page_user_address = NULL;
|
||||
static uintptr_t g_user_page_user_address = 0ULL;
|
||||
|
||||
static inline uintptr_t get_page_for_address(void *address) {
|
||||
return ((uintptr_t)(address)) & ~0xFFF;
|
||||
return ((uintptr_t)(address)) & ~0xFFFULL;
|
||||
}
|
||||
|
||||
/* Create a user page reference for the desired address. */
|
||||
|
@ -17,7 +17,7 @@ bool upage_init(upage_ref_t *upage, void *user_address) {
|
|||
upage->user_address = get_page_for_address(user_address);
|
||||
upage->secure_monitor_address = 0ULL;
|
||||
|
||||
if (g_user_page_user_address != NULL) {
|
||||
if (g_user_page_user_address != 0ULL) {
|
||||
/* Different physical address indicate SPL was rebooted, or another process got access to svcCallSecureMonitor. Panic. */
|
||||
if (g_user_page_user_address != upage->user_address) {
|
||||
generic_panic();
|
||||
|
@ -26,7 +26,8 @@ bool upage_init(upage_ref_t *upage, void *user_address) {
|
|||
} else {
|
||||
/* Weakly validate SPL's physically random address is in DRAM. */
|
||||
if (upage->user_address >> 31) {
|
||||
static const userpage_attributes = MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_INNER_SHAREBLE | MMU_PTE_BLOCK_NS | ATTRIB_MEMTYPE_NORMAL;
|
||||
static const uint64_t userpage_attributes = MMU_PTE_BLOCK_XN | MMU_PTE_BLOCK_INNER_SHAREBLE | MMU_PTE_BLOCK_NS | ATTRIB_MEMTYPE_NORMAL;
|
||||
uintptr_t *mmu_l3_tbl = (uintptr_t *)tzram_get_segment_address(TZRAM_SEGMENT_ID_L3_TRANSLATION_TABLE);
|
||||
g_user_page_user_address = upage->user_address;
|
||||
mmu_map_page(mmu_l3_tbl, USER_PAGE_SECURE_MONITOR_ADDR, upage->user_address, userpage_attributes);
|
||||
tlb_invalidate_page_inner_shareable((void *)USER_PAGE_SECURE_MONITOR_ADDR);
|
18
exosphere/src/utils.c
Normal file
18
exosphere/src/utils.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include "utils.h"
|
||||
|
||||
void panic(uint32_t code) {
|
||||
(void)code; /* TODO */
|
||||
}
|
||||
|
||||
void generic_panic(void) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
__attribute__((noinline)) bool overlaps(uint64_t as, uint64_t ae, uint64_t bs, uint64_t be)
|
||||
{
|
||||
if(as <= bs && bs <= ae)
|
||||
return true;
|
||||
if(bs <= as && as <= be)
|
||||
return true;
|
||||
return false;
|
||||
}
|
44
exosphere/src/utils.h
Normal file
44
exosphere/src/utils.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
#ifndef EXOSPHERE_UTILS_H
|
||||
#define EXOSPHERE_UTILS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define BIT(x) (1u << (x))
|
||||
#define BITL(x) (1ull << (x))
|
||||
|
||||
void panic(uint32_t code);
|
||||
void generic_panic(void);
|
||||
bool overlaps(uint64_t as, uint64_t ae, uint64_t bs, uint64_t be);
|
||||
|
||||
static inline uintptr_t get_physical_address(const void *vaddr) {
|
||||
uintptr_t PAR;
|
||||
__asm__ __volatile__ ("at s1e3r, %0" :: "r"(vaddr));
|
||||
__asm__ __volatile__ ("mrs %0, par_el1" : "=r"(PAR));
|
||||
return (PAR & 1) ? 0ULL : (PAR & 0x00000FFFFFFFF000ULL) | ((uintptr_t)vaddr & 0xFFF);
|
||||
}
|
||||
|
||||
static inline uint32_t read32le(const volatile void *dword, size_t offset) {
|
||||
return *(uint32_t *)((uintptr_t)dword + offset);
|
||||
}
|
||||
|
||||
static inline uint32_t read32be(const volatile void *dword, size_t offset) {
|
||||
return __builtin_bswap32(read32le(dword, offset));
|
||||
}
|
||||
|
||||
static inline uint64_t read64le(const volatile void *qword, size_t offset) {
|
||||
return *(uint64_t *)((uintptr_t)qword + offset);
|
||||
}
|
||||
|
||||
static inline unsigned int get_core_id(void) {
|
||||
uint64_t core_id;
|
||||
__asm__ __volatile__ ("mrs %0, mpidr_el1" : "=r"(core_id));
|
||||
return (unsigned int)core_id & 3;
|
||||
}
|
||||
|
||||
static inline bool check_32bit_additive_overflow(uint32_t a, uint32_t b) {
|
||||
return __builtin_add_overflow_p(a, b, (uint32_t)0);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -11,6 +11,6 @@ void invalidate_icache_all_tzram_pa(void) {
|
|||
/* TODO */
|
||||
}
|
||||
|
||||
uintptr_t get_coldboot_crt0_stack_address(void) {
|
||||
uintptr_t get_warmboot_crt0_stack_address(void) {
|
||||
return tzram_get_segment_pa(TZRAM_SEGMENT_ID_CORE3_STACK) + 0x800;
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
#ifndef EXOSPHERE_UTILS_H
|
||||
#define EXOSPHERE_UTILS_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define BIT(x) (1u << (x))
|
||||
#define BITL(x) (1ull << (x))
|
||||
|
||||
void panic(uint32_t code);
|
||||
void generic_panic(void);
|
||||
|
||||
uint32_t get_physical_address(void *vaddr);
|
||||
|
||||
static inline uint32_t read32le(const void *dword, size_t offset) {
|
||||
return *(uint32_t *)((uintptr_t)dword + offset);
|
||||
}
|
||||
|
||||
static inline uint32_t read32be(const unsigned char *dword, size_t offset) {
|
||||
return __builtin_bswap32(read32le(dword, offset));
|
||||
}
|
||||
|
||||
static inline uint64_t read64le(const void *qword, size_t offset) {
|
||||
return *(uint64_t *)((uintptr_t)dword + offset);
|
||||
}
|
||||
|
||||
static __attribute__((noinline)) bool check_32bit_additive_overflow(uint32_t a, uint32_t b) {
|
||||
uint64_t x = (uint64_t)a + (uint64_t)b;
|
||||
return x > (uint64_t)(UINT32_MAX);
|
||||
}
|
||||
|
||||
static __attribute__((noinline)) bool overlaps(uint64_t as, uint64_t ae, uint64_t bs, uint64_t be)
|
||||
{
|
||||
if(as <= bs && bs <= ae)
|
||||
return true;
|
||||
if(bs <= as && as <= be)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static inline unsigned int get_core_id(void) {
|
||||
uint64_t core_id;
|
||||
__asm__ __volatile__ ("mrs %0, MPIDR_EL1" : "=r"(core_id));
|
||||
return (unsigned int)core_id & 3;
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue