diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/abort.c (renamed from lib/stdlib/abort.c) | 0 | ||||
-rw-r--r-- | lib/libc/assert.c (renamed from lib/stdlib/assert.c) | 0 | ||||
-rw-r--r-- | lib/libc/exit.c | 26 | ||||
-rw-r--r-- | lib/libc/libc.mk (renamed from lib/stdlib/stdlib.mk) | 6 | ||||
-rw-r--r-- | lib/libc/mem.c (renamed from lib/stdlib/mem.c) | 0 | ||||
-rw-r--r-- | lib/libc/printf.c (renamed from lib/stdlib/printf.c) | 0 | ||||
-rw-r--r-- | lib/libc/putchar.c (renamed from lib/stdlib/putchar.c) | 0 | ||||
-rw-r--r-- | lib/libc/puts.c (renamed from lib/stdlib/puts.c) | 0 | ||||
-rw-r--r-- | lib/libc/sscanf.c (renamed from lib/stdlib/sscanf.c) | 0 | ||||
-rw-r--r-- | lib/libc/strchr.c (renamed from lib/stdlib/strchr.c) | 0 | ||||
-rw-r--r-- | lib/libc/strcmp.c (renamed from lib/stdlib/strcmp.c) | 0 | ||||
-rw-r--r-- | lib/libc/strlen.c (renamed from lib/stdlib/strlen.c) | 0 | ||||
-rw-r--r-- | lib/libc/strncmp.c (renamed from lib/stdlib/strncmp.c) | 0 | ||||
-rw-r--r-- | lib/libc/strnlen.c (renamed from lib/stdlib/strnlen.c) | 0 | ||||
-rw-r--r-- | lib/libc/subr_prf.c (renamed from lib/stdlib/subr_prf.c) | 0 | ||||
-rw-r--r-- | lib/libc/timingsafe_bcmp.c (renamed from lib/stdlib/timingsafe_bcmp.c) | 0 | ||||
-rw-r--r-- | lib/libfdt/libfdt.mk | 2 | ||||
-rw-r--r-- | lib/romlib/Makefile | 71 | ||||
-rwxr-xr-x | lib/romlib/gentbl.sh | 40 | ||||
-rwxr-xr-x | lib/romlib/genvar.sh | 36 | ||||
-rwxr-xr-x | lib/romlib/genwrappers.sh | 52 | ||||
-rw-r--r-- | lib/romlib/init.s | 30 | ||||
-rw-r--r-- | lib/romlib/jmptbl.i | 35 | ||||
-rw-r--r-- | lib/romlib/romlib.ld.S | 44 | ||||
-rw-r--r-- | lib/stdlib/exit.c | 14 | ||||
-rw-r--r-- | lib/xlat_tables/aarch32/xlat_tables.c | 16 | ||||
-rw-r--r-- | lib/xlat_tables_v2/aarch32/enable_mmu.S | 60 | ||||
-rw-r--r-- | lib/xlat_tables_v2/aarch32/xlat_tables_arch.c | 91 | ||||
-rw-r--r-- | lib/xlat_tables_v2/aarch64/enable_mmu.S | 28 | ||||
-rw-r--r-- | lib/xlat_tables_v2/aarch64/xlat_tables_arch.c | 13 | ||||
-rw-r--r-- | lib/xlat_tables_v2/xlat_tables_context.c | 32 | ||||
-rw-r--r-- | lib/xlat_tables_v2/xlat_tables_core.c | 4 | ||||
-rw-r--r-- | lib/xlat_tables_v2/xlat_tables_utils.c | 7 |
33 files changed, 543 insertions, 64 deletions
diff --git a/lib/stdlib/abort.c b/lib/libc/abort.c index 65ce4cca..65ce4cca 100644 --- a/lib/stdlib/abort.c +++ b/lib/libc/abort.c diff --git a/lib/stdlib/assert.c b/lib/libc/assert.c index 97fab4b0..97fab4b0 100644 --- a/lib/stdlib/assert.c +++ b/lib/libc/assert.c diff --git a/lib/libc/exit.c b/lib/libc/exit.c new file mode 100644 index 00000000..b2fde9ca --- /dev/null +++ b/lib/libc/exit.c @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdlib.h> + +static void (*exitfun)(void); + +void exit(int status) +{ + if (exitfun) + (*exitfun)(); + for (;;) + ; +} + +int atexit(void (*fun)(void)) +{ + if (exitfun) + return -1; + exitfun = fun; + + return 0; +} diff --git a/lib/stdlib/stdlib.mk b/lib/libc/libc.mk index 82116235..ded3d745 100644 --- a/lib/stdlib/stdlib.mk +++ b/lib/libc/libc.mk @@ -4,7 +4,7 @@ # SPDX-License-Identifier: BSD-3-Clause # -STDLIB_SRCS := $(addprefix lib/stdlib/, \ +LIBC_SRCS := $(addprefix lib/libc/, \ abort.c \ assert.c \ exit.c \ @@ -21,5 +21,5 @@ STDLIB_SRCS := $(addprefix lib/stdlib/, \ subr_prf.c \ timingsafe_bcmp.c) -INCLUDES += -Iinclude/lib/stdlib \ - -Iinclude/lib/stdlib/sys +INCLUDES += -Iinclude/lib/libc \ + -Iinclude/lib/libc/sys diff --git a/lib/stdlib/mem.c b/lib/libc/mem.c index 65b62fde..65b62fde 100644 --- a/lib/stdlib/mem.c +++ b/lib/libc/mem.c diff --git a/lib/stdlib/printf.c b/lib/libc/printf.c index f6156414..f6156414 100644 --- a/lib/stdlib/printf.c +++ b/lib/libc/printf.c diff --git a/lib/stdlib/putchar.c b/lib/libc/putchar.c index 8265667b..8265667b 100644 --- a/lib/stdlib/putchar.c +++ b/lib/libc/putchar.c diff --git a/lib/stdlib/puts.c b/lib/libc/puts.c index 284cf8c5..284cf8c5 100644 --- a/lib/stdlib/puts.c +++ b/lib/libc/puts.c diff --git a/lib/stdlib/sscanf.c b/lib/libc/sscanf.c index a5876cff..a5876cff 100644 --- a/lib/stdlib/sscanf.c +++ b/lib/libc/sscanf.c diff --git a/lib/stdlib/strchr.c b/lib/libc/strchr.c index 4247dcd3..4247dcd3 100644 --- a/lib/stdlib/strchr.c +++ b/lib/libc/strchr.c diff --git a/lib/stdlib/strcmp.c b/lib/libc/strcmp.c index bb86e0f2..bb86e0f2 100644 --- a/lib/stdlib/strcmp.c +++ b/lib/libc/strcmp.c diff --git a/lib/stdlib/strlen.c b/lib/libc/strlen.c index 23c3d392..23c3d392 100644 --- a/lib/stdlib/strlen.c +++ b/lib/libc/strlen.c diff --git a/lib/stdlib/strncmp.c b/lib/libc/strncmp.c index f45f4a22..f45f4a22 100644 --- a/lib/stdlib/strncmp.c +++ b/lib/libc/strncmp.c diff --git a/lib/stdlib/strnlen.c b/lib/libc/strnlen.c index d48502bd..d48502bd 100644 --- a/lib/stdlib/strnlen.c +++ b/lib/libc/strnlen.c diff --git a/lib/stdlib/subr_prf.c b/lib/libc/subr_prf.c index c1035624..c1035624 100644 --- a/lib/stdlib/subr_prf.c +++ b/lib/libc/subr_prf.c diff --git a/lib/stdlib/timingsafe_bcmp.c b/lib/libc/timingsafe_bcmp.c index d0981580..d0981580 100644 --- a/lib/stdlib/timingsafe_bcmp.c +++ b/lib/libc/timingsafe_bcmp.c diff --git a/lib/libfdt/libfdt.mk b/lib/libfdt/libfdt.mk index d03dde20..1cbbd785 100644 --- a/lib/libfdt/libfdt.mk +++ b/lib/libfdt/libfdt.mk @@ -15,3 +15,5 @@ LIBFDT_SRCS := $(addprefix lib/libfdt/, \ fdt_wip.c) \ INCLUDES += -Iinclude/lib/libfdt + +$(eval $(call MAKE_LIB,fdt)) diff --git a/lib/romlib/Makefile b/lib/romlib/Makefile new file mode 100644 index 00000000..46b92068 --- /dev/null +++ b/lib/romlib/Makefile @@ -0,0 +1,71 @@ +# +# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +AS = $(CROSS_COMPILE)as +LD = $(CROSS_COMPILE)ld +OC = $(CROSS_COMPILE)objcopy +CPP = $(CROSS_COMPILE)cpp +BUILD_DIR = ../../$(BUILD_PLAT)/romlib +LIB_DIR = ../../$(BUILD_PLAT)/lib +WRAPPER_DIR = ../../$(BUILD_PLAT)/libwrapper +LIBS = -lmbedtls -lfdt -lc +INC = $(INCLUDES:-I%=-I../../%) +PPFLAGS = $(INC) $(DEFINES) -P -D__ASSEMBLY__ -D__LINKER__ -MD -MP -MT $(BUILD_DIR)/romlib.ld +OBJS = $(BUILD_DIR)/jmptbl.o $(BUILD_DIR)/init.o + +V ?= 0 +ifeq ($(V),0) + Q := @ +else + Q := +endif + +ifeq ($(DEBUG),1) + CFLAGS := -g + LDFLAGS := -g +endif + + +.PHONY: all clean distclean + +all: $(BUILD_DIR)/romlib.bin $(LIB_DIR)/libwrappers.a + +%.o: %.s + @echo " AS $@" + $(Q)$(AS) $(ASFLAGS) -o $@ $< + +$(BUILD_DIR)/%.o: %.s + @echo " AS $@" + $(Q)$(AS) $(ASFLAGS) -o $@ $< + +$(BUILD_DIR)/romlib.ld: romlib.ld.S + @echo " PP $@" + $(Q)$(CPP) $(PPFLAGS) -o $@ romlib.ld.S + +$(BUILD_DIR)/romlib.elf: $(OBJS) $(BUILD_DIR)/romlib.ld + @echo " LD $@" + $(Q)$(LD) -T $(BUILD_DIR)/romlib.ld -L$(LIB_DIR) $(LDFLAGS) -o $@ $(OBJS) $(LIBS) + +$(BUILD_DIR)/romlib.bin: $(BUILD_DIR)/romlib.elf + @echo " BIN $@" + $(Q)$(OC) -O binary $(BUILD_DIR)/romlib.elf $@ + +$(WRAPPER_DIR)/jmpvar.s: $(BUILD_DIR)/romlib.elf + @echo " VAR $@" + $(Q)./genvar.sh -o $@ $(BUILD_DIR)/romlib.elf + +$(LIB_DIR)/libwrappers.a: jmptbl.i $(WRAPPER_DIR)/jmpvar.o + @echo " AR $@" + $(Q)./genwrappers.sh -b $(WRAPPER_DIR) -o $@ jmptbl.i + +$(BUILD_DIR)/jmptbl.s: jmptbl.i + @echo " TBL $@" + $(Q)./gentbl.sh -o $@ jmptbl.i + +clean: + @rm -f $(BUILD_DIR)/* + +-include $(BUILD_DIR)/romlib.d diff --git a/lib/romlib/gentbl.sh b/lib/romlib/gentbl.sh new file mode 100755 index 00000000..0695f6e4 --- /dev/null +++ b/lib/romlib/gentbl.sh @@ -0,0 +1,40 @@ +#!/bin/sh +# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +set -e + +output=jmptbl.s + +for i +do + case $i in + -o) + output=$2 + shift 2 + ;; + --) + shift + break + ;; + -*) + echo usage: gentbl.sh [-o output] file ... >&2 + exit 1 + ;; + esac +done + +tmp=`mktemp` +trap "rm -f $tmp" EXIT INT QUIT + +rm -f $output + +awk -v OFS="\n" ' +BEGIN {print "\t.text", + "\t.globl\tjmptbl", + "jmptbl:"} + {sub(/[:blank:]*#.*/,"")} +!/^$/ {print "\tb\t" $3}' "$@" > $tmp + +mv $tmp $output diff --git a/lib/romlib/genvar.sh b/lib/romlib/genvar.sh new file mode 100755 index 00000000..a3e2cdf6 --- /dev/null +++ b/lib/romlib/genvar.sh @@ -0,0 +1,36 @@ +#!/bin/sh +# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +set -e + +output=jmpvar.s +for i +do + case $i in + -o) + output=$2 + shift 2 + ;; + --) + shift + break + ;; + -*) + echo usage: genvar.sh [-o output] file... >&2 + ;; + esac +done + +tmp=`mktemp` +trap "rm -f $tmp" EXIT INT QUIT + +nm -a "$@" | +awk -v OFS="\n" ' +$3 == ".text" {print "\t.data", + "\t.globl\tjmptbl", + "\t.align\t4", + "jmptbl:\t.quad\t0x" $1}' > $tmp + +mv $tmp $output diff --git a/lib/romlib/genwrappers.sh b/lib/romlib/genwrappers.sh new file mode 100755 index 00000000..bcf670b9 --- /dev/null +++ b/lib/romlib/genwrappers.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause + +set -e + +build=. +out=output.a + +for i +do + case $i in + -o) + out=$2 + shift 2 + ;; + -b) + build=$2 + shift 2 + ;; + --) + shift + break + ;; + -*) + echo usage: genwrappers.sh [-o output] [-b dir] file ... >&2 + exit 1 + ;; + esac +done + +awk '{sub(/[:blank:]*#.*/,"")} +!/^$/ {print $1*4, $2, $3}' "$@" | +while read idx lib sym +do + file=$build/${lib}_$sym + + cat <<EOF > $file.s + .globl $sym +$sym: + ldr x17, =jmptbl + ldr x17, [x17] + mov x16, $idx + add x16, x16, x17 + br x16 +EOF + + ${CROSS_COMPILE}as -o $file.o $file.s +done + +${CROSS_COMPILE}ar -rc $out $build/*.o diff --git a/lib/romlib/init.s b/lib/romlib/init.s new file mode 100644 index 00000000..5cf2aca0 --- /dev/null +++ b/lib/romlib/init.s @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + + .globl rom_lib_init + .extern __DATA_RAM_START__, __DATA_ROM_START__, __DATA_SIZE__ + .extern memset, memcpy + +rom_lib_init: + cmp w0, #1 + mov w0, #0 + b.le 1f + ret + +1: stp x29, x30, [sp, #-16]! + adrp x0, __DATA_RAM_START__ + ldr x1,= __DATA_ROM_START__ + ldr x2, =__DATA_SIZE__ + bl memcpy + + ldr x0, =__BSS_START__ + mov x1, #0 + ldr x2, =__BSS_SIZE__ + bl memset + ldp x29, x30, [sp], #16 + + mov w0, #1 + ret diff --git a/lib/romlib/jmptbl.i b/lib/romlib/jmptbl.i new file mode 100644 index 00000000..338cd8a7 --- /dev/null +++ b/lib/romlib/jmptbl.i @@ -0,0 +1,35 @@ +# +# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +0 rom rom_lib_init +1 fdt fdt_getprop_namelen +2 fdt fdt_setprop_inplace +3 fdt fdt_check_header +4 fdt fdt_node_offset_by_compatible +5 mbedtls mbedtls_asn1_get_alg +6 mbedtls mbedtls_asn1_get_alg_null +7 mbedtls mbedtls_asn1_get_bitstring_null +8 mbedtls mbedtls_asn1_get_bool +9 mbedtls mbedtls_asn1_get_int +10 mbedtls mbedtls_asn1_get_tag +11 mbedtls mbedtls_free +12 mbedtls mbedtls_md +13 mbedtls mbedtls_md_get_size +14 mbedtls mbedtls_memory_buffer_alloc_init +15 mbedtls mbedtls_oid_get_md_alg +16 mbedtls mbedtls_oid_get_numeric_string +17 mbedtls mbedtls_oid_get_pk_alg +18 mbedtls mbedtls_oid_get_sig_alg +19 mbedtls mbedtls_pk_free +20 mbedtls mbedtls_pk_init +21 mbedtls mbedtls_pk_parse_subpubkey +22 mbedtls mbedtls_pk_verify_ext +23 mbedtls mbedtls_platform_set_snprintf +24 mbedtls mbedtls_x509_get_rsassa_pss_params +25 mbedtls mbedtls_x509_get_sig_alg +26 mbedtls mbedtls_md_info_from_type +27 c exit +28 c atexit diff --git a/lib/romlib/romlib.ld.S b/lib/romlib/romlib.ld.S new file mode 100644 index 00000000..8f0bc62b --- /dev/null +++ b/lib/romlib/romlib.ld.S @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <platform_def.h> +#include <xlat_tables_defs.h> + +MEMORY { + ROM (rx): ORIGIN = ROMLIB_RO_BASE, LENGTH = ROMLIB_RO_LIMIT - ROMLIB_RO_BASE + RAM (rwx): ORIGIN = ROMLIB_RW_BASE, LENGTH = ROMLIB_RW_END - ROMLIB_RW_BASE +} + +OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT) +OUTPUT_ARCH(PLATFORM_LINKER_ARCH) +ENTRY(jmptbl) + +SECTIONS +{ + . = ROMLIB_RO_BASE; + .text : { + *jmptbl.o(.text) + *(.text*) + *(.rodata*) + } >ROM + + __DATA_ROM_START__ = LOADADDR(.data); + + .data : { + __DATA_RAM_START__ = .; + *(.data*) + __DATA_RAM_END__ = .; + } >RAM AT>ROM + + __DATA_SIZE__ = SIZEOF(.data); + + .bss : { + __BSS_START__ = .; + *(.bss*) + __BSS_END__ = .; + } >RAM + __BSS_SIZE__ = SIZEOF(.bss); +} diff --git a/lib/stdlib/exit.c b/lib/stdlib/exit.c deleted file mode 100644 index afc3f934..00000000 --- a/lib/stdlib/exit.c +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <debug.h> -#include <stdlib.h> - -void exit(int v) -{ - ERROR("EXIT\n"); - panic(); -} diff --git a/lib/xlat_tables/aarch32/xlat_tables.c b/lib/xlat_tables/aarch32/xlat_tables.c index 87b15b8c..033e2375 100644 --- a/lib/xlat_tables/aarch32/xlat_tables.c +++ b/lib/xlat_tables/aarch32/xlat_tables.c @@ -65,8 +65,20 @@ void init_xlat_tables(void) * Function for enabling the MMU in Secure PL1, assuming that the * page-tables have already been created. ******************************************************************************/ +#if !ERROR_DEPRECATED void enable_mmu_secure(unsigned int flags) { + enable_mmu_svc_mon(flags); +} + +void enable_mmu_direct(unsigned int flags) +{ + enable_mmu_direct_svc_mon(flags); +} +#endif + +void enable_mmu_svc_mon(unsigned int flags) +{ unsigned int mair0, ttbcr, sctlr; uint64_t ttbr0; @@ -131,7 +143,7 @@ void enable_mmu_secure(unsigned int flags) isb(); } -void enable_mmu_direct(unsigned int flags) +void enable_mmu_direct_svc_mon(unsigned int flags) { - enable_mmu_secure(flags); + enable_mmu_svc_mon(flags); } diff --git a/lib/xlat_tables_v2/aarch32/enable_mmu.S b/lib/xlat_tables_v2/aarch32/enable_mmu.S index 99cf0881..4a4ac30f 100644 --- a/lib/xlat_tables_v2/aarch32/enable_mmu.S +++ b/lib/xlat_tables_v2/aarch32/enable_mmu.S @@ -8,9 +8,11 @@ #include <assert_macros.S> #include <xlat_tables_v2.h> - .global enable_mmu_direct + .global enable_mmu_direct_svc_mon + .global enable_mmu_direct_hyp -func enable_mmu_direct + /* void enable_mmu_direct_svc_mon(unsigned int flags) */ +func enable_mmu_direct_svc_mon /* Assert that MMU is turned off */ #if ENABLE_ASSERTIONS ldcopr r1, SCTLR @@ -63,4 +65,56 @@ func enable_mmu_direct isb bx lr -endfunc enable_mmu_direct +endfunc enable_mmu_direct_svc_mon + + + /* void enable_mmu_direct_hyp(unsigned int flags) */ +func enable_mmu_direct_hyp + /* Assert that MMU is turned off */ +#if ENABLE_ASSERTIONS + ldcopr r1, HSCTLR + tst r1, #HSCTLR_M_BIT + ASM_ASSERT(eq) +#endif + + /* Invalidate TLB entries */ + TLB_INVALIDATE(r0, TLBIALL) + + mov r3, r0 + ldr r0, =mmu_cfg_params + + /* HMAIR0 */ + ldr r1, [r0, #(MMU_CFG_MAIR << 3)] + stcopr r1, HMAIR0 + + /* HTCR */ + ldr r2, [r0, #(MMU_CFG_TCR << 3)] + stcopr r2, HTCR + + /* HTTBR */ + ldr r1, [r0, #(MMU_CFG_TTBR0 << 3)] + ldr r2, [r0, #((MMU_CFG_TTBR0 << 3) + 4)] + stcopr16 r1, r2, HTTBR_64 + + /* + * Ensure all translation table writes have drained into memory, the TLB + * invalidation is complete, and translation register writes are + * committed before enabling the MMU + */ + dsb ish + isb + + /* Enable enable MMU by honoring flags */ + ldcopr r1, HSCTLR + ldr r2, =(HSCTLR_WXN_BIT | HSCTLR_C_BIT | HSCTLR_M_BIT) + orr r1, r1, r2 + + /* Clear C bit if requested */ + tst r3, #DISABLE_DCACHE + bicne r1, r1, #HSCTLR_C_BIT + + stcopr r1, HSCTLR + isb + + bx lr +endfunc enable_mmu_direct_hyp diff --git a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c index 24828409..66938e5f 100644 --- a/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c +++ b/lib/xlat_tables_v2/aarch32/xlat_tables_arch.c @@ -43,22 +43,38 @@ unsigned long long xlat_arch_get_max_supported_pa(void) } #endif /* ENABLE_ASSERTIONS*/ -bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx __unused) +bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx) { - return (read_sctlr() & SCTLR_M_BIT) != 0; + if (ctx->xlat_regime == EL1_EL0_REGIME) { + assert(xlat_arch_current_el() == 1U); + return (read_sctlr() & SCTLR_M_BIT) != 0U; + } else { + assert(ctx->xlat_regime == EL2_REGIME); + assert(xlat_arch_current_el() == 2U); + return (read_hsctlr() & HSCTLR_M_BIT) != 0U; + } } bool is_dcache_enabled(void) { - return (read_sctlr() & SCTLR_C_BIT) != 0; + if (IS_IN_EL2()) { + return (read_hsctlr() & HSCTLR_C_BIT) != 0U; + } else { + return (read_sctlr() & SCTLR_C_BIT) != 0U; + } } -uint64_t xlat_arch_regime_get_xn_desc(int xlat_regime __unused) +uint64_t xlat_arch_regime_get_xn_desc(int xlat_regime) { - return UPPER_ATTRS(XN); + if (xlat_regime == EL1_EL0_REGIME) { + return UPPER_ATTRS(XN) | UPPER_ATTRS(PXN); + } else { + assert(xlat_regime == EL2_REGIME); + return UPPER_ATTRS(XN); + } } -void xlat_arch_tlbi_va(uintptr_t va, int xlat_regime __unused) +void xlat_arch_tlbi_va(uintptr_t va, int xlat_regime) { /* * Ensure the translation table write has drained into memory before @@ -66,7 +82,12 @@ void xlat_arch_tlbi_va(uintptr_t va, int xlat_regime __unused) */ dsbishst(); - tlbimvaais(TLBI_ADDR(va)); + if (xlat_regime == EL1_EL0_REGIME) { + tlbimvaais(TLBI_ADDR(va)); + } else { + assert(xlat_regime == EL2_REGIME); + tlbimvahis(TLBI_ADDR(va)); + } } void xlat_arch_tlbi_va_sync(void) @@ -97,19 +118,25 @@ void xlat_arch_tlbi_va_sync(void) unsigned int xlat_arch_current_el(void) { - /* - * If EL3 is in AArch32 mode, all secure PL1 modes (Monitor, System, - * SVC, Abort, UND, IRQ and FIQ modes) execute at EL3. - * - * The PL1&0 translation regime in AArch32 behaves like the EL1&0 regime - * in AArch64 except for the XN bits, but we set and unset them at the - * same time, so there's no difference in practice. - */ - return 1U; + if (IS_IN_HYP()) { + return 2U; + } else { + assert(IS_IN_SVC() || IS_IN_MON()); + /* + * If EL3 is in AArch32 mode, all secure PL1 modes (Monitor, + * System, SVC, Abort, UND, IRQ and FIQ modes) execute at EL3. + * + * The PL1&0 translation regime in AArch32 behaves like the + * EL1&0 regime in AArch64 except for the XN bits, but we set + * and unset them at the same time, so there's no difference in + * practice. + */ + return 1U; + } } /******************************************************************************* - * Function for enabling the MMU in Secure PL1, assuming that the page tables + * Function for enabling the MMU in PL1 or PL2, assuming that the page tables * have already been created. ******************************************************************************/ void setup_mmu_cfg(uint64_t *params, unsigned int flags, @@ -119,8 +146,6 @@ void setup_mmu_cfg(uint64_t *params, unsigned int flags, uint64_t mair, ttbr0; uint32_t ttbcr; - assert(IS_IN_SECURE()); - /* Set attributes in the right indices of the MAIR */ mair = MAIR0_ATTR_SET(ATTR_DEVICE, ATTR_DEVICE_INDEX); mair |= MAIR0_ATTR_SET(ATTR_IWBWA_OWBWA_NTR, @@ -129,18 +154,32 @@ void setup_mmu_cfg(uint64_t *params, unsigned int flags, ATTR_NON_CACHEABLE_INDEX); /* - * Configure the control register for stage 1 of the PL1&0 translation - * regime. + * Configure the control register for stage 1 of the PL1&0 or EL2 + * translation regimes. */ /* Use the Long-descriptor translation table format. */ ttbcr = TTBCR_EAE_BIT; - /* - * Disable translation table walk for addresses that are translated - * using TTBR1. Therefore, only TTBR0 is used. - */ - ttbcr |= TTBCR_EPD1_BIT; + if (xlat_regime == EL1_EL0_REGIME) { + assert(IS_IN_SVC() || IS_IN_MON()); + /* + * Disable translation table walk for addresses that are + * translated using TTBR1. Therefore, only TTBR0 is used. + */ + ttbcr |= TTBCR_EPD1_BIT; + } else { + assert(xlat_regime == EL2_REGIME); + assert(IS_IN_HYP()); + + /* + * Set HTCR bits as well. Set HTTBR table properties + * as Inner & outer WBWA & shareable. + */ + ttbcr |= HTCR_RES1 | + HTCR_SH0_INNER_SHAREABLE | HTCR_RGN0_OUTER_WBA | + HTCR_RGN0_INNER_WBA; + } /* * Limit the input address ranges and memory region sizes translated diff --git a/lib/xlat_tables_v2/aarch64/enable_mmu.S b/lib/xlat_tables_v2/aarch64/enable_mmu.S index 5c5a2a92..21717d28 100644 --- a/lib/xlat_tables_v2/aarch64/enable_mmu.S +++ b/lib/xlat_tables_v2/aarch64/enable_mmu.S @@ -9,6 +9,7 @@ #include <xlat_tables_v2.h> .global enable_mmu_direct_el1 + .global enable_mmu_direct_el2 .global enable_mmu_direct_el3 /* Macros to read and write to system register for a given EL. */ @@ -20,6 +21,19 @@ mrs \gp_reg, \reg_name\()_el\()\el .endm + .macro tlbi_invalidate_all el + .if \el == 1 + TLB_INVALIDATE(vmalle1) + .elseif \el == 2 + TLB_INVALIDATE(alle2) + .elseif \el == 3 + TLB_INVALIDATE(alle3) + .else + .error "EL must be 1, 2 or 3" + .endif + .endm + + /* void enable_mmu_direct_el<x>(unsigned int flags) */ .macro define_mmu_enable_func el func enable_mmu_direct_\()el\el #if ENABLE_ASSERTIONS @@ -27,17 +41,8 @@ tst x1, #SCTLR_M_BIT ASM_ASSERT(eq) #endif - - /* Invalidate TLB entries */ - .if \el == 1 - TLB_INVALIDATE(vmalle1) - .else - .if \el == 3 - TLB_INVALIDATE(alle3) - .else - .error "EL must be 1 or 3" - .endif - .endif + /* Invalidate all TLB entries */ + tlbi_invalidate_all \el mov x7, x0 ldr x0, =mmu_cfg_params @@ -86,4 +91,5 @@ * enable_mmu_direct_el3 */ define_mmu_enable_func 1 + define_mmu_enable_func 2 define_mmu_enable_func 3 diff --git a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c index cf8070ad..d1555bf2 100644 --- a/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c +++ b/lib/xlat_tables_v2/aarch64/xlat_tables_arch.c @@ -105,6 +105,9 @@ bool is_mmu_enabled_ctx(const xlat_ctx_t *ctx) if (ctx->xlat_regime == EL1_EL0_REGIME) { assert(xlat_arch_current_el() >= 1U); return (read_sctlr_el1() & SCTLR_M_BIT) != 0U; + } else if (ctx->xlat_regime == EL2_REGIME) { + assert(xlat_arch_current_el() >= 2U); + return (read_sctlr_el2() & SCTLR_M_BIT) != 0U; } else { assert(ctx->xlat_regime == EL3_REGIME); assert(xlat_arch_current_el() >= 3U); @@ -118,6 +121,8 @@ bool is_dcache_enabled(void) if (el == 1U) { return (read_sctlr_el1() & SCTLR_C_BIT) != 0U; + } else if (el == 2U) { + return (read_sctlr_el2() & SCTLR_C_BIT) != 0U; } else { return (read_sctlr_el3() & SCTLR_C_BIT) != 0U; } @@ -128,7 +133,8 @@ uint64_t xlat_arch_regime_get_xn_desc(int xlat_regime) if (xlat_regime == EL1_EL0_REGIME) { return UPPER_ATTRS(UXN) | UPPER_ATTRS(PXN); } else { - assert(xlat_regime == EL3_REGIME); + assert((xlat_regime == EL2_REGIME) || + (xlat_regime == EL3_REGIME)); return UPPER_ATTRS(XN); } } @@ -151,6 +157,9 @@ void xlat_arch_tlbi_va(uintptr_t va, int xlat_regime) if (xlat_regime == EL1_EL0_REGIME) { assert(xlat_arch_current_el() >= 1U); tlbivaae1is(TLBI_ADDR(va)); + } else if (xlat_regime == EL2_REGIME) { + assert(xlat_arch_current_el() >= 2U); + tlbivae2is(TLBI_ADDR(va)); } else { assert(xlat_regime == EL3_REGIME); assert(xlat_arch_current_el() >= 3U); @@ -245,6 +254,8 @@ void setup_mmu_cfg(uint64_t *params, unsigned int flags, * that are translated using TTBR1_EL1. */ tcr |= TCR_EPD1_BIT | (tcr_ps_bits << TCR_EL1_IPS_SHIFT); + } else if (xlat_regime == EL2_REGIME) { + tcr |= TCR_EL2_RES1 | (tcr_ps_bits << TCR_EL2_PS_SHIFT); } else { assert(xlat_regime == EL3_REGIME); tcr |= TCR_EL3_RES1 | (tcr_ps_bits << TCR_EL3_PS_SHIFT); diff --git a/lib/xlat_tables_v2/xlat_tables_context.c b/lib/xlat_tables_v2/xlat_tables_context.c index 143f08ab..bf0cc9f5 100644 --- a/lib/xlat_tables_v2/xlat_tables_context.c +++ b/lib/xlat_tables_v2/xlat_tables_context.c @@ -82,6 +82,8 @@ void init_xlat_tables(void) if (current_el == 1U) { tf_xlat_ctx.xlat_regime = EL1_EL0_REGIME; + } else if (current_el == 2U) { + tf_xlat_ctx.xlat_regime = EL2_REGIME; } else { assert(current_el == 3U); tf_xlat_ctx.xlat_regime = EL3_REGIME; @@ -119,12 +121,32 @@ int xlat_change_mem_attributes(uintptr_t base_va, size_t size, uint32_t attr) #ifdef AARCH32 +#if !ERROR_DEPRECATED void enable_mmu_secure(unsigned int flags) { + enable_mmu_svc_mon(flags); +} + +void enable_mmu_direct(unsigned int flags) +{ + enable_mmu_direct_svc_mon(flags); +} +#endif + +void enable_mmu_svc_mon(unsigned int flags) +{ setup_mmu_cfg((uint64_t *)&mmu_cfg_params, flags, tf_xlat_ctx.base_table, MAX_PHYS_ADDR, tf_xlat_ctx.va_max_address, EL1_EL0_REGIME); - enable_mmu_direct(flags); + enable_mmu_direct_svc_mon(flags); +} + +void enable_mmu_hyp(unsigned int flags) +{ + setup_mmu_cfg((uint64_t *)&mmu_cfg_params, flags, + tf_xlat_ctx.base_table, MAX_PHYS_ADDR, + tf_xlat_ctx.va_max_address, EL2_REGIME); + enable_mmu_direct_hyp(flags); } #else @@ -137,6 +159,14 @@ void enable_mmu_el1(unsigned int flags) enable_mmu_direct_el1(flags); } +void enable_mmu_el2(unsigned int flags) +{ + setup_mmu_cfg((uint64_t *)&mmu_cfg_params, flags, + tf_xlat_ctx.base_table, MAX_PHYS_ADDR, + tf_xlat_ctx.va_max_address, EL2_REGIME); + enable_mmu_direct_el2(flags); +} + void enable_mmu_el3(unsigned int flags) { setup_mmu_cfg((uint64_t *)&mmu_cfg_params, flags, diff --git a/lib/xlat_tables_v2/xlat_tables_core.c b/lib/xlat_tables_v2/xlat_tables_core.c index 56b9514c..0340bf63 100644 --- a/lib/xlat_tables_v2/xlat_tables_core.c +++ b/lib/xlat_tables_v2/xlat_tables_core.c @@ -142,7 +142,8 @@ uint64_t xlat_desc(const xlat_ctx_t *ctx, uint32_t attr, desc |= LOWER_ATTRS(AP_NO_ACCESS_UNPRIVILEGED); } } else { - assert(ctx->xlat_regime == EL3_REGIME); + assert((ctx->xlat_regime == EL2_REGIME) || + (ctx->xlat_regime == EL3_REGIME)); desc |= LOWER_ATTRS(AP_ONE_VA_RANGE_RES1); } @@ -1016,6 +1017,7 @@ void init_xlat_tables_ctx(xlat_ctx_t *ctx) assert(ctx != NULL); assert(!ctx->initialized); assert((ctx->xlat_regime == EL3_REGIME) || + (ctx->xlat_regime == EL2_REGIME) || (ctx->xlat_regime == EL1_EL0_REGIME)); assert(!is_mmu_enabled_ctx(ctx)); diff --git a/lib/xlat_tables_v2/xlat_tables_utils.c b/lib/xlat_tables_v2/xlat_tables_utils.c index 8cad3483..05533c61 100644 --- a/lib/xlat_tables_v2/xlat_tables_utils.c +++ b/lib/xlat_tables_v2/xlat_tables_utils.c @@ -60,8 +60,8 @@ static void xlat_desc_print(const xlat_ctx_t *ctx, uint64_t desc) tf_printf("DEV"); } - if (xlat_regime == EL3_REGIME) { - /* For EL3 only check the AP[2] and XN bits. */ + if ((xlat_regime == EL3_REGIME) || (xlat_regime == EL2_REGIME)) { + /* For EL3 and EL2 only check the AP[2] and XN bits. */ tf_printf(((desc & LOWER_ATTRS(AP_RO)) != 0ULL) ? "-RO" : "-RW"); tf_printf(((desc & UPPER_ATTRS(XN)) != 0ULL) ? "-XN" : "-EXEC"); } else { @@ -200,6 +200,8 @@ void xlat_tables_print(xlat_ctx_t *ctx) if (ctx->xlat_regime == EL1_EL0_REGIME) { xlat_regime_str = "1&0"; + } else if (ctx->xlat_regime == EL2_REGIME) { + xlat_regime_str = "2"; } else { assert(ctx->xlat_regime == EL3_REGIME); xlat_regime_str = "3"; @@ -329,6 +331,7 @@ static int xlat_get_mem_attributes_internal(const xlat_ctx_t *ctx, assert(ctx != NULL); assert(ctx->initialized); assert((ctx->xlat_regime == EL1_EL0_REGIME) || + (ctx->xlat_regime == EL2_REGIME) || (ctx->xlat_regime == EL3_REGIME)); virt_addr_space_size = (unsigned long long)ctx->va_max_address + 1ULL; |