diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | docs/conf.py | 10 | ||||
-rw-r--r-- | docs/index.rst | 11 | ||||
-rw-r--r-- | docs/requirements.txt | 2 | ||||
-rw-r--r-- | drivers/arm/gic/v3/gicv3_main.c | 9 | ||||
-rw-r--r-- | lib/cpus/aarch64/cortex_a76.S | 5 | ||||
-rw-r--r-- | lib/cpus/aarch64/cortex_a76ae.S | 5 | ||||
-rw-r--r-- | lib/cpus/aarch64/cortex_deimos.S | 5 | ||||
-rw-r--r-- | lib/cpus/aarch64/neoverse_e1.S | 5 | ||||
-rw-r--r-- | lib/cpus/aarch64/neoverse_n1.S | 5 | ||||
-rw-r--r-- | lib/cpus/aarch64/neoverse_zeus.S | 5 | ||||
-rw-r--r-- | lib/romlib/Makefile | 9 | ||||
-rwxr-xr-x | lib/romlib/gentbl.sh | 13 | ||||
-rwxr-xr-x | lib/romlib/genwrappers.sh | 27 | ||||
-rw-r--r-- | plat/arm/board/fvp/platform.mk | 25 | ||||
-rw-r--r-- | plat/mediatek/mt8183/aarch64/platform_common.c | 31 | ||||
-rw-r--r-- | plat/mediatek/mt8183/bl31_plat_setup.c | 13 | ||||
-rw-r--r-- | plat/mediatek/mt8183/drivers/mcsi/mcsi.c | 211 | ||||
-rw-r--r-- | plat/mediatek/mt8183/drivers/mcsi/mcsi.h | 116 | ||||
-rw-r--r-- | plat/mediatek/mt8183/include/mt_gic_v3.h | 35 | ||||
-rw-r--r-- | plat/mediatek/mt8183/include/plat_private.h | 9 | ||||
-rw-r--r-- | plat/mediatek/mt8183/plat_mt_gic.c | 146 | ||||
-rw-r--r-- | plat/mediatek/mt8183/platform.mk | 11 | ||||
-rw-r--r-- | readme.rst | 11 |
24 files changed, 677 insertions, 44 deletions
@@ -937,7 +937,7 @@ ${SPTOOL}: .PHONY: libraries romlib.bin: libraries - ${Q}${MAKE} PLAT_DIR=${PLAT_DIR} BUILD_PLAT=${BUILD_PLAT} INCLUDES='${INCLUDES}' DEFINES='${DEFINES}' --no-print-directory -C ${ROMLIBPATH} all + ${Q}${MAKE} PLAT_DIR=${PLAT_DIR} BUILD_PLAT=${BUILD_PLAT} ENABLE_BTI=${ENABLE_BTI} ARM_ARCH_MINOR=${ARM_ARCH_MINOR} INCLUDES='${INCLUDES}' DEFINES='${DEFINES}' --no-print-directory -C ${ROMLIBPATH} all cscope: @echo " CSCOPE" diff --git a/docs/conf.py b/docs/conf.py index 697b8711..64f12431 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -23,7 +23,7 @@ release = version # We don't need these to be distinct # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = [] +extensions = ['sphinx.ext.autosectionlabel'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -54,6 +54,9 @@ pygments_style = 'sphinx' with open('global_substitutions.txt', 'r') as subs: rst_prolog = subs.read() +# Minimum version of sphinx required +needs_sphinx = '2.0' + # -- Options for HTML output ------------------------------------------------- # Don't show the "Built with Sphinx" footer @@ -75,3 +78,8 @@ html_theme_options = { 'prev_next_buttons_location': 'both', # Top and bottom of the page 'style_external_links': True # Display an icon next to external links } + +# -- Options for autosectionlabel -------------------------------------------- + +# Only generate automatic section labels for document titles +autosectionlabel_maxdepth = 1
\ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 4e8f17a5..7ac0584c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -260,13 +260,13 @@ See the `Contributing Guidelines`_ for information on how to contribute to this project and the `Acknowledgments`_ file for a list of contributors to the project. -Feedback and support -~~~~~~~~~~~~~~~~~~~~ +Contact us +~~~~~~~~~~ -Arm welcomes any feedback on TF-A. If you think you have found a security +We welcome any feedback on TF-A. If you think you have found a security vulnerability, please report this using the process defined in the TF-A -`Security Center`_. For all other feedback, please use the -`issue tracker`_. +`Security Center`_. For all other feedback, you can use either the +`issue tracker`_ or our `mailing list`_. Arm licensees may contact Arm directly via their partner managers. @@ -293,6 +293,7 @@ Arm licensees may contact Arm directly via their partner managers. .. _Trusty Secure OS: https://source.android.com/security/trusty .. _trustedfirmware.org: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git .. _issue tracker: https://issues.trustedfirmware.org +.. _mailing list: https://lists.trustedfirmware.org/mailman/listinfo/tf-a .. _Security Center: ./process/security.rst .. _license: ./license.rst .. _Contributing Guidelines: ./process/contributing.rst diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000..8f95774b --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +sphinx>=2.0.0 +sphinx-rtd-theme>=0.4.3
\ No newline at end of file diff --git a/drivers/arm/gic/v3/gicv3_main.c b/drivers/arm/gic/v3/gicv3_main.c index cf92f10b..a94dbf67 100644 --- a/drivers/arm/gic/v3/gicv3_main.c +++ b/drivers/arm/gic/v3/gicv3_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -265,6 +265,10 @@ void gicv3_cpuif_enable(unsigned int proc_num) write_scr_el3(scr_el3 & (~SCR_NS_BIT)); isb(); + /* Write the secure ICC_SRE_EL1 register */ + write_icc_sre_el1(ICC_SRE_SRE_BIT); + isb(); + /* Program the idle priority in the PMR */ write_icc_pmr_el1(GIC_PRI_MASK); @@ -274,9 +278,6 @@ void gicv3_cpuif_enable(unsigned int proc_num) /* Enable Group1 Secure interrupts */ write_icc_igrpen1_el3(read_icc_igrpen1_el3() | IGRPEN1_EL3_ENABLE_G1S_BIT); - - /* Write the secure ICC_SRE_EL1 register */ - write_icc_sre_el1(ICC_SRE_SRE_BIT); isb(); } diff --git a/lib/cpus/aarch64/cortex_a76.S b/lib/cpus/aarch64/cortex_a76.S index b48283cb..868667eb 100644 --- a/lib/cpus/aarch64/cortex_a76.S +++ b/lib/cpus/aarch64/cortex_a76.S @@ -18,6 +18,11 @@ #error "Cortex-A76 must be compiled with HW_ASSISTED_COHERENCY enabled" #endif +/* 64-bit only core */ +#if CTX_INCLUDE_AARCH32_REGS == 1 +#error "Cortex-A76 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" +#endif + #define ESR_EL3_A64_SMC0 0x5e000000 #define ESR_EL3_A32_SMC0 0x4e000000 diff --git a/lib/cpus/aarch64/cortex_a76ae.S b/lib/cpus/aarch64/cortex_a76ae.S index 46e9450f..888f98b5 100644 --- a/lib/cpus/aarch64/cortex_a76ae.S +++ b/lib/cpus/aarch64/cortex_a76ae.S @@ -13,6 +13,11 @@ #error "Cortex-A76AE must be compiled with HW_ASSISTED_COHERENCY enabled" #endif +/* 64-bit only core */ +#if CTX_INCLUDE_AARCH32_REGS == 1 +#error "Cortex-A76AE supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" +#endif + /* --------------------------------------------- * HW will do the cache maintenance while powering down * --------------------------------------------- diff --git a/lib/cpus/aarch64/cortex_deimos.S b/lib/cpus/aarch64/cortex_deimos.S index e73e89f7..df4c1285 100644 --- a/lib/cpus/aarch64/cortex_deimos.S +++ b/lib/cpus/aarch64/cortex_deimos.S @@ -16,6 +16,11 @@ #error "Deimos must be compiled with HW_ASSISTED_COHERENCY enabled" #endif +/* 64-bit only core */ +#if CTX_INCLUDE_AARCH32_REGS == 1 +#error "Cortex-Deimos supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" +#endif + /* --------------------------------------------- * HW will do the cache maintenance while powering down * --------------------------------------------- diff --git a/lib/cpus/aarch64/neoverse_e1.S b/lib/cpus/aarch64/neoverse_e1.S index 71e7b517..d840da84 100644 --- a/lib/cpus/aarch64/neoverse_e1.S +++ b/lib/cpus/aarch64/neoverse_e1.S @@ -16,6 +16,11 @@ #error "Neoverse E1 must be compiled with HW_ASSISTED_COHERENCY enabled" #endif +/* 64-bit only core */ +#if CTX_INCLUDE_AARCH32_REGS == 1 +#error "Neoverse-E1 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" +#endif + func neoverse_e1_cpu_pwr_dwn mrs x0, NEOVERSE_E1_CPUPWRCTLR_EL1 orr x0, x0, #NEOVERSE_E1_CPUPWRCTLR_EL1_CORE_PWRDN_BIT diff --git a/lib/cpus/aarch64/neoverse_n1.S b/lib/cpus/aarch64/neoverse_n1.S index a0babb0e..dadaf98b 100644 --- a/lib/cpus/aarch64/neoverse_n1.S +++ b/lib/cpus/aarch64/neoverse_n1.S @@ -15,6 +15,11 @@ #error "Neoverse N1 must be compiled with HW_ASSISTED_COHERENCY enabled" #endif +/* 64-bit only core */ +#if CTX_INCLUDE_AARCH32_REGS == 1 +#error "Neoverse-N1 supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" +#endif + /* -------------------------------------------------- * Errata Workaround for Neoverse N1 Errata * This applies to revision r0p0 and r1p0 of Neoverse N1. diff --git a/lib/cpus/aarch64/neoverse_zeus.S b/lib/cpus/aarch64/neoverse_zeus.S index c5241afa..3d850137 100644 --- a/lib/cpus/aarch64/neoverse_zeus.S +++ b/lib/cpus/aarch64/neoverse_zeus.S @@ -16,6 +16,11 @@ #error "Neoverse Zeus must be compiled with HW_ASSISTED_COHERENCY enabled" #endif +/* 64-bit only core */ +#if CTX_INCLUDE_AARCH32_REGS == 1 +#error "Neoverse-Zeus supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0" +#endif + /* --------------------------------------------- * HW will do the cache maintenance while powering down * --------------------------------------------- diff --git a/lib/romlib/Makefile b/lib/romlib/Makefile index 7a3a51ea..bc05d0fa 100644 --- a/lib/romlib/Makefile +++ b/lib/romlib/Makefile @@ -29,6 +29,11 @@ ifeq ($(DEBUG),1) LDFLAGS += -Map=$(MAPFILE) endif +ifeq (${ARM_ARCH_MINOR},0) + ASFLAGS = -march=armv8-a +else + ASFLAGS = -march=armv8.${ARM_ARCH_MINOR}-a +endif .PHONY: all clean distclean @@ -60,13 +65,13 @@ $(WRAPPER_DIR)/jmpvar.s: $(BUILD_DIR)/romlib.elf $(LIB_DIR)/libwrappers.a: $(BUILD_DIR)/jmptbl.i $(WRAPPER_DIR)/jmpvar.o @echo " AR $@" - $(Q)./genwrappers.sh -b $(WRAPPER_DIR) -o $@ $(BUILD_DIR)/jmptbl.i + $(Q)./genwrappers.sh -b $(WRAPPER_DIR) -o $@ --bti=$(ENABLE_BTI) --asflags=$(ASFLAGS) $(BUILD_DIR)/jmptbl.i $(BUILD_DIR)/jmptbl.i: $(BUILD_DIR)/jmptbl.s $(BUILD_DIR)/jmptbl.s: ../../$(PLAT_DIR)/jmptbl.i @echo " TBL $@" - $(Q)./gentbl.sh -o $@ -b $(BUILD_DIR) ../../$(PLAT_DIR)/jmptbl.i + $(Q)./gentbl.sh -o $@ -b $(BUILD_DIR) --bti=$(ENABLE_BTI) ../../$(PLAT_DIR)/jmptbl.i clean: @rm -f $(BUILD_DIR)/* diff --git a/lib/romlib/gentbl.sh b/lib/romlib/gentbl.sh index e64cfe2b..bfb1ec3cf 100755 --- a/lib/romlib/gentbl.sh +++ b/lib/romlib/gentbl.sh @@ -1,5 +1,5 @@ #!/bin/sh -# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause @@ -19,6 +19,10 @@ do build=$2 shift 2 ;; + --bti=*) + enable_bti=$(echo $1 | sed 's/--bti=\(.*\)/\1/') + shift 1 + ;; --) shift break @@ -47,12 +51,15 @@ if (NF == 2 && $1 == "include") { awk -v OFS="\t" ' BEGIN{print "#index\tlib\tfunction\t[patch]"} {print NR-1, $0}' | tee $build/jmptbl.i | -awk -v OFS="\n" ' +awk -v OFS="\n" -v BTI=$enable_bti ' BEGIN {print "\t.text", "\t.globl\tjmptbl", "jmptbl:"} {sub(/[:blank:]*#.*/,"")} -!/^$/ {if ($3 == "reserved") +!/^$/ { + if (BTI == 1) + print "\tbti\tj" + if ($3 == "reserved") print "\t.word\t0x0" else print "\tb\t" $3}' > $$.tmp && diff --git a/lib/romlib/genwrappers.sh b/lib/romlib/genwrappers.sh index 07d59ac4..e092548e 100755 --- a/lib/romlib/genwrappers.sh +++ b/lib/romlib/genwrappers.sh @@ -19,6 +19,14 @@ do build=$2 shift 2 ;; + --bti=*) + enable_bti=$(echo $1 | sed 's/--bti=\(.*\)/\1/') + shift 1 + ;; + --asflags=*) + asflags=$(echo $1 | sed 's/--asflags=\(.*\)/\1/') + shift 1 + ;; --) shift break @@ -30,8 +38,13 @@ do esac done -awk '{sub(/[:blank:]*#.*/,"")} -!/^$/ && $NF != "patch" && $NF != "reserved" {print $1*4, $2, $3}' "$@" | +awk -v BTI=$enable_bti ' +{sub(/[:blank:]*#.*/,"")} +!/^$/ && $NF != "patch" && $NF != "reserved" { + if (BTI == 1) + print $1*8, $2, $3 + else + print $1*4, $2, $3}' "$@" | while read idx lib sym do file=$build/${lib}_$sym @@ -39,14 +52,20 @@ do cat <<EOF > $file.s .globl $sym $sym: +EOF +if [ $enable_bti = 1 ] +then + echo "\tbti\tjc" >> $file.s +fi + cat <<EOF >> $file.s ldr x17, =jmptbl - ldr x17, [x17] mov x16, #$idx + ldr x17, [x17] add x16, x16, x17 br x16 EOF - ${CROSS_COMPILE}as -o $file.o $file.s + ${CROSS_COMPILE}as ${asflags} -o $file.o $file.s done ${CROSS_COMPILE}ar -rc $out $build/*.o diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index dbc5c21b..3cbdfbc4 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -96,8 +96,8 @@ FVP_CPU_LIBS := lib/cpus/${ARCH}/aem_generic.S ifeq (${ARCH}, aarch64) -# select a different set of CPU files, depending on whether we compile with -# hardware assisted coherency configurations or not +# select a different set of CPU files, depending on whether we compile for +# hardware assisted coherency cores or not ifeq (${HW_ASSISTED_COHERENCY}, 0) FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a35.S \ lib/cpus/aarch64/cortex_a53.S \ @@ -105,14 +105,19 @@ ifeq (${HW_ASSISTED_COHERENCY}, 0) lib/cpus/aarch64/cortex_a72.S \ lib/cpus/aarch64/cortex_a73.S else - FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a55.S \ - lib/cpus/aarch64/cortex_a75.S \ - lib/cpus/aarch64/cortex_a76.S \ - lib/cpus/aarch64/cortex_a76ae.S \ - lib/cpus/aarch64/neoverse_n1.S \ - lib/cpus/aarch64/neoverse_e1.S \ - lib/cpus/aarch64/cortex_deimos.S \ - lib/cpus/aarch64/neoverse_zeus.S + # AArch64-only cores + ifeq (${CTX_INCLUDE_AARCH32_REGS}, 0) + FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a76.S \ + lib/cpus/aarch64/cortex_a76ae.S \ + lib/cpus/aarch64/neoverse_n1.S \ + lib/cpus/aarch64/neoverse_e1.S \ + lib/cpus/aarch64/cortex_deimos.S \ + lib/cpus/aarch64/neoverse_zeus.S + # AArch64/AArch32 + else + FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a55.S \ + lib/cpus/aarch64/cortex_a75.S + endif endif else diff --git a/plat/mediatek/mt8183/aarch64/platform_common.c b/plat/mediatek/mt8183/aarch64/platform_common.c index ff0aaeb9..31d13390 100644 --- a/plat/mediatek/mt8183/aarch64/platform_common.c +++ b/plat/mediatek/mt8183/aarch64/platform_common.c @@ -7,10 +7,16 @@ #include <arch_helpers.h> #include <common/bl_common.h> #include <common/debug.h> +#include <mcsi/mcsi.h> #include <platform_def.h> #include <lib/utils.h> #include <lib/xlat_tables/xlat_tables.h> +static const int cci_map[] = { + PLAT_MT_CCI_CLUSTER0_SL_IFACE_IX, + PLAT_MT_CCI_CLUSTER1_SL_IFACE_IX +}; + /* Table of regions to map using the MMU. */ const mmap_region_t plat_mmap[] = { /* for TF text, RO, RW */ @@ -51,3 +57,28 @@ unsigned int plat_get_syscnt_freq2(void) { return SYS_COUNTER_FREQ_IN_TICKS; } + +void plat_mtk_cci_init(void) +{ + /* Initialize CCI driver */ + mcsi_init(PLAT_MT_CCI_BASE, ARRAY_SIZE(cci_map)); +} + +void plat_mtk_cci_enable(void) +{ + /* Enable CCI coherency for this cluster. + * No need for locks as no other cpu is active at the moment. + */ + cci_enable_cluster_coherency(read_mpidr()); +} + +void plat_mtk_cci_disable(void) +{ + cci_disable_cluster_coherency(read_mpidr()); +} + +void plat_mtk_cci_init_sf(void) +{ + /* Init mcsi snoop filter. */ + cci_init_sf(); +} diff --git a/plat/mediatek/mt8183/bl31_plat_setup.c b/plat/mediatek/mt8183/bl31_plat_setup.c index 1e5367fc..b451189d 100644 --- a/plat/mediatek/mt8183/bl31_plat_setup.c +++ b/plat/mediatek/mt8183/bl31_plat_setup.c @@ -12,6 +12,7 @@ #include <common/debug.h> #include <drivers/generic_delay_timer.h> #include <mcucfg.h> +#include <mt_gic_v3.h> #include <lib/mmio.h> #include <mtk_plat_common.h> #include <plat_debug.h> @@ -69,8 +70,8 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { struct mtk_bl31_params *arg_from_bl2 = (struct mtk_bl31_params *)arg0; - static console_16550_t console; + console_16550_register(UART0_BASE, UART_CLOCK, UART_BAUDRATE, &console); NOTICE("MT8183 bl31_setup\n"); @@ -91,6 +92,13 @@ void bl31_platform_setup(void) { platform_setup_cpu(); generic_delay_timer_init(); + + /* Initialize the GIC driver, CPU and distributor interfaces */ + mt_gic_driver_init(); + mt_gic_init(); + + /* Init mcsi SF */ + plat_mtk_cci_init_sf(); } /******************************************************************************* @@ -99,6 +107,9 @@ void bl31_platform_setup(void) ******************************************************************************/ void bl31_plat_arch_setup(void) { + plat_mtk_cci_init(); + plat_mtk_cci_enable(); + enable_scu(read_mpidr()); plat_configure_mmu_el3(BL_CODE_BASE, diff --git a/plat/mediatek/mt8183/drivers/mcsi/mcsi.c b/plat/mediatek/mt8183/drivers/mcsi/mcsi.c new file mode 100644 index 00000000..cbe7f0a4 --- /dev/null +++ b/plat/mediatek/mt8183/drivers/mcsi/mcsi.c @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <arch_helpers.h> +#include <assert.h> +#include <common/debug.h> +#include <lib/mmio.h> +#include <scu.h> +#include <mcucfg.h> +#include <drivers/delay_timer.h> +#include <mcsi/mcsi.h> + +#define MAX_CLUSTERS 5 + +static unsigned long cci_base_addr; +static unsigned int cci_cluster_ix_to_iface[MAX_CLUSTERS]; + +void mcsi_init(unsigned long cci_base, + unsigned int num_cci_masters) +{ + int i; + + assert(cci_base); + assert(num_cci_masters < MAX_CLUSTERS); + + cci_base_addr = cci_base; + + for (i = 0; i < num_cci_masters; i++) + cci_cluster_ix_to_iface[i] = SLAVE_IFACE_OFFSET(i); +} + +void mcsi_cache_flush(void) +{ + /* timeout is 10ms */ + int timeout = 10000; + + /* to make flush by SF safe, need to disable BIU DCM */ + mmio_clrbits_32(CCI_CLK_CTRL, 1 << 8); + mmio_write_32(cci_base_addr + FLUSH_SF, 0x1); + + for (; timeout; timeout--, udelay(1)) { + if ((mmio_read_32(cci_base_addr + FLUSH_SF) & 0x1) == 0x0) + break; + } + + if (!timeout) { + INFO("SF lush timeout\n"); + return; + } + + /* enable BIU DCM as it was */ + mmio_setbits_32(CCI_CLK_CTRL, 1 << 8); +} + +static inline unsigned long get_slave_iface_base(unsigned long mpidr) +{ + /* + * We assume the TF topology code allocates affinity instances + * consecutively from zero. + * It is a programming error if this is called without initializing + * the slave interface to use for this cluster. + */ + unsigned int cluster_id = + (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; + + assert(cluster_id < MAX_CLUSTERS); + assert(cci_cluster_ix_to_iface[cluster_id] != 0); + + return cci_base_addr + cci_cluster_ix_to_iface[cluster_id]; +} + +void cci_enable_cluster_coherency(unsigned long mpidr) +{ + unsigned long slave_base; + unsigned int support_ability; + unsigned int config = 0; + unsigned int pending = 0; + + assert(cci_base_addr); + slave_base = get_slave_iface_base(mpidr); + support_ability = mmio_read_32(slave_base); + + pending = (mmio_read_32( + cci_base_addr + SNP_PENDING_REG)) >> SNP_PENDING; + while (pending) { + pending = (mmio_read_32( + cci_base_addr + SNP_PENDING_REG)) >> SNP_PENDING; + } + + if (support_ability & SNP_SUPPORT) + config |= SNOOP_EN_BIT; + if (support_ability & DVM_SUPPORT) + config |= DVM_EN_BIT; + + mmio_write_32(slave_base, support_ability | config); + + /* Wait for the dust to settle down */ + while (mmio_read_32(cci_base_addr + SNP_PENDING_REG) >> SNP_PENDING) + ; +} + +#if ERRATA_MCSIB_SW +#pragma weak mcsib_sw_workaround_main +#endif + +void cci_disable_cluster_coherency(unsigned long mpidr) +{ + unsigned long slave_base; + unsigned int config = 0; + + assert(cci_base_addr); + slave_base = get_slave_iface_base(mpidr); + + while (mmio_read_32(cci_base_addr + SNP_PENDING_REG) >> SNP_PENDING) + ; + + config = mmio_read_32(slave_base); + config &= ~(DVM_EN_BIT | SNOOP_EN_BIT); + + /* Disable Snoops and DVM messages */ + mmio_write_32(slave_base, config); + +#if ERRATA_MCSIB_SW + mcsib_sw_workaround_main(); +#endif + + /* Wait for the dust to settle down */ + while (mmio_read_32(cci_base_addr + SNP_PENDING_REG) >> SNP_PENDING) + ; +} + +void cci_secure_switch(unsigned int status) +{ + unsigned int config; + + config = mmio_read_32(cci_base_addr + CENTRAL_CTRL_REG); + if (status == NS_ACC) + config |= SECURE_ACC_EN; + else + config &= ~SECURE_ACC_EN; + mmio_write_32(cci_base_addr + CENTRAL_CTRL_REG, config); +} + +void cci_pmu_secure_switch(unsigned int status) +{ + unsigned int config; + + config = mmio_read_32(cci_base_addr + CENTRAL_CTRL_REG); + if (status == NS_ACC) + config |= PMU_SECURE_ACC_EN; + else + config &= ~PMU_SECURE_ACC_EN; + mmio_write_32(cci_base_addr + CENTRAL_CTRL_REG, config); +} + +void cci_init_sf(void) +{ + while (mmio_read_32(cci_base_addr + SNP_PENDING_REG) >> SNP_PENDING) + ; + /* init sf1 */ + mmio_write_32(cci_base_addr + SF_INIT_REG, TRIG_SF1_INIT); + while (mmio_read_32(cci_base_addr + SF_INIT_REG) & TRIG_SF1_INIT) + ; + while (!(mmio_read_32(cci_base_addr + SF_INIT_REG) & SF1_INIT_DONE)) + ; + /* init sf2 */ + mmio_write_32(cci_base_addr + SF_INIT_REG, TRIG_SF2_INIT); + while (mmio_read_32(cci_base_addr + SF_INIT_REG) & TRIG_SF2_INIT) + ; + while (!(mmio_read_32(cci_base_addr + SF_INIT_REG) & SF2_INIT_DONE)) + ; +} + +void cci_interrupt_en(void) +{ + mmio_setbits_32(cci_base_addr + CENTRAL_CTRL_REG, INT_EN); +} + +unsigned long cci_reg_access(unsigned int op, unsigned long offset, + unsigned long val) +{ + unsigned long ret = 0; + + if ((cci_base_addr == 0) || (offset > MSCI_MEMORY_SZ)) + panic(); + + switch (op) { + case MCSI_REG_ACCESS_READ: + ret = mmio_read_32(cci_base_addr + offset); + break; + case MCSI_REG_ACCESS_WRITE: + mmio_write_32(cci_base_addr + offset, val); + dsb(); + break; + case MCSI_REG_ACCESS_SET_BITMASK: + mmio_setbits_32(cci_base_addr + offset, val); + dsb(); + break; + case MCSI_REG_ACCESS_CLEAR_BITMASK: + mmio_clrbits_32(cci_base_addr + offset, val); + dsb(); + break; + default: + break; + } + return ret; +} diff --git a/plat/mediatek/mt8183/drivers/mcsi/mcsi.h b/plat/mediatek/mt8183/drivers/mcsi/mcsi.h new file mode 100644 index 00000000..c13e22ad --- /dev/null +++ b/plat/mediatek/mt8183/drivers/mcsi/mcsi.h @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MCSI_H +#define MCSI_H + +#define SLAVE_IFACE7_OFFSET 0x1700 +#define SLAVE_IFACE6_OFFSET 0x1600 +#define SLAVE_IFACE5_OFFSET 0x1500 +#define SLAVE_IFACE4_OFFSET 0x1400 +#define SLAVE_IFACE3_OFFSET 0x1300 +#define SLAVE_IFACE2_OFFSET 0x1200 +#define SLAVE_IFACE1_OFFSET 0x1100 +#define SLAVE_IFACE0_OFFSET 0x1000 +#define SLAVE_IFACE_OFFSET(index) (SLAVE_IFACE0_OFFSET + \ + (0x100 * (index))) +/* Control and ID register offsets */ +#define CENTRAL_CTRL_REG 0x0 +#define ERR_FLAG_REG 0x4 +#define SF_INIT_REG 0x10 +#define SF_CTRL_REG 0x14 +#define DCM_CTRL_REG 0x18 +#define ERR_FLAG2_REG 0x20 +#define SNP_PENDING_REG 0x28 +#define ACP_PENDING_REG 0x2c +#define FLUSH_SF 0x500 +#define SYS_CCE_CTRL 0x2000 +#define MST1_CTRL 0x2100 +#define MTS2_CTRL 0x2200 +#define XBAR_ARAW_ARB 0x3000 +#define XBAR_R_ARB 0x3004 + +/* Slave interface register offsets */ +#define SNOOP_CTRL_REG 0x0 +#define QOS_CTRL_REG 0x4 +#define QOS_OVERRIDE_REG 0x8 +#define QOS_TARGET_REG 0xc +#define BD_CTRL_REG 0x40 + +/* Snoop Control register bit definitions */ +#define DVM_SUPPORT (1 << 31) +#define SNP_SUPPORT (1 << 30) +#define SHAREABLE_OVWRT (1 << 2) +#define DVM_EN_BIT (1 << 1) +#define SNOOP_EN_BIT (1 << 0) +#define SF2_INIT_DONE (1 << 17) +#define SF1_INIT_DONE (1 << 16) +#define TRIG_SF2_INIT (1 << 1) +#define TRIG_SF1_INIT (1 << 0) + +/* Status register bit definitions */ +#define SNP_PENDING 31 + +/* Status bit */ +#define NS_ACC 1 +#define S_ACC 0 + +/* Central control register bit definitions */ +#define PMU_SECURE_ACC_EN (1 << 4) +#define INT_EN (1 << 3) +#define SECURE_ACC_EN (1 << 2) +#define DVM_DIS (1 << 1) +#define SNOOP_DIS (1 << 0) + +#define MSCI_MEMORY_SZ (0x10000) + +#define MCSI_REG_ACCESS_READ (0x0) +#define MCSI_REG_ACCESS_WRITE (0x1) +#define MCSI_REG_ACCESS_SET_BITMASK (0x2) +#define MCSI_REG_ACCESS_CLEAR_BITMASK (0x3) + +#define NR_MAX_SLV (7) + +/* ICCS */ +#define CACHE_INSTR_EN (1 << 2) +#define IDLE_CACHE (1 << 3) +#define USE_SHARED_CACHE (1 << 4) +#define CACHE_SHARED_PRE_EN (1 << 5) +#define CACHE_SHARED_POST_EN (1 << 6) + +#define ACP_PENDING_MASK (0x1007f) + +#define CCI_CLK_CTRL (MCUCFG_BASE + 0x660) + +#ifndef __ASSEMBLY__ + +#include <plat/common/common_def.h> +#include <stdint.h> + +/* Function declarations */ + +/* + * The MCSI driver must be initialized with the base address of the + * MCSI device in the platform memory map, and the cluster indices for + * the MCSI slave interfaces 3 and 4 respectively. These are the fully + * coherent ACE slave interfaces of MCSI. + * The cluster indices must either be 0 or 1, corresponding to the level 1 + * affinity instance of the mpidr representing the cluster. A negative cluster + * index indicates that no cluster is present on that slave interface. + */ +void mcsi_init(unsigned long cci_base, + unsigned int num_cci_masters); +void mcsi_cache_flush(void); + +void cci_enable_cluster_coherency(unsigned long mpidr); +void cci_disable_cluster_coherency(unsigned long mpidr); + +void cci_secure_switch(unsigned int ns); +void cci_init_sf(void); +unsigned long cci_reg_access(unsigned int op, unsigned long offset, unsigned long val); + +#endif /* __ASSEMBLY__ */ +#endif /* MCSI_H */ diff --git a/plat/mediatek/mt8183/include/mt_gic_v3.h b/plat/mediatek/mt8183/include/mt_gic_v3.h new file mode 100644 index 00000000..e2706f46 --- /dev/null +++ b/plat/mediatek/mt8183/include/mt_gic_v3.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_GIC_V3_H +#define MT_GIC_V3_H + +#include <lib/mmio.h> + +enum irq_schedule_mode { + SW_MODE, + HW_MODE +}; + +#define GIC_INT_MASK (MCUCFG_BASE + 0x5e8) +#define GIC500_ACTIVE_SEL_SHIFT 3 +#define GIC500_ACTIVE_SEL_MASK (0x7 << GIC500_ACTIVE_SEL_SHIFT) +#define GIC500_ACTIVE_CPU_SHIFT 16 +#define GIC500_ACTIVE_CPU_MASK (0xff << GIC500_ACTIVE_CPU_SHIFT) + +void mt_gic_driver_init(void); +void mt_gic_init(void); +void mt_gic_set_pending(uint32_t irq); +uint32_t mt_gic_get_pending(uint32_t irq); +void mt_gic_cpuif_enable(void); +void mt_gic_cpuif_disable(void); +void mt_gic_pcpu_init(void); +void mt_gic_irq_save(void); +void mt_gic_irq_restore(void); +void mt_gic_sync_dcm_enable(void); +void mt_gic_sync_dcm_disable(void); + +#endif /* MT_GIC_V3_H */ diff --git a/plat/mediatek/mt8183/include/plat_private.h b/plat/mediatek/mt8183/include/plat_private.h index e57ae45d..0853934b 100644 --- a/plat/mediatek/mt8183/include/plat_private.h +++ b/plat/mediatek/mt8183/include/plat_private.h @@ -17,11 +17,10 @@ void plat_configure_mmu_el3(uintptr_t total_base, uintptr_t coh_start, uintptr_t coh_limit); -void plat_cci_init(void); -void plat_cci_enable(void); -void plat_cci_disable(void); -void plat_cci_init_sf(void); -void plat_gic_init(void); +void plat_mtk_cci_init(void); +void plat_mtk_cci_enable(void); +void plat_mtk_cci_disable(void); +void plat_mtk_cci_init_sf(void); /* Declarations for plat_topology.c */ int mt_setup_topology(void); diff --git a/plat/mediatek/mt8183/plat_mt_gic.c b/plat/mediatek/mt8183/plat_mt_gic.c new file mode 100644 index 00000000..21443799 --- /dev/null +++ b/plat/mediatek/mt8183/plat_mt_gic.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/bl_common.h> +#include <common/debug.h> +#include <drivers/arm/gicv3.h> +#include <bl31/interrupt_mgmt.h> +#include <../drivers/arm/gic/v3/gicv3_private.h> +#include <mt_gic_v3.h> +#include <mtk_plat_common.h> +#include "plat_private.h" +#include <plat/common/platform.h> +#include <platform_def.h> +#include <stdint.h> +#include <stdio.h> + +#define NR_INT_POL_CTL 20 + +uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; + +/* + * We save and restore the GICv3 context on system suspend. Allocate the + * data in the designated EL3 Secure carve-out memory + */ +gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram"); +gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram"); + + +static unsigned int mt_mpidr_to_core_pos(u_register_t mpidr) +{ + return plat_core_pos_by_mpidr(mpidr); +} + +gicv3_driver_data_t mt_gicv3_data = { + .gicd_base = MT_GIC_BASE, + .gicr_base = MT_GIC_RDIST_BASE, + .rdistif_num = PLATFORM_CORE_COUNT, + .rdistif_base_addrs = rdistif_base_addrs, + .mpidr_to_core_pos = mt_mpidr_to_core_pos, +}; + +void setup_int_schedule_mode(enum irq_schedule_mode mode, + unsigned int active_cpu) +{ + assert(mode <= HW_MODE); + assert(active_cpu <= 0xFF); + + if (mode == HW_MODE) { + mmio_write_32(GIC_INT_MASK, + (mmio_read_32(GIC_INT_MASK) & ~(GIC500_ACTIVE_SEL_MASK)) + | (0x1 << GIC500_ACTIVE_SEL_SHIFT)); + } else if (mode == SW_MODE) { + mmio_write_32(GIC_INT_MASK, + (mmio_read_32(GIC_INT_MASK) & ~(GIC500_ACTIVE_SEL_MASK))); + } + + mmio_write_32(GIC_INT_MASK, + (mmio_read_32(GIC_INT_MASK) & ~(GIC500_ACTIVE_CPU_MASK)) + | (active_cpu << GIC500_ACTIVE_CPU_SHIFT)); + return; +} + +void clear_sec_pol_ctl_en(void) +{ + unsigned int i; + + /* total 19 polarity ctrl registers */ + for (i = 0; i <= NR_INT_POL_CTL - 1; i++) { + mmio_write_32((SEC_POL_CTL_EN0 + (i * 4)), 0); + } + dsb(); +} + +void mt_gic_driver_init(void) +{ + gicv3_driver_init(&mt_gicv3_data); +} + +void mt_gic_init(void) +{ + gicv3_distif_init(); + gicv3_rdistif_init(plat_my_core_pos()); + gicv3_cpuif_enable(plat_my_core_pos()); + + setup_int_schedule_mode(SW_MODE, 0xf); + clear_sec_pol_ctl_en(); +} + +void mt_gic_set_pending(uint32_t irq) +{ + gicv3_set_interrupt_pending(irq, plat_my_core_pos()); +} + +uint32_t mt_gic_get_pending(uint32_t irq) +{ + uint32_t bit = 1 << (irq % 32); + + return (mmio_read_32(gicv3_driver_data->gicd_base + + GICD_ISPENDR + irq / 32 * 4) & bit) ? 1 : 0; +} + +void mt_gic_cpuif_enable(void) +{ + gicv3_cpuif_enable(plat_my_core_pos()); +} + +void mt_gic_cpuif_disable(void) +{ + gicv3_cpuif_disable(plat_my_core_pos()); +} + +void mt_gic_pcpu_init(void) +{ + gicv3_rdistif_init(plat_my_core_pos()); +} + +void mt_gic_irq_save(void) +{ + gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx); + gicv3_distif_save(&dist_ctx); +} + +void mt_gic_irq_restore(void) +{ + gicv3_distif_init_restore(&dist_ctx); + gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx); +} + +void mt_gic_sync_dcm_enable(void) +{ + unsigned int val = mmio_read_32(GIC_SYNC_DCM); + + val &= ~GIC_SYNC_DCM_MASK; + mmio_write_32(GIC_SYNC_DCM, val | GIC_SYNC_DCM_ON); +} + +void mt_gic_sync_dcm_disable(void) +{ + unsigned int val = mmio_read_32(GIC_SYNC_DCM); + + val &= ~GIC_SYNC_DCM_MASK; + mmio_write_32(GIC_SYNC_DCM, val | GIC_SYNC_DCM_OFF); +} diff --git a/plat/mediatek/mt8183/platform.mk b/plat/mediatek/mt8183/platform.mk index 2ceb4597..8c8e2fe9 100644 --- a/plat/mediatek/mt8183/platform.mk +++ b/plat/mediatek/mt8183/platform.mk @@ -8,18 +8,20 @@ MTK_PLAT := plat/mediatek MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT} PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ + -I${MTK_PLAT_SOC}/drivers/ \ -I${MTK_PLAT_SOC}/include/ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/aarch64/xlat_tables.c \ lib/xlat_tables/xlat_tables_common.c \ - plat/common/plat_gicv2.c \ plat/common/plat_psci_common.c \ plat/common/aarch64/crash_console_helpers.S BL31_SOURCES += drivers/arm/cci/cci.c \ drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ + drivers/arm/gic/v3/arm_gicv3_common.c \ + drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gic500.c \ + drivers/arm/gic/v3/gicv3_main.c \ drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ drivers/gpio/gpio.c \ @@ -27,11 +29,14 @@ BL31_SOURCES += drivers/arm/cci/cci.c \ lib/cpus/aarch64/aem_generic.S \ lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a73.S \ + plat/common/plat_gicv3.c \ ${MTK_PLAT}/common/mtk_plat_common.c \ ${MTK_PLAT_SOC}/aarch64/plat_helpers.S \ ${MTK_PLAT_SOC}/aarch64/platform_common.c \ + ${MTK_PLAT_SOC}/drivers/mcsi/mcsi.c \ ${MTK_PLAT_SOC}/plat_pm.c \ ${MTK_PLAT_SOC}/plat_topology.c \ + ${MTK_PLAT_SOC}/plat_mt_gic.c \ ${MTK_PLAT_SOC}/bl31_plat_setup.c \ ${MTK_PLAT_SOC}/plat_debug.c \ ${MTK_PLAT_SOC}/scu.c @@ -282,13 +282,13 @@ See the `Contributing Guidelines`_ for information on how to contribute to this project and the `Acknowledgments`_ file for a list of contributors to the project. -Feedback and support -~~~~~~~~~~~~~~~~~~~~ +Contact us +~~~~~~~~~~ -Arm welcomes any feedback on TF-A. If you think you have found a security +We welcome any feedback on TF-A. If you think you have found a security vulnerability, please report this using the process defined in the TF-A -`Security Center`_. For all other feedback, please use the -`issue tracker`_. +`Security Center`_. For all other feedback, you can use either the +`issue tracker`_ or our `mailing list`_. Arm licensees may contact Arm directly via their partner managers. @@ -328,6 +328,7 @@ Security advisories .. _Trusty Secure OS: https://source.android.com/security/trusty .. _trustedfirmware.org: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git .. _issue tracker: https://developer.trustedfirmware.org/project/board/1/ +.. _mailing list: https://lists.trustedfirmware.org/mailman/listinfo/tf-a .. _Security Center: ./docs/process/security.rst .. _license: ./license.rst .. _Contributing Guidelines: ./docs/process/contributing.rst |