diff options
149 files changed, 3096 insertions, 2329 deletions
diff --git a/.gitreview b/.gitreview new file mode 100644 index 000000000..36f25485b --- /dev/null +++ b/.gitreview @@ -0,0 +1,4 @@ +[gerrit] +host=review.trustedfirmware.org +port=29418 +project=TF-A/trusted-firmware-a @@ -1000,6 +1000,8 @@ endif ifeq (${NEED_BL31},yes) BL31_SOURCES += ${SPD_SOURCES} +# Sort BL31 source files to remove duplicates +BL31_SOURCES := $(sort ${BL31_SOURCES}) ifneq (${DECRYPTION_SUPPORT},none) $(if ${BL31}, $(eval $(call TOOL_ADD_IMG,bl31,--soc-fw,,$(ENCRYPT_BL31))),\ $(eval $(call MAKE_BL,31,soc-fw,,$(ENCRYPT_BL31)))) @@ -1013,7 +1015,8 @@ endif # build system will call TOOL_ADD_IMG to print a warning message and abort the # process. Note that the dependency on BL32 applies to the FIP only. ifeq (${NEED_BL32},yes) - +# Sort BL32 source files to remove duplicates +BL32_SOURCES := $(sort ${BL32_SOURCES}) BUILD_BL32 := $(if $(BL32),,$(if $(BL32_SOURCES),1)) ifneq (${DECRYPTION_SUPPORT},none) diff --git a/bl31/aarch64/crash_reporting.S b/bl31/aarch64/crash_reporting.S index 97db2a167..d56b513b8 100644 --- a/bl31/aarch64/crash_reporting.S +++ b/bl31/aarch64/crash_reporting.S @@ -16,6 +16,7 @@ .globl report_unhandled_exception .globl report_unhandled_interrupt .globl el3_panic + .globl elx_panic #if CRASH_REPORTING @@ -59,7 +60,11 @@ panic_msg: excpt_msg: .asciz "Unhandled Exception in EL3.\nx30" intr_excpt_msg: - .asciz "Unhandled Interrupt Exception in EL3.\nx30" + .ascii "Unhandled Interrupt Exception in EL3.\n" +x30_msg: + .asciz "x30" +excpt_msg_el: + .asciz "Unhandled Exception from EL" /* * Helper function to print from crash buf. @@ -170,7 +175,6 @@ func report_unhandled_exception b do_crash_reporting endfunc report_unhandled_exception - /* ----------------------------------------------------- * This function allows to report a crash (if crash * reporting is enabled) when an unhandled interrupt @@ -188,6 +192,112 @@ func report_unhandled_interrupt endfunc report_unhandled_interrupt /* ----------------------------------------------------- + * This function allows to report a crash from the lower + * exception level (if crash reporting is enabled) when + * panic() is invoked from C Runtime. + * It prints the CPU state via the crash console making + * use of 'cpu_context' structure where general purpose + * registers are saved and the crash buf. + * This function will not return. + * + * x0: Exception level + * ----------------------------------------------------- + */ +func elx_panic + msr spsel, #MODE_SP_ELX + mov x8, x0 + + /* Print the crash message */ + adr x4, excpt_msg_el + bl asm_print_str + + /* Print exception level */ + add x0, x8, #'0' + bl plat_crash_console_putc + bl asm_print_newline + + /* Report x0 - x29 values stored in 'gpregs_ctx' structure */ + /* Store the ascii list pointer in x6 */ + adr x6, gp_regs + add x7, sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0 + +print_next: + ldrb w4, [x6] + /* Test whether we are at end of list */ + cbz w4, print_x30 + mov x4, x6 + /* asm_print_str updates x4 to point to next entry in list */ + bl asm_print_str + /* x0 = number of symbols printed + 1 */ + sub x0, x4, x6 + /* Update x6 with the updated list pointer */ + mov x6, x4 + bl print_alignment + ldr x4, [x7], #REGSZ + bl asm_print_hex + bl asm_print_newline + b print_next + +print_x30: + adr x4, x30_msg + bl asm_print_str + + /* Print spaces to align "x30" string */ + mov x0, #4 + bl print_alignment + + /* Report x30 */ + ldr x4, [x7] + + /* ---------------------------------------------------------------- + * Different virtual address space size can be defined for each EL. + * Ensure that we use the proper one by reading the corresponding + * TCR_ELx register. + * ---------------------------------------------------------------- + */ + cmp x8, #MODE_EL2 + b.lt from_el1 /* EL1 */ + mrs x2, sctlr_el2 + mrs x1, tcr_el2 + + /* ---------------------------------------------------------------- + * Check if pointer authentication is enabled at the specified EL. + * If it isn't, we can then skip stripping a PAC code. + * ---------------------------------------------------------------- + */ +test_pauth: + tst x2, #(SCTLR_EnIA_BIT | SCTLR_EnIB_BIT) + b.eq no_pauth + + /* Demangle address */ + and x1, x1, #0x3F /* T0SZ = TCR_ELx[5:0] */ + sub x1, x1, #64 + neg x1, x1 /* bottom_pac_bit = 64 - T0SZ */ + mov x2, #-1 + lsl x2, x2, x1 + bic x4, x4, x2 + +no_pauth: + bl asm_print_hex + bl asm_print_newline + + /* tpidr_el3 contains the address to cpu_data structure */ + mrs x0, tpidr_el3 + /* Calculate the Crash buffer offset in cpu_data */ + add x0, x0, #CPU_DATA_CRASH_BUF_OFFSET + /* Store crash buffer address in tpidr_el3 */ + msr tpidr_el3, x0 + + /* Print the rest of crash dump */ + b print_el3_sys_regs + +from_el1: + mrs x2, sctlr_el1 + mrs x1, tcr_el1 + b test_pauth +endfunc elx_panic + + /* ----------------------------------------------------- * This function allows to report a crash (if crash * reporting is enabled) when panic() is invoked from * C Runtime. It prints the CPU state via the crash @@ -200,9 +310,7 @@ func el3_panic prepare_crash_buf_save_x0_x1 adr x0, panic_msg mov sp, x0 - /* This call will not return */ - b do_crash_reporting -endfunc el3_panic + /* Fall through to 'do_crash_reporting' */ /* ------------------------------------------------------------ * The common crash reporting functionality. It requires x0 @@ -223,7 +331,7 @@ endfunc el3_panic * the crash buf to the crash console. * ------------------------------------------------------------ */ -func do_crash_reporting +do_crash_reporting: /* Retrieve the crash buf from tpidr_el3 */ mrs x0, tpidr_el3 /* Store x2 - x6, x30 in the crash buffer */ @@ -240,9 +348,9 @@ func do_crash_reporting /* Print spaces to align "x30" string */ mov x0, #4 bl print_alignment - /* load the crash buf address */ + /* Load the crash buf address */ mrs x0, tpidr_el3 - /* report x30 first from the crash buf */ + /* Report x30 first from the crash buf */ ldr x4, [x0, #REGSZ * 7] #if ENABLE_PAUTH @@ -256,7 +364,7 @@ func do_crash_reporting /* Now mov x7 into crash buf */ str x7, [x0, #REGSZ * 7] - /* Report x0 - x29 values stored in crash buf*/ + /* Report x0 - x29 values stored in crash buf */ /* Store the ascii list pointer in x6 */ adr x6, gp_regs /* Print x0 to x7 from the crash buf */ @@ -279,6 +387,7 @@ func do_crash_reporting bl size_controlled_print /* Print the el3 sys registers */ +print_el3_sys_regs: adr x6, el3_sys_regs mrs x8, scr_el3 mrs x9, sctlr_el3 @@ -354,7 +463,7 @@ func do_crash_reporting /* Done reporting */ no_ret plat_panic_handler -endfunc do_crash_reporting +endfunc el3_panic #else /* CRASH_REPORTING */ func report_unhandled_exception @@ -363,7 +472,6 @@ report_unhandled_interrupt: endfunc report_unhandled_exception #endif /* CRASH_REPORTING */ - func crash_panic no_ret plat_panic_handler endfunc crash_panic diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index e0138acbb..5f9f9df5b 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -55,6 +55,11 @@ SECTIONS KEEP(*(rt_svc_descs)) __RT_SVC_DESCS_END__ = .; + . = ALIGN(8); + __FCONF_POPULATOR_START__ = .; + KEEP(*(.fconf_populator)) + __FCONF_POPULATOR_END__ = .; + #if ENABLE_PMF /* Ensure 8-byte alignment for descriptors and ensure inclusion */ . = ALIGN(8); @@ -102,6 +107,11 @@ SECTIONS KEEP(*(rt_svc_descs)) __RT_SVC_DESCS_END__ = .; + . = ALIGN(8); + __FCONF_POPULATOR_START__ = .; + KEEP(*(.fconf_populator)) + __FCONF_POPULATOR_END__ = .; + #if ENABLE_PMF /* Ensure 8-byte alignment for descriptors and ensure inclusion */ . = ALIGN(8); diff --git a/bl32/sp_min/sp_min.ld.S b/bl32/sp_min/sp_min.ld.S index 3b1ca1b58..a90a805a0 100644 --- a/bl32/sp_min/sp_min.ld.S +++ b/bl32/sp_min/sp_min.ld.S @@ -56,6 +56,11 @@ SECTIONS KEEP(*(rt_svc_descs)) __RT_SVC_DESCS_END__ = .; + . = ALIGN(8); + __FCONF_POPULATOR_START__ = .; + KEEP(*(.fconf_populator)) + __FCONF_POPULATOR_END__ = .; + #if ENABLE_PMF /* Ensure 4-byte alignment for descriptors and ensure inclusion */ . = ALIGN(4); @@ -93,6 +98,11 @@ SECTIONS KEEP(*(rt_svc_descs)) __RT_SVC_DESCS_END__ = .; + . = ALIGN(8); + __FCONF_POPULATOR_START__ = .; + KEEP(*(.fconf_populator)) + __FCONF_POPULATOR_END__ = .; + /* * Ensure 4-byte alignment for cpu_ops so that its fields are also * aligned. Also ensure cpu_ops inclusion. diff --git a/bl32/tsp/tsp_main.c b/bl32/tsp/tsp_main.c index 9da2f9af9..e9478380c 100644 --- a/bl32/tsp/tsp_main.c +++ b/bl32/tsp/tsp_main.c @@ -371,12 +371,16 @@ tsp_args_t *tsp_smc_handler(uint64_t func, tsp_stats[linear_id].smc_count++; tsp_stats[linear_id].eret_count++; +#if LOG_LEVEL >= LOG_LEVEL_INFO + spin_lock(&console_lock); INFO("TSP: cpu 0x%lx received %s smc 0x%llx\n", read_mpidr(), ((func >> 31) & 1) == 1 ? "fast" : "yielding", func); INFO("TSP: cpu 0x%lx: %d smcs, %d erets\n", read_mpidr(), tsp_stats[linear_id].smc_count, tsp_stats[linear_id].eret_count); + spin_unlock(&console_lock); +#endif /* Render secure services and obtain results here */ results[0] = arg1; diff --git a/common/aarch64/debug.S b/common/aarch64/debug.S index e6e329853..7db24396e 100644 --- a/common/aarch64/debug.S +++ b/common/aarch64/debug.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -156,16 +156,32 @@ endfunc asm_print_newline /* This is for the non el3 BL stages to compile through */ .weak el3_panic + .weak elx_panic func do_panic #if CRASH_REPORTING str x0, [sp, #-0x10]! mrs x0, currentel - ubfx x0, x0, #2, #2 - cmp x0, #0x3 + ubfx x0, x0, #MODE_EL_SHIFT, #MODE_EL_WIDTH + cmp x0, #MODE_EL3 +#if !HANDLE_EA_EL3_FIRST ldr x0, [sp], #0x10 b.eq el3_panic -#endif +#else + b.ne to_panic_common + + /* Check EL the exception taken from */ + mrs x0, spsr_el3 + ubfx x0, x0, #SPSR_EL_SHIFT, #SPSR_EL_WIDTH + cmp x0, #MODE_EL3 + b.ne elx_panic + ldr x0, [sp], #0x10 + b el3_panic + +to_panic_common: + ldr x0, [sp], #0x10 +#endif /* HANDLE_EA_EL3_FIRST */ +#endif /* CRASH_REPORTING */ panic_common: /* diff --git a/common/backtrace/backtrace.c b/common/backtrace/backtrace.c index 907117f36..ef575006f 100644 --- a/common/backtrace/backtrace.c +++ b/common/backtrace/backtrace.c @@ -37,7 +37,7 @@ struct frame_record { uintptr_t return_addr; }; -static const char *get_el_str(unsigned int el) +const char *get_el_str(unsigned int el) { if (el == 3U) { return "EL3"; diff --git a/docs/about/maintainers.rst b/docs/about/maintainers.rst index 2bf5eb7ba..9e55e60e0 100644 --- a/docs/about/maintainers.rst +++ b/docs/about/maintainers.rst @@ -217,6 +217,17 @@ Raspberry Pi 3 platform port :G: `grandpaul`_ :F: docs/plat/rpi3.rst :F: plat/rpi/rpi3/ +:F: plat/rpi/common/ +:F: drivers/rpi3/ +:F: include/drivers/rpi3/ + +Raspberry Pi 4 platform port +---------------------------- +:M: Andre Przywara <andre.przywara@arm.com> +:G: `Andre-ARM`_ +:F: docs/plat/rpi4.rst +:F: plat/rpi/rpi4/ +:F: plat/rpi/common/ :F: drivers/rpi3/ :F: include/drivers/rpi3/ diff --git a/docs/change-log-upcoming.rst b/docs/change-log-upcoming.rst index 15f39de63..f86280f76 100644 --- a/docs/change-log-upcoming.rst +++ b/docs/change-log-upcoming.rst @@ -24,6 +24,8 @@ New Features - Build System - Add support for documentation build as a target in Makefile + - Add ``COT`` build option to select the chain of trust to use when the + Trusted Boot feature is enabled (default: ``tbbr``). - CPU Support - Example: "cortex-a55: Workaround for erratum 1221012" @@ -40,6 +42,7 @@ New Features - Platforms - Example: "arm/common: Introduce wrapper functions to setup secure watchdog" + - plat/arm: Add support for the new `dualroot` chain of trust. - PSCI - Example: "Adding new optional PSCI hook ``pwr_domain_on_finish_late``" @@ -47,6 +50,7 @@ New Features - Security - Example: "UBSAN support and handlers" - Add support for optional firmware encryption feature (experimental). + - Introduce a new `dualroot` chain of trust. - Tools - Example: "fiptool: Add support to build fiptool on Windows." diff --git a/docs/components/fconf.rst b/docs/components/fconf.rst index cec3cebe4..385660083 100644 --- a/docs/components/fconf.rst +++ b/docs/components/fconf.rst @@ -28,29 +28,45 @@ Examples namespace can be: - (|TBBR|) Chain of Trust data: tbbr.cot.trusted_boot_fw_cert - (|TBBR|) dynamic configuration info: tbbr.dyn_config.disable_auth - Arm io policies: arm.io_policies.bl2_image +- GICv3 properties: hw_config.gicv3_config.gicr_base Properties can be accessed with the ``FCONF_GET_PROPERTY(a,b,property)`` macro. Defining properties ~~~~~~~~~~~~~~~~~~~ -Properties composing the |FCONF| have to be stored in C structures. If another -backing store is wanted to be used, the platform has to provide a ``populate()`` -function to fill the corresponding C structure. - -The ``populate()`` function must be registered to the |FCONF| framework with -the ``FCONF_REGISTER_POPULATOR()`` macro. This ensures that the function would -be called inside the generic ``fconf_populate()`` function during +Properties composing the |FCONF| have to be stored in C structures. If +properties originate from a different backend source such as a device tree, +then the platform has to provide a ``populate()`` function which essentially +captures the property and stores them into a corresponding |FCONF| based C +structure. + +Such a ``populate()`` function is usually platform specific and is associated +with a specific backend source. For example, a populator function which +captures the hardware topology of the platform from the HW_CONFIG device tree. +Hence each ``populate()`` function must be registered with a specific +``config_type`` identifier. It broadly represents a logical grouping of +configuration properties which is usually a device tree file. + +Example: + - TB_FW: properties related to trusted firmware such as IO policies, + base address of other DTBs, mbedtls heap info etc. + - HW_CONFIG: properties related to hardware configuration of the SoC + such as topology, GIC controller, PSCI hooks, CPU ID etc. + +Hence the ``populate()`` callback must be registered to the (|FCONF|) framework +with the ``FCONF_REGISTER_POPULATOR()`` macro. This ensures that the function +would be called inside the generic ``fconf_populate()`` function during initialization. :: - int fconf_populate_tbbr_dyn_config(uintptr_t config) + int fconf_populate_topology(uintptr_t config) { - /* read dtb and fill tbbr_dyn_config struct */ + /* read hw config dtb and fill soc_topology struct */ } - FCONF_REGISTER_POPULATOR(fconf_populate_tbbr_dyn_config); + FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology); Then, a wrapper has to be provided to match the ``FCONF_GET_PROPERTY()`` macro: @@ -60,7 +76,7 @@ Then, a wrapper has to be provided to match the ``FCONF_GET_PROPERTY()`` macro: #define FCONF_GET_PROPERTY(a,b,property) a##__##b##_getter(property) /* my specific getter */ - #define tbbr__dyn_config_getter(id) tbbr_dyn_config.id + #define hw_config__topology_getter(prop) soc_topology.prop This second level wrapper can be used to remap the ``FCONF_GET_PROPERTY()`` to anything appropriate: structure, array, function, etc.. @@ -80,6 +96,33 @@ Populating the properties Once a valid device tree is available, the ``fconf_populate(config)`` function can be used to fill the C data structure with the data from the config |DTB|. This function will call all the ``populate()`` callbacks which have been -registered with ``FCONF_REGISTER_POPULATOR()``. +registered with ``FCONF_REGISTER_POPULATOR()`` as described above. .. uml:: ../resources/diagrams/plantuml/fconf_bl2_populate.puml + +Namespace guidance +~~~~~~~~~~~~~~~~~~ + +As mentioned above, properties are logically grouped around namespaces and +sub-namespaces. The following concepts should be considered when adding new +properties/namespaces. +The framework differentiates two types of properties: + - Properties used inside common code. + - Properties used inside platform specific code. + +The first category applies to properties being part of the firmware and shared +across multiple platforms. They should be globally accessible and defined +inside the ``lib/fconf`` directory. The namespace must be chosen to reflect the +feature/data abstracted. +Example: + - |TBBR| related properties: tbbr.cot.bl2_id + - Dynamic configuration information: dyn_cfg.dtb_info.hw_config_id + +The second category should represent the majority of the properties defined +within the framework: Platform specific properties. They must be accessed only +within the platform API and are defined only inside the platform scope. The +namespace must contain the platform name under which the properties defined +belong. +Example: + - Arm io framework: arm.io_policies.bl31_id + diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst index d0d6ef697..8e9dc38e4 100644 --- a/docs/design/firmware-design.rst +++ b/docs/design/firmware-design.rst @@ -1177,83 +1177,104 @@ The sample crash output is shown below. :: - x0 :0x000000004F00007C - x1 :0x0000000007FFFFFF - x2 :0x0000000004014D50 - x3 :0x0000000000000000 - x4 :0x0000000088007998 - x5 :0x00000000001343AC - x6 :0x0000000000000016 - x7 :0x00000000000B8A38 - x8 :0x00000000001343AC - x9 :0x00000000000101A8 - x10 :0x0000000000000002 - x11 :0x000000000000011C - x12 :0x00000000FEFDC644 - x13 :0x00000000FED93FFC - x14 :0x0000000000247950 - x15 :0x00000000000007A2 - x16 :0x00000000000007A4 - x17 :0x0000000000247950 - x18 :0x0000000000000000 - x19 :0x00000000FFFFFFFF - x20 :0x0000000004014D50 - x21 :0x000000000400A38C - x22 :0x0000000000247950 - x23 :0x0000000000000010 - x24 :0x0000000000000024 - x25 :0x00000000FEFDC868 - x26 :0x00000000FEFDC86A - x27 :0x00000000019EDEDC - x28 :0x000000000A7CFDAA - x29 :0x0000000004010780 - x30 :0x000000000400F004 - scr_el3 :0x0000000000000D3D - sctlr_el3 :0x0000000000C8181F - cptr_el3 :0x0000000000000000 - tcr_el3 :0x0000000080803520 - daif :0x00000000000003C0 - mair_el3 :0x00000000000004FF - spsr_el3 :0x00000000800003CC - elr_el3 :0x000000000400C0CC - ttbr0_el3 :0x00000000040172A0 - esr_el3 :0x0000000096000210 - sp_el3 :0x0000000004014D50 - far_el3 :0x000000004F00007C - spsr_el1 :0x0000000000000000 - elr_el1 :0x0000000000000000 - spsr_abt :0x0000000000000000 - spsr_und :0x0000000000000000 - spsr_irq :0x0000000000000000 - spsr_fiq :0x0000000000000000 - sctlr_el1 :0x0000000030C81807 - actlr_el1 :0x0000000000000000 - cpacr_el1 :0x0000000000300000 - csselr_el1 :0x0000000000000002 - sp_el1 :0x0000000004028800 - esr_el1 :0x0000000000000000 - ttbr0_el1 :0x000000000402C200 - ttbr1_el1 :0x0000000000000000 - mair_el1 :0x00000000000004FF - amair_el1 :0x0000000000000000 - tcr_el1 :0x0000000000003520 - tpidr_el1 :0x0000000000000000 - tpidr_el0 :0x0000000000000000 - tpidrro_el0 :0x0000000000000000 - dacr32_el2 :0x0000000000000000 - ifsr32_el2 :0x0000000000000000 - par_el1 :0x0000000000000000 - far_el1 :0x0000000000000000 - afsr0_el1 :0x0000000000000000 - afsr1_el1 :0x0000000000000000 - contextidr_el1 :0x0000000000000000 - vbar_el1 :0x0000000004027000 - cntp_ctl_el0 :0x0000000000000000 - cntp_cval_el0 :0x0000000000000000 - cntv_ctl_el0 :0x0000000000000000 - cntv_cval_el0 :0x0000000000000000 - cntkctl_el1 :0x0000000000000000 - sp_el0 :0x0000000004010780 + x0 = 0x000000002a4a0000 + x1 = 0x0000000000000001 + x2 = 0x0000000000000002 + x3 = 0x0000000000000003 + x4 = 0x0000000000000004 + x5 = 0x0000000000000005 + x6 = 0x0000000000000006 + x7 = 0x0000000000000007 + x8 = 0x0000000000000008 + x9 = 0x0000000000000009 + x10 = 0x0000000000000010 + x11 = 0x0000000000000011 + x12 = 0x0000000000000012 + x13 = 0x0000000000000013 + x14 = 0x0000000000000014 + x15 = 0x0000000000000015 + x16 = 0x0000000000000016 + x17 = 0x0000000000000017 + x18 = 0x0000000000000018 + x19 = 0x0000000000000019 + x20 = 0x0000000000000020 + x21 = 0x0000000000000021 + x22 = 0x0000000000000022 + x23 = 0x0000000000000023 + x24 = 0x0000000000000024 + x25 = 0x0000000000000025 + x26 = 0x0000000000000026 + x27 = 0x0000000000000027 + x28 = 0x0000000000000028 + x29 = 0x0000000000000029 + x30 = 0x0000000088000b78 + scr_el3 = 0x000000000003073d + sctlr_el3 = 0x00000000b0cd183f + cptr_el3 = 0x0000000000000000 + tcr_el3 = 0x000000008080351c + daif = 0x00000000000002c0 + mair_el3 = 0x00000000004404ff + spsr_el3 = 0x0000000060000349 + elr_el3 = 0x0000000088000114 + ttbr0_el3 = 0x0000000004018201 + esr_el3 = 0x00000000be000000 + far_el3 = 0x0000000000000000 + spsr_el1 = 0x0000000000000000 + elr_el1 = 0x0000000000000000 + spsr_abt = 0x0000000000000000 + spsr_und = 0x0000000000000000 + spsr_irq = 0x0000000000000000 + spsr_fiq = 0x0000000000000000 + sctlr_el1 = 0x0000000030d00800 + actlr_el1 = 0x0000000000000000 + cpacr_el1 = 0x0000000000000000 + csselr_el1 = 0x0000000000000000 + sp_el1 = 0x0000000000000000 + esr_el1 = 0x0000000000000000 + ttbr0_el1 = 0x0000000000000000 + ttbr1_el1 = 0x0000000000000000 + mair_el1 = 0x0000000000000000 + amair_el1 = 0x0000000000000000 + tcr_el1 = 0x0000000000000000 + tpidr_el1 = 0x0000000000000000 + tpidr_el0 = 0x0000000000000000 + tpidrro_el0 = 0x0000000000000000 + par_el1 = 0x0000000000000000 + mpidr_el1 = 0x0000000080000000 + afsr0_el1 = 0x0000000000000000 + afsr1_el1 = 0x0000000000000000 + contextidr_el1 = 0x0000000000000000 + vbar_el1 = 0x0000000000000000 + cntp_ctl_el0 = 0x0000000000000000 + cntp_cval_el0 = 0x0000000000000000 + cntv_ctl_el0 = 0x0000000000000000 + cntv_cval_el0 = 0x0000000000000000 + cntkctl_el1 = 0x0000000000000000 + sp_el0 = 0x0000000004014940 + isr_el1 = 0x0000000000000000 + dacr32_el2 = 0x0000000000000000 + ifsr32_el2 = 0x0000000000000000 + icc_hppir0_el1 = 0x00000000000003ff + icc_hppir1_el1 = 0x00000000000003ff + icc_ctlr_el3 = 0x0000000000080400 + gicd_ispendr regs (Offsets 0x200-0x278) + Offset Value + 0x200: 0x0000000000000000 + 0x208: 0x0000000000000000 + 0x210: 0x0000000000000000 + 0x218: 0x0000000000000000 + 0x220: 0x0000000000000000 + 0x228: 0x0000000000000000 + 0x230: 0x0000000000000000 + 0x238: 0x0000000000000000 + 0x240: 0x0000000000000000 + 0x248: 0x0000000000000000 + 0x250: 0x0000000000000000 + 0x258: 0x0000000000000000 + 0x260: 0x0000000000000000 + 0x268: 0x0000000000000000 + 0x270: 0x0000000000000000 + 0x278: 0x0000000000000000 Guidelines for Reset Handlers ----------------------------- @@ -1838,7 +1859,7 @@ BL image during boot. | BL2 | <<<<<<<<<<<<< | | |----------| <<<<<<<<<<<<< |----------------| | SCP_BL2 | <<<<<<<<<<<<< | BL31 PROGBITS | - |----------| <<<<<<<<<<<<< |----------------| + | | <<<<<<<<<<<<< |----------------| | | <<<<<<<<<<<<< | BL32 | | | +----------------+ | | @@ -1875,7 +1896,7 @@ BL image during boot. | BL2 | <<<<<<<<<<<<< | | |----------| <<<<<<<<<<<<< |----------------| | SCP_BL2 | <<<<<<<<<<<<< | BL31 PROGBITS | - |----------| +----------------+ + | | +----------------+ 0x04001000 +----------+ | MHU | 0x04000000 +----------+ diff --git a/docs/design/trusted-board-boot-build.rst b/docs/design/trusted-board-boot-build.rst index f5c8bc98c..dd61b61f5 100644 --- a/docs/design/trusted-board-boot-build.rst +++ b/docs/design/trusted-board-boot-build.rst @@ -32,25 +32,28 @@ images with support for these features: - ``TRUSTED_BOARD_BOOT=1`` - ``GENERATE_COT=1`` + By default, this will use the Chain of Trust described in the TBBR-client + document. To select a different one, use the ``COT`` build option. + In the case of Arm platforms, the location of the ROTPK hash must also be specified at build time. The following locations are currently supported (see ``ARM_ROTPK_LOCATION`` build option): - ``ARM_ROTPK_LOCATION=regs``: the ROTPK hash is obtained from the Trusted - root-key storage registers present in the platform. On Juno, this + root-key storage registers present in the platform. On Juno, these registers are read-only. On FVP Base and Cortex models, the registers - are read-only, but the value can be specified using the command line + are also read-only, but the value can be specified using the command line option ``bp.trusted_key_storage.public_key`` when launching the model. On Juno board, the default value corresponds to an ECDSA-SECP256R1 public key hash, whose private part is not currently available. - ``ARM_ROTPK_LOCATION=devel_rsa``: use the default hash located in - plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin. Enforce generation - of the new hash if ROT_KEY is specified. + ``plat/arm/board/common/rotpk/arm_rotpk_rsa_sha256.bin``. Enforce + generation of the new hash if ``ROT_KEY`` is specified. - ``ARM_ROTPK_LOCATION=devel_ecdsa``: use the default hash located in - plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin. Enforce generation - of the new hash if ROT_KEY is specified. + ``plat/arm/board/common/rotpk/arm_rotpk_ecdsa_sha256.bin``. Enforce + generation of the new hash if ``ROT_KEY`` is specified. Example of command line using RSA development keys: @@ -64,9 +67,8 @@ images with support for these features: all fip The result of this build will be the bl1.bin and the fip.bin binaries. This - FIP will include the certificates corresponding to the Chain of Trust - described in the TBBR-client document. These certificates can also be found - in the output build directory. + FIP will include the certificates corresponding to the selected Chain of + Trust. These certificates can also be found in the output build directory. #. The optional FWU_FIP contains any additional images to be loaded from Non-Volatile storage during the :ref:`Firmware Update (FWU)` process. To build the @@ -102,8 +104,8 @@ images with support for these features: The result of this build will be bl1.bin, fip.bin and fwu_fip.bin binaries. Both the FIP and FWU_FIP will include the certificates corresponding to the - Chain of Trust described in the TBBR-client document. These certificates - can also be found in the output build directory. + selected Chain of Trust. These certificates can also be found in the output + build directory. -------------- diff --git a/docs/design/trusted-board-boot.rst b/docs/design/trusted-board-boot.rst index 4802c97f3..96cf24c0b 100644 --- a/docs/design/trusted-board-boot.rst +++ b/docs/design/trusted-board-boot.rst @@ -19,7 +19,9 @@ A Chain of Trust (CoT) starts with a set of implicitly trusted components. On the Arm development platforms, these components are: - A SHA-256 hash of the Root of Trust Public Key (ROTPK). It is stored in the - trusted root-key storage registers. + trusted root-key storage registers. Alternatively, a development ROTPK might + be used and its hash embedded into the BL1 and BL2 images (only for + development purposes). - The BL1 image, on the assumption that it resides in ROM so cannot be tampered with. @@ -32,17 +34,17 @@ essential information to establish the CoT. In the TBB CoT all certificates are self-signed. There is no need for a Certificate Authority (CA) because the CoT is not established by verifying the validity of a certificate's issuer but by the content of the certificate -extensions. To sign the certificates, the PKCS#1 SHA-256 with RSA Encryption -signature scheme is used with a RSA key length of 2048 bits. Future version of -TF-A will support additional cryptographic algorithms. +extensions. To sign the certificates, different signature schemes are available, +please refer to the :ref:`Build Options` for more details. The certificates are categorised as "Key" and "Content" certificates. Key certificates are used to verify public keys which have been used to sign content certificates. Content certificates are used to store the hash of a boot loader image. An image can be authenticated by calculating its hash and matching it -with the hash extracted from the content certificate. The SHA-256 function is -used to calculate all hashes. The public keys and hashes are included as -non-standard extension fields in the `X.509 v3`_ certificates. +with the hash extracted from the content certificate. Various hash algorithms +are supported to calculate all hashes, please refer to the :ref:`Build Options` +for more details.. The public keys and hashes are included as non-standard +extension fields in the `X.509 v3`_ certificates. The keys used to establish the CoT are: @@ -63,10 +65,10 @@ The keys used to establish the CoT are: non secure world image (BL33). The public part is stored in one of the extension fields in the trusted world certificate. -- **BL3-X keys** +- **BL3X keys** For each of SCP_BL2, BL31, BL32 and BL33, the private part is used to - sign the content certificate for the BL3-X image. The public part is stored + sign the content certificate for the BL3X image. The public part is stored in one of the extension fields in the corresponding key certificate. The following images are included in the CoT: @@ -219,8 +221,7 @@ certificates (in DER format) required to establish the CoT. New keys can be generated by the tool in case they are not provided. The certificates are then passed as inputs to the ``fiptool`` utility for creating the FIP. -The certificates are also stored individually in the in the output build -directory. +The certificates are also stored individually in the output build directory. The tool resides in the ``tools/cert_create`` directory. It uses the OpenSSL SSL library version to generate the X.509 certificates. The specific version of the @@ -259,7 +260,7 @@ Instructions for building and using the tool can be found in the -------------- -*Copyright (c) 2015-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved.* .. _X.509 v3: https://tools.ietf.org/rfc/rfc5280.txt .. _Trusted Board Boot Requirements (TBBR): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a diff --git a/docs/design_documents/cmake_framework.rst b/docs/design_documents/cmake_framework.rst new file mode 100644 index 000000000..d88942e82 --- /dev/null +++ b/docs/design_documents/cmake_framework.rst @@ -0,0 +1,165 @@ +TF-A CMake buildsystem +====================== + +:Author: Balint Dobszay +:Organization: Arm Limited +:Contact: Balint Dobszay <balint.dobszay@arm.com> +:Status: Accepted + +.. contents:: Table of Contents + +Abstract +-------- +This document presents a proposal for a new buildsystem for TF-A using CMake, +and as part of this a reusable CMake framework for embedded projects. For a +summary about the proposal, please see the `Phabricator wiki page +<https://developer.trustedfirmware.org/w/tf_a/cmake-buildsystem-proposal/>`_. As +mentioned there, the proposal consists of two phases. The subject of this +document is the first phase only. + +Introduction +------------ +The current Makefile based buildsystem of TF-A has become complicated and hard +to maintain, there is a need for a new, more flexible solution. The proposal is +to use CMake language for the new buildsystem. The main reasons of this decision +are the following: + +* It is a well-established, mature tool, widely accepted by open-source + projects. +* TF-M is already using CMake, reducing fragmentation for tf.org projects can be + beneficial. +* CMake has various advantages over Make, e.g.: + + * Host and target system agnostic project. + * CMake project is scalable, supports project modularization. + * Supports software integration. + * Out-of-the-box support for integration with several tools (e.g. project + generation for various IDEs, integration with cppcheck, etc). + +Of course there are drawbacks too: + +* Language is problematic (e.g. variable scope). +* Not embedded approach. + +To overcome these and other problems, we need to create workarounds for some +tasks, wrap CMake functions, etc. Since this functionality can be useful in +other embedded projects too, it is beneficial to collect the new code into a +reusable framework and store this in a separate repository. The following +diagram provides an overview of the framework structure: + +|Framework structure| + +Main features +------------- + +Structured configuration description +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +In the current Makefile system the build configuration description, validation, +processing, and the target creation, source file description are mixed and +spread across several files. One of the goals of the framework is to organize +this. + +The framework provides a solution to describe the input build parameters, flags, +macros, etc. in a structured way. It contains two utilities for this purpose: + +* Map: simple key-value pair implementation. +* Group: collection of related maps. + +The related parameters shall be packed into a group (or "setting group"). The +setting groups shall be defined and filled with content in config files. +Currently the config files are created and edited manually, but later a +configuration management tool (e.g. Kconfig) shall be used to generate these +files. Therefore, the framework does not contain parameter validation and +conflict checking, these shall be handled by the configuration tool. + +Target description +^^^^^^^^^^^^^^^^^^ +The framework provides an API called STGT ('simple target') to describe the +targets, i.e. what is the build output, what source files are used, what +libraries are linked, etc. The API wraps the CMake target functions, and also +extends the built-in functionality, it can use the setting groups described in +the previous section. A group can be applied onto a target, i.e. a collection of +macros, flags, etc. can be applied onto the given output executable/library. +This provides a more granular way than the current Makefile system where most of +these are global and applied onto each target. + +Compiler abstraction +^^^^^^^^^^^^^^^^^^^^ +Apart from the built-in CMake usage of the compiler, there are some common tasks +that CMake does not solve (e.g. preprocessing a file). For these tasks the +framework uses wrapper functions instead of direct calls to the compiler. This +way it is not tied to one specific compiler. + +External tools +^^^^^^^^^^^^^^ +In the TF-A buildsystem some external tools are used, e.g. fiptool for image +generation or dtc for device tree compilation. These tools have to be found +and/or built by the framework. For this, the CMake find_package functionality is +used, any other necessary tools can be added later. + +Workflow +-------- +The following diagram demonstrates the development workflow using the framework: + +|Framework workflow| + +The process can be split into two main phases: + +In the provisioning phase, first we have to obtain the necessary resources, i.e. +clone the code repository and other dependencies. Next we have to do the +configuration, preferably using a config tool like KConfig. + +In the development phase first we run CMake, which will generate the buildsystem +using the selected generator backend (currently only the Makefile generator is +supported). After this we run the selected build tool which in turn calls the +compiler, linker, packaging tool, etc. Finally we can run and debug the output +executables. + +Usually during development only the steps in this second phase have to be +repeated, while the provisioning phase needs to be done only once (or rarely). + +Example +------- +This is a short example for the basic framework usage. + +First, we create a setting group called *mem_conf* and fill it with several +parameters. It is worth noting the difference between *CONFIG* and *DEFINE* +types: the former is only a CMake domain option, the latter is only a C language +macro. + +Next, we create a target called *fw1* and add the *mem_conf* setting group to +it. This means that all source and header files used by the target will have all +the parameters declared in the setting group. Then we set the target type to +executable, and add some source files. Since the target has the parameters from +the settings group, we can use it for conditionally adding source files. E.g. +*dram_controller.c* will only be added if MEM_TYPE equals dram. + +.. code-block:: cmake + + group_new(NAME mem_conf) + group_add(NAME mem_conf TYPE DEFINE KEY MEM_SIZE VAL 1024) + group_add(NAME mem_conf TYPE CONFIG DEFINE KEY MEM_TYPE VAL dram) + group_add(NAME mem_conf TYPE CFLAG KEY -Os) + + stgt_create(NAME fw1) + stgt_add_setting(NAME fw1 GROUPS mem_conf) + stgt_set_target(NAME fw1 TYPE exe) + + stgt_add_src(NAME fw1 SRC + ${CMAKE_SOURCE_DIR}/main.c + ) + + stgt_add_src_cond(NAME fw1 KEY MEM_TYPE VAL dram SRC + ${CMAKE_SOURCE_DIR}/dram_controller.c + ) + +.. |Framework structure| image:: + ../resources/diagrams/cmake_framework_structure.png + :width: 75 % + +.. |Framework workflow| image:: + ../resources/diagrams/cmake_framework_workflow.png + +-------------- + +*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.* diff --git a/docs/design_documents/index.rst b/docs/design_documents/index.rst new file mode 100644 index 000000000..187510a64 --- /dev/null +++ b/docs/design_documents/index.rst @@ -0,0 +1,13 @@ +Design Documents +================ + +.. toctree:: + :maxdepth: 1 + :caption: Contents + :numbered: + + cmake_framework + +-------------- + +*Copyright (c) 2020, Arm Limited and Contributors. All rights reserved.* diff --git a/docs/getting_started/porting-guide.rst b/docs/getting_started/porting-guide.rst index d634d2e70..d6572f507 100644 --- a/docs/getting_started/porting-guide.rst +++ b/docs/getting_started/porting-guide.rst @@ -1116,6 +1116,35 @@ can override the common implementation to define a different prefix string for the log output. The implementation should be robust to future changes that increase the number of log levels. +Function : plat_get_soc_version() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : int32_t + +This function returns soc version which mainly consist of below fields + +:: + + soc_version[30:24] = JEP-106 continuation code for the SiP + soc_version[23:16] = JEP-106 identification code with parity bit for the SiP + +Function : plat_get_soc_revision() +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + Argument : void + Return : int32_t + +This function returns soc revision in below format + +:: + + soc_revision[0:30] = SOC revision of specific SOC + Modifications specific to a Boot Loader stage --------------------------------------------- diff --git a/docs/index.rst b/docs/index.rst index 5088bfd87..7413edd1b 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -14,6 +14,7 @@ Trusted Firmware-A Documentation plat/index perf/index security_advisories/index + design_documents/index change-log change-log-upcoming glossary @@ -82,7 +83,7 @@ have previously been raised against the software. -------------- -*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.* +*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.* .. _Armv7-A and Armv8-A: https://developer.arm.com/products/architecture/a-profile .. _Secure Monitor: http://www.arm.com/products/processors/technologies/trustzone/tee-smc.php diff --git a/docs/plat/hikey.rst b/docs/plat/hikey.rst index 372d38867..6c488b827 100644 --- a/docs/plat/hikey.rst +++ b/docs/plat/hikey.rst @@ -26,9 +26,6 @@ Code Locations - l-loader: `link <https://github.com/96boards-hikey/l-loader/tree/testing/hikey960_v1.2>`__ -- uefi-tools: - `link <https://git.linaro.org/uefi/uefi-tools.git>`__ - - atf-fastboot: `link <https://github.com/96boards-hikey/atf-fastboot/tree/master>`__ @@ -45,7 +42,6 @@ Build Procedure git clone https://github.com/96boards-hikey/edk2 -b testing/hikey960_v2.5 git clone https://github.com/96boards-hikey/OpenPlatformPkg -b testing/hikey960_v1.3.4 git clone https://github.com/96boards-hikey/l-loader -b testing/hikey960_v1.2 - git clone https://git.linaro.org/uefi/uefi-tools git clone https://github.com/96boards-hikey/atf-fastboot - Create the symbol link to OpenPlatformPkg in edk2. @@ -57,13 +53,12 @@ Build Procedure - Prepare AARCH64 && AARCH32 toolchain. Prepare python. -- If your hikey hardware is built by CircuitCo, update *uefi-tools/platform.config* first. *(optional)* - **Uncomment the below sentence. Otherwise, UEFI can't output messages on serial +- If your hikey hardware is built by CircuitCo, update *OpenPlatformPkg/Platforms/Hisilicon/HiKey/HiKey.dsc* first. *(optional)* console on hikey.** .. code:: shell - BUILDFLAGS=-DSERIAL_BASE=0xF8015000 + DEFINE SERIAL_BASE=0xF8015000 If your hikey hardware is built by LeMaker, nothing to do. @@ -71,19 +66,8 @@ Build Procedure .. code:: shell - BUILD_OPTION=DEBUG - export AARCH64_TOOLCHAIN=GCC5 - export UEFI_TOOLS_DIR=${BUILD_PATH}/uefi-tools - export EDK2_DIR=${BUILD_PATH}/edk2 - EDK2_OUTPUT_DIR=${EDK2_DIR}/Build/HiKey/${BUILD_OPTION}_${AARCH64_TOOLCHAIN} - # Build fastboot for Trusted Firmware-A. It's used for recovery mode. - cd ${BUILD_PATH}/atf-fastboot - CROSS_COMPILE=aarch64-linux-gnu- make PLAT=hikey DEBUG=1 - # Convert DEBUG/RELEASE to debug/release - FASTBOOT_BUILD_OPTION=$(echo ${BUILD_OPTION} | tr '[A-Z]' '[a-z]') - cd ${EDK2_DIR} - # Build UEFI & Trusted Firmware-A - ${UEFI_TOOLS_DIR}/uefi-build.sh -b ${BUILD_OPTION} -a ../arm-trusted-firmware -s ../optee_os hikey + cd {BUILD_PATH}/arm-trusted-firmware + sh ../l-loader/build_uefi.sh hikey - Generate l-loader.bin and partition table for aosp. The eMMC capacity is either 8GB or 4GB. Just change "aosp-8g" to "linux-8g" for debian. diff --git a/docs/plat/hikey960.rst b/docs/plat/hikey960.rst index 3d42a77c5..982c2c854 100644 --- a/docs/plat/hikey960.rst +++ b/docs/plat/hikey960.rst @@ -26,9 +26,6 @@ Code Locations - l-loader: `link <https://github.com/96boards-hikey/l-loader/tree/testing/hikey960_v1.2>`__ -- uefi-tools: - `link <https://git.linaro.org/uefi/uefi-tools.git>`__ - Build Procedure ~~~~~~~~~~~~~~~ @@ -42,7 +39,6 @@ Build Procedure git clone https://github.com/96boards-hikey/edk2 -b testing/hikey960_v2.5 git clone https://github.com/96boards-hikey/OpenPlatformPkg -b testing/hikey960_v1.3.4 git clone https://github.com/96boards-hikey/l-loader -b testing/hikey960_v1.2 - git clone https://git.linaro.org/uefi/uefi-tools - Create the symbol link to OpenPlatformPkg in edk2. @@ -53,13 +49,11 @@ Build Procedure - Prepare AARCH64 toolchain. -- If your hikey960 hardware is v1, update *uefi-tools/platform.config* first. *(optional)* - **Uncomment the below sentence. Otherwise, UEFI can't output messages on serial - console on hikey960 v1.** +- If your hikey960 hardware is v1, update *OpenPlatformPkg/Platforms/Hisilicon/HiKey960/HiKey960.dsc* first. *(optional)* .. code:: shell - BUILDFLAGS=-DSERIAL_BASE=0xFDF05000 + DEFINE SERIAL_BASE=0xFDF05000 If your hikey960 hardware is v2 or newer, nothing to do. @@ -67,14 +61,8 @@ Build Procedure .. code:: shell - BUILD_OPTION=DEBUG - export AARCH64_TOOLCHAIN=GCC5 - export UEFI_TOOLS_DIR=${BUILD_PATH}/uefi-tools - export EDK2_DIR=${BUILD_PATH}/edk2 - EDK2_OUTPUT_DIR=${EDK2_DIR}/Build/HiKey960/${BUILD_OPTION}_${AARCH64_TOOLCHAIN} - cd ${EDK2_DIR} - # Build UEFI & Trusted Firmware-A - ${UEFI_TOOLS_DIR}/uefi-build.sh -b ${BUILD_OPTION} -a ../arm-trusted-firmware -s ../optee_os hikey960 + cd {BUILD_PATH}/arm-trusted-firmware + sh ../l-loader/build_uefi.sh hikey960 - Generate l-loader.bin and partition table. *Make sure that you're using the sgdisk in the l-loader directory.* diff --git a/docs/resources/diagrams/cmake_framework_structure.png b/docs/resources/diagrams/cmake_framework_structure.png Binary files differnew file mode 100644 index 000000000..6006f1c30 --- /dev/null +++ b/docs/resources/diagrams/cmake_framework_structure.png diff --git a/docs/resources/diagrams/cmake_framework_workflow.png b/docs/resources/diagrams/cmake_framework_workflow.png Binary files differnew file mode 100644 index 000000000..7311529c4 --- /dev/null +++ b/docs/resources/diagrams/cmake_framework_workflow.png diff --git a/drivers/arm/gic/v3/gicdv3_helpers.c b/drivers/arm/gic/v3/gicdv3_helpers.c new file mode 100644 index 000000000..3f5ff45fc --- /dev/null +++ b/drivers/arm/gic/v3/gicdv3_helpers.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdint.h> + +#include "gicv3_private.h" + +/******************************************************************************* + * GIC Distributor interface accessors for bit operations + ******************************************************************************/ + +/* + * Accessor to read the GIC Distributor IGRPMODR corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +uint32_t gicd_read_igrpmodr(uintptr_t base, unsigned int id) +{ + return GICD_READ(IGRPMODR, base, id); +} + +/* + * Accessor to write the GIC Distributor IGRPMODR corresponding to the + * interrupt `id`, 32 interrupt IDs at a time. + */ +void gicd_write_igrpmodr(uintptr_t base, unsigned int id, uint32_t val) +{ + GICD_WRITE(IGRPMODR, base, id, val); +} + +/* + * Accessor to get the bit corresponding to interrupt ID + * in GIC Distributor IGRPMODR. + */ +unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id) +{ + return GICD_GET_BIT(IGRPMODR, base, id); +} + +/* + * Accessor to set the bit corresponding to interrupt ID + * in GIC Distributor IGRPMODR. + */ +void gicd_set_igrpmodr(uintptr_t base, unsigned int id) +{ + GICD_SET_BIT(IGRPMODR, base, id); +} + +/* + * Accessor to clear the bit corresponding to interrupt ID + * in GIC Distributor IGRPMODR. + */ +void gicd_clr_igrpmodr(uintptr_t base, unsigned int id) +{ + GICD_CLR_BIT(IGRPMODR, base, id); +} diff --git a/drivers/arm/gic/v3/gicrv3_helpers.c b/drivers/arm/gic/v3/gicrv3_helpers.c new file mode 100644 index 000000000..294acda5a --- /dev/null +++ b/drivers/arm/gic/v3/gicrv3_helpers.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2015-2020, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <arch_helpers.h> +#include <common/debug.h> +#include <common/interrupt_props.h> +#include <drivers/arm/gicv3.h> +#include "gicv3_private.h" + +/******************************************************************************* + * GIC Redistributor functions + * Note: The raw register values correspond to multiple interrupt IDs and + * the number of interrupt IDs involved depends on the register accessed. + ******************************************************************************/ + +/* + * Accessor to read the GIC Redistributor IPRIORITYR corresponding to the + * interrupt `id`, 4 interrupts IDs at a time. + */ +unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id) +{ + unsigned int n = id >> IPRIORITYR_SHIFT; + + return mmio_read_32(base + GICR_IPRIORITYR + (n << 2)); +} + +/* + * Accessor to write the GIC Redistributor IPRIORITYR corresponding to the + * interrupt `id`, 4 interrupts IDs at a time. + */ +void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) +{ + unsigned int n = id >> IPRIORITYR_SHIFT; + + mmio_write_32(base + GICR_IPRIORITYR + (n << 2), val); +} + +/* + * Accessor to set the byte corresponding to interrupt ID + * in GIC Redistributor IPRIORITYR. + */ +void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) +{ + GICR_WRITE_8(IPRIORITYR, base, id, pri & GIC_PRI_MASK); +} + +/* + * Accessor to get the bit corresponding to interrupt ID + * from GIC Redistributor IGROUPR0. + */ +unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); + unsigned int reg_val = gicr_read_igroupr0(base); + + return (reg_val >> bit_num) & 0x1U; +} + +/* + * Accessor to set the bit corresponding to interrupt ID + * in GIC Redistributor IGROUPR0. + */ +void gicr_set_igroupr0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); + unsigned int reg_val = gicr_read_igroupr0(base); + + gicr_write_igroupr0(base, reg_val | (1U << bit_num)); +} + +/* + * Accessor to clear the bit corresponding to interrupt ID + * in GIC Redistributor IGROUPR0. + */ +void gicr_clr_igroupr0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); + unsigned int reg_val = gicr_read_igroupr0(base); + + gicr_write_igroupr0(base, reg_val & ~(1U << bit_num)); +} + +/* + * Accessor to get the bit corresponding to interrupt ID + * from GIC Redistributor IGRPMODR0. + */ +unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); + unsigned int reg_val = gicr_read_igrpmodr0(base); + + return (reg_val >> bit_num) & 0x1U; +} + +/* + * Accessor to set the bit corresponding to interrupt ID + * in GIC Redistributor IGRPMODR0. + */ +void gicr_set_igrpmodr0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); + unsigned int reg_val = gicr_read_igrpmodr0(base); + + gicr_write_igrpmodr0(base, reg_val | (1U << bit_num)); +} + +/* + * Accessor to clear the bit corresponding to interrupt ID + * in GIC Redistributor IGRPMODR0. + */ +void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); + unsigned int reg_val = gicr_read_igrpmodr0(base); + + gicr_write_igrpmodr0(base, reg_val & ~(1U << bit_num)); +} + +/* + * Accessor to set the bit corresponding to interrupt ID + * in GIC Redistributor ISENABLER0. + */ +void gicr_set_isenabler0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U); + + gicr_write_isenabler0(base, (1U << bit_num)); +} + +/* + * Accessor to set the bit corresponding to interrupt ID in GIC Redistributor + * ICENABLER0. + */ +void gicr_set_icenabler0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U); + + gicr_write_icenabler0(base, (1U << bit_num)); +} + +/* + * Accessor to set the bit corresponding to interrupt ID in GIC Redistributor + * ISACTIVER0. + */ +unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U); + unsigned int reg_val = gicr_read_isactiver0(base); + + return (reg_val >> bit_num) & 0x1U; +} + +/* + * Accessor to clear the bit corresponding to interrupt ID in GIC Redistributor + * ICPENDRR0. + */ +void gicr_set_icpendr0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U); + + gicr_write_icpendr0(base, (1U << bit_num)); +} + +/* + * Accessor to set the bit corresponding to interrupt ID in GIC Redistributor + * ISPENDR0. + */ +void gicr_set_ispendr0(uintptr_t base, unsigned int id) +{ + unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U); + + gicr_write_ispendr0(base, (1U << bit_num)); +} + +/* + * Accessor to set the bit fields corresponding to interrupt ID + * in GIC Redistributor ICFGR0. + */ +void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg) +{ + /* Interrupt configuration is a 2-bit field */ + unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U); + unsigned int bit_shift = bit_num << 1U; + + uint32_t reg_val = gicr_read_icfgr0(base); + + /* Clear the field, and insert required configuration */ + reg_val &= ~(GIC_CFG_MASK << bit_shift); + reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift); + + gicr_write_icfgr0(base, reg_val); +} + +/* + * Accessor to set the bit fields corresponding to interrupt ID + * in GIC Redistributor ICFGR1. + */ +void gicr_set_icfgr1(uintptr_t base, unsigned int id, unsigned int cfg) +{ + /* Interrupt configuration is a 2-bit field */ + unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U); + unsigned int bit_shift = bit_num << 1U; + + uint32_t reg_val = gicr_read_icfgr1(base); + + /* Clear the field, and insert required configuration */ + reg_val &= ~(GIC_CFG_MASK << bit_shift); + reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift); + + gicr_write_icfgr1(base, reg_val); +} diff --git a/drivers/arm/gic/v3/gicv3_helpers.c b/drivers/arm/gic/v3/gicv3_helpers.c index 710532e3c..d5aaf9696 100644 --- a/drivers/arm/gic/v3/gicv3_helpers.c +++ b/drivers/arm/gic/v3/gicv3_helpers.c @@ -15,263 +15,6 @@ #include "../common/gic_common_private.h" #include "gicv3_private.h" -/* - * Accessor to read the GIC Distributor IGRPMODR corresponding to the - * interrupt `id`, 32 interrupt IDs at a time. - */ -unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id) -{ - unsigned int n = id >> IGRPMODR_SHIFT; - - return mmio_read_32(base + GICD_IGRPMODR + (n << 2)); -} - -/* - * Accessor to write the GIC Distributor IGRPMODR corresponding to the - * interrupt `id`, 32 interrupt IDs at a time. - */ -void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val) -{ - unsigned int n = id >> IGRPMODR_SHIFT; - - mmio_write_32(base + GICD_IGRPMODR + (n << 2), val); -} - -/* - * Accessor to get the bit corresponding to interrupt ID - * in GIC Distributor IGRPMODR. - */ -unsigned int gicd_get_igrpmodr(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicd_read_igrpmodr(base, id); - - return (reg_val >> bit_num) & 0x1U; -} - -/* - * Accessor to set the bit corresponding to interrupt ID - * in GIC Distributor IGRPMODR. - */ -void gicd_set_igrpmodr(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicd_read_igrpmodr(base, id); - - gicd_write_igrpmodr(base, id, reg_val | (1U << bit_num)); -} - -/* - * Accessor to clear the bit corresponding to interrupt ID - * in GIC Distributor IGRPMODR. - */ -void gicd_clr_igrpmodr(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicd_read_igrpmodr(base, id); - - gicd_write_igrpmodr(base, id, reg_val & ~(1U << bit_num)); -} - -/* - * Accessor to read the GIC Re-distributor IPRIORITYR corresponding to the - * interrupt `id`, 4 interrupts IDs at a time. - */ -unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id) -{ - unsigned int n = id >> IPRIORITYR_SHIFT; - - return mmio_read_32(base + GICR_IPRIORITYR + (n << 2)); -} - -/* - * Accessor to write the GIC Re-distributor IPRIORITYR corresponding to the - * interrupt `id`, 4 interrupts IDs at a time. - */ -void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val) -{ - unsigned int n = id >> IPRIORITYR_SHIFT; - - mmio_write_32(base + GICR_IPRIORITYR + (n << 2), val); -} - -/* - * Accessor to get the bit corresponding to interrupt ID - * from GIC Re-distributor IGROUPR0. - */ -unsigned int gicr_get_igroupr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igroupr0(base); - - return (reg_val >> bit_num) & 0x1U; -} - -/* - * Accessor to set the bit corresponding to interrupt ID - * in GIC Re-distributor IGROUPR0. - */ -void gicr_set_igroupr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igroupr0(base); - - gicr_write_igroupr0(base, reg_val | (1U << bit_num)); -} - -/* - * Accessor to clear the bit corresponding to interrupt ID - * in GIC Re-distributor IGROUPR0. - */ -void gicr_clr_igroupr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGROUPR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igroupr0(base); - - gicr_write_igroupr0(base, reg_val & ~(1U << bit_num)); -} - -/* - * Accessor to get the bit corresponding to interrupt ID - * from GIC Re-distributor IGRPMODR0. - */ -unsigned int gicr_get_igrpmodr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igrpmodr0(base); - - return (reg_val >> bit_num) & 0x1U; -} - -/* - * Accessor to set the bit corresponding to interrupt ID - * in GIC Re-distributor IGRPMODR0. - */ -void gicr_set_igrpmodr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igrpmodr0(base); - - gicr_write_igrpmodr0(base, reg_val | (1U << bit_num)); -} - -/* - * Accessor to clear the bit corresponding to interrupt ID - * in GIC Re-distributor IGRPMODR0. - */ -void gicr_clr_igrpmodr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << IGRPMODR_SHIFT) - 1U); - unsigned int reg_val = gicr_read_igrpmodr0(base); - - gicr_write_igrpmodr0(base, reg_val & ~(1U << bit_num)); -} - -/* - * Accessor to set the bit corresponding to interrupt ID - * in GIC Re-distributor ISENABLER0. - */ -void gicr_set_isenabler0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << ISENABLER_SHIFT) - 1U); - - gicr_write_isenabler0(base, (1U << bit_num)); -} - -/* - * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor - * ICENABLER0. - */ -void gicr_set_icenabler0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << ICENABLER_SHIFT) - 1U); - - gicr_write_icenabler0(base, (1U << bit_num)); -} - -/* - * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor - * ISACTIVER0. - */ -unsigned int gicr_get_isactiver0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << ISACTIVER_SHIFT) - 1U); - unsigned int reg_val = gicr_read_isactiver0(base); - - return (reg_val >> bit_num) & 0x1U; -} - -/* - * Accessor to clear the bit corresponding to interrupt ID in GIC Re-distributor - * ICPENDRR0. - */ -void gicr_set_icpendr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << ICPENDR_SHIFT) - 1U); - - gicr_write_icpendr0(base, (1U << bit_num)); -} - -/* - * Accessor to set the bit corresponding to interrupt ID in GIC Re-distributor - * ISPENDR0. - */ -void gicr_set_ispendr0(uintptr_t base, unsigned int id) -{ - unsigned int bit_num = id & ((1U << ISPENDR_SHIFT) - 1U); - - gicr_write_ispendr0(base, (1U << bit_num)); -} - -/* - * Accessor to set the byte corresponding to interrupt ID - * in GIC Re-distributor IPRIORITYR. - */ -void gicr_set_ipriorityr(uintptr_t base, unsigned int id, unsigned int pri) -{ - uint8_t val = pri & GIC_PRI_MASK; - - mmio_write_8(base + GICR_IPRIORITYR + id, val); -} - -/* - * Accessor to set the bit fields corresponding to interrupt ID - * in GIC Re-distributor ICFGR0. - */ -void gicr_set_icfgr0(uintptr_t base, unsigned int id, unsigned int cfg) -{ - /* Interrupt configuration is a 2-bit field */ - unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U); - unsigned int bit_shift = bit_num << 1U; - - uint32_t reg_val = gicr_read_icfgr0(base); - - /* Clear the field, and insert required configuration */ - reg_val &= ~(GIC_CFG_MASK << bit_shift); - reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift); - - gicr_write_icfgr0(base, reg_val); -} - -/* - * Accessor to set the bit fields corresponding to interrupt ID - * in GIC Re-distributor ICFGR1. - */ -void gicr_set_icfgr1(uintptr_t base, unsigned int id, unsigned int cfg) -{ - /* Interrupt configuration is a 2-bit field */ - unsigned int bit_num = id & ((1U << ICFGR_SHIFT) - 1U); - unsigned int bit_shift = bit_num << 1U; - - uint32_t reg_val = gicr_read_icfgr1(base); - - /* Clear the field, and insert required configuration */ - reg_val &= ~(GIC_CFG_MASK << bit_shift); - reg_val |= ((cfg & GIC_CFG_MASK) << bit_shift); - - gicr_write_icfgr1(base, reg_val); -} - /****************************************************************************** * This function marks the core as awake in the re-distributor and * ensures that the interface is active. @@ -292,7 +35,6 @@ void gicv3_rdistif_mark_core_awake(uintptr_t gicr_base) ; } - /****************************************************************************** * This function marks the core as asleep in the re-distributor and ensures * that the interface is quiescent. diff --git a/drivers/arm/gic/v3/gicv3_private.h b/drivers/arm/gic/v3/gicv3_private.h index 327a9a149..dae01cb1e 100644 --- a/drivers/arm/gic/v3/gicv3_private.h +++ b/drivers/arm/gic/v3/gicv3_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -24,6 +24,100 @@ #define RWP_TRUE U(1) #define RWP_FALSE U(0) +/* Calculate GIC register bit number corresponding to its interrupt ID */ +#define BIT_NUM(REG, id) \ + ((id) & ((1U << REG##_SHIFT) - 1U)) + +/* Calculate 8-bit GICD register offset corresponding to its interrupt ID */ +#define GICD_OFFSET_8(REG, id) \ + GICD_##REG + (id) + +/* Calculate 32-bit GICD register offset corresponding to its interrupt ID */ +#define GICD_OFFSET(REG, id) \ + GICD_##REG + (((id) >> REG##_SHIFT) << 2) + +/* Calculate 64-bit GICD register offset corresponding to its interrupt ID */ +#define GICD_OFFSET_64(REG, id) \ + GICD_##REG + (((id) >> REG##_SHIFT) << 3) + +/* Read 32-bit GIC Distributor register corresponding to its interrupt ID */ +#define GICD_READ(REG, base, id) \ + mmio_read_32((base) + GICD_OFFSET(REG, (id))) + +/* Read 64-bit GIC Distributor register corresponding to its interrupt ID */ +#define GICD_READ_64(REG, base, id) \ + mmio_read_64((base) + GICD_OFFSET_64(REG, (id))) + +/* Write to 64-bit GIC Distributor register corresponding to its interrupt ID */ +#define GICD_WRITE_64(REG, base, id, val) \ + mmio_write_64((base) + GICD_OFFSET_64(REG, (id)), (val)) + +/* Write to 32-bit GIC Distributor register corresponding to its interrupt ID */ +#define GICD_WRITE(REG, base, id, val) \ + mmio_write_32((base) + GICD_OFFSET(REG, (id)), (val)) + +/* Write to 8-bit GIC Distributor register corresponding to its interrupt ID */ +#define GICD_WRITE_8(REG, base, id, val) \ + mmio_write_8((base) + GICD_OFFSET_8(REG, (id)), (val)) + +/* + * Bit operations on GIC Distributor register corresponding + * to its interrupt ID + */ +/* Get bit in GIC Distributor register */ +#define GICD_GET_BIT(REG, base, id) \ + ((mmio_read_32((base) + GICD_OFFSET(REG, (id))) >> \ + BIT_NUM(REG, (id))) & 1U) + +/* Set bit in GIC Distributor register */ +#define GICD_SET_BIT(REG, base, id) \ + mmio_setbits_32((base) + GICD_OFFSET(REG, (id)), \ + ((uint32_t)1 << BIT_NUM(REG, (id)))) + +/* Clear bit in GIC Distributor register */ +#define GICD_CLR_BIT(REG, base, id) \ + mmio_clrbits_32((base) + GICD_OFFSET(REG, (id)), \ + ((uint32_t)1 << BIT_NUM(REG, (id)))) + +/* Write bit in GIC Distributor register */ +#define GICD_WRITE_BIT(REG, base, id) \ + mmio_write_32((base) + GICD_OFFSET(REG, (id)), \ + ((uint32_t)1 << BIT_NUM(REG, (id)))) + +/* + * Calculate GICv3 GICR register offset + */ +#define GICR_OFFSET(REG, id) \ + GICR_##REG + (((id) >> REG##_SHIFT) << 2) + +/* Write to GIC Redistributor register corresponding to its interrupt ID */ +#define GICR_WRITE_8(REG, base, id, val) \ + mmio_write_8((base) + GICR_##REG + (id), (val)) + +/* + * Bit operations on GIC Redistributor register + * corresponding to its interrupt ID + */ +/* Get bit in GIC Redistributor register */ +#define GICR_GET_BIT(REG, base, id) \ + ((mmio_read_32((base) + GICR_OFFSET(REG, (id))) >> \ + BIT_NUM(REG, (id))) & 1U) + +/* Write bit in GIC Redistributor register */ +#define GICR_WRITE_BIT(REG, base, id) \ + mmio_write_32((base) + GICR_OFFSET(REG, (id)), \ + ((uint32_t)1 << BIT_NUM(REG, (id)))) + +/* Set bit in GIC Redistributor register */ +#define GICR_SET_BIT(REG, base, id) \ + mmio_setbits_32((base) + GICR_OFFSET(REG, (id)), \ + ((uint32_t)1 << BIT_NUM(REG, (id)))) + +/* Clear bit in GIC Redistributor register */ +#define GICR_CLR_BIT(REG, base, id) \ + mmio_clrbits_32((base) + GICR_OFFSET(REG, (id)), \ + ((uint32_t)1 << BIT_NUM(REG, (id)))) + /* * Macro to convert an mpidr to a value suitable for programming into a * GICD_IROUTER. Bits[31:24] in the MPIDR are cleared as they are not relevant @@ -63,9 +157,9 @@ extern const gicv3_driver_data_t *gicv3_driver_data; * Note: The raw register values correspond to multiple interrupt IDs and * the number of interrupt IDs involved depends on the register accessed. ******************************************************************************/ -unsigned int gicd_read_igrpmodr(uintptr_t base, unsigned int id); +uint32_t gicd_read_igrpmodr(uintptr_t base, unsigned int id); unsigned int gicr_read_ipriorityr(uintptr_t base, unsigned int id); -void gicd_write_igrpmodr(uintptr_t base, unsigned int id, unsigned int val); +void gicd_write_igrpmodr(uintptr_t base, unsigned int id, uint32_t val); void gicr_write_ipriorityr(uintptr_t base, unsigned int id, unsigned int val); /******************************************************************************* @@ -121,27 +215,27 @@ void gicv3_rdistif_mark_core_asleep(uintptr_t gicr_base); */ static inline void gicd_wait_for_pending_write(uintptr_t gicd_base) { - while ((gicd_read_ctlr(gicd_base) & GICD_CTLR_RWP_BIT) != 0U) - ; + while ((gicd_read_ctlr(gicd_base) & GICD_CTLR_RWP_BIT) != 0U) { + } } -static inline unsigned int gicd_read_pidr2(uintptr_t base) +static inline uint32_t gicd_read_pidr2(uintptr_t base) { return mmio_read_32(base + GICD_PIDR2_GICV3); } -static inline unsigned long long gicd_read_irouter(uintptr_t base, unsigned int id) +static inline uint64_t gicd_read_irouter(uintptr_t base, unsigned int id) { assert(id >= MIN_SPI_ID); - return mmio_read_64(base + GICD_IROUTER + (id << 3)); + return GICD_READ_64(IROUTER, base, id); } static inline void gicd_write_irouter(uintptr_t base, unsigned int id, - unsigned long long affinity) + uint64_t affinity) { assert(id >= MIN_SPI_ID); - mmio_write_64(base + GICD_IROUTER + (id << 3), affinity); + GICD_WRITE_64(IROUTER, base, id, affinity); } static inline void gicd_clr_ctlr(uintptr_t base, @@ -149,8 +243,9 @@ static inline void gicd_clr_ctlr(uintptr_t base, unsigned int rwp) { gicd_write_ctlr(base, gicd_read_ctlr(base) & ~bitmap); - if (rwp != 0U) + if (rwp != 0U) { gicd_wait_for_pending_write(base); + } } static inline void gicd_set_ctlr(uintptr_t base, @@ -158,8 +253,9 @@ static inline void gicd_set_ctlr(uintptr_t base, unsigned int rwp) { gicd_write_ctlr(base, gicd_read_ctlr(base) | bitmap); - if (rwp != 0U) + if (rwp != 0U) { gicd_wait_for_pending_write(base); + } } /******************************************************************************* @@ -175,17 +271,17 @@ static inline void gicr_write_ctlr(uintptr_t base, uint32_t val) mmio_write_32(base + GICR_CTLR, val); } -static inline unsigned long long gicr_read_typer(uintptr_t base) +static inline uint64_t gicr_read_typer(uintptr_t base) { return mmio_read_64(base + GICR_TYPER); } -static inline unsigned int gicr_read_waker(uintptr_t base) +static inline uint32_t gicr_read_waker(uintptr_t base) { return mmio_read_32(base + GICR_WAKER); } -static inline void gicr_write_waker(uintptr_t base, unsigned int val) +static inline void gicr_write_waker(uintptr_t base, uint32_t val) { mmio_write_32(base + GICR_WAKER, val); } @@ -199,14 +295,14 @@ static inline void gicr_write_waker(uintptr_t base, unsigned int val) */ static inline void gicr_wait_for_pending_write(uintptr_t gicr_base) { - while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_RWP_BIT) != 0U) - ; + while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_RWP_BIT) != 0U) { + } } static inline void gicr_wait_for_upstream_pending_write(uintptr_t gicr_base) { - while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT) != 0U) - ; + while ((gicr_read_ctlr(gicr_base) & GICR_CTLR_UWP_BIT) != 0U) { + } } /* Private implementation of Distributor power control hooks */ @@ -214,7 +310,7 @@ void arm_gicv3_distif_pre_save(unsigned int rdist_proc_num); void arm_gicv3_distif_post_restore(unsigned int rdist_proc_num); /******************************************************************************* - * GIC Re-distributor functions for accessing entire registers. + * GIC Redistributor functions for accessing entire registers. * Note: The raw register values correspond to multiple interrupt IDs and * the number of interrupt IDs involved depends on the register accessed. ******************************************************************************/ @@ -341,7 +437,7 @@ static inline uint32_t gits_read_ctlr(uintptr_t base) return mmio_read_32(base + GITS_CTLR); } -static inline void gits_write_ctlr(uintptr_t base, unsigned int val) +static inline void gits_write_ctlr(uintptr_t base, uint32_t val) { mmio_write_32(base + GITS_CTLR, val); } @@ -366,13 +462,15 @@ static inline void gits_write_cwriter(uintptr_t base, uint64_t val) mmio_write_64(base + GITS_CWRITER, val); } -static inline uint64_t gits_read_baser(uintptr_t base, unsigned int its_table_id) +static inline uint64_t gits_read_baser(uintptr_t base, + unsigned int its_table_id) { assert(its_table_id < 8U); return mmio_read_64(base + GITS_BASER + (8U * its_table_id)); } -static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id, uint64_t val) +static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id, + uint64_t val) { assert(its_table_id < 8U); mmio_write_64(base + GITS_BASER + (8U * its_table_id), val); @@ -384,9 +482,8 @@ static inline void gits_write_baser(uintptr_t base, unsigned int its_table_id, u static inline void gits_wait_for_quiescent_bit(uintptr_t gits_base) { assert((gits_read_ctlr(gits_base) & GITS_CTLR_ENABLED_BIT) == 0U); - while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0U) - ; + while ((gits_read_ctlr(gits_base) & GITS_CTLR_QUIESCENT_BIT) == 0U) { + } } - #endif /* GICV3_PRIVATE_H */ diff --git a/drivers/rpi3/gpio/rpi3_gpio.c b/drivers/rpi3/gpio/rpi3_gpio.c index b39808ff7..f938f563f 100644 --- a/drivers/rpi3/gpio/rpi3_gpio.c +++ b/drivers/rpi3/gpio/rpi3_gpio.c @@ -11,7 +11,7 @@ #include <drivers/delay_timer.h> #include <drivers/rpi3/gpio/rpi3_gpio.h> -static struct rpi3_gpio_params rpi3_gpio_params; +static uintptr_t reg_base; static int rpi3_gpio_get_direction(int gpio); static void rpi3_gpio_set_direction(int gpio, int direction); @@ -43,7 +43,6 @@ static const gpio_ops_t rpi3_gpio_ops = { int rpi3_gpio_get_select(int gpio) { int ret; - uintptr_t reg_base = rpi3_gpio_params.reg_base; int regN = gpio / 10; int shift = 3 * (gpio % 10); uintptr_t reg_sel = reg_base + RPI3_GPIO_GPFSEL(regN); @@ -69,7 +68,6 @@ int rpi3_gpio_get_select(int gpio) */ void rpi3_gpio_set_select(int gpio, int fsel) { - uintptr_t reg_base = rpi3_gpio_params.reg_base; int regN = gpio / 10; int shift = 3 * (gpio % 10); uintptr_t reg_sel = reg_base + RPI3_GPIO_GPFSEL(regN); @@ -106,7 +104,6 @@ static void rpi3_gpio_set_direction(int gpio, int direction) static int rpi3_gpio_get_value(int gpio) { - uintptr_t reg_base = rpi3_gpio_params.reg_base; int regN = gpio / 32; int shift = gpio % 32; uintptr_t reg_lev = reg_base + RPI3_GPIO_GPLEV(regN); @@ -119,7 +116,6 @@ static int rpi3_gpio_get_value(int gpio) static void rpi3_gpio_set_value(int gpio, int value) { - uintptr_t reg_base = rpi3_gpio_params.reg_base; int regN = gpio / 32; int shift = gpio % 32; uintptr_t reg_set = reg_base + RPI3_GPIO_GPSET(regN); @@ -137,7 +133,6 @@ static void rpi3_gpio_set_value(int gpio, int value) static void rpi3_gpio_set_pull(int gpio, int pull) { - uintptr_t reg_base = rpi3_gpio_params.reg_base; int regN = gpio / 32; int shift = gpio % 32; uintptr_t reg_pud = reg_base + RPI3_GPIO_GPPUD; @@ -161,9 +156,8 @@ static void rpi3_gpio_set_pull(int gpio, int pull) mmio_write_32(reg_pud, 0x0); } -void rpi3_gpio_init(struct rpi3_gpio_params *params) +void rpi3_gpio_init(void) { - assert(params != 0); - memcpy(&rpi3_gpio_params, params, sizeof(struct rpi3_gpio_params)); + reg_base = RPI3_GPIO_BASE; gpio_init(&rpi3_gpio_ops); } diff --git a/fdts/fvp-base-gicv2-psci-aarch32.dts b/fdts/fvp-base-gicv2-psci-aarch32.dts index e71a39519..fcef927b3 100644 --- a/fdts/fvp-base-gicv2-psci-aarch32.dts +++ b/fdts/fvp-base-gicv2-psci-aarch32.dts @@ -35,6 +35,7 @@ cpu_on = <0x84000003>; sys_poweroff = <0x84000008>; sys_reset = <0x84000009>; + max-pwr-lvl = <2>; }; cpus { diff --git a/fdts/fvp-base-gicv2-psci.dts b/fdts/fvp-base-gicv2-psci.dts index c9c9d9594..1e0a81c3c 100644 --- a/fdts/fvp-base-gicv2-psci.dts +++ b/fdts/fvp-base-gicv2-psci.dts @@ -35,6 +35,7 @@ cpu_on = <0xc4000003>; sys_poweroff = <0x84000008>; sys_reset = <0x84000009>; + max-pwr-lvl = <2>; }; cpus { diff --git a/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi b/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi index f9809db8b..a28a4a537 100644 --- a/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi +++ b/fdts/fvp-base-gicv3-psci-aarch32-common.dtsi @@ -33,6 +33,7 @@ cpu_on = <0x84000003>; sys_poweroff = <0x84000008>; sys_reset = <0x84000009>; + max-pwr-lvl = <2>; }; cpus { diff --git a/fdts/fvp-base-gicv3-psci-common.dtsi b/fdts/fvp-base-gicv3-psci-common.dtsi index 5b0470d89..fb73f6053 100644 --- a/fdts/fvp-base-gicv3-psci-common.dtsi +++ b/fdts/fvp-base-gicv3-psci-common.dtsi @@ -33,6 +33,7 @@ cpu_on = <0xc4000003>; sys_poweroff = <0x84000008>; sys_reset = <0x84000009>; + max-pwr-lvl = <2>; }; cpus { diff --git a/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi b/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi index f3f768417..4bed36ff4 100644 --- a/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi +++ b/fdts/fvp-base-gicv3-psci-dynamiq-common.dtsi @@ -11,6 +11,9 @@ /* DynamIQ based designs have upto 8 CPUs in each cluster */ &CPU_MAP { + /delete-node/ cluster0; + /delete-node/ cluster1; + cluster0 { core0 { cpu = <&CPU0>; diff --git a/fdts/fvp-foundation-gicv2-psci.dts b/fdts/fvp-foundation-gicv2-psci.dts index b6da90549..3a204cb24 100644 --- a/fdts/fvp-foundation-gicv2-psci.dts +++ b/fdts/fvp-foundation-gicv2-psci.dts @@ -35,6 +35,7 @@ cpu_on = <0xc4000003>; sys_poweroff = <0x84000008>; sys_reset = <0x84000009>; + max-pwr-lvl = <2>; }; cpus { diff --git a/fdts/fvp-foundation-gicv3-psci.dts b/fdts/fvp-foundation-gicv3-psci.dts index 81071e255..d85305afe 100644 --- a/fdts/fvp-foundation-gicv3-psci.dts +++ b/fdts/fvp-foundation-gicv3-psci.dts @@ -35,6 +35,7 @@ cpu_on = <0xc4000003>; sys_poweroff = <0x84000008>; sys_reset = <0x84000009>; + max-pwr-lvl = <2>; }; cpus { diff --git a/include/arch/aarch32/asm_macros.S b/include/arch/aarch32/asm_macros.S index ea1636e24..f75da0ce6 100644 --- a/include/arch/aarch32/asm_macros.S +++ b/include/arch/aarch32/asm_macros.S @@ -108,11 +108,16 @@ #else /* * Macro for mitigating against speculative execution beyond ERET. + * If possible use Speculation Barrier instruction defined in ARMv8.5 */ .macro exception_return eret +#if ARM_ARCH_AT_LEAST(8, 5) + sb +#else dsb nsh isb +#endif .endm #endif diff --git a/include/arch/aarch32/el3_common_macros.S b/include/arch/aarch32/el3_common_macros.S index 7559de446..4fd746d5a 100644 --- a/include/arch/aarch32/el3_common_macros.S +++ b/include/arch/aarch32/el3_common_macros.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -329,6 +329,11 @@ bl inv_dcache_range #endif + /* + * zeromem uses r12 whereas it is used to save previous BL arg3, + * save it in r7 + */ + mov r7, r12 ldr r0, =__BSS_START__ ldr r1, =__BSS_SIZE__ bl zeromem @@ -339,6 +344,9 @@ bl zeromem #endif + /* Restore r12 */ + mov r12, r7 + #if defined(IMAGE_BL1) || (defined(IMAGE_BL2) && BL2_AT_EL3 && BL2_IN_XIP_MEM) /* ----------------------------------------------------- * Copy data from ROM to RAM. diff --git a/include/arch/aarch64/arch.h b/include/arch/aarch64/arch.h index b0c265047..2b2c11652 100644 --- a/include/arch/aarch64/arch.h +++ b/include/arch/aarch64/arch.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -452,6 +452,9 @@ #define SPSR_M_AARCH64 U(0x0) #define SPSR_M_AARCH32 U(0x1) +#define SPSR_EL_SHIFT U(2) +#define SPSR_EL_WIDTH U(2) + #define SPSR_SSBS_BIT_AARCH64 BIT_64(12) #define SPSR_SSBS_BIT_AARCH32 BIT_64(23) @@ -557,6 +560,7 @@ #define MODE_EL_SHIFT U(0x2) #define MODE_EL_MASK U(0x3) +#define MODE_EL_WIDTH U(0x2) #define MODE_EL3 U(0x3) #define MODE_EL2 U(0x2) #define MODE_EL1 U(0x1) diff --git a/include/arch/aarch64/asm_macros.S b/include/arch/aarch64/asm_macros.S index a7d5a3dd6..cbb9f0be8 100644 --- a/include/arch/aarch64/asm_macros.S +++ b/include/arch/aarch64/asm_macros.S @@ -220,11 +220,16 @@ /* * Macro for mitigating against speculative execution beyond ERET. + * If possible use Speculation Barrier instruction defined in ARMv8.5 */ .macro exception_return eret - dsb nsh +#if ARM_ARCH_AT_LEAST(8, 5) + sb +#else + dsb nsh isb +#endif .endm #endif /* ASM_MACROS_S */ diff --git a/include/bl32/payloads/tlk.h b/include/bl32/payloads/tlk.h index ce8e3e890..5162d1340 100644 --- a/include/bl32/payloads/tlk.h +++ b/include/bl32/payloads/tlk.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -26,7 +27,7 @@ #define TLK_RESUME_FID TLK_TOS_YIELD_FID(0x100) #define TLK_SYSTEM_SUSPEND TLK_TOS_YIELD_FID(0xE001) #define TLK_SYSTEM_RESUME TLK_TOS_YIELD_FID(0xE002) -#define TLK_SYSTEM_OFF TLK_TOS_YIELD_FID(0xE003) +#define TLK_IRQ_FIRED TLK_TOS_YIELD_FID(0xE004) /* * SMC function IDs that TLK uses to signal various forms of completions @@ -38,7 +39,7 @@ #define TLK_VA_TRANSLATE (0x32000004 | (ULL(1) << 31)) #define TLK_SUSPEND_DONE (0x32000005 | (ULL(1) << 31)) #define TLK_RESUME_DONE (0x32000006 | (ULL(1) << 31)) -#define TLK_SYSTEM_OFF_DONE (0x32000007 | (ULL(1) << 31)) +#define TLK_IRQ_DONE (0x32000008 | (ULL(1) << 31)) /* * Trusted Application specific function IDs diff --git a/include/common/debug.h b/include/common/debug.h index 245e69865..9aef15b51 100644 --- a/include/common/debug.h +++ b/include/common/debug.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -91,6 +91,7 @@ #if ENABLE_BACKTRACE void backtrace(const char *cookie); +const char *get_el_str(unsigned int el); #else #define backtrace(x) #endif diff --git a/include/drivers/arm/gicv3.h b/include/drivers/arm/gicv3.h index c4f42d04d..e6339bcfe 100644 --- a/include/drivers/arm/gicv3.h +++ b/include/drivers/arm/gicv3.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -32,7 +32,7 @@ #define GICD_SETSPI_NSR U(0x40) #define GICD_CLRSPI_NSR U(0x48) #define GICD_SETSPI_SR U(0x50) -#define GICD_CLRSPI_SR U(0x50) +#define GICD_CLRSPI_SR U(0x58) #define GICD_IGRPMODR U(0xd00) /* * GICD_IROUTER<n> register is at 0x6000 + 8n, where n is the interrupt id and @@ -79,7 +79,7 @@ #define NUM_OF_DIST_REGS 30 /******************************************************************************* - * GICv3 Re-distributor interface registers & constants + * GICv3 Redistributor interface registers & constants ******************************************************************************/ #define GICR_PCPUBASE_SHIFT 0x11 #define GICR_SGIBASE_OFFSET U(65536) /* 64 KB */ diff --git a/include/drivers/rpi3/gpio/rpi3_gpio.h b/include/drivers/rpi3/gpio/rpi3_gpio.h index 159a2e08b..7bb3ee25b 100644 --- a/include/drivers/rpi3/gpio/rpi3_gpio.h +++ b/include/drivers/rpi3/gpio/rpi3_gpio.h @@ -11,11 +11,7 @@ #include <stdint.h> #include <drivers/gpio.h> -struct rpi3_gpio_params { - uintptr_t reg_base; -}; - -void rpi3_gpio_init(struct rpi3_gpio_params *params); +void rpi3_gpio_init(void); int rpi3_gpio_get_select(int gpio); void rpi3_gpio_set_select(int gpio, int fsel); diff --git a/include/lib/cpus/aarch64/denver.h b/include/lib/cpus/aarch64/denver.h index 02657a0fb..b98abdf4d 100644 --- a/include/lib/cpus/aarch64/denver.h +++ b/include/lib/cpus/aarch64/denver.h @@ -34,6 +34,11 @@ #define DENVER_CPU_PMSTATE_C7 U(0x7) #define DENVER_CPU_PMSTATE_MASK U(0xF) +/* ACTRL_ELx bits to enable dual execution*/ +#define DENVER_CPU_ENABLE_DUAL_EXEC_EL2 (ULL(1) << 9) +#define DENVER_CPU_ENABLE_DUAL_EXEC_EL3 (ULL(1) << 9) +#define DENVER_CPU_ENABLE_DUAL_EXEC_EL1 (U(1) << 4) + #ifndef __ASSEMBLER__ /* Disable Dynamic Code Optimisation */ diff --git a/include/lib/fconf/fconf.h b/include/lib/fconf/fconf.h index 0401e5c06..09d2b59aa 100644 --- a/include/lib/fconf/fconf.h +++ b/include/lib/fconf/fconf.h @@ -12,9 +12,16 @@ /* Public API */ #define FCONF_GET_PROPERTY(a, b, c) a##__##b##_getter(c) -#define FCONF_REGISTER_POPULATOR(name, callback) \ +/* + * This macro takes three arguments: + * config: Configuration identifier + * name: property namespace + * callback: populate() function + */ +#define FCONF_REGISTER_POPULATOR(config, name, callback) \ __attribute__((used, section(".fconf_populator"))) \ const struct fconf_populator (name##__populator) = { \ + .config_type = (#config), \ .info = (#name), \ .populate = (callback) \ }; @@ -27,6 +34,7 @@ */ struct fconf_populator { /* Description of the data loaded by the callback */ + const char *config_type; const char *info; /* Callback used by fconf_populate function with a provided config dtb. @@ -45,7 +53,7 @@ void fconf_load_config(void); * * Panic on error. */ -void fconf_populate(uintptr_t config); +void fconf_populate(const char *config_type, uintptr_t config); /* FCONF specific getter */ #define fconf__dtb_getter(prop) fconf_dtb_info.prop diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h index babde41fe..a84047aac 100644 --- a/include/plat/arm/common/plat_arm.h +++ b/include/plat/arm/common/plat_arm.h @@ -148,6 +148,12 @@ void arm_setup_romlib(void); #define ARM_ROTPK_DEVEL_RSA_ID 2 #define ARM_ROTPK_DEVEL_ECDSA_ID 3 +/* Defines used to retrieve ARM SOC revision */ +#define ARM_SOC_CONTINUATION_CODE U(0x4) +#define ARM_SOC_IDENTIFICATION_CODE U(0x3B) +#define ARM_SOC_CONTINUATION_SHIFT U(24) +#define ARM_SOC_IDENTIFICATION_SHIFT U(16) + /* IO storage utility functions */ int arm_io_setup(void); @@ -222,6 +228,7 @@ void arm_tsp_early_platform_setup(void); void arm_sp_min_early_platform_setup(void *from_bl2, uintptr_t tos_fw_config, uintptr_t hw_config, void *plat_params_from_bl2); void arm_sp_min_plat_runtime_setup(void); +void arm_sp_min_plat_arch_setup(void); /* FIP TOC validity check */ bool arm_io_is_toc_valid(void); @@ -322,4 +329,7 @@ extern const unsigned int arm_pm_idle_states[]; void plat_arm_secure_wdt_start(void); void plat_arm_secure_wdt_stop(void); +/* Get SOC-ID of ARM platform */ +uint32_t plat_arm_get_soc_id(void); + #endif /* PLAT_ARM_H */ diff --git a/include/plat/common/platform.h b/include/plat/common/platform.h index 5b5ebb973..e4431d2f0 100644 --- a/include/plat/common/platform.h +++ b/include/plat/common/platform.h @@ -322,4 +322,14 @@ void plat_flush_next_bl_params(void); */ unsigned int platform_core_pos_helper(unsigned long mpidr); +/* + * Optional function to get SOC version + */ +int32_t plat_get_soc_version(void); + +/* + * Optional function to get SOC revision + */ +int32_t plat_get_soc_revision(void); + #endif /* PLATFORM_H */ diff --git a/include/services/arm_arch_svc.h b/include/services/arm_arch_svc.h index 1cb2038c6..5bbd8bb6c 100644 --- a/include/services/arm_arch_svc.h +++ b/include/services/arm_arch_svc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,7 +9,11 @@ #define SMCCC_VERSION U(0x80000000) #define SMCCC_ARCH_FEATURES U(0x80000001) +#define SMCCC_ARCH_SOC_ID U(0x80000002) #define SMCCC_ARCH_WORKAROUND_1 U(0x80008000) #define SMCCC_ARCH_WORKAROUND_2 U(0x80007FFF) +#define SMCCC_GET_SOC_VERSION U(0) +#define SMCCC_GET_SOC_REVISION U(1) + #endif /* ARM_ARCH_SVC_H */ diff --git a/include/services/spm_core_manifest.h b/include/services/spm_core_manifest.h index 78748826d..71e6cfbe4 100644 --- a/include/services/spm_core_manifest.h +++ b/include/services/spm_core_manifest.h @@ -43,6 +43,11 @@ typedef struct spm_core_manifest_sect_attribute { */ uint32_t binary_size; + /* + * ID of the SPMD (mandatory) + */ + uint16_t spmc_id; + } spmc_manifest_sect_attribute_t; #endif /* SPMC_MANIFEST_H */ diff --git a/lib/fconf/fconf.c b/lib/fconf/fconf.c index a6da56b00..9ce46354d 100644 --- a/lib/fconf/fconf.c +++ b/lib/fconf/fconf.c @@ -53,17 +53,17 @@ void fconf_load_config(void) INFO("FCONF: FW_CONFIG loaded at address = 0x%lx\n", arm_tb_fw_info.image_base); } -void fconf_populate(uintptr_t config) +void fconf_populate(const char *config_type, uintptr_t config) { assert(config != 0UL); /* Check if the pointer to DTB is correct */ if (fdt_check_header((void *)config) != 0) { - ERROR("FCONF: Invalid DTB file passed for FW_CONFIG\n"); + ERROR("FCONF: Invalid DTB file passed for %s\n", config_type); panic(); } - INFO("FCONF: Reading firmware configuration file from: 0x%lx\n", config); + INFO("FCONF: Reading %s firmware configuration file from: 0x%lx\n", config_type, config); /* Go through all registered populate functions */ IMPORT_SYM(struct fconf_populator *, __FCONF_POPULATOR_START__, start); @@ -73,10 +73,12 @@ void fconf_populate(uintptr_t config) for (populator = start; populator != end; populator++) { assert((populator->info != NULL) && (populator->populate != NULL)); - INFO("FCONF: Reading firmware configuration information for: %s\n", populator->info); - if (populator->populate(config) != 0) { - /* TODO: handle property miss */ - panic(); + if (strcmp(populator->config_type, config_type) == 0) { + INFO("FCONF: Reading firmware configuration information for: %s\n", populator->info); + if (populator->populate(config) != 0) { + /* TODO: handle property miss */ + panic(); + } } } diff --git a/lib/fconf/fconf_dyn_cfg_getter.c b/lib/fconf/fconf_dyn_cfg_getter.c index d313a5618..317d3e5d3 100644 --- a/lib/fconf/fconf_dyn_cfg_getter.c +++ b/lib/fconf/fconf_dyn_cfg_getter.c @@ -92,4 +92,4 @@ int fconf_populate_dtb_registry(uintptr_t config) return 0; } -FCONF_REGISTER_POPULATOR(dyn_cfg, fconf_populate_dtb_registry); +FCONF_REGISTER_POPULATOR(TB_FW, dyn_cfg, fconf_populate_dtb_registry); diff --git a/lib/fconf/fconf_tbbr_getter.c b/lib/fconf/fconf_tbbr_getter.c index c6df9c876..a4d61d8cd 100644 --- a/lib/fconf/fconf_tbbr_getter.c +++ b/lib/fconf/fconf_tbbr_getter.c @@ -72,4 +72,4 @@ int fconf_populate_tbbr_dyn_config(uintptr_t config) return 0; } -FCONF_REGISTER_POPULATOR(tbbr, fconf_populate_tbbr_dyn_config); +FCONF_REGISTER_POPULATOR(TB_FW, tbbr, fconf_populate_tbbr_dyn_config); diff --git a/lib/locks/bakery/bakery_lock_normal.c b/lib/locks/bakery/bakery_lock_normal.c index caced8f46..0605fceb9 100644 --- a/lib/locks/bakery/bakery_lock_normal.c +++ b/lib/locks/bakery/bakery_lock_normal.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -77,6 +78,8 @@ static inline void read_cache_op(uintptr_t addr, bool cached) { if (cached) dccivac(addr); + + dmbish(); } /* Helper function to check if the lock is acquired */ diff --git a/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c new file mode 100644 index 000000000..2952cde80 --- /dev/null +++ b/plat/arm/board/fvp/fconf/fconf_hw_config_getter.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <common/debug.h> +#include <common/fdt_wrappers.h> +#include <fconf_hw_config_getter.h> +#include <libfdt.h> +#include <plat/common/platform.h> + +struct gicv3_config_t gicv3_config; +struct hw_topology_t soc_topology; + +int fconf_populate_gicv3_config(uintptr_t config) +{ + int err; + int node; + int addr[20]; + + /* Necessary to work with libfdt APIs */ + const void *hw_config_dtb = (const void *)config; + + /* + * Find the offset of the node containing "arm,gic-v3" compatible property. + * Populating fconf strucutures dynamically is not supported for legacy + * systems which use GICv2 IP. Simply skip extracting GIC properties. + */ + node = fdt_node_offset_by_compatible(hw_config_dtb, -1, "arm,gic-v3"); + if (node < 0) { + WARN("FCONF: Unable to locate node with arm,gic-v3 compatible property\n"); + return 0; + } + /* Read the reg cell holding base address of GIC controller modules + A sample reg cell array is shown here: + reg = <0x0 0x2f000000 0 0x10000>, // GICD + <0x0 0x2f100000 0 0x200000>, // GICR + <0x0 0x2c000000 0 0x2000>, // GICC + <0x0 0x2c010000 0 0x2000>, // GICH + <0x0 0x2c02f000 0 0x2000>; // GICV + */ + + err = fdtw_read_array(hw_config_dtb, node, "reg", 20, &addr); + if (err < 0) { + ERROR("FCONF: Failed to read reg property of GIC node\n"); + } + return err; +} + +int fconf_populate_topology(uintptr_t config) +{ + int err, node, cluster_node, core_node, thread_node, max_pwr_lvl = 0; + uint32_t cluster_count = 0, max_cpu_per_cluster = 0, total_cpu_count = 0; + + /* Necessary to work with libfdt APIs */ + const void *hw_config_dtb = (const void *)config; + + /* Find the offset of the node containing "arm,psci-1.0" compatible property */ + node = fdt_node_offset_by_compatible(hw_config_dtb, -1, "arm,psci-1.0"); + if (node < 0) { + ERROR("FCONF: Unable to locate node with arm,psci-1.0 compatible property\n"); + return node; + } + + err = fdtw_read_cells(hw_config_dtb, node, "max-pwr-lvl", 1, &max_pwr_lvl); + if (err < 0) { + /* + * Some legacy FVP dts may not have this property. Assign the default + * value. + */ + WARN("FCONF: Could not locate max-pwr-lvl property\n"); + max_pwr_lvl = 2; + } + + assert((uint32_t)max_pwr_lvl <= MPIDR_AFFLVL2); + + /* Find the offset of the "cpus" node */ + node = fdt_path_offset(hw_config_dtb, "/cpus"); + if (node < 0) { + ERROR("FCONF: Node '%s' not found in hardware configuration dtb\n", "cpus"); + return node; + } + + /* A typical cpu-map node in a device tree is shown here for reference + cpu-map { + cluster0 { + core0 { + cpu = <&CPU0>; + }; + core1 { + cpu = <&CPU1>; + }; + }; + + cluster1 { + core0 { + cpu = <&CPU2>; + }; + core1 { + cpu = <&CPU3>; + }; + }; + }; + */ + + /* Locate the cpu-map child node */ + node = fdt_subnode_offset(hw_config_dtb, node, "cpu-map"); + if (node < 0) { + ERROR("FCONF: Node '%s' not found in hardware configuration dtb\n", "cpu-map"); + return node; + } + + uint32_t cpus_per_cluster[PLAT_ARM_CLUSTER_COUNT] = {0}; + + /* Iterate through cluster nodes */ + fdt_for_each_subnode(cluster_node, hw_config_dtb, node) { + assert(cluster_count < PLAT_ARM_CLUSTER_COUNT); + + /* Iterate through core nodes */ + fdt_for_each_subnode(core_node, hw_config_dtb, cluster_node) { + /* core nodes may have child nodes i.e., "thread" nodes */ + if (fdt_first_subnode(hw_config_dtb, core_node) < 0) { + cpus_per_cluster[cluster_count]++; + } else { + /* Multi-threaded CPU description is found in dtb */ + fdt_for_each_subnode(thread_node, hw_config_dtb, core_node) { + cpus_per_cluster[cluster_count]++; + } + + /* Since in some dtbs, core nodes may not have thread node, + * no need to error if even one child node is not found. + */ + } + } + + /* Ensure every cluster node has at least 1 child node */ + if (cpus_per_cluster[cluster_count] < 1U) { + ERROR("FCONF: Unable to locate the core node in cluster %d\n", cluster_count); + return -1; + } + + INFO("CLUSTER ID: %d cpu-count: %d\n", cluster_count, cpus_per_cluster[cluster_count]); + + /* Find the maximum number of cpus in any cluster */ + max_cpu_per_cluster = MAX(max_cpu_per_cluster, cpus_per_cluster[cluster_count]); + total_cpu_count += cpus_per_cluster[cluster_count]; + cluster_count++; + } + + + /* At least one cluster node is expected in hardware configuration dtb */ + if (cluster_count < 1U) { + ERROR("FCONF: Unable to locate the cluster node in cpu-map node\n"); + return -1; + } + + soc_topology.plat_max_pwr_level = (uint32_t)max_pwr_lvl; + soc_topology.plat_cluster_count = cluster_count; + soc_topology.cluster_cpu_count = max_cpu_per_cluster; + soc_topology.plat_cpu_count = total_cpu_count; + + return 0; +} + +FCONF_REGISTER_POPULATOR(HW_CONFIG, gicv3_config, fconf_populate_gicv3_config); +FCONF_REGISTER_POPULATOR(HW_CONFIG, topology, fconf_populate_topology); diff --git a/plat/arm/board/fvp/fdts/fvp_fw_config.dts b/plat/arm/board/fvp/fdts/fvp_fw_config.dts index 9a4a05799..61bd69c17 100644 --- a/plat/arm/board/fvp/fdts/fvp_fw_config.dts +++ b/plat/arm/board/fvp/fdts/fvp_fw_config.dts @@ -39,7 +39,7 @@ tos_fw-config { load-address = <0x0 0x04001200>; - max-size = <0x200>; + max-size = <0x1000>; id = <TOS_FW_CONFIG_ID>; }; @@ -102,12 +102,12 @@ secure-partitions { compatible = "arm,sp"; - cactus { + cactus-primary { uuid = <0x1e67b5b4 0xe14f904a 0x13fb1fb8 0xcbdae1da>; load-address = <0x7000000>; }; - ivy { + cactus-secondary { uuid = <0x092358d1 0xb94723f0 0x64447c82 0xc88f57f5>; load-address = <0x7100000>; }; diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts index c94a209fd..79c4c07f6 100644 --- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts +++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts @@ -6,13 +6,62 @@ /dts-v1/; / { - compatible = "spci-core-manifest-1.0"; + compatible = "arm,spci-core-manifest-1.0"; attribute { + spmc_id = <0x8000>; maj_ver = <0x0>; min_ver = <0x9>; exec_state = <0x0>; load_address = <0x0 0x6000000>; entrypoint = <0x0 0x6000000>; }; + + chosen { + linux,initrd-start = <0>; + linux,initrd-end = <0>; + }; + + hypervisor { + compatible = "hafnium,hafnium"; + vm1 { + is_spci_partition; + debug_name = "cactus-primary"; + load-addr = <0x7000000>; + }; + vm2 { + is_spci_partition; + debug_name = "cactus-secondary"; + load-addr = <0x7100000>; + vcpu_count = <2>; + mem_size = <1048576>; + }; + }; + + cpus { + #address-cells = <0x2>; + #size-cells = <0x0>; + + cpu-map { + cluster0 { + core0 { + cpu = <0x2>; + }; + }; + }; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,armv8"; + reg = <0x0 0x0>; + enable-method = "psci"; + next-level-cache = <0xc>; + phandle = <0x2>; + }; + }; + + memory@60000000 { + device_type = "memory"; + reg = <0x6000000 0x2000000>; /* Trusted DRAM */ + }; }; diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c index 8627c5ef0..dc7bfa2dc 100644 --- a/plat/arm/board/fvp/fvp_bl31_setup.c +++ b/plat/arm/board/fvp/fvp_bl31_setup.c @@ -1,16 +1,21 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include <assert.h> +#include <common/debug.h> #include <drivers/arm/smmu_v3.h> +#include <lib/fconf/fconf.h> #include <plat/arm/common/arm_config.h> #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> #include "fvp_private.h" +uintptr_t hw_config_dtb; + void __init bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { @@ -40,4 +45,23 @@ void __init bl31_early_platform_setup2(u_register_t arg0, /* On FVP RevC, initialize SMMUv3 */ if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U) smmuv3_init(PLAT_FVP_SMMUV3_BASE); + + hw_config_dtb = arg2; +} + +void __init bl31_plat_arch_setup(void) +{ + arm_bl31_plat_arch_setup(); + + /* + * For RESET_TO_BL31 systems, BL31 is the first bootloader to run. + * So there is no BL2 to load the HW_CONFIG dtb into memory before + * control is passed to BL31. + */ +#if !RESET_TO_BL31 && !BL2_AT_EL3 + assert(hw_config_dtb != 0U); + + INFO("BL31 FCONF: HW_CONFIG address = %p\n", (void *)hw_config_dtb); + fconf_populate("HW_CONFIG", hw_config_dtb); +#endif } diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index 2c880fc30..c5fae56d7 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -134,6 +134,8 @@ const mmap_region_t plat_arm_mmap[] = { #if SPM_MM ARM_SPM_BUF_EL3_MMAP, #endif + /* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */ + ARM_DTB_DRAM_NS, {0} }; @@ -160,6 +162,8 @@ const mmap_region_t plat_arm_mmap[] = { V2M_MAP_IOFPGA, MAP_DEVICE0, MAP_DEVICE1, + /* Required by fconf APIs to read HW_CONFIG dtb loaded into DRAM */ + ARM_DTB_DRAM_NS, {0} }; #endif diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c index 24e79b4d4..80cfbd5ce 100644 --- a/plat/arm/board/fvp/fvp_topology.c +++ b/plat/arm/board/fvp/fvp_topology.c @@ -1,18 +1,21 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#include <platform_def.h> +#include <assert.h> #include <arch.h> #include <drivers/arm/fvp/fvp_pwrc.h> +#include <fconf_hw_config_getter.h> #include <lib/cassert.h> #include <plat/arm/common/arm_config.h> #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> +#include <platform_def.h> + /* The FVP power domain tree descriptor */ static unsigned char fvp_power_domain_tree_desc[FVP_CLUSTER_COUNT + 2]; @@ -21,24 +24,47 @@ CASSERT(((FVP_CLUSTER_COUNT > 0) && (FVP_CLUSTER_COUNT <= 256)), assert_invalid_fvp_cluster_count); /******************************************************************************* - * This function dynamically constructs the topology according to - * FVP_CLUSTER_COUNT and returns it. + * This function dynamically constructs the topology according to cpu-map node + * in HW_CONFIG dtb and returns it. ******************************************************************************/ const unsigned char *plat_get_power_domain_tree_desc(void) { - int i; + unsigned int i; + uint32_t cluster_count, cpus_per_cluster; + + /* + * fconf APIs are not supported for RESET_TO_SP_MIN, RESET_TO_BL31 and + * BL2_AT_EL3 systems. + */ +#if RESET_TO_SP_MIN || RESET_TO_BL31 || BL2_AT_EL3 + cluster_count = FVP_CLUSTER_COUNT; + cpus_per_cluster = FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU; +#else + cluster_count = FCONF_GET_PROPERTY(hw_config, topology, plat_cluster_count); + cpus_per_cluster = FCONF_GET_PROPERTY(hw_config, topology, cluster_cpu_count); + /* Several FVP Models use the same blanket dts. Ex: FVP_Base_Cortex-A65x4 + * and FVP_Base_Cortex-A65AEx8 both use same dts but have different number of + * CPUs in the cluster, as reflected by build flags FVP_MAX_CPUS_PER_CLUSTER. + * Take the minimum of two to ensure PSCI functions do not exceed the size of + * the PSCI data structures allocated at build time. + */ + cpus_per_cluster = MIN(cpus_per_cluster, + (uint32_t)(FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU)); + +#endif + + assert(cluster_count > 0U); + assert(cpus_per_cluster > 0U); /* * The highest level is the system level. The next level is constituted * by clusters and then cores in clusters. */ fvp_power_domain_tree_desc[0] = 1; - fvp_power_domain_tree_desc[1] = FVP_CLUSTER_COUNT; - - for (i = 0; i < FVP_CLUSTER_COUNT; i++) - fvp_power_domain_tree_desc[i + 2] = - FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU; + fvp_power_domain_tree_desc[1] = (unsigned char)cluster_count; + for (i = 0; i < cluster_count; i++) + fvp_power_domain_tree_desc[i + 2] = (unsigned char)cpus_per_cluster; return fvp_power_domain_tree_desc; } diff --git a/plat/arm/board/fvp/include/fconf_hw_config_getter.h b/plat/arm/board/fvp/include/fconf_hw_config_getter.h new file mode 100644 index 000000000..cab832f68 --- /dev/null +++ b/plat/arm/board/fvp/include/fconf_hw_config_getter.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2020, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef FCONF_HW_CONFIG_GETTER_H +#define FCONF_HW_CONFIG_GETTER_H + +#include <lib/fconf/fconf.h> + +/* Hardware Config related getter */ +#define hw_config__gicv3_config_getter(prop) gicv3_config.prop + +#define hw_config__topology_getter(prop) soc_topology.prop + +struct gicv3_config_t { + void *gicd_base; + void *gicr_base; +}; + +struct hw_topology_t { + uint32_t plat_cluster_count; + uint32_t cluster_cpu_count; + uint32_t plat_cpu_count; + uint32_t plat_max_pwr_level; +}; + +int fconf_populate_gicv3_config(uintptr_t config); +int fconf_populate_topology(uintptr_t config); + +extern struct gicv3_config_t gicv3_config; +extern struct hw_topology_t soc_topology; + +#endif /* FCONF_HW_CONFIG_GETTER_H */ diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index bfe207a29..1f569c250 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -52,6 +52,13 @@ #define PLAT_ARM_DRAM2_BASE ULL(0x880000000) #define PLAT_ARM_DRAM2_SIZE UL(0x80000000) +#define PLAT_HW_CONFIG_DTB_BASE ULL(0x82000000) +#define PLAT_HW_CONFIG_DTB_SIZE ULL(0x8000) + +#define ARM_DTB_DRAM_NS MAP_REGION_FLAT( \ + PLAT_HW_CONFIG_DTB_BASE, \ + PLAT_HW_CONFIG_DTB_SIZE, \ + MT_MEMORY | MT_RO | MT_NS) /* * Load address of BL33 for this platform port */ @@ -63,21 +70,21 @@ */ #if defined(IMAGE_BL31) # if SPM_MM -# define PLAT_ARM_MMAP_ENTRIES 9 +# define PLAT_ARM_MMAP_ENTRIES 10 # define MAX_XLAT_TABLES 9 # define PLAT_SP_IMAGE_MMAP_REGIONS 30 # define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10 # else -# define PLAT_ARM_MMAP_ENTRIES 8 +# define PLAT_ARM_MMAP_ENTRIES 9 # if USE_DEBUGFS -# define MAX_XLAT_TABLES 6 +# define MAX_XLAT_TABLES 8 # else -# define MAX_XLAT_TABLES 5 +# define MAX_XLAT_TABLES 7 # endif # endif #elif defined(IMAGE_BL32) -# define PLAT_ARM_MMAP_ENTRIES 8 -# define MAX_XLAT_TABLES 5 +# define PLAT_ARM_MMAP_ENTRIES 9 +# define MAX_XLAT_TABLES 6 #elif !USE_ROMLIB # define PLAT_ARM_MMAP_ENTRIES 11 # define MAX_XLAT_TABLES 5 @@ -126,7 +133,7 @@ * calculated using the current BL31 PROGBITS debug size plus the sizes of * BL2 and BL1-RW */ -#define PLAT_ARM_MAX_BL31_SIZE UL(0x3B000) +#define PLAT_ARM_MAX_BL31_SIZE UL(0x3E000) #endif /* RESET_TO_BL31 */ #ifndef __aarch64__ diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i index b1b9ed463..0c93d0aab 100644 --- a/plat/arm/board/fvp/jmptbl.i +++ b/plat/arm/board/fvp/jmptbl.i @@ -22,6 +22,8 @@ fdt fdt_node_offset_by_compatible fdt fdt_setprop_inplace_namelen_partial fdt fdt_first_subnode fdt fdt_next_subnode +fdt fdt_path_offset +fdt fdt_subnode_offset mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 05c11ce52..4e20632c9 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -56,6 +56,8 @@ $(eval $(call add_define,FVP_INTERCONNECT_DRIVER)) FVP_GICV3_SOURCES := drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ plat/common/plat_gicv3.c \ plat/arm/common/arm_gicv3.c @@ -202,6 +204,14 @@ BL31_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ ${FVP_INTERCONNECT_SOURCES} \ ${FVP_SECURITY_SOURCES} +# Support for fconf in BL31 +# Added separately from the above list for better readability +ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_BL31}),) +BL31_SOURCES += common/fdt_wrappers.c \ + lib/fconf/fconf.c \ + plat/arm/board/fvp/fconf/fconf_hw_config_getter.c +endif + ifeq (${FVP_USE_SP804_TIMER},1) BL31_SOURCES += drivers/arm/sp804/sp804_delay_timer.c else diff --git a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c index 88c91e6fe..763b42afb 100644 --- a/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c +++ b/plat/arm/board/fvp/sp_min/fvp_sp_min_setup.c @@ -1,13 +1,20 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include <assert.h> + +#include <bl32/sp_min/platform_sp_min.h> +#include <common/debug.h> +#include <lib/fconf/fconf.h> #include <plat/arm/common/plat_arm.h> #include "../fvp_private.h" +uintptr_t hw_config_dtb; + void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { @@ -30,4 +37,24 @@ void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1, * FVP PSCI code will enable coherency for other clusters. */ fvp_interconnect_enable(); + + hw_config_dtb = arg2; +} + +void sp_min_plat_arch_setup(void) +{ + arm_sp_min_plat_arch_setup(); + + /* + * For RESET_TO_SP_MIN systems, SP_MIN(BL32) is the first bootloader + * to run. So there is no BL2 to load the HW_CONFIG dtb into memory + * before control is passed to SP_MIN. + * Also, BL2 skips loading HW_CONFIG dtb for BL2_AT_EL3 builds. + */ +#if !RESET_TO_SP_MIN && !BL2_AT_EL3 + assert(hw_config_dtb != 0U); + + INFO("SP_MIN FCONF: HW_CONFIG address = %p\n", (void *)hw_config_dtb); + fconf_populate("HW_CONFIG", hw_config_dtb); +#endif } diff --git a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk index 0250a5f1a..36bf441ab 100644 --- a/plat/arm/board/fvp/sp_min/sp_min-fvp.mk +++ b/plat/arm/board/fvp/sp_min/sp_min-fvp.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -18,4 +18,12 @@ BL32_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ ${FVP_INTERCONNECT_SOURCES} \ ${FVP_SECURITY_SOURCES} +# Support for fconf in SP_MIN(BL32) +# Added separately from the above list for better readability +ifeq ($(filter 1,${BL2_AT_EL3} ${RESET_TO_SP_MIN}),) +BL32_SOURCES += common/fdt_wrappers.c \ + lib/fconf/fconf.c \ + plat/arm/board/fvp/fconf/fconf_hw_config_getter.c +endif + include plat/arm/common/sp_min/arm_sp_min.mk diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index cfac80182..b44639528 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -249,16 +249,12 @@ #endif /* - * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current - * SCP_BL2 size plus a little space for growth. + * SCP_BL2 uses up whatever remaining space is available as it is loaded before + * anything else in this memory region and is handed over to the SCP before + * BL31 is loaded over the top. */ -#define PLAT_CSS_MAX_SCP_BL2_SIZE UL(0x14000) - -/* - * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current - * SCP_BL2U size plus a little space for growth. - */ -#define PLAT_CSS_MAX_SCP_BL2U_SIZE UL(0x14000) +#define PLAT_CSS_MAX_SCP_BL2_SIZE (SCP_BL2_LIMIT - ARM_TB_FW_CONFIG_LIMIT) +#define PLAT_CSS_MAX_SCP_BL2U_SIZE PLAT_CSS_MAX_SCP_BL2_SIZE #define PLAT_ARM_G1S_IRQ_PROPS(grp) \ CSS_G1S_IRQ_PROPS(grp), \ diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk index 8816670dc..5856c9f4f 100644 --- a/plat/arm/board/n1sdp/platform.mk +++ b/plat/arm/board/n1sdp/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -18,6 +18,8 @@ N1SDP_CPU_SOURCES := lib/cpus/aarch64/neoverse_n1.S N1SDP_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/gic600_multichip.c \ plat/common/plat_gicv3.c \ plat/arm/common/arm_gicv3.c \ @@ -63,6 +65,9 @@ HW_ASSISTED_COHERENCY := 1 # When building for systems with hardware-assisted coherency, there's no need to # use USE_COHERENT_MEM. Require that USE_COHERENT_MEM must be set to 0 too. USE_COHERENT_MEM := 0 + +# Enable the flag since N1SDP has a system level cache +NEOVERSE_N1_EXTERNAL_LLC := 1 include plat/arm/common/arm_common.mk include plat/arm/css/common/css_common.mk include plat/arm/board/common/board_common.mk diff --git a/plat/arm/board/rddaniel/include/platform_def.h b/plat/arm/board/rddaniel/include/platform_def.h index 790ed696b..a118ca38a 100644 --- a/plat/arm/board/rddaniel/include/platform_def.h +++ b/plat/arm/board/rddaniel/include/platform_def.h @@ -32,9 +32,19 @@ (n * TZC400_OFFSET)) #define TZC_NSAID_ALL_AP U(0) +#define TZC_NSAID_PCI U(1) +#define TZC_NSAID_HDLCD0 U(2) +#define TZC_NSAID_CLCD U(7) +#define TZC_NSAID_AP U(9) +#define TZC_NSAID_VIRTIO U(15) #define PLAT_ARM_TZC_NS_DEV_ACCESS \ - (TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_ALL_AP)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_HDLCD0)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_PCI)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_AP)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_CLCD)) | \ + (TZC_REGION_ACCESS_RDWR(TZC_NSAID_VIRTIO)) /* * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes diff --git a/plat/arm/common/arm_bl2_setup.c b/plat/arm/common/arm_bl2_setup.c index 136e65a1f..d9fc84e8c 100644 --- a/plat/arm/common/arm_bl2_setup.c +++ b/plat/arm/common/arm_bl2_setup.c @@ -61,7 +61,7 @@ void arm_bl2_early_platform_setup(uintptr_t tb_fw_config, /* Fill the properties struct with the info from the config dtb */ if (tb_fw_config != 0U) { - fconf_populate(tb_fw_config); + fconf_populate("TB_FW", tb_fw_config); } /* Initialise the IO layer and register platform IO devices */ diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index d1eee08d1..60c777ed8 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -25,6 +25,9 @@ * conflicts with the definition in plat/common. */ #pragma weak plat_get_syscnt_freq2 +/* Get ARM SOC-ID */ +#pragma weak plat_arm_get_soc_id + /******************************************************************************* * Changes the memory attributes for the region of mapped memory where the BL * image's translation tables are located such that the tables will have @@ -231,3 +234,22 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode) return arm_validate_ns_entrypoint(pa); } #endif + +/* + * Weak function to get ARM platform SOC-ID, Always return SOC-ID=0 + * ToDo: Get proper SOC-ID for every ARM platform and define this + * function separately for every ARM platform. + */ +uint32_t plat_arm_get_soc_id(void) +{ + return 0U; +} + +/* Get SOC version */ +int32_t plat_get_soc_version(void) +{ + return (int32_t) + ((ARM_SOC_IDENTIFICATION_CODE << ARM_SOC_IDENTIFICATION_SHIFT) + | (ARM_SOC_CONTINUATION_CODE << ARM_SOC_CONTINUATION_SHIFT) + | plat_arm_get_soc_id()); +} diff --git a/plat/arm/common/fconf/arm_fconf_io.c b/plat/arm/common/fconf/arm_fconf_io.c index cfcddc2b2..017af79a5 100644 --- a/plat/arm/common/fconf/arm_fconf_io.c +++ b/plat/arm/common/fconf/arm_fconf_io.c @@ -138,6 +138,6 @@ int fconf_populate_arm_io_policies(uintptr_t config) return 0; } -FCONF_REGISTER_POPULATOR(arm_io, fconf_populate_arm_io_policies); +FCONF_REGISTER_POPULATOR(TB_FW, arm_io, fconf_populate_arm_io_policies); #endif /* IMAGE_BL2 */ diff --git a/plat/arm/common/fconf/arm_fconf_sp.c b/plat/arm/common/fconf/arm_fconf_sp.c index bb88aff6f..9b6fa9b1f 100644 --- a/plat/arm/common/fconf/arm_fconf_sp.c +++ b/plat/arm/common/fconf/arm_fconf_sp.c @@ -102,6 +102,6 @@ int fconf_populate_arm_sp(uintptr_t config) return 0; } -FCONF_REGISTER_POPULATOR(arm_sp, fconf_populate_arm_sp); +FCONF_REGISTER_POPULATOR(TB_FW, arm_sp, fconf_populate_arm_sp); #endif /* IMAGE_BL2 */ diff --git a/plat/arm/common/sp_min/arm_sp_min_setup.c b/plat/arm/common/sp_min/arm_sp_min_setup.c index cbbdfa21b..2904ad942 100644 --- a/plat/arm/common/sp_min/arm_sp_min_setup.c +++ b/plat/arm/common/sp_min/arm_sp_min_setup.c @@ -217,7 +217,7 @@ void sp_min_plat_runtime_setup(void) * Perform the very early platform specific architectural setup here. At the * moment this only initializes the MMU ******************************************************************************/ -void sp_min_plat_arch_setup(void) +void arm_sp_min_plat_arch_setup(void) { const mmap_region_t bl_regions[] = { MAP_BL_SP_MIN_TOTAL, @@ -232,3 +232,8 @@ void sp_min_plat_arch_setup(void) enable_mmu_svc_mon(0); } + +void sp_min_plat_arch_setup(void) +{ + arm_sp_min_plat_arch_setup(); +} diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk index 40a7fd8a3..ea5a56356 100644 --- a/plat/arm/css/sgi/sgi-common.mk +++ b/plat/arm/css/sgi/sgi-common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -25,6 +25,8 @@ PLAT_INCLUDES += -I${CSS_ENT_BASE}/include ENT_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ plat/common/plat_gicv3.c \ plat/arm/common/arm_gicv3.c \ drivers/arm/gic/v3/gic600.c diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h index 90511ac6a..0ac0c2b3c 100644 --- a/plat/arm/css/sgm/include/sgm_base_platform_def.h +++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h @@ -133,16 +133,12 @@ #endif /* - * PLAT_CSS_MAX_SCP_BL2_SIZE is calculated using the current - * SCP_BL2 size plus a little space for growth. + * SCP_BL2 uses up whatever remaining space is available as it is loaded before + * anything else in this memory region and is handed over to the SCP before + * BL31 is loaded over the top. */ -#define PLAT_CSS_MAX_SCP_BL2_SIZE 0x15000 - -/* - * PLAT_CSS_MAX_SCP_BL2U_SIZE is calculated using the current - * SCP_BL2U size plus a little space for growth. - */ -#define PLAT_CSS_MAX_SCP_BL2U_SIZE 0x15000 +#define PLAT_CSS_MAX_SCP_BL2_SIZE (SCP_BL2_LIMIT - ARM_TB_FW_CONFIG_LIMIT) +#define PLAT_CSS_MAX_SCP_BL2U_SIZE PLAT_CSS_MAX_SCP_BL2_SIZE /* * Most platform porting definitions provided by included headers diff --git a/plat/arm/css/sgm/sgm-common.mk b/plat/arm/css/sgm/sgm-common.mk index ac34450a7..49fc7176a 100644 --- a/plat/arm/css/sgm/sgm-common.mk +++ b/plat/arm/css/sgm/sgm-common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -25,6 +25,8 @@ INTERCONNECT_SOURCES := ${CSS_SGM_BASE}/sgm_interconnect.c SGM_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ plat/common/plat_gicv3.c \ plat/arm/common/arm_gicv3.c \ drivers/arm/gic/v3/gic600.c \ diff --git a/plat/common/aarch64/plat_common.c b/plat/common/aarch64/plat_common.c index f8d312952..63871d9e5 100644 --- a/plat/common/aarch64/plat_common.c +++ b/plat/common/aarch64/plat_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -64,6 +64,18 @@ int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode) } #endif +#if !ENABLE_BACKTRACE +static const char *get_el_str(unsigned int el) +{ + if (el == MODE_EL3) { + return "EL3"; + } else if (el == MODE_EL2) { + return "EL2"; + } + return "S-EL1"; +} +#endif /* !ENABLE_BACKTRACE */ + /* RAS functions common to AArch64 ARM platforms */ void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, void *handle, uint64_t flags) @@ -74,9 +86,17 @@ void plat_ea_handler(unsigned int ea_reason, uint64_t syndrome, void *cookie, if (handled != 0) return; #endif + unsigned int level = (unsigned int)GET_EL(read_spsr_el3()); - ERROR("Unhandled External Abort received on 0x%lx at EL3!\n", - read_mpidr_el1()); - ERROR(" exception reason=%u syndrome=0x%llx\n", ea_reason, syndrome); + ERROR("Unhandled External Abort received on 0x%lx from %s\n", + read_mpidr_el1(), get_el_str(level)); + ERROR("exception reason=%u syndrome=0x%llx\n", ea_reason, syndrome); +#if HANDLE_EA_EL3_FIRST + /* Skip backtrace for lower EL */ + if (level != MODE_EL3) { + (void)console_flush(); + do_panic(); + } +#endif panic(); } diff --git a/plat/common/plat_bl_common.c b/plat/common/plat_bl_common.c index de6c1d176..d38fc6f75 100644 --- a/plat/common/plat_bl_common.c +++ b/plat/common/plat_bl_common.c @@ -11,6 +11,7 @@ #include <common/debug.h> #include <lib/xlat_tables/xlat_tables_compat.h> #include <plat/common/platform.h> +#include <smccc_helpers.h> #include <tools_share/firmware_encrypted.h> /* @@ -24,6 +25,18 @@ #pragma weak bl2_plat_handle_post_image_load #pragma weak plat_try_next_boot_source #pragma weak plat_get_enc_key_info +#pragma weak plat_get_soc_version +#pragma weak plat_get_soc_revision + +int32_t plat_get_soc_version(void) +{ + return SMC_ARCH_CALL_NOT_SUPPORTED; +} + +int32_t plat_get_soc_revision(void) +{ + return SMC_ARCH_CALL_NOT_SUPPORTED; +} void bl2_el3_plat_prepare_exit(void) { diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c index 9c3dc7177..f0aa27cfb 100644 --- a/plat/common/plat_spmd_manifest.c +++ b/plat/common/plat_spmd_manifest.c @@ -37,6 +37,12 @@ static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr, return -ENOENT; } + rc = fdtw_read_cells(fdt, node, "spmc_id", 1, &attr->spmc_id); + if (rc) { + ERROR("Missing SPMC ID in manifest.\n"); + return -ENOENT; + } + rc = fdtw_read_cells(fdt, node, "exec_state", 1, &attr->exec_state); if (rc) NOTICE("Execution state not specified in SPM core manifest.\n"); @@ -55,6 +61,7 @@ static int manifest_parse_attribute(spmc_manifest_sect_attribute_t *attr, VERBOSE("SPM core manifest attribute section:\n"); VERBOSE(" version: %x.%x\n", attr->major_version, attr->minor_version); + VERBOSE(" spmc_id: %x\n", attr->spmc_id); VERBOSE(" binary_size: 0x%x\n", attr->binary_size); VERBOSE(" load_address: 0x%llx\n", attr->load_address); VERBOSE(" entrypoint: 0x%llx\n", attr->entrypoint); diff --git a/plat/imx/common/include/imx8_iomux.h b/plat/imx/common/include/imx8_iomux.h index 0e93d9800..264c295bb 100644 --- a/plat/imx/common/include/imx8_iomux.h +++ b/plat/imx/common/include/imx8_iomux.h @@ -7,19 +7,19 @@ #ifndef IMX8_IOMUX_H #define IMX8_IOMUX_H -#define PADRING_IFMUX_EN_SHIFT 31 -#define PADRING_IFMUX_EN_MASK (1 << PADRING_IFMUX_EN_SHIFT) -#define PADRING_GP_EN_SHIFT 30 -#define PADRING_GP_EN_MASK (1 << PADRING_GP_EN_SHIFT) -#define PADRING_IFMUX_SHIFT 27 -#define PADRING_IFMUX_MASK (0x7 << PADRING_IFMUX_SHIFT) -#define PADRING_CONFIG_SHIFT 25 -#define PADRING_CONFIG_MASK (0x3 << PADRING_CONFIG_SHIFT) -#define PADRING_LPCONFIG_SHIFT 23 -#define PADRING_LPCONFIG_MASK (0x3 << PADRING_LPCONFIG_SHIFT) -#define PADRING_PULL_SHIFT 5 -#define PADRING_PULL_MASK (0x3 << PADRING_PULL_SHIFT) -#define PADRING_DSE_SHIFT 0 -#define PADRING_DSE_MASK (0x7 << PADRING_DSE_SHIFT) +#define PADRING_IFMUX_EN_SHIFT U(31) +#define PADRING_IFMUX_EN_MASK (U(0x1) << PADRING_IFMUX_EN_SHIFT) +#define PADRING_GP_EN_SHIFT U(30) +#define PADRING_GP_EN_MASK (U(0x1) << PADRING_GP_EN_SHIFT) +#define PADRING_IFMUX_SHIFT U(27) +#define PADRING_IFMUX_MASK (U(0x7) << PADRING_IFMUX_SHIFT) +#define PADRING_CONFIG_SHIFT U(25) +#define PADRING_CONFIG_MASK (U(0x3) << PADRING_CONFIG_SHIFT) +#define PADRING_LPCONFIG_SHIFT U(23) +#define PADRING_LPCONFIG_MASK (U(0x3) << PADRING_LPCONFIG_SHIFT) +#define PADRING_PULL_SHIFT U(5) +#define PADRING_PULL_MASK (U(0x3) << PADRING_PULL_SHIFT) +#define PADRING_DSE_SHIFT U(0) +#define PADRING_DSE_MASK (U(0x7) << PADRING_DSE_SHIFT) #endif /* IMX8_IOMUX_H */ diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk index e28f73952..5fa300304 100644 --- a/plat/imx/imx8m/imx8mm/platform.mk +++ b/plat/imx/imx8m/imx8mm/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -9,6 +9,8 @@ PLAT_INCLUDES := -Iplat/imx/common/include \ -Iplat/imx/imx8m/imx8mm/include IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/arm_gicv3_common.c \ drivers/arm/gic/v3/gic500.c \ drivers/arm/gic/v3/gicv3_main.c \ diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk index 80ebe4062..e419f05c9 100644 --- a/plat/imx/imx8m/imx8mq/platform.mk +++ b/plat/imx/imx8m/imx8mq/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -9,6 +9,8 @@ PLAT_INCLUDES := -Iplat/imx/common/include \ -Iplat/imx/imx8m/imx8mq/include IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/arm_gicv3_common.c \ drivers/arm/gic/v3/gic500.c \ drivers/arm/gic/v3/gicv3_main.c \ diff --git a/plat/imx/imx8qm/imx8qm_bl31_setup.c b/plat/imx/imx8qm/imx8qm_bl31_setup.c index cffb140fb..4ca6a5db4 100644 --- a/plat/imx/imx8qm/imx8qm_bl31_setup.c +++ b/plat/imx/imx8qm/imx8qm_bl31_setup.c @@ -44,6 +44,22 @@ static entry_point_info_t bl33_image_ep_info; (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | \ (SC_PAD_28FDSOI_PS_PD << PADRING_PULL_SHIFT)) +#if defined(IMX_USE_UART0) +#define IMX_RES_UART SC_R_UART_0 +#define IMX_PAD_UART_RX SC_P_UART0_RX +#define IMX_PAD_UART_TX SC_P_UART0_TX +#define IMX_PAD_UART_RTS_B SC_P_UART0_RTS_B +#define IMX_PAD_UART_CTS_B SC_P_UART0_CTS_B +#elif defined(IMX_USE_UART1) +#define IMX_RES_UART SC_R_UART_1 +#define IMX_PAD_UART_RX SC_P_UART1_RX +#define IMX_PAD_UART_TX SC_P_UART1_TX +#define IMX_PAD_UART_RTS_B SC_P_UART1_RTS_B +#define IMX_PAD_UART_CTS_B SC_P_UART1_CTS_B +#else +#error "Provide proper UART number in IMX_DEBUG_UART" +#endif + const static int imx8qm_cci_map[] = { CLUSTER0_CCI_SLVAE_IFACE, CLUSTER1_CCI_SLVAE_IFACE @@ -79,7 +95,7 @@ static void lpuart32_serial_setbrg(unsigned int base, int baudrate) if (baudrate == 0) panic(); - sc_pm_get_clock_rate(ipc_handle, SC_R_UART_0, 2, &rate); + sc_pm_get_clock_rate(ipc_handle, IMX_RES_UART, 2, &rate); baud_diff = baudrate; osr = 0; @@ -301,16 +317,17 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, panic(); #if DEBUG_CONSOLE_A53 - sc_pm_set_resource_power_mode(ipc_handle, SC_R_UART_0, SC_PM_PW_MODE_ON); + sc_pm_set_resource_power_mode(ipc_handle, IMX_RES_UART, + SC_PM_PW_MODE_ON); sc_pm_clock_rate_t rate = 80000000; - sc_pm_set_clock_rate(ipc_handle, SC_R_UART_0, 2, &rate); - sc_pm_clock_enable(ipc_handle, SC_R_UART_0, 2, true, false); + sc_pm_set_clock_rate(ipc_handle, IMX_RES_UART, 2, &rate); + sc_pm_clock_enable(ipc_handle, IMX_RES_UART, 2, true, false); /* configure UART pads */ - sc_pad_set(ipc_handle, SC_P_UART0_RX, UART_PAD_CTRL); - sc_pad_set(ipc_handle, SC_P_UART0_TX, UART_PAD_CTRL); - sc_pad_set(ipc_handle, SC_P_UART0_RTS_B, UART_PAD_CTRL); - sc_pad_set(ipc_handle, SC_P_UART0_CTS_B, UART_PAD_CTRL); + sc_pad_set(ipc_handle, IMX_PAD_UART_RX, UART_PAD_CTRL); + sc_pad_set(ipc_handle, IMX_PAD_UART_TX, UART_PAD_CTRL); + sc_pad_set(ipc_handle, IMX_PAD_UART_RTS_B, UART_PAD_CTRL); + sc_pad_set(ipc_handle, IMX_PAD_UART_CTS_B, UART_PAD_CTRL); lpuart32_serial_init(IMX_BOOT_UART_BASE); #endif diff --git a/plat/imx/imx8qm/include/platform_def.h b/plat/imx/imx8qm/include/platform_def.h index b54943da0..671c77f76 100644 --- a/plat/imx/imx8qm/include/platform_def.h +++ b/plat/imx/imx8qm/include/platform_def.h @@ -40,12 +40,22 @@ #define PLAT_CCI_BASE 0x52090000 #define CLUSTER0_CCI_SLVAE_IFACE 3 #define CLUSTER1_CCI_SLVAE_IFACE 4 + +/* UART */ +#if defined(IMX_USE_UART0) #define IMX_BOOT_UART_BASE 0x5a060000 +#elif defined(IMX_USE_UART1) +#define IMX_BOOT_UART_BASE 0x5a070000 +#else +#error "Provide proper UART number in IMX_DEBUG_UART" +#endif + #define IMX_BOOT_UART_BAUDRATE 115200 #define IMX_BOOT_UART_CLK_IN_HZ 24000000 #define PLAT_CRASH_UART_BASE IMX_BOOT_UART_BASE #define PLAT__CRASH_UART_CLK_IN_HZ 24000000 #define IMX_CONSOLE_BAUDRATE 115200 + #define SC_IPC_BASE 0x5d1b0000 #define IMX_GPT_LPCG_BASE 0x5d540000 #define IMX_GPT_BASE 0x5d140000 @@ -64,7 +74,6 @@ #define MAX_XLAT_TABLES 8 #define MAX_MMAP_REGIONS 12 -#define DEBUG_CONSOLE 0 -#define DEBUG_CONSOLE_A53 0 +#define DEBUG_CONSOLE_A53 DEBUG_CONSOLE #endif /* PLATFORM_DEF_H */ diff --git a/plat/imx/imx8qm/platform.mk b/plat/imx/imx8qm/platform.mk index 3a772e51a..20ee05be9 100644 --- a/plat/imx/imx8qm/platform.mk +++ b/plat/imx/imx8qm/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -8,6 +8,8 @@ PLAT_INCLUDES := -Iplat/imx/imx8qm/include \ -Iplat/imx/common/include \ IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/arm_gicv3_common.c \ drivers/arm/gic/v3/gic500.c \ drivers/arm/gic/v3/gicv3_main.c \ @@ -41,3 +43,9 @@ ERRATA_A72_859971 := 1 ERRATA_A53_835769 := 1 ERRATA_A53_843419 := 1 ERRATA_A53_855873 := 1 + +IMX_DEBUG_UART ?= 0 +$(eval $(call add_define,IMX_USE_UART${IMX_DEBUG_UART})) + +DEBUG_CONSOLE ?= 0 +$(eval $(call add_define,DEBUG_CONSOLE)) diff --git a/plat/imx/imx8qx/platform.mk b/plat/imx/imx8qx/platform.mk index d5629d124..5e8ba063c 100644 --- a/plat/imx/imx8qx/platform.mk +++ b/plat/imx/imx8qx/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -8,6 +8,8 @@ PLAT_INCLUDES := -Iplat/imx/imx8qx/include \ -Iplat/imx/common/include \ IMX_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/arm_gicv3_common.c \ drivers/arm/gic/v3/gic500.c \ drivers/arm/gic/v3/gicv3_main.c \ diff --git a/plat/marvell/a3700/common/a3700_common.mk b/plat/marvell/a3700/common/a3700_common.mk index 1e2756734..fd2b7ed79 100644 --- a/plat/marvell/a3700/common/a3700_common.mk +++ b/plat/marvell/a3700/common/a3700_common.mk @@ -81,6 +81,8 @@ $(eval $(call add_define,USE_CCI)) MARVELL_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/arm_gicv3_common.c \ plat/common/plat_gicv3.c \ drivers/arm/gic/v3/gic500.c diff --git a/plat/mediatek/mt8183/platform.mk b/plat/mediatek/mt8183/platform.mk index 597e18b90..59ffe5dc0 100644 --- a/plat/mediatek/mt8183/platform.mk +++ b/plat/mediatek/mt8183/platform.mk @@ -31,6 +31,8 @@ BL31_SOURCES += common/desc_image_load.c \ drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/arm_gicv3_common.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/gic500.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/delay_timer/delay_timer.c \ diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S index 7cba3a449..5f01416d8 100644 --- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S +++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S @@ -39,6 +39,7 @@ .globl plat_crash_console_init .globl plat_crash_console_putc .globl plat_crash_console_flush + .weak plat_core_pos_by_mpidr .globl tegra_secure_entrypoint .globl plat_reset_handler @@ -140,17 +141,14 @@ endfunc plat_is_my_cpu_primary * unsigned int plat_my_core_pos(void); * * result: CorePos = CoreId + (ClusterId * cpus per cluster) + * Registers clobbered: x0, x8 * ---------------------------------------------------------- */ func plat_my_core_pos + mov x8, x30 mrs x0, mpidr_el1 - and x1, x0, #MPIDR_CPU_MASK - and x0, x0, #MPIDR_CLUSTER_MASK - lsr x0, x0, #MPIDR_AFFINITY_BITS - mov x2, #PLATFORM_MAX_CPUS_PER_CLUSTER - mul x0, x0, x2 - add x0, x1, x0 - ret + bl plat_core_pos_by_mpidr + ret x8 endfunc plat_my_core_pos /* ----------------------------------------------------- @@ -273,6 +271,42 @@ _end: mov x0, x20 ret endfunc plat_reset_handler + /* ------------------------------------------------------ + * int32_t plat_core_pos_by_mpidr(u_register_t mpidr) + * + * This function implements a part of the critical + * interface between the psci generic layer and the + * platform that allows the former to query the platform + * to convert an MPIDR to a unique linear index. An error + * code (-1) is returned in case the MPIDR is invalid. + * + * Clobbers: x0-x3 + * ------------------------------------------------------ + */ +func plat_core_pos_by_mpidr + lsr x1, x0, #MPIDR_AFF0_SHIFT + and x1, x1, #MPIDR_AFFLVL_MASK /* core id */ + lsr x2, x0, #MPIDR_AFF1_SHIFT + and x2, x2, #MPIDR_AFFLVL_MASK /* cluster id */ + + /* core_id >= PLATFORM_MAX_CPUS_PER_CLUSTER */ + mov x0, #-1 + cmp x1, #(PLATFORM_MAX_CPUS_PER_CLUSTER - 1) + b.gt 1f + + /* cluster_id >= PLATFORM_CLUSTER_COUNT */ + cmp x2, #(PLATFORM_CLUSTER_COUNT - 1) + b.gt 1f + + /* CorePos = CoreId + (ClusterId * cpus per cluster) */ + mov x3, #PLATFORM_MAX_CPUS_PER_CLUSTER + mul x3, x3, x2 + add x0, x1, x3 + +1: + ret +endfunc plat_core_pos_by_mpidr + /* ---------------------------------------- * Secure entrypoint function for CPU boot * ---------------------------------------- diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index c2ef981ee..a53f66078 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -21,6 +21,7 @@ #include <smmu.h> #include <tegra_def.h> #include <tegra_platform.h> +#include <tegra_private.h> /* Video Memory base and size (live values) */ static uint64_t video_mem_base; @@ -223,6 +224,58 @@ void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes) mce_update_gsc_tzram(); } +/* + * Save MC settings before "System Suspend" to TZDRAM + */ +void tegra_mc_save_context(uint64_t mc_ctx_addr) +{ + const tegra_mc_settings_t *plat_mc_settings = tegra_get_mc_settings(); + uint32_t i, num_entries = 0; + mc_regs_t *mc_ctx_regs; + const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); + uint64_t tzdram_base = params_from_bl2->tzdram_base; + uint64_t tzdram_end = tzdram_base + params_from_bl2->tzdram_size; + + assert((mc_ctx_addr >= tzdram_base) && (mc_ctx_addr <= tzdram_end)); + + /* get MC context table */ + mc_ctx_regs = plat_mc_settings->get_mc_system_suspend_ctx(); + assert(mc_ctx_regs != NULL); + + /* + * mc_ctx_regs[0].val contains the size of the context table minus + * the last entry. Sanity check the table size before we start with + * the context save operation. + */ + while (mc_ctx_regs[num_entries].reg != 0xFFFFFFFFU) { + num_entries++; + } + + /* panic if the sizes do not match */ + if (num_entries != mc_ctx_regs[0].val) { + ERROR("MC context size mismatch!"); + panic(); + } + + /* save MC register values */ + for (i = 1U; i < num_entries; i++) { + mc_ctx_regs[i].val = mmio_read_32(mc_ctx_regs[i].reg); + } + + /* increment by 1 to take care of the last entry */ + num_entries++; + + /* Save MC config settings */ + (void)memcpy((void *)mc_ctx_addr, mc_ctx_regs, + sizeof(mc_regs_t) * num_entries); + + /* save the MC table address */ + mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_LO, + (uint32_t)mc_ctx_addr); + mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_MC_TABLE_ADDR_HI, + (uint32_t)(mc_ctx_addr >> 32)); +} + static void tegra_lock_videomem_nonoverlap(uint64_t phys_base, uint64_t size_in_bytes) { diff --git a/plat/nvidia/tegra/common/drivers/smmu/smmu.c b/plat/nvidia/tegra/common/drivers/smmu/smmu.c index 8c1b899f7..a4a4354e8 100644 --- a/plat/nvidia/tegra/common/drivers/smmu/smmu.c +++ b/plat/nvidia/tegra/common/drivers/smmu/smmu.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,121 +18,8 @@ extern void memcpy16(void *dest, const void *src, unsigned int length); -/* SMMU IDs currently supported by the driver */ -enum { - TEGRA_SMMU0 = 0U, - TEGRA_SMMU1, - TEGRA_SMMU2 -}; - -static uint32_t tegra_smmu_read_32(uint32_t smmu_id, uint32_t off) -{ - uint32_t ret = 0U; - -#if defined(TEGRA_SMMU0_BASE) - if (smmu_id == TEGRA_SMMU0) { - ret = mmio_read_32(TEGRA_SMMU0_BASE + (uint64_t)off); - } -#endif - -#if defined(TEGRA_SMMU1_BASE) - if (smmu_id == TEGRA_SMMU1) { - ret = mmio_read_32(TEGRA_SMMU1_BASE + (uint64_t)off); - } -#endif - -#if defined(TEGRA_SMMU2_BASE) - if (smmu_id == TEGRA_SMMU2) { - ret = mmio_read_32(TEGRA_SMMU2_BASE + (uint64_t)off); - } -#endif - - return ret; -} - -static void tegra_smmu_write_32(uint32_t smmu_id, - uint32_t off, uint32_t val) -{ -#if defined(TEGRA_SMMU0_BASE) - if (smmu_id == TEGRA_SMMU0) { - mmio_write_32(TEGRA_SMMU0_BASE + (uint64_t)off, val); - } -#endif - -#if defined(TEGRA_SMMU1_BASE) - if (smmu_id == TEGRA_SMMU1) { - mmio_write_32(TEGRA_SMMU1_BASE + (uint64_t)off, val); - } -#endif - -#if defined(TEGRA_SMMU2_BASE) - if (smmu_id == TEGRA_SMMU2) { - mmio_write_32(TEGRA_SMMU2_BASE + (uint64_t)off, val); - } -#endif -} - -/* - * Save SMMU settings before "System Suspend" to TZDRAM - */ -void tegra_smmu_save_context(uint64_t smmu_ctx_addr) -{ - uint32_t i, num_entries = 0; - smmu_regs_t *smmu_ctx_regs; - const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); - uint64_t tzdram_base = params_from_bl2->tzdram_base; - uint64_t tzdram_end = tzdram_base + params_from_bl2->tzdram_size; - uint32_t reg_id1, pgshift, cb_size; - - /* sanity check SMMU settings c*/ - reg_id1 = mmio_read_32((TEGRA_SMMU0_BASE + SMMU_GNSR0_IDR1)); - pgshift = ((reg_id1 & ID1_PAGESIZE) != 0U) ? 16U : 12U; - cb_size = ((uint32_t)2 << pgshift) * \ - ((uint32_t)1 << (((reg_id1 >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1U)); - - assert(!((pgshift != PGSHIFT) || (cb_size != CB_SIZE))); - assert((smmu_ctx_addr >= tzdram_base) && (smmu_ctx_addr <= tzdram_end)); - - /* get SMMU context table */ - smmu_ctx_regs = plat_get_smmu_ctx(); - assert(smmu_ctx_regs != NULL); - - /* - * smmu_ctx_regs[0].val contains the size of the context table minus - * the last entry. Sanity check the table size before we start with - * the context save operation. - */ - while ((smmu_ctx_regs[num_entries].reg != 0xFFFFFFFFU)) { - num_entries++; - } - - /* panic if the sizes do not match */ - if (num_entries != smmu_ctx_regs[0].val) { - ERROR("SMMU context size mismatch!"); - panic(); - } - - /* save SMMU register values */ - for (i = 1U; i < num_entries; i++) { - smmu_ctx_regs[i].val = mmio_read_32(smmu_ctx_regs[i].reg); - } - - /* increment by 1 to take care of the last entry */ - num_entries++; - - /* Save SMMU config settings */ - (void)memcpy16((uint8_t *)smmu_ctx_addr, (uint8_t *)smmu_ctx_regs, - (sizeof(smmu_regs_t) * num_entries)); - - /* save the SMMU table address */ - mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SMMU_TABLE_ADDR_LO, - (uint32_t)smmu_ctx_addr); - mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SMMU_TABLE_ADDR_HI, - (uint32_t)(smmu_ctx_addr >> 32)); -} - -#define SMMU_NUM_CONTEXTS 64 -#define SMMU_CONTEXT_BANK_MAX_IDX 64 +#define SMMU_NUM_CONTEXTS 64U +#define SMMU_CONTEXT_BANK_MAX_IDX 64U /* * Init SMMU during boot or "System Suspend" exit diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk index 50c9592f1..66d037fdf 100644 --- a/plat/nvidia/tegra/common/tegra_common.mk +++ b/plat/nvidia/tegra/common/tegra_common.mk @@ -32,5 +32,4 @@ BL31_SOURCES += drivers/delay_timer/delay_timer.c \ ${COMMON_DIR}/tegra_io_storage.c \ ${COMMON_DIR}/tegra_platform.c \ ${COMMON_DIR}/tegra_pm.c \ - ${COMMON_DIR}/tegra_sip_calls.c \ - ${COMMON_DIR}/tegra_topology.c + ${COMMON_DIR}/tegra_sip_calls.c diff --git a/plat/nvidia/tegra/common/tegra_topology.c b/plat/nvidia/tegra/common/tegra_topology.c deleted file mode 100644 index 205b05165..000000000 --- a/plat/nvidia/tegra/common/tegra_topology.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <platform_def.h> - -#include <arch.h> -#include <lib/psci/psci.h> -#include <plat/common/platform.h> - -#pragma weak plat_core_pos_by_mpidr - -/******************************************************************************* - * This function implements a part of the critical interface between the psci - * generic layer and the platform that allows the former to query the platform - * to convert an MPIDR to a unique linear index. An error code (-1) is returned - * in case the MPIDR is invalid. - ******************************************************************************/ -int32_t plat_core_pos_by_mpidr(u_register_t mpidr) -{ - u_register_t cluster_id, cpu_id; - int32_t result; - - cluster_id = (mpidr >> (u_register_t)MPIDR_AFF1_SHIFT) & - (u_register_t)MPIDR_AFFLVL_MASK; - cpu_id = (mpidr >> (u_register_t)MPIDR_AFF0_SHIFT) & - (u_register_t)MPIDR_AFFLVL_MASK; - - /* CorePos = CoreId + (ClusterId * cpus per cluster) */ - result = (int32_t)cpu_id + ((int32_t)cluster_id * - PLATFORM_MAX_CPUS_PER_CLUSTER); - - if (cluster_id >= (u_register_t)PLATFORM_CLUSTER_COUNT) { - result = PSCI_E_NOT_PRESENT; - } - - /* - * Validate cpu_id by checking whether it represents a CPU in - * one of the two clusters present on the platform. - */ - if (cpu_id >= (u_register_t)PLATFORM_MAX_CPUS_PER_CLUSTER) { - result = PSCI_E_NOT_PRESENT; - } - - return result; -} diff --git a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h index a0d02c949..401a07a24 100644 --- a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h +++ b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h @@ -19,11 +19,6 @@ #define TEGRA_RESET_ID_GPCDMA U(70) /** - * Clock identifier for the SE device - */ -#define TEGRA_CLK_SE U(124) - -/** * Function to initialise the IPC with the bpmp */ int32_t tegra_bpmp_ipc_init(void); diff --git a/plat/nvidia/tegra/include/drivers/memctrl_v2.h b/plat/nvidia/tegra/include/drivers/memctrl_v2.h index a4085e247..509fe32bb 100644 --- a/plat/nvidia/tegra/include/drivers/memctrl_v2.h +++ b/plat/nvidia/tegra/include/drivers/memctrl_v2.h @@ -84,6 +84,41 @@ typedef struct mc_streamid_security_cfg { .override_enable = OVERRIDE_ ## access \ } +typedef struct mc_regs { + uint32_t reg; + uint32_t val; +} mc_regs_t; + +#define mc_make_sid_override_cfg(name) \ + { \ + .reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_CFG_ ## name, \ + .val = 0x00000000U, \ + } + +#define mc_make_sid_security_cfg(name) \ + { \ + .reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(MC_STREAMID_OVERRIDE_CFG_ ## name), \ + .val = 0x00000000U, \ + } + +#define mc_smmu_bypass_cfg \ + { \ + .reg = TEGRA_MC_BASE + MC_SMMU_BYPASS_CONFIG, \ + .val = 0x00000000U, \ + } + +#define _START_OF_TABLE_ \ + { \ + .reg = 0xCAFE05C7U, \ + .val = 0x00000000U, \ + } + +#define _END_OF_TABLE_ \ + { \ + .reg = 0xFFFFFFFFU, \ + .val = 0xFFFFFFFFU, \ + } + /******************************************************************************* * Structure to hold Memory Controller's Configuration settings ******************************************************************************/ @@ -96,6 +131,7 @@ typedef struct tegra_mc_settings { uint32_t num_txn_override_cfgs; void (*reconfig_mss_clients)(void); void (*set_txn_overrides)(void); + mc_regs_t* (*get_mc_system_suspend_ctx)(void); } tegra_mc_settings_t; static inline uint32_t tegra_mc_read_32(uint32_t off) @@ -166,6 +202,13 @@ static inline void tegra_mc_streamid_write_32(uint32_t off, uint32_t val) tegra_mc_settings_t *tegra_get_mc_settings(void); /******************************************************************************* + * Handler to save MC settings before "System Suspend" to TZDRAM + * + * Implemented by Tegra common memctrl_v2 driver under common/drivers/memctrl + ******************************************************************************/ +void tegra_mc_save_context(uint64_t mc_ctx_addr); + +/******************************************************************************* * Handler to program the scratch registers with TZDRAM settings for the * resume firmware. * diff --git a/plat/nvidia/tegra/include/drivers/smmu.h b/plat/nvidia/tegra/include/drivers/smmu.h index 424a91aea..601864fb5 100644 --- a/plat/nvidia/tegra/include/drivers/smmu.h +++ b/plat/nvidia/tegra/include/drivers/smmu.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,566 +13,7 @@ #include <memctrl_v2.h> #include <tegra_def.h> -/******************************************************************************* - * SMMU Register constants - ******************************************************************************/ -#define SMMU_CBn_SCTLR (0x0U) -#define SMMU_CBn_SCTLR_STAGE2 (0x0U) #define SMMU_CBn_ACTLR (0x4U) -#define SMMU_CBn_RESUME (0x8U) -#define SMMU_CBn_TCR2 (0x10U) -#define SMMU_CBn_TTBR0_LO (0x20U) -#define SMMU_CBn_TTBR0_HI (0x24U) -#define SMMU_CBn_TTBR1_LO (0x28U) -#define SMMU_CBn_TTBR1_HI (0x2cU) -#define SMMU_CBn_TCR_LPAE (0x30U) -#define SMMU_CBn_TCR (0x30U) -#define SMMU_CBn_TCR_EAE_1 (0x30U) -#define SMMU_CBn_TCR (0x30U) -#define SMMU_CBn_CONTEXTIDR (0x34U) -#define SMMU_CBn_CONTEXTIDR_EAE_1 (0x34U) -#define SMMU_CBn_PRRR_MAIR0 (0x38U) -#define SMMU_CBn_NMRR_MAIR1 (0x3cU) -#define SMMU_CBn_SMMU_CBn_PAR (0x50U) -#define SMMU_CBn_SMMU_CBn_PAR0 (0x50U) -#define SMMU_CBn_SMMU_CBn_PAR1 (0x54U) -/* SMMU_CBn_SMMU_CBn_PAR0_Fault (0x50U) */ -/* SMMU_CBn_SMMU_CBn_PAR0_Fault (0x54U) */ -#define SMMU_CBn_FSR (0x58U) -#define SMMU_CBn_FSRRESTORE (0x5cU) -#define SMMU_CBn_FAR_LO (0x60U) -#define SMMU_CBn_FAR_HI (0x64U) -#define SMMU_CBn_FSYNR0 (0x68U) -#define SMMU_CBn_IPAFAR_LO (0x70U) -#define SMMU_CBn_IPAFAR_HI (0x74U) -#define SMMU_CBn_TLBIVA_LO (0x600U) -#define SMMU_CBn_TLBIVA_HI (0x604U) -#define SMMU_CBn_TLBIVA_AARCH_32 (0x600U) -#define SMMU_CBn_TLBIVAA_LO (0x608U) -#define SMMU_CBn_TLBIVAA_HI (0x60cU) -#define SMMU_CBn_TLBIVAA_AARCH_32 (0x608U) -#define SMMU_CBn_TLBIASID (0x610U) -#define SMMU_CBn_TLBIALL (0x618U) -#define SMMU_CBn_TLBIVAL_LO (0x620U) -#define SMMU_CBn_TLBIVAL_HI (0x624U) -#define SMMU_CBn_TLBIVAL_AARCH_32 (0x618U) -#define SMMU_CBn_TLBIVAAL_LO (0x628U) -#define SMMU_CBn_TLBIVAAL_HI (0x62cU) -#define SMMU_CBn_TLBIVAAL_AARCH_32 (0x628U) -#define SMMU_CBn_TLBIIPAS2_LO (0x630U) -#define SMMU_CBn_TLBIIPAS2_HI (0x634U) -#define SMMU_CBn_TLBIIPAS2L_LO (0x638U) -#define SMMU_CBn_TLBIIPAS2L_HI (0x63cU) -#define SMMU_CBn_TLBSYNC (0x7f0U) -#define SMMU_CBn_TLBSTATUS (0x7f4U) -#define SMMU_CBn_ATSR (0x800U) -#define SMMU_CBn_PMEVCNTR0 (0xe00U) -#define SMMU_CBn_PMEVCNTR1 (0xe04U) -#define SMMU_CBn_PMEVCNTR2 (0xe08U) -#define SMMU_CBn_PMEVCNTR3 (0xe0cU) -#define SMMU_CBn_PMEVTYPER0 (0xe80U) -#define SMMU_CBn_PMEVTYPER1 (0xe84U) -#define SMMU_CBn_PMEVTYPER2 (0xe88U) -#define SMMU_CBn_PMEVTYPER3 (0xe8cU) -#define SMMU_CBn_PMCFGR (0xf00U) -#define SMMU_CBn_PMCR (0xf04U) -#define SMMU_CBn_PMCEID (0xf20U) -#define SMMU_CBn_PMCNTENSE (0xf40U) -#define SMMU_CBn_PMCNTENCLR (0xf44U) -#define SMMU_CBn_PMCNTENSET (0xf48U) -#define SMMU_CBn_PMINTENCLR (0xf4cU) -#define SMMU_CBn_PMOVSCLR (0xf50U) -#define SMMU_CBn_PMOVSSET (0xf58U) -#define SMMU_CBn_PMAUTHSTATUS (0xfb8U) -#define SMMU_GNSR0_CR0 (0x0U) -#define SMMU_GNSR0_CR2 (0x8U) -#define SMMU_GNSR0_ACR (0x10U) -#define SMMU_GNSR0_IDR0 (0x20U) -#define SMMU_GNSR0_IDR1 (0x24U) -#define SMMU_GNSR0_IDR2 (0x28U) -#define SMMU_GNSR0_IDR7 (0x3cU) -#define SMMU_GNSR0_GFAR_LO (0x40U) -#define SMMU_GNSR0_GFAR_HI (0x44U) -#define SMMU_GNSR0_GFSR (0x48U) -#define SMMU_GNSR0_GFSRRESTORE (0x4cU) -#define SMMU_GNSR0_GFSYNR0 (0x50U) -#define SMMU_GNSR0_GFSYNR1 (0x54U) -#define SMMU_GNSR0_GFSYNR1_v2 (0x54U) -#define SMMU_GNSR0_TLBIVMID (0x64U) -#define SMMU_GNSR0_TLBIALLNSNH (0x68U) -#define SMMU_GNSR0_TLBIALLH (0x6cU) -#define SMMU_GNSR0_TLBGSYNC (0x70U) -#define SMMU_GNSR0_TLBGSTATUS (0x74U) -#define SMMU_GNSR0_TLBIVAH_LO (0x78U) -#define SMMU_GNSR0_TLBIVALH64_LO (0xb0U) -#define SMMU_GNSR0_TLBIVALH64_HI (0xb4U) -#define SMMU_GNSR0_TLBIVMIDS1 (0xb8U) -#define SMMU_GNSR0_TLBIVAH64_LO (0xc0U) -#define SMMU_GNSR0_TLBIVAH64_HI (0xc4U) -#define SMMU_GNSR0_SMR0 (0x800U) -#define SMMU_GNSR0_SMRn (0x800U) -#define SMMU_GNSR0_SMR1 (0x804U) -#define SMMU_GNSR0_SMR2 (0x808U) -#define SMMU_GNSR0_SMR3 (0x80cU) -#define SMMU_GNSR0_SMR4 (0x810U) -#define SMMU_GNSR0_SMR5 (0x814U) -#define SMMU_GNSR0_SMR6 (0x818U) -#define SMMU_GNSR0_SMR7 (0x81cU) -#define SMMU_GNSR0_SMR8 (0x820U) -#define SMMU_GNSR0_SMR9 (0x824U) -#define SMMU_GNSR0_SMR10 (0x828U) -#define SMMU_GNSR0_SMR11 (0x82cU) -#define SMMU_GNSR0_SMR12 (0x830U) -#define SMMU_GNSR0_SMR13 (0x834U) -#define SMMU_GNSR0_SMR14 (0x838U) -#define SMMU_GNSR0_SMR15 (0x83cU) -#define SMMU_GNSR0_SMR16 (0x840U) -#define SMMU_GNSR0_SMR17 (0x844U) -#define SMMU_GNSR0_SMR18 (0x848U) -#define SMMU_GNSR0_SMR19 (0x84cU) -#define SMMU_GNSR0_SMR20 (0x850U) -#define SMMU_GNSR0_SMR21 (0x854U) -#define SMMU_GNSR0_SMR22 (0x858U) -#define SMMU_GNSR0_SMR23 (0x85cU) -#define SMMU_GNSR0_SMR24 (0x860U) -#define SMMU_GNSR0_SMR25 (0x864U) -#define SMMU_GNSR0_SMR26 (0x868U) -#define SMMU_GNSR0_SMR27 (0x86cU) -#define SMMU_GNSR0_SMR28 (0x870U) -#define SMMU_GNSR0_SMR29 (0x874U) -#define SMMU_GNSR0_SMR30 (0x878U) -#define SMMU_GNSR0_SMR31 (0x87cU) -#define SMMU_GNSR0_SMR32 (0x880U) -#define SMMU_GNSR0_SMR33 (0x884U) -#define SMMU_GNSR0_SMR34 (0x888U) -#define SMMU_GNSR0_SMR35 (0x88cU) -#define SMMU_GNSR0_SMR36 (0x890U) -#define SMMU_GNSR0_SMR37 (0x894U) -#define SMMU_GNSR0_SMR38 (0x898U) -#define SMMU_GNSR0_SMR39 (0x89cU) -#define SMMU_GNSR0_SMR40 (0x8a0U) -#define SMMU_GNSR0_SMR41 (0x8a4U) -#define SMMU_GNSR0_SMR42 (0x8a8U) -#define SMMU_GNSR0_SMR43 (0x8acU) -#define SMMU_GNSR0_SMR44 (0x8b0U) -#define SMMU_GNSR0_SMR45 (0x8b4U) -#define SMMU_GNSR0_SMR46 (0x8b8U) -#define SMMU_GNSR0_SMR47 (0x8bcU) -#define SMMU_GNSR0_SMR48 (0x8c0U) -#define SMMU_GNSR0_SMR49 (0x8c4U) -#define SMMU_GNSR0_SMR50 (0x8c8U) -#define SMMU_GNSR0_SMR51 (0x8ccU) -#define SMMU_GNSR0_SMR52 (0x8d0U) -#define SMMU_GNSR0_SMR53 (0x8d4U) -#define SMMU_GNSR0_SMR54 (0x8d8U) -#define SMMU_GNSR0_SMR55 (0x8dcU) -#define SMMU_GNSR0_SMR56 (0x8e0U) -#define SMMU_GNSR0_SMR57 (0x8e4U) -#define SMMU_GNSR0_SMR58 (0x8e8U) -#define SMMU_GNSR0_SMR59 (0x8ecU) -#define SMMU_GNSR0_SMR60 (0x8f0U) -#define SMMU_GNSR0_SMR61 (0x8f4U) -#define SMMU_GNSR0_SMR62 (0x8f8U) -#define SMMU_GNSR0_SMR63 (0x8fcU) -#define SMMU_GNSR0_SMR64 (0x900U) -#define SMMU_GNSR0_SMR65 (0x904U) -#define SMMU_GNSR0_SMR66 (0x908U) -#define SMMU_GNSR0_SMR67 (0x90cU) -#define SMMU_GNSR0_SMR68 (0x910U) -#define SMMU_GNSR0_SMR69 (0x914U) -#define SMMU_GNSR0_SMR70 (0x918U) -#define SMMU_GNSR0_SMR71 (0x91cU) -#define SMMU_GNSR0_SMR72 (0x920U) -#define SMMU_GNSR0_SMR73 (0x924U) -#define SMMU_GNSR0_SMR74 (0x928U) -#define SMMU_GNSR0_SMR75 (0x92cU) -#define SMMU_GNSR0_SMR76 (0x930U) -#define SMMU_GNSR0_SMR77 (0x934U) -#define SMMU_GNSR0_SMR78 (0x938U) -#define SMMU_GNSR0_SMR79 (0x93cU) -#define SMMU_GNSR0_SMR80 (0x940U) -#define SMMU_GNSR0_SMR81 (0x944U) -#define SMMU_GNSR0_SMR82 (0x948U) -#define SMMU_GNSR0_SMR83 (0x94cU) -#define SMMU_GNSR0_SMR84 (0x950U) -#define SMMU_GNSR0_SMR85 (0x954U) -#define SMMU_GNSR0_SMR86 (0x958U) -#define SMMU_GNSR0_SMR87 (0x95cU) -#define SMMU_GNSR0_SMR88 (0x960U) -#define SMMU_GNSR0_SMR89 (0x964U) -#define SMMU_GNSR0_SMR90 (0x968U) -#define SMMU_GNSR0_SMR91 (0x96cU) -#define SMMU_GNSR0_SMR92 (0x970U) -#define SMMU_GNSR0_SMR93 (0x974U) -#define SMMU_GNSR0_SMR94 (0x978U) -#define SMMU_GNSR0_SMR95 (0x97cU) -#define SMMU_GNSR0_SMR96 (0x980U) -#define SMMU_GNSR0_SMR97 (0x984U) -#define SMMU_GNSR0_SMR98 (0x988U) -#define SMMU_GNSR0_SMR99 (0x98cU) -#define SMMU_GNSR0_SMR100 (0x990U) -#define SMMU_GNSR0_SMR101 (0x994U) -#define SMMU_GNSR0_SMR102 (0x998U) -#define SMMU_GNSR0_SMR103 (0x99cU) -#define SMMU_GNSR0_SMR104 (0x9a0U) -#define SMMU_GNSR0_SMR105 (0x9a4U) -#define SMMU_GNSR0_SMR106 (0x9a8U) -#define SMMU_GNSR0_SMR107 (0x9acU) -#define SMMU_GNSR0_SMR108 (0x9b0U) -#define SMMU_GNSR0_SMR109 (0x9b4U) -#define SMMU_GNSR0_SMR110 (0x9b8U) -#define SMMU_GNSR0_SMR111 (0x9bcU) -#define SMMU_GNSR0_SMR112 (0x9c0U) -#define SMMU_GNSR0_SMR113 (0x9c4U) -#define SMMU_GNSR0_SMR114 (0x9c8U) -#define SMMU_GNSR0_SMR115 (0x9ccU) -#define SMMU_GNSR0_SMR116 (0x9d0U) -#define SMMU_GNSR0_SMR117 (0x9d4U) -#define SMMU_GNSR0_SMR118 (0x9d8U) -#define SMMU_GNSR0_SMR119 (0x9dcU) -#define SMMU_GNSR0_SMR120 (0x9e0U) -#define SMMU_GNSR0_SMR121 (0x9e4U) -#define SMMU_GNSR0_SMR122 (0x9e8U) -#define SMMU_GNSR0_SMR123 (0x9ecU) -#define SMMU_GNSR0_SMR124 (0x9f0U) -#define SMMU_GNSR0_SMR125 (0x9f4U) -#define SMMU_GNSR0_SMR126 (0x9f8U) -#define SMMU_GNSR0_SMR127 (0x9fcU) -#define SMMU_GNSR0_S2CR0 (0xc00U) -#define SMMU_GNSR0_S2CRn (0xc00U) -#define SMMU_GNSR0_S2CRn (0xc00U) -#define SMMU_GNSR0_S2CR1 (0xc04U) -#define SMMU_GNSR0_S2CR2 (0xc08U) -#define SMMU_GNSR0_S2CR3 (0xc0cU) -#define SMMU_GNSR0_S2CR4 (0xc10U) -#define SMMU_GNSR0_S2CR5 (0xc14U) -#define SMMU_GNSR0_S2CR6 (0xc18U) -#define SMMU_GNSR0_S2CR7 (0xc1cU) -#define SMMU_GNSR0_S2CR8 (0xc20U) -#define SMMU_GNSR0_S2CR9 (0xc24U) -#define SMMU_GNSR0_S2CR10 (0xc28U) -#define SMMU_GNSR0_S2CR11 (0xc2cU) -#define SMMU_GNSR0_S2CR12 (0xc30U) -#define SMMU_GNSR0_S2CR13 (0xc34U) -#define SMMU_GNSR0_S2CR14 (0xc38U) -#define SMMU_GNSR0_S2CR15 (0xc3cU) -#define SMMU_GNSR0_S2CR16 (0xc40U) -#define SMMU_GNSR0_S2CR17 (0xc44U) -#define SMMU_GNSR0_S2CR18 (0xc48U) -#define SMMU_GNSR0_S2CR19 (0xc4cU) -#define SMMU_GNSR0_S2CR20 (0xc50U) -#define SMMU_GNSR0_S2CR21 (0xc54U) -#define SMMU_GNSR0_S2CR22 (0xc58U) -#define SMMU_GNSR0_S2CR23 (0xc5cU) -#define SMMU_GNSR0_S2CR24 (0xc60U) -#define SMMU_GNSR0_S2CR25 (0xc64U) -#define SMMU_GNSR0_S2CR26 (0xc68U) -#define SMMU_GNSR0_S2CR27 (0xc6cU) -#define SMMU_GNSR0_S2CR28 (0xc70U) -#define SMMU_GNSR0_S2CR29 (0xc74U) -#define SMMU_GNSR0_S2CR30 (0xc78U) -#define SMMU_GNSR0_S2CR31 (0xc7cU) -#define SMMU_GNSR0_S2CR32 (0xc80U) -#define SMMU_GNSR0_S2CR33 (0xc84U) -#define SMMU_GNSR0_S2CR34 (0xc88U) -#define SMMU_GNSR0_S2CR35 (0xc8cU) -#define SMMU_GNSR0_S2CR36 (0xc90U) -#define SMMU_GNSR0_S2CR37 (0xc94U) -#define SMMU_GNSR0_S2CR38 (0xc98U) -#define SMMU_GNSR0_S2CR39 (0xc9cU) -#define SMMU_GNSR0_S2CR40 (0xca0U) -#define SMMU_GNSR0_S2CR41 (0xca4U) -#define SMMU_GNSR0_S2CR42 (0xca8U) -#define SMMU_GNSR0_S2CR43 (0xcacU) -#define SMMU_GNSR0_S2CR44 (0xcb0U) -#define SMMU_GNSR0_S2CR45 (0xcb4U) -#define SMMU_GNSR0_S2CR46 (0xcb8U) -#define SMMU_GNSR0_S2CR47 (0xcbcU) -#define SMMU_GNSR0_S2CR48 (0xcc0U) -#define SMMU_GNSR0_S2CR49 (0xcc4U) -#define SMMU_GNSR0_S2CR50 (0xcc8U) -#define SMMU_GNSR0_S2CR51 (0xcccU) -#define SMMU_GNSR0_S2CR52 (0xcd0U) -#define SMMU_GNSR0_S2CR53 (0xcd4U) -#define SMMU_GNSR0_S2CR54 (0xcd8U) -#define SMMU_GNSR0_S2CR55 (0xcdcU) -#define SMMU_GNSR0_S2CR56 (0xce0U) -#define SMMU_GNSR0_S2CR57 (0xce4U) -#define SMMU_GNSR0_S2CR58 (0xce8U) -#define SMMU_GNSR0_S2CR59 (0xcecU) -#define SMMU_GNSR0_S2CR60 (0xcf0U) -#define SMMU_GNSR0_S2CR61 (0xcf4U) -#define SMMU_GNSR0_S2CR62 (0xcf8U) -#define SMMU_GNSR0_S2CR63 (0xcfcU) -#define SMMU_GNSR0_S2CR64 (0xd00U) -#define SMMU_GNSR0_S2CR65 (0xd04U) -#define SMMU_GNSR0_S2CR66 (0xd08U) -#define SMMU_GNSR0_S2CR67 (0xd0cU) -#define SMMU_GNSR0_S2CR68 (0xd10U) -#define SMMU_GNSR0_S2CR69 (0xd14U) -#define SMMU_GNSR0_S2CR70 (0xd18U) -#define SMMU_GNSR0_S2CR71 (0xd1cU) -#define SMMU_GNSR0_S2CR72 (0xd20U) -#define SMMU_GNSR0_S2CR73 (0xd24U) -#define SMMU_GNSR0_S2CR74 (0xd28U) -#define SMMU_GNSR0_S2CR75 (0xd2cU) -#define SMMU_GNSR0_S2CR76 (0xd30U) -#define SMMU_GNSR0_S2CR77 (0xd34U) -#define SMMU_GNSR0_S2CR78 (0xd38U) -#define SMMU_GNSR0_S2CR79 (0xd3cU) -#define SMMU_GNSR0_S2CR80 (0xd40U) -#define SMMU_GNSR0_S2CR81 (0xd44U) -#define SMMU_GNSR0_S2CR82 (0xd48U) -#define SMMU_GNSR0_S2CR83 (0xd4cU) -#define SMMU_GNSR0_S2CR84 (0xd50U) -#define SMMU_GNSR0_S2CR85 (0xd54U) -#define SMMU_GNSR0_S2CR86 (0xd58U) -#define SMMU_GNSR0_S2CR87 (0xd5cU) -#define SMMU_GNSR0_S2CR88 (0xd60U) -#define SMMU_GNSR0_S2CR89 (0xd64U) -#define SMMU_GNSR0_S2CR90 (0xd68U) -#define SMMU_GNSR0_S2CR91 (0xd6cU) -#define SMMU_GNSR0_S2CR92 (0xd70U) -#define SMMU_GNSR0_S2CR93 (0xd74U) -#define SMMU_GNSR0_S2CR94 (0xd78U) -#define SMMU_GNSR0_S2CR95 (0xd7cU) -#define SMMU_GNSR0_S2CR96 (0xd80U) -#define SMMU_GNSR0_S2CR97 (0xd84U) -#define SMMU_GNSR0_S2CR98 (0xd88U) -#define SMMU_GNSR0_S2CR99 (0xd8cU) -#define SMMU_GNSR0_S2CR100 (0xd90U) -#define SMMU_GNSR0_S2CR101 (0xd94U) -#define SMMU_GNSR0_S2CR102 (0xd98U) -#define SMMU_GNSR0_S2CR103 (0xd9cU) -#define SMMU_GNSR0_S2CR104 (0xda0U) -#define SMMU_GNSR0_S2CR105 (0xda4U) -#define SMMU_GNSR0_S2CR106 (0xda8U) -#define SMMU_GNSR0_S2CR107 (0xdacU) -#define SMMU_GNSR0_S2CR108 (0xdb0U) -#define SMMU_GNSR0_S2CR109 (0xdb4U) -#define SMMU_GNSR0_S2CR110 (0xdb8U) -#define SMMU_GNSR0_S2CR111 (0xdbcU) -#define SMMU_GNSR0_S2CR112 (0xdc0U) -#define SMMU_GNSR0_S2CR113 (0xdc4U) -#define SMMU_GNSR0_S2CR114 (0xdc8U) -#define SMMU_GNSR0_S2CR115 (0xdccU) -#define SMMU_GNSR0_S2CR116 (0xdd0U) -#define SMMU_GNSR0_S2CR117 (0xdd4U) -#define SMMU_GNSR0_S2CR118 (0xdd8U) -#define SMMU_GNSR0_S2CR119 (0xddcU) -#define SMMU_GNSR0_S2CR120 (0xde0U) -#define SMMU_GNSR0_S2CR121 (0xde4U) -#define SMMU_GNSR0_S2CR122 (0xde8U) -#define SMMU_GNSR0_S2CR123 (0xdecU) -#define SMMU_GNSR0_S2CR124 (0xdf0U) -#define SMMU_GNSR0_S2CR125 (0xdf4U) -#define SMMU_GNSR0_S2CR126 (0xdf8U) -#define SMMU_GNSR0_S2CR127 (0xdfcU) -#define SMMU_GNSR0_PIDR0 (0xfe0U) -#define SMMU_GNSR0_PIDR1 (0xfe4U) -#define SMMU_GNSR0_PIDR2 (0xfe8U) -#define SMMU_GNSR0_PIDR3 (0xfecU) -#define SMMU_GNSR0_PIDR4 (0xfd0U) -#define SMMU_GNSR0_PIDR5 (0xfd4U) -#define SMMU_GNSR0_PIDR6 (0xfd8U) -#define SMMU_GNSR0_PIDR7 (0xfdcU) -#define SMMU_GNSR0_CIDR0 (0xff0U) -#define SMMU_GNSR0_CIDR1 (0xff4U) -#define SMMU_GNSR0_CIDR2 (0xff8U) -#define SMMU_GNSR0_CIDR3 (0xffcU) -#define SMMU_GNSR1_CBAR0 (0x0U) -#define SMMU_GNSR1_CBARn (0x0U) -#define SMMU_GNSR1_CBFRSYNRA0 (0x400U) -#define SMMU_GNSR1_CBA2R0 (0x800U) -#define SMMU_GNSR1_CBAR1 (0x4U) -#define SMMU_GNSR1_CBFRSYNRA1 (0x404U) -#define SMMU_GNSR1_CBA2R1 (0x804U) -#define SMMU_GNSR1_CBAR2 (0x8U) -#define SMMU_GNSR1_CBFRSYNRA2 (0x408U) -#define SMMU_GNSR1_CBA2R2 (0x808U) -#define SMMU_GNSR1_CBAR3 (0xcU) -#define SMMU_GNSR1_CBFRSYNRA3 (0x40cU) -#define SMMU_GNSR1_CBA2R3 (0x80cU) -#define SMMU_GNSR1_CBAR4 (0x10U) -#define SMMU_GNSR1_CBFRSYNRA4 (0x410U) -#define SMMU_GNSR1_CBA2R4 (0x810U) -#define SMMU_GNSR1_CBAR5 (0x14U) -#define SMMU_GNSR1_CBFRSYNRA5 (0x414U) -#define SMMU_GNSR1_CBA2R5 (0x814U) -#define SMMU_GNSR1_CBAR6 (0x18U) -#define SMMU_GNSR1_CBFRSYNRA6 (0x418U) -#define SMMU_GNSR1_CBA2R6 (0x818U) -#define SMMU_GNSR1_CBAR7 (0x1cU) -#define SMMU_GNSR1_CBFRSYNRA7 (0x41cU) -#define SMMU_GNSR1_CBA2R7 (0x81cU) -#define SMMU_GNSR1_CBAR8 (0x20U) -#define SMMU_GNSR1_CBFRSYNRA8 (0x420U) -#define SMMU_GNSR1_CBA2R8 (0x820U) -#define SMMU_GNSR1_CBAR9 (0x24U) -#define SMMU_GNSR1_CBFRSYNRA9 (0x424U) -#define SMMU_GNSR1_CBA2R9 (0x824U) -#define SMMU_GNSR1_CBAR10 (0x28U) -#define SMMU_GNSR1_CBFRSYNRA10 (0x428U) -#define SMMU_GNSR1_CBA2R10 (0x828U) -#define SMMU_GNSR1_CBAR11 (0x2cU) -#define SMMU_GNSR1_CBFRSYNRA11 (0x42cU) -#define SMMU_GNSR1_CBA2R11 (0x82cU) -#define SMMU_GNSR1_CBAR12 (0x30U) -#define SMMU_GNSR1_CBFRSYNRA12 (0x430U) -#define SMMU_GNSR1_CBA2R12 (0x830U) -#define SMMU_GNSR1_CBAR13 (0x34U) -#define SMMU_GNSR1_CBFRSYNRA13 (0x434U) -#define SMMU_GNSR1_CBA2R13 (0x834U) -#define SMMU_GNSR1_CBAR14 (0x38U) -#define SMMU_GNSR1_CBFRSYNRA14 (0x438U) -#define SMMU_GNSR1_CBA2R14 (0x838U) -#define SMMU_GNSR1_CBAR15 (0x3cU) -#define SMMU_GNSR1_CBFRSYNRA15 (0x43cU) -#define SMMU_GNSR1_CBA2R15 (0x83cU) -#define SMMU_GNSR1_CBAR16 (0x40U) -#define SMMU_GNSR1_CBFRSYNRA16 (0x440U) -#define SMMU_GNSR1_CBA2R16 (0x840U) -#define SMMU_GNSR1_CBAR17 (0x44U) -#define SMMU_GNSR1_CBFRSYNRA17 (0x444U) -#define SMMU_GNSR1_CBA2R17 (0x844U) -#define SMMU_GNSR1_CBAR18 (0x48U) -#define SMMU_GNSR1_CBFRSYNRA18 (0x448U) -#define SMMU_GNSR1_CBA2R18 (0x848U) -#define SMMU_GNSR1_CBAR19 (0x4cU) -#define SMMU_GNSR1_CBFRSYNRA19 (0x44cU) -#define SMMU_GNSR1_CBA2R19 (0x84cU) -#define SMMU_GNSR1_CBAR20 (0x50U) -#define SMMU_GNSR1_CBFRSYNRA20 (0x450U) -#define SMMU_GNSR1_CBA2R20 (0x850U) -#define SMMU_GNSR1_CBAR21 (0x54U) -#define SMMU_GNSR1_CBFRSYNRA21 (0x454U) -#define SMMU_GNSR1_CBA2R21 (0x854U) -#define SMMU_GNSR1_CBAR22 (0x58U) -#define SMMU_GNSR1_CBFRSYNRA22 (0x458U) -#define SMMU_GNSR1_CBA2R22 (0x858U) -#define SMMU_GNSR1_CBAR23 (0x5cU) -#define SMMU_GNSR1_CBFRSYNRA23 (0x45cU) -#define SMMU_GNSR1_CBA2R23 (0x85cU) -#define SMMU_GNSR1_CBAR24 (0x60U) -#define SMMU_GNSR1_CBFRSYNRA24 (0x460U) -#define SMMU_GNSR1_CBA2R24 (0x860U) -#define SMMU_GNSR1_CBAR25 (0x64U) -#define SMMU_GNSR1_CBFRSYNRA25 (0x464U) -#define SMMU_GNSR1_CBA2R25 (0x864U) -#define SMMU_GNSR1_CBAR26 (0x68U) -#define SMMU_GNSR1_CBFRSYNRA26 (0x468U) -#define SMMU_GNSR1_CBA2R26 (0x868U) -#define SMMU_GNSR1_CBAR27 (0x6cU) -#define SMMU_GNSR1_CBFRSYNRA27 (0x46cU) -#define SMMU_GNSR1_CBA2R27 (0x86cU) -#define SMMU_GNSR1_CBAR28 (0x70U) -#define SMMU_GNSR1_CBFRSYNRA28 (0x470U) -#define SMMU_GNSR1_CBA2R28 (0x870U) -#define SMMU_GNSR1_CBAR29 (0x74U) -#define SMMU_GNSR1_CBFRSYNRA29 (0x474U) -#define SMMU_GNSR1_CBA2R29 (0x874U) -#define SMMU_GNSR1_CBAR30 (0x78U) -#define SMMU_GNSR1_CBFRSYNRA30 (0x478U) -#define SMMU_GNSR1_CBA2R30 (0x878U) -#define SMMU_GNSR1_CBAR31 (0x7cU) -#define SMMU_GNSR1_CBFRSYNRA31 (0x47cU) -#define SMMU_GNSR1_CBA2R31 (0x87cU) -#define SMMU_GNSR1_CBAR32 (0x80U) -#define SMMU_GNSR1_CBFRSYNRA32 (0x480U) -#define SMMU_GNSR1_CBA2R32 (0x880U) -#define SMMU_GNSR1_CBAR33 (0x84U) -#define SMMU_GNSR1_CBFRSYNRA33 (0x484U) -#define SMMU_GNSR1_CBA2R33 (0x884U) -#define SMMU_GNSR1_CBAR34 (0x88U) -#define SMMU_GNSR1_CBFRSYNRA34 (0x488U) -#define SMMU_GNSR1_CBA2R34 (0x888U) -#define SMMU_GNSR1_CBAR35 (0x8cU) -#define SMMU_GNSR1_CBFRSYNRA35 (0x48cU) -#define SMMU_GNSR1_CBA2R35 (0x88cU) -#define SMMU_GNSR1_CBAR36 (0x90U) -#define SMMU_GNSR1_CBFRSYNRA36 (0x490U) -#define SMMU_GNSR1_CBA2R36 (0x890U) -#define SMMU_GNSR1_CBAR37 (0x94U) -#define SMMU_GNSR1_CBFRSYNRA37 (0x494U) -#define SMMU_GNSR1_CBA2R37 (0x894U) -#define SMMU_GNSR1_CBAR38 (0x98U) -#define SMMU_GNSR1_CBFRSYNRA38 (0x498U) -#define SMMU_GNSR1_CBA2R38 (0x898U) -#define SMMU_GNSR1_CBAR39 (0x9cU) -#define SMMU_GNSR1_CBFRSYNRA39 (0x49cU) -#define SMMU_GNSR1_CBA2R39 (0x89cU) -#define SMMU_GNSR1_CBAR40 (0xa0U) -#define SMMU_GNSR1_CBFRSYNRA40 (0x4a0U) -#define SMMU_GNSR1_CBA2R40 (0x8a0U) -#define SMMU_GNSR1_CBAR41 (0xa4U) -#define SMMU_GNSR1_CBFRSYNRA41 (0x4a4U) -#define SMMU_GNSR1_CBA2R41 (0x8a4U) -#define SMMU_GNSR1_CBAR42 (0xa8U) -#define SMMU_GNSR1_CBFRSYNRA42 (0x4a8U) -#define SMMU_GNSR1_CBA2R42 (0x8a8U) -#define SMMU_GNSR1_CBAR43 (0xacU) -#define SMMU_GNSR1_CBFRSYNRA43 (0x4acU) -#define SMMU_GNSR1_CBA2R43 (0x8acU) -#define SMMU_GNSR1_CBAR44 (0xb0U) -#define SMMU_GNSR1_CBFRSYNRA44 (0x4b0U) -#define SMMU_GNSR1_CBA2R44 (0x8b0U) -#define SMMU_GNSR1_CBAR45 (0xb4U) -#define SMMU_GNSR1_CBFRSYNRA45 (0x4b4U) -#define SMMU_GNSR1_CBA2R45 (0x8b4U) -#define SMMU_GNSR1_CBAR46 (0xb8U) -#define SMMU_GNSR1_CBFRSYNRA46 (0x4b8U) -#define SMMU_GNSR1_CBA2R46 (0x8b8U) -#define SMMU_GNSR1_CBAR47 (0xbcU) -#define SMMU_GNSR1_CBFRSYNRA47 (0x4bcU) -#define SMMU_GNSR1_CBA2R47 (0x8bcU) -#define SMMU_GNSR1_CBAR48 (0xc0U) -#define SMMU_GNSR1_CBFRSYNRA48 (0x4c0U) -#define SMMU_GNSR1_CBA2R48 (0x8c0U) -#define SMMU_GNSR1_CBAR49 (0xc4U) -#define SMMU_GNSR1_CBFRSYNRA49 (0x4c4U) -#define SMMU_GNSR1_CBA2R49 (0x8c4U) -#define SMMU_GNSR1_CBAR50 (0xc8U) -#define SMMU_GNSR1_CBFRSYNRA50 (0x4c8U) -#define SMMU_GNSR1_CBA2R50 (0x8c8U) -#define SMMU_GNSR1_CBAR51 (0xccU) -#define SMMU_GNSR1_CBFRSYNRA51 (0x4ccU) -#define SMMU_GNSR1_CBA2R51 (0x8ccU) -#define SMMU_GNSR1_CBAR52 (0xd0U) -#define SMMU_GNSR1_CBFRSYNRA52 (0x4d0U) -#define SMMU_GNSR1_CBA2R52 (0x8d0U) -#define SMMU_GNSR1_CBAR53 (0xd4U) -#define SMMU_GNSR1_CBFRSYNRA53 (0x4d4U) -#define SMMU_GNSR1_CBA2R53 (0x8d4U) -#define SMMU_GNSR1_CBAR54 (0xd8U) -#define SMMU_GNSR1_CBFRSYNRA54 (0x4d8U) -#define SMMU_GNSR1_CBA2R54 (0x8d8U) -#define SMMU_GNSR1_CBAR55 (0xdcU) -#define SMMU_GNSR1_CBFRSYNRA55 (0x4dcU) -#define SMMU_GNSR1_CBA2R55 (0x8dcU) -#define SMMU_GNSR1_CBAR56 (0xe0U) -#define SMMU_GNSR1_CBFRSYNRA56 (0x4e0U) -#define SMMU_GNSR1_CBA2R56 (0x8e0U) -#define SMMU_GNSR1_CBAR57 (0xe4U) -#define SMMU_GNSR1_CBFRSYNRA57 (0x4e4U) -#define SMMU_GNSR1_CBA2R57 (0x8e4U) -#define SMMU_GNSR1_CBAR58 (0xe8U) -#define SMMU_GNSR1_CBFRSYNRA58 (0x4e8U) -#define SMMU_GNSR1_CBA2R58 (0x8e8U) -#define SMMU_GNSR1_CBAR59 (0xecU) -#define SMMU_GNSR1_CBFRSYNRA59 (0x4ecU) -#define SMMU_GNSR1_CBA2R59 (0x8ecU) -#define SMMU_GNSR1_CBAR60 (0xf0U) -#define SMMU_GNSR1_CBFRSYNRA60 (0x4f0U) -#define SMMU_GNSR1_CBA2R60 (0x8f0U) -#define SMMU_GNSR1_CBAR61 (0xf4U) -#define SMMU_GNSR1_CBFRSYNRA61 (0x4f4U) -#define SMMU_GNSR1_CBA2R61 (0x8f4U) -#define SMMU_GNSR1_CBAR62 (0xf8U) -#define SMMU_GNSR1_CBFRSYNRA62 (0x4f8U) -#define SMMU_GNSR1_CBA2R62 (0x8f8U) -#define SMMU_GNSR1_CBAR63 (0xfcU) -#define SMMU_GNSR1_CBFRSYNRA63 (0x4fcU) -#define SMMU_GNSR1_CBA2R63 (0x8fcU) /******************************************************************************* * SMMU Global Secure Aux. Configuration Register @@ -581,269 +23,69 @@ #define SMMU_GSR0_PGSIZE_SHIFT 16U #define SMMU_GSR0_PGSIZE_4K (0U << SMMU_GSR0_PGSIZE_SHIFT) #define SMMU_GSR0_PGSIZE_64K (1U << SMMU_GSR0_PGSIZE_SHIFT) -#define SMMU_ACR_CACHE_LOCK_ENABLE_BIT (1U << 26) +#define SMMU_ACR_CACHE_LOCK_ENABLE_BIT (1ULL << 26U) +#define SMMU_GSR0_PER (0x20200U) /******************************************************************************* * SMMU Global Aux. Control Register ******************************************************************************/ #define SMMU_CBn_ACTLR_CPRE_BIT (1ULL << 1U) -/******************************************************************************* - * SMMU configuration constants - ******************************************************************************/ -#define ID1_PAGESIZE (1U << 31U) -#define ID1_NUMPAGENDXB_SHIFT 28U -#define ID1_NUMPAGENDXB_MASK 7U -#define ID1_NUMS2CB_SHIFT 16U -#define ID1_NUMS2CB_MASK 0xffU -#define ID1_NUMCB_SHIFT 0U -#define ID1_NUMCB_MASK 0xffU -#define PGSHIFT 16U -#define CB_SIZE 0x800000U +/* SMMU IDs currently supported by the driver */ +enum { + TEGRA_SMMU0 = 0U, + TEGRA_SMMU1 = 1U, + TEGRA_SMMU2 = 2U +}; -typedef struct smmu_regs { - uint32_t reg; - uint32_t val; -} smmu_regs_t; +static inline uint32_t tegra_smmu_read_32(uint32_t smmu_id, uint32_t off) +{ + uint32_t ret = 0U; -#define mc_make_sid_override_cfg(name) \ - { \ - .reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_CFG_ ## name, \ - .val = 0x00000000U, \ +#if defined(TEGRA_SMMU0_BASE) + if (smmu_id == TEGRA_SMMU0) { + ret = mmio_read_32(TEGRA_SMMU0_BASE + (uint64_t)off); } +#endif -#define mc_make_sid_security_cfg(name) \ - { \ - .reg = TEGRA_MC_STREAMID_BASE + MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(MC_STREAMID_OVERRIDE_CFG_ ## name), \ - .val = 0x00000000U, \ +#if defined(TEGRA_SMMU1_BASE) + if (smmu_id == TEGRA_SMMU1) { + ret = mmio_read_32(TEGRA_SMMU1_BASE + (uint64_t)off); } +#endif -#define smmu_make_gnsr0_sec_cfg(base_addr, name) \ - { \ - .reg = base_addr + SMMU_GNSR0_ ## name, \ - .val = 0x00000000U, \ +#if defined(TEGRA_SMMU2_BASE) + if (smmu_id == TEGRA_SMMU2) { + ret = mmio_read_32(TEGRA_SMMU2_BASE + (uint64_t)off); } +#endif -/* - * On ARM-SMMU, conditional offset to access secure aliases of non-secure registers - * is 0x400. So, add it to register address - */ -#define smmu_make_gnsr0_nsec_cfg(base_addr, name) \ - { \ - .reg = base_addr + 0x400U + SMMU_GNSR0_ ## name, \ - .val = 0x00000000U, \ - } - -#define smmu_make_gnsr0_smr_cfg(base_addr, n) \ - { \ - .reg = base_addr + SMMU_GNSR0_SMR ## n, \ - .val = 0x00000000U, \ - } - -#define smmu_make_gnsr0_s2cr_cfg(base_addr, n) \ - { \ - .reg = base_addr + SMMU_GNSR0_S2CR ## n, \ - .val = 0x00000000U, \ - } + return ret; +} -#define smmu_make_gnsr1_cbar_cfg(base_addr, n) \ - { \ - .reg = base_addr + (1U << PGSHIFT) + SMMU_GNSR1_CBAR ## n, \ - .val = 0x00000000U, \ +static inline void tegra_smmu_write_32(uint32_t smmu_id, + uint32_t off, uint32_t val) +{ +#if defined(TEGRA_SMMU0_BASE) + if (smmu_id == TEGRA_SMMU0) { + mmio_write_32(TEGRA_SMMU0_BASE + (uint64_t)off, val); } +#endif -#define smmu_make_gnsr1_cba2r_cfg(base_addr, n) \ - { \ - .reg = base_addr + (1U << PGSHIFT) + SMMU_GNSR1_CBA2R ## n, \ - .val = 0x00000000U, \ +#if defined(TEGRA_SMMU1_BASE) + if (smmu_id == TEGRA_SMMU1) { + mmio_write_32(TEGRA_SMMU1_BASE + (uint64_t)off, val); } +#endif -#define smmu_make_cb_cfg(base_addr, name, n) \ - { \ - .reg = base_addr + (CB_SIZE >> 1) + (n * (1 << PGSHIFT)) \ - + SMMU_CBn_ ## name, \ - .val = 0x00000000U, \ +#if defined(TEGRA_SMMU2_BASE) + if (smmu_id == TEGRA_SMMU2) { + mmio_write_32(TEGRA_SMMU2_BASE + (uint64_t)off, val); } - -#define smmu_make_smrg_group(base_addr, n) \ - smmu_make_gnsr0_smr_cfg(base_addr, n), \ - smmu_make_gnsr0_s2cr_cfg(base_addr, n), \ - smmu_make_gnsr1_cbar_cfg(base_addr, n), \ - smmu_make_gnsr1_cba2r_cfg(base_addr, n) /* don't put "," here. */ - -#define smmu_make_cb_group(base_addr, n) \ - smmu_make_cb_cfg(base_addr, SCTLR, n), \ - smmu_make_cb_cfg(base_addr, TCR2, n), \ - smmu_make_cb_cfg(base_addr, TTBR0_LO, n), \ - smmu_make_cb_cfg(base_addr, TTBR0_HI, n), \ - smmu_make_cb_cfg(base_addr, TCR, n), \ - smmu_make_cb_cfg(base_addr, PRRR_MAIR0, n),\ - smmu_make_cb_cfg(base_addr, FSR, n), \ - smmu_make_cb_cfg(base_addr, FAR_LO, n), \ - smmu_make_cb_cfg(base_addr, FAR_HI, n), \ - smmu_make_cb_cfg(base_addr, FSYNR0, n) /* don't put "," here. */ - -#define smmu_make_cfg(base_addr) \ - smmu_make_gnsr0_nsec_cfg(base_addr, CR0), \ - smmu_make_gnsr0_sec_cfg(base_addr, IDR0), \ - smmu_make_gnsr0_sec_cfg(base_addr, IDR1), \ - smmu_make_gnsr0_sec_cfg(base_addr, IDR2), \ - smmu_make_gnsr0_nsec_cfg(base_addr, GFSR), \ - smmu_make_gnsr0_nsec_cfg(base_addr, GFSYNR0), \ - smmu_make_gnsr0_nsec_cfg(base_addr, GFSYNR1), \ - smmu_make_gnsr0_nsec_cfg(base_addr, TLBGSTATUS),\ - smmu_make_gnsr0_nsec_cfg(base_addr, PIDR2), \ - smmu_make_smrg_group(base_addr, 0), \ - smmu_make_smrg_group(base_addr, 1), \ - smmu_make_smrg_group(base_addr, 2), \ - smmu_make_smrg_group(base_addr, 3), \ - smmu_make_smrg_group(base_addr, 4), \ - smmu_make_smrg_group(base_addr, 5), \ - smmu_make_smrg_group(base_addr, 6), \ - smmu_make_smrg_group(base_addr, 7), \ - smmu_make_smrg_group(base_addr, 8), \ - smmu_make_smrg_group(base_addr, 9), \ - smmu_make_smrg_group(base_addr, 10), \ - smmu_make_smrg_group(base_addr, 11), \ - smmu_make_smrg_group(base_addr, 12), \ - smmu_make_smrg_group(base_addr, 13), \ - smmu_make_smrg_group(base_addr, 14), \ - smmu_make_smrg_group(base_addr, 15), \ - smmu_make_smrg_group(base_addr, 16), \ - smmu_make_smrg_group(base_addr, 17), \ - smmu_make_smrg_group(base_addr, 18), \ - smmu_make_smrg_group(base_addr, 19), \ - smmu_make_smrg_group(base_addr, 20), \ - smmu_make_smrg_group(base_addr, 21), \ - smmu_make_smrg_group(base_addr, 22), \ - smmu_make_smrg_group(base_addr, 23), \ - smmu_make_smrg_group(base_addr, 24), \ - smmu_make_smrg_group(base_addr, 25), \ - smmu_make_smrg_group(base_addr, 26), \ - smmu_make_smrg_group(base_addr, 27), \ - smmu_make_smrg_group(base_addr, 28), \ - smmu_make_smrg_group(base_addr, 29), \ - smmu_make_smrg_group(base_addr, 30), \ - smmu_make_smrg_group(base_addr, 31), \ - smmu_make_smrg_group(base_addr, 32), \ - smmu_make_smrg_group(base_addr, 33), \ - smmu_make_smrg_group(base_addr, 34), \ - smmu_make_smrg_group(base_addr, 35), \ - smmu_make_smrg_group(base_addr, 36), \ - smmu_make_smrg_group(base_addr, 37), \ - smmu_make_smrg_group(base_addr, 38), \ - smmu_make_smrg_group(base_addr, 39), \ - smmu_make_smrg_group(base_addr, 40), \ - smmu_make_smrg_group(base_addr, 41), \ - smmu_make_smrg_group(base_addr, 42), \ - smmu_make_smrg_group(base_addr, 43), \ - smmu_make_smrg_group(base_addr, 44), \ - smmu_make_smrg_group(base_addr, 45), \ - smmu_make_smrg_group(base_addr, 46), \ - smmu_make_smrg_group(base_addr, 47), \ - smmu_make_smrg_group(base_addr, 48), \ - smmu_make_smrg_group(base_addr, 49), \ - smmu_make_smrg_group(base_addr, 50), \ - smmu_make_smrg_group(base_addr, 51), \ - smmu_make_smrg_group(base_addr, 52), \ - smmu_make_smrg_group(base_addr, 53), \ - smmu_make_smrg_group(base_addr, 54), \ - smmu_make_smrg_group(base_addr, 55), \ - smmu_make_smrg_group(base_addr, 56), \ - smmu_make_smrg_group(base_addr, 57), \ - smmu_make_smrg_group(base_addr, 58), \ - smmu_make_smrg_group(base_addr, 59), \ - smmu_make_smrg_group(base_addr, 60), \ - smmu_make_smrg_group(base_addr, 61), \ - smmu_make_smrg_group(base_addr, 62), \ - smmu_make_smrg_group(base_addr, 63), \ - smmu_make_cb_group(base_addr, 0), \ - smmu_make_cb_group(base_addr, 1), \ - smmu_make_cb_group(base_addr, 2), \ - smmu_make_cb_group(base_addr, 3), \ - smmu_make_cb_group(base_addr, 4), \ - smmu_make_cb_group(base_addr, 5), \ - smmu_make_cb_group(base_addr, 6), \ - smmu_make_cb_group(base_addr, 7), \ - smmu_make_cb_group(base_addr, 8), \ - smmu_make_cb_group(base_addr, 9), \ - smmu_make_cb_group(base_addr, 10), \ - smmu_make_cb_group(base_addr, 11), \ - smmu_make_cb_group(base_addr, 12), \ - smmu_make_cb_group(base_addr, 13), \ - smmu_make_cb_group(base_addr, 14), \ - smmu_make_cb_group(base_addr, 15), \ - smmu_make_cb_group(base_addr, 16), \ - smmu_make_cb_group(base_addr, 17), \ - smmu_make_cb_group(base_addr, 18), \ - smmu_make_cb_group(base_addr, 19), \ - smmu_make_cb_group(base_addr, 20), \ - smmu_make_cb_group(base_addr, 21), \ - smmu_make_cb_group(base_addr, 22), \ - smmu_make_cb_group(base_addr, 23), \ - smmu_make_cb_group(base_addr, 24), \ - smmu_make_cb_group(base_addr, 25), \ - smmu_make_cb_group(base_addr, 26), \ - smmu_make_cb_group(base_addr, 27), \ - smmu_make_cb_group(base_addr, 28), \ - smmu_make_cb_group(base_addr, 29), \ - smmu_make_cb_group(base_addr, 30), \ - smmu_make_cb_group(base_addr, 31), \ - smmu_make_cb_group(base_addr, 32), \ - smmu_make_cb_group(base_addr, 33), \ - smmu_make_cb_group(base_addr, 34), \ - smmu_make_cb_group(base_addr, 35), \ - smmu_make_cb_group(base_addr, 36), \ - smmu_make_cb_group(base_addr, 37), \ - smmu_make_cb_group(base_addr, 38), \ - smmu_make_cb_group(base_addr, 39), \ - smmu_make_cb_group(base_addr, 40), \ - smmu_make_cb_group(base_addr, 41), \ - smmu_make_cb_group(base_addr, 42), \ - smmu_make_cb_group(base_addr, 43), \ - smmu_make_cb_group(base_addr, 44), \ - smmu_make_cb_group(base_addr, 45), \ - smmu_make_cb_group(base_addr, 46), \ - smmu_make_cb_group(base_addr, 47), \ - smmu_make_cb_group(base_addr, 48), \ - smmu_make_cb_group(base_addr, 49), \ - smmu_make_cb_group(base_addr, 50), \ - smmu_make_cb_group(base_addr, 51), \ - smmu_make_cb_group(base_addr, 52), \ - smmu_make_cb_group(base_addr, 53), \ - smmu_make_cb_group(base_addr, 54), \ - smmu_make_cb_group(base_addr, 55), \ - smmu_make_cb_group(base_addr, 56), \ - smmu_make_cb_group(base_addr, 57), \ - smmu_make_cb_group(base_addr, 58), \ - smmu_make_cb_group(base_addr, 59), \ - smmu_make_cb_group(base_addr, 60), \ - smmu_make_cb_group(base_addr, 61), \ - smmu_make_cb_group(base_addr, 62), \ - smmu_make_cb_group(base_addr, 63) /* don't put "," here. */ - -#define smmu_bypass_cfg \ - { \ - .reg = TEGRA_MC_BASE + MC_SMMU_BYPASS_CONFIG, \ - .val = 0x00000000U, \ - } - -#define _START_OF_TABLE_ \ - { \ - .reg = 0xCAFE05C7U, \ - .val = 0x00000000U, \ - } - -#define _END_OF_TABLE_ \ - { \ - .reg = 0xFFFFFFFFU, \ - .val = 0xFFFFFFFFU, \ - } - +#endif +} void tegra_smmu_init(void); -void tegra_smmu_save_context(uint64_t smmu_ctx_addr); -smmu_regs_t *plat_get_smmu_ctx(void); uint32_t plat_get_num_smmu_devices(void); #endif /* SMMU_H */ diff --git a/plat/nvidia/tegra/include/t186/tegra186_private.h b/plat/nvidia/tegra/include/t186/tegra186_private.h index 9e2c02b4b..4514e1477 100644 --- a/plat/nvidia/tegra/include/t186/tegra186_private.h +++ b/plat/nvidia/tegra/include/t186/tegra186_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,10 +7,6 @@ #ifndef TEGRA186_PRIVATE_H #define TEGRA186_PRIVATE_H -void tegra186_cpu_reset_handler(void); -uint64_t tegra186_get_cpu_reset_handler_base(void); -uint64_t tegra186_get_cpu_reset_handler_size(void); -uint64_t tegra186_get_smmu_ctx_offset(void); -void tegra186_set_system_suspend_entry(void); +uint64_t tegra186_get_mc_ctx_size(void); #endif /* TEGRA186_PRIVATE_H */ diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h index 3d037e134..1da9b4639 100644 --- a/plat/nvidia/tegra/include/t186/tegra_def.h +++ b/plat/nvidia/tegra/include/t186/tegra_def.h @@ -73,6 +73,12 @@ #define TEGRA186_SEC_IRQ_TARGET_MASK U(0xF3) /* 4 A57 - 2 Denver */ /******************************************************************************* + * Clock identifier for the SE device + ******************************************************************************/ +#define TEGRA186_CLK_SE U(103) +#define TEGRA_CLK_SE TEGRA186_CLK_SE + +/******************************************************************************* * Tegra Miscellanous register constants ******************************************************************************/ #define TEGRA_MISC_BASE U(0x00100000) @@ -269,8 +275,8 @@ #define SCRATCH_RESET_VECTOR_LO SECURE_SCRATCH_RSV1_LO #define SCRATCH_RESET_VECTOR_HI SECURE_SCRATCH_RSV1_HI #define SCRATCH_SECURE_BOOTP_FCFG SECURE_SCRATCH_RSV6 -#define SCRATCH_SMMU_TABLE_ADDR_LO SECURE_SCRATCH_RSV11_LO -#define SCRATCH_SMMU_TABLE_ADDR_HI SECURE_SCRATCH_RSV11_HI +#define SCRATCH_MC_TABLE_ADDR_LO SECURE_SCRATCH_RSV11_LO +#define SCRATCH_MC_TABLE_ADDR_HI SECURE_SCRATCH_RSV11_HI #define SCRATCH_BL31_PARAMS_ADDR SECURE_SCRATCH_RSV53_LO #define SCRATCH_BL31_PLAT_PARAMS_ADDR SECURE_SCRATCH_RSV53_HI #define SCRATCH_TZDRAM_ADDR_LO SECURE_SCRATCH_RSV55_LO diff --git a/plat/nvidia/tegra/include/t194/tegra194_private.h b/plat/nvidia/tegra/include/t194/tegra194_private.h index 8f1deb2a3..c5a51e951 100644 --- a/plat/nvidia/tegra/include/t194/tegra194_private.h +++ b/plat/nvidia/tegra/include/t194/tegra194_private.h @@ -10,7 +10,7 @@ void tegra194_cpu_reset_handler(void); uint64_t tegra194_get_cpu_reset_handler_base(void); uint64_t tegra194_get_cpu_reset_handler_size(void); -uint64_t tegra194_get_smmu_ctx_offset(void); +uint64_t tegra194_get_mc_ctx_offset(void); void tegra194_set_system_suspend_entry(void); #endif /* TEGRA194_PRIVATE_H */ diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h index a58ae9d93..dc0644514 100644 --- a/plat/nvidia/tegra/include/t194/tegra_def.h +++ b/plat/nvidia/tegra/include/t194/tegra_def.h @@ -43,6 +43,12 @@ #define TEGRA194_SEC_IRQ_TARGET_MASK U(0xFF) /* 8 Carmel */ /******************************************************************************* + * Clock identifier for the SE device + ******************************************************************************/ +#define TEGRA194_CLK_SE U(124) +#define TEGRA_CLK_SE TEGRA194_CLK_SE + +/******************************************************************************* * Tegra Miscellanous register constants ******************************************************************************/ #define TEGRA_MISC_BASE U(0x00100000) @@ -197,6 +203,16 @@ * Tegra scratch registers constants ******************************************************************************/ #define TEGRA_SCRATCH_BASE U(0x0C390000) +#define SECURE_SCRATCH_RSV68_LO U(0x284) +#define SECURE_SCRATCH_RSV68_HI U(0x288) +#define SECURE_SCRATCH_RSV69_LO U(0x28C) +#define SECURE_SCRATCH_RSV69_HI U(0x290) +#define SECURE_SCRATCH_RSV70_LO U(0x294) +#define SECURE_SCRATCH_RSV70_HI U(0x298) +#define SECURE_SCRATCH_RSV71_LO U(0x29C) +#define SECURE_SCRATCH_RSV71_HI U(0x2A0) +#define SECURE_SCRATCH_RSV72_LO U(0x2A4) +#define SECURE_SCRATCH_RSV72_HI U(0x2A8) #define SECURE_SCRATCH_RSV75 U(0x2BC) #define SECURE_SCRATCH_RSV81_LO U(0x2EC) #define SECURE_SCRATCH_RSV81_HI U(0x2F0) @@ -215,8 +231,8 @@ #define SCRATCH_BL31_PLAT_PARAMS_HI_ADDR_SHIFT U(16) #define SCRATCH_BL31_PLAT_PARAMS_LO_ADDR SECURE_SCRATCH_RSV81_HI #define SCRATCH_SECURE_BOOTP_FCFG SECURE_SCRATCH_RSV97 -#define SCRATCH_SMMU_TABLE_ADDR_LO SECURE_SCRATCH_RSV99_LO -#define SCRATCH_SMMU_TABLE_ADDR_HI SECURE_SCRATCH_RSV99_HI +#define SCRATCH_MC_TABLE_ADDR_LO SECURE_SCRATCH_RSV99_LO +#define SCRATCH_MC_TABLE_ADDR_HI SECURE_SCRATCH_RSV99_HI #define SCRATCH_RESET_VECTOR_LO SECURE_SCRATCH_RSV109_LO #define SCRATCH_RESET_VECTOR_HI SECURE_SCRATCH_RSV109_HI diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h index e8bce5e05..f3013a8a5 100644 --- a/plat/nvidia/tegra/include/t210/tegra_def.h +++ b/plat/nvidia/tegra/include/t210/tegra_def.h @@ -44,6 +44,11 @@ #define SC7ENTRY_FW_HEADER_SIZE_BYTES U(0x400) /******************************************************************************* + * Counter-timer physical secure timer PPI + ******************************************************************************/ +#define TEGRA210_TIMER1_IRQ 32 + +/******************************************************************************* * iRAM memory constants ******************************************************************************/ #define TEGRA_IRAM_BASE U(0x40000000) diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index ad3cee4b4..f72c9cf3c 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -47,6 +47,8 @@ typedef struct plat_params_from_bl2 { uint64_t sc7entry_fw_size; /* System Suspend Entry Firmware base address */ uint64_t sc7entry_fw_base; + /* Enable dual execution */ + uint8_t enable_ccplex_lock_step; } plat_params_from_bl2_t; /******************************************************************************* diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk index d0ed5d57a..14b99130c 100644 --- a/plat/nvidia/tegra/platform.mk +++ b/plat/nvidia/tegra/platform.mk @@ -13,7 +13,7 @@ $(eval $(call add_define,CRASH_REPORTING)) # enable assert() for release/debug builds ENABLE_ASSERTIONS := 1 -PLAT_LOG_LEVEL_ASSERT := 40 +PLAT_LOG_LEVEL_ASSERT := 50 $(eval $(call add_define,PLAT_LOG_LEVEL_ASSERT)) # enable dynamic memory mapping diff --git a/plat/nvidia/tegra/soc/t186/drivers/se/se.c b/plat/nvidia/tegra/soc/t186/drivers/se/se.c index dfb9de882..25f8cd028 100644 --- a/plat/nvidia/tegra/soc/t186/drivers/se/se.c +++ b/plat/nvidia/tegra/soc/t186/drivers/se/se.c @@ -12,7 +12,6 @@ #include <bpmp_ipc.h> #include <pmc.h> #include <security_engine.h> -#include <tegra186_private.h> #include <tegra_private.h> #include "se_private.h" diff --git a/plat/nvidia/tegra/soc/t186/plat_memctrl.c b/plat/nvidia/tegra/soc/t186/plat_memctrl.c index a97496bd1..7ff7e77d9 100644 --- a/plat/nvidia/tegra/soc/t186/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t186/plat_memctrl.c @@ -10,8 +10,8 @@ #include <mce.h> #include <memctrl_v2.h> -#include <tegra_mc_def.h> #include <tegra186_private.h> +#include <tegra_mc_def.h> #include <tegra_platform.h> #include <tegra_private.h> @@ -516,6 +516,171 @@ static void tegra186_memctrl_set_overrides(void) } } + +/******************************************************************************* + * Array to hold MC context for Tegra186 + ******************************************************************************/ +static __attribute__((aligned(16))) mc_regs_t tegra186_mc_context[] = { + _START_OF_TABLE_, + mc_make_sid_security_cfg(SCEW), + mc_make_sid_security_cfg(AFIR), + mc_make_sid_security_cfg(NVDISPLAYR1), + mc_make_sid_security_cfg(XUSB_DEVR), + mc_make_sid_security_cfg(VICSRD1), + mc_make_sid_security_cfg(NVENCSWR), + mc_make_sid_security_cfg(TSECSRDB), + mc_make_sid_security_cfg(AXISW), + mc_make_sid_security_cfg(SDMMCWAB), + mc_make_sid_security_cfg(AONDMAW), + mc_make_sid_security_cfg(GPUSWR2), + mc_make_sid_security_cfg(SATAW), + mc_make_sid_security_cfg(UFSHCW), + mc_make_sid_security_cfg(AFIW), + mc_make_sid_security_cfg(SDMMCR), + mc_make_sid_security_cfg(SCEDMAW), + mc_make_sid_security_cfg(UFSHCR), + mc_make_sid_security_cfg(SDMMCWAA), + mc_make_sid_security_cfg(APEDMAW), + mc_make_sid_security_cfg(SESWR), + mc_make_sid_security_cfg(MPCORER), + mc_make_sid_security_cfg(PTCR), + mc_make_sid_security_cfg(BPMPW), + mc_make_sid_security_cfg(ETRW), + mc_make_sid_security_cfg(GPUSRD), + mc_make_sid_security_cfg(VICSWR), + mc_make_sid_security_cfg(SCEDMAR), + mc_make_sid_security_cfg(HDAW), + mc_make_sid_security_cfg(ISPWA), + mc_make_sid_security_cfg(EQOSW), + mc_make_sid_security_cfg(XUSB_HOSTW), + mc_make_sid_security_cfg(TSECSWR), + mc_make_sid_security_cfg(SDMMCRAA), + mc_make_sid_security_cfg(APER), + mc_make_sid_security_cfg(VIW), + mc_make_sid_security_cfg(APEW), + mc_make_sid_security_cfg(AXISR), + mc_make_sid_security_cfg(SDMMCW), + mc_make_sid_security_cfg(BPMPDMAW), + mc_make_sid_security_cfg(ISPRA), + mc_make_sid_security_cfg(NVDECSWR), + mc_make_sid_security_cfg(XUSB_DEVW), + mc_make_sid_security_cfg(NVDECSRD), + mc_make_sid_security_cfg(MPCOREW), + mc_make_sid_security_cfg(NVDISPLAYR), + mc_make_sid_security_cfg(BPMPDMAR), + mc_make_sid_security_cfg(NVJPGSWR), + mc_make_sid_security_cfg(NVDECSRD1), + mc_make_sid_security_cfg(TSECSRD), + mc_make_sid_security_cfg(NVJPGSRD), + mc_make_sid_security_cfg(SDMMCWA), + mc_make_sid_security_cfg(SCER), + mc_make_sid_security_cfg(XUSB_HOSTR), + mc_make_sid_security_cfg(VICSRD), + mc_make_sid_security_cfg(AONDMAR), + mc_make_sid_security_cfg(AONW), + mc_make_sid_security_cfg(SDMMCRA), + mc_make_sid_security_cfg(HOST1XDMAR), + mc_make_sid_security_cfg(EQOSR), + mc_make_sid_security_cfg(SATAR), + mc_make_sid_security_cfg(BPMPR), + mc_make_sid_security_cfg(HDAR), + mc_make_sid_security_cfg(SDMMCRAB), + mc_make_sid_security_cfg(ETRR), + mc_make_sid_security_cfg(AONR), + mc_make_sid_security_cfg(APEDMAR), + mc_make_sid_security_cfg(SESRD), + mc_make_sid_security_cfg(NVENCSRD), + mc_make_sid_security_cfg(GPUSWR), + mc_make_sid_security_cfg(TSECSWRB), + mc_make_sid_security_cfg(ISPWB), + mc_make_sid_security_cfg(GPUSRD2), + mc_make_sid_override_cfg(APER), + mc_make_sid_override_cfg(VICSRD), + mc_make_sid_override_cfg(NVENCSRD), + mc_make_sid_override_cfg(NVJPGSWR), + mc_make_sid_override_cfg(AONW), + mc_make_sid_override_cfg(BPMPR), + mc_make_sid_override_cfg(BPMPW), + mc_make_sid_override_cfg(HDAW), + mc_make_sid_override_cfg(NVDISPLAYR1), + mc_make_sid_override_cfg(APEDMAR), + mc_make_sid_override_cfg(AFIR), + mc_make_sid_override_cfg(AXISR), + mc_make_sid_override_cfg(VICSRD1), + mc_make_sid_override_cfg(TSECSRD), + mc_make_sid_override_cfg(BPMPDMAW), + mc_make_sid_override_cfg(MPCOREW), + mc_make_sid_override_cfg(XUSB_HOSTR), + mc_make_sid_override_cfg(GPUSWR), + mc_make_sid_override_cfg(XUSB_DEVR), + mc_make_sid_override_cfg(UFSHCW), + mc_make_sid_override_cfg(XUSB_HOSTW), + mc_make_sid_override_cfg(SDMMCWAB), + mc_make_sid_override_cfg(SATAW), + mc_make_sid_override_cfg(SCEDMAR), + mc_make_sid_override_cfg(HOST1XDMAR), + mc_make_sid_override_cfg(SDMMCWA), + mc_make_sid_override_cfg(APEDMAW), + mc_make_sid_override_cfg(SESWR), + mc_make_sid_override_cfg(AXISW), + mc_make_sid_override_cfg(AONDMAW), + mc_make_sid_override_cfg(TSECSWRB), + mc_make_sid_override_cfg(MPCORER), + mc_make_sid_override_cfg(ISPWB), + mc_make_sid_override_cfg(AONR), + mc_make_sid_override_cfg(BPMPDMAR), + mc_make_sid_override_cfg(HDAR), + mc_make_sid_override_cfg(SDMMCRA), + mc_make_sid_override_cfg(ETRW), + mc_make_sid_override_cfg(GPUSWR2), + mc_make_sid_override_cfg(EQOSR), + mc_make_sid_override_cfg(TSECSWR), + mc_make_sid_override_cfg(ETRR), + mc_make_sid_override_cfg(NVDECSRD), + mc_make_sid_override_cfg(TSECSRDB), + mc_make_sid_override_cfg(SDMMCRAA), + mc_make_sid_override_cfg(NVDECSRD1), + mc_make_sid_override_cfg(SDMMCR), + mc_make_sid_override_cfg(NVJPGSRD), + mc_make_sid_override_cfg(SCEDMAW), + mc_make_sid_override_cfg(SDMMCWAA), + mc_make_sid_override_cfg(APEW), + mc_make_sid_override_cfg(AONDMAR), + mc_make_sid_override_cfg(PTCR), + mc_make_sid_override_cfg(SCER), + mc_make_sid_override_cfg(ISPRA), + mc_make_sid_override_cfg(ISPWA), + mc_make_sid_override_cfg(VICSWR), + mc_make_sid_override_cfg(SESRD), + mc_make_sid_override_cfg(SDMMCW), + mc_make_sid_override_cfg(SDMMCRAB), + mc_make_sid_override_cfg(EQOSW), + mc_make_sid_override_cfg(GPUSRD2), + mc_make_sid_override_cfg(SCEW), + mc_make_sid_override_cfg(GPUSRD), + mc_make_sid_override_cfg(NVDECSWR), + mc_make_sid_override_cfg(XUSB_DEVW), + mc_make_sid_override_cfg(SATAR), + mc_make_sid_override_cfg(NVDISPLAYR), + mc_make_sid_override_cfg(VIW), + mc_make_sid_override_cfg(UFSHCR), + mc_make_sid_override_cfg(NVENCSWR), + mc_make_sid_override_cfg(AFIW), + mc_smmu_bypass_cfg, /* TBU settings */ + _END_OF_TABLE_, +}; + +/******************************************************************************* + * Handler to return the pointer to the MC's context struct + ******************************************************************************/ +static mc_regs_t *tegra186_get_mc_system_suspend_ctx(void) +{ + /* index of _END_OF_TABLE_ */ + tegra186_mc_context[0].val = (uint32_t)(ARRAY_SIZE(tegra186_mc_context)) - 1U; + + return tegra186_mc_context; +} + /******************************************************************************* * Struct to hold the memory controller settings ******************************************************************************/ @@ -528,6 +693,7 @@ static tegra_mc_settings_t tegra186_mc_settings = { .num_txn_override_cfgs = (uint32_t)ARRAY_SIZE(tegra186_txn_override_cfgs), .reconfig_mss_clients = tegra186_memctrl_reconfig_mss_clients, .set_txn_overrides = tegra186_memctrl_set_overrides, + .get_mc_system_suspend_ctx = tegra186_get_mc_system_suspend_ctx, }; /******************************************************************************* @@ -545,13 +711,6 @@ tegra_mc_settings_t *tegra_get_mc_settings(void) void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes) { uint32_t val; - uint64_t src_base_tzdram; - const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); - uint64_t src_len_in_bytes = BL31_END - BL31_START; - - /* base address of BL3-1 source in TZDRAM */ - src_base_tzdram = params_from_bl2->tzdram_base + - tegra186_get_cpu_reset_handler_size(); /* * Setup the Memory controller to allow only secure accesses to @@ -581,15 +740,6 @@ void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes) mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_TZDRAM_ADDR_HI, val); /* - * save tzdram_addr_lo and ATF-size, this would be used in SC7-RF to - * generate SHA256. - */ - mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV68_LO, - (uint32_t)src_base_tzdram); - mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV0_HI, - (uint32_t)src_len_in_bytes); - - /* * MCE propagates the security configuration values across the * CCPLEX. */ diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c index a0879cc0d..6f58427b3 100644 --- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c @@ -22,6 +22,7 @@ #include <bpmp_ipc.h> #include <mce.h> +#include <memctrl_v2.h> #include <security_engine.h> #include <smmu.h> #include <t18x_ari.h> @@ -99,7 +100,7 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) uint32_t cpu = plat_my_core_pos(); const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); mce_cstate_info_t cstate_info = { 0 }; - uint64_t smmu_ctx_base; + uint64_t mc_ctx_base; uint32_t val; /* get the state ID */ @@ -132,10 +133,9 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG); mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_BOOTP_FCFG, val); - /* save SMMU context to TZDRAM */ - smmu_ctx_base = params_from_bl2->tzdram_base + - tegra186_get_smmu_ctx_offset(); - tegra_smmu_save_context((uintptr_t)smmu_ctx_base); + /* save MC context to TZDRAM */ + mc_ctx_base = params_from_bl2->tzdram_base; + tegra_mc_save_context((uintptr_t)mc_ctx_base); /* Prepare for system suspend */ cstate_info.cluster = (uint32_t)TEGRA_ARI_CLUSTER_CC7; @@ -157,9 +157,6 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, (uint64_t)TEGRA_ARI_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U); - /* set system suspend state for house-keeping */ - tegra186_set_system_suspend_entry(); - } else { ; /* do nothing */ } @@ -288,13 +285,13 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { val = params_from_bl2->tzdram_base + - tegra186_get_cpu_reset_handler_size(); + tegra186_get_mc_ctx_size(); /* Initialise communication channel with BPMP */ assert(tegra_bpmp_ipc_init() == 0); /* Enable SE clock */ - ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_enable_clock(TEGRA186_CLK_SE); if (ret != 0) { ERROR("Failed to enable clock\n"); return ret; @@ -315,11 +312,20 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta * BL3-1 over to TZDRAM. */ val = params_from_bl2->tzdram_base + - tegra186_get_cpu_reset_handler_size(); + tegra186_get_mc_ctx_size(); memcpy16((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE, (uintptr_t)BL31_END - (uintptr_t)BL31_BASE); - ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE); + /* + * Save code base and size; this would be used by SC7-RF to + * verify binary + */ + mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV68_LO, + (uint32_t)val); + mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV0_HI, + (uint32_t)src_len_in_bytes); + + ret = tegra_bpmp_ipc_disable_clock(TEGRA186_CLK_SE); if (ret != 0) { ERROR("Failed to disable clock\n"); return ret; diff --git a/plat/nvidia/tegra/soc/t186/plat_secondary.c b/plat/nvidia/tegra/soc/t186/plat_secondary.c index 16508093e..fbb550af9 100644 --- a/plat/nvidia/tegra/soc/t186/plat_secondary.c +++ b/plat/nvidia/tegra/soc/t186/plat_secondary.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,56 +12,30 @@ #include <lib/mmio.h> #include <mce.h> -#include <tegra186_private.h> #include <tegra_def.h> #include <tegra_private.h> -#define MISCREG_AA64_RST_LOW 0x2004U -#define MISCREG_AA64_RST_HIGH 0x2008U - #define SCRATCH_SECURE_RSV1_SCRATCH_0 0x658U #define SCRATCH_SECURE_RSV1_SCRATCH_1 0x65CU #define CPU_RESET_MODE_AA64 1U -extern void memcpy16(void *dest, const void *src, unsigned int length); - /******************************************************************************* * Setup secondary CPU vectors ******************************************************************************/ void plat_secondary_setup(void) { uint32_t addr_low, addr_high; - const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); - uint64_t cpu_reset_handler_base, cpu_reset_handler_size; INFO("Setting up secondary CPU boot\n"); - /* - * The BL31 code resides in the TZSRAM which loses state - * when we enter System Suspend. Copy the wakeup trampoline - * code to TZDRAM to help us exit from System Suspend. - */ - cpu_reset_handler_base = tegra186_get_cpu_reset_handler_base(); - cpu_reset_handler_size = tegra186_get_cpu_reset_handler_size(); - (void)memcpy16((void *)(uintptr_t)params_from_bl2->tzdram_base, - (const void *)(uintptr_t)cpu_reset_handler_base, - cpu_reset_handler_size); - /* TZDRAM base will be used as the "resume" address */ - addr_low = (uint32_t)params_from_bl2->tzdram_base | CPU_RESET_MODE_AA64; - addr_high = (uint32_t)((params_from_bl2->tzdram_base >> 32U) & 0x7ffU); - - /* write lower 32 bits first, then the upper 11 bits */ - mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low); - mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH, addr_high); + addr_low = (uintptr_t)&tegra_secure_entrypoint | CPU_RESET_MODE_AA64; + addr_high = (uintptr_t)(((uintptr_t)&tegra_secure_entrypoint >> 32U) & 0x7ffU); /* save reset vector to be used during SYSTEM_SUSPEND exit */ mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO, addr_low); mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI, addr_high); - - /* update reset vector address to the CCPLEX */ - (void)mce_update_reset_vector(); } diff --git a/plat/nvidia/tegra/soc/t186/plat_smmu.c b/plat/nvidia/tegra/soc/t186/plat_smmu.c index b4a7fe596..f1bc235e8 100644 --- a/plat/nvidia/tegra/soc/t186/plat_smmu.c +++ b/plat/nvidia/tegra/soc/t186/plat_smmu.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -13,171 +14,6 @@ #define MAX_NUM_SMMU_DEVICES U(1) /******************************************************************************* - * Array to hold SMMU context for Tegra186 - ******************************************************************************/ -static __attribute__((aligned(16))) smmu_regs_t tegra186_smmu_context[] = { - _START_OF_TABLE_, - mc_make_sid_security_cfg(SCEW), - mc_make_sid_security_cfg(AFIR), - mc_make_sid_security_cfg(NVDISPLAYR1), - mc_make_sid_security_cfg(XUSB_DEVR), - mc_make_sid_security_cfg(VICSRD1), - mc_make_sid_security_cfg(NVENCSWR), - mc_make_sid_security_cfg(TSECSRDB), - mc_make_sid_security_cfg(AXISW), - mc_make_sid_security_cfg(SDMMCWAB), - mc_make_sid_security_cfg(AONDMAW), - mc_make_sid_security_cfg(GPUSWR2), - mc_make_sid_security_cfg(SATAW), - mc_make_sid_security_cfg(UFSHCW), - mc_make_sid_security_cfg(AFIW), - mc_make_sid_security_cfg(SDMMCR), - mc_make_sid_security_cfg(SCEDMAW), - mc_make_sid_security_cfg(UFSHCR), - mc_make_sid_security_cfg(SDMMCWAA), - mc_make_sid_security_cfg(APEDMAW), - mc_make_sid_security_cfg(SESWR), - mc_make_sid_security_cfg(MPCORER), - mc_make_sid_security_cfg(PTCR), - mc_make_sid_security_cfg(BPMPW), - mc_make_sid_security_cfg(ETRW), - mc_make_sid_security_cfg(GPUSRD), - mc_make_sid_security_cfg(VICSWR), - mc_make_sid_security_cfg(SCEDMAR), - mc_make_sid_security_cfg(HDAW), - mc_make_sid_security_cfg(ISPWA), - mc_make_sid_security_cfg(EQOSW), - mc_make_sid_security_cfg(XUSB_HOSTW), - mc_make_sid_security_cfg(TSECSWR), - mc_make_sid_security_cfg(SDMMCRAA), - mc_make_sid_security_cfg(APER), - mc_make_sid_security_cfg(VIW), - mc_make_sid_security_cfg(APEW), - mc_make_sid_security_cfg(AXISR), - mc_make_sid_security_cfg(SDMMCW), - mc_make_sid_security_cfg(BPMPDMAW), - mc_make_sid_security_cfg(ISPRA), - mc_make_sid_security_cfg(NVDECSWR), - mc_make_sid_security_cfg(XUSB_DEVW), - mc_make_sid_security_cfg(NVDECSRD), - mc_make_sid_security_cfg(MPCOREW), - mc_make_sid_security_cfg(NVDISPLAYR), - mc_make_sid_security_cfg(BPMPDMAR), - mc_make_sid_security_cfg(NVJPGSWR), - mc_make_sid_security_cfg(NVDECSRD1), - mc_make_sid_security_cfg(TSECSRD), - mc_make_sid_security_cfg(NVJPGSRD), - mc_make_sid_security_cfg(SDMMCWA), - mc_make_sid_security_cfg(SCER), - mc_make_sid_security_cfg(XUSB_HOSTR), - mc_make_sid_security_cfg(VICSRD), - mc_make_sid_security_cfg(AONDMAR), - mc_make_sid_security_cfg(AONW), - mc_make_sid_security_cfg(SDMMCRA), - mc_make_sid_security_cfg(HOST1XDMAR), - mc_make_sid_security_cfg(EQOSR), - mc_make_sid_security_cfg(SATAR), - mc_make_sid_security_cfg(BPMPR), - mc_make_sid_security_cfg(HDAR), - mc_make_sid_security_cfg(SDMMCRAB), - mc_make_sid_security_cfg(ETRR), - mc_make_sid_security_cfg(AONR), - mc_make_sid_security_cfg(APEDMAR), - mc_make_sid_security_cfg(SESRD), - mc_make_sid_security_cfg(NVENCSRD), - mc_make_sid_security_cfg(GPUSWR), - mc_make_sid_security_cfg(TSECSWRB), - mc_make_sid_security_cfg(ISPWB), - mc_make_sid_security_cfg(GPUSRD2), - mc_make_sid_override_cfg(APER), - mc_make_sid_override_cfg(VICSRD), - mc_make_sid_override_cfg(NVENCSRD), - mc_make_sid_override_cfg(NVJPGSWR), - mc_make_sid_override_cfg(AONW), - mc_make_sid_override_cfg(BPMPR), - mc_make_sid_override_cfg(BPMPW), - mc_make_sid_override_cfg(HDAW), - mc_make_sid_override_cfg(NVDISPLAYR1), - mc_make_sid_override_cfg(APEDMAR), - mc_make_sid_override_cfg(AFIR), - mc_make_sid_override_cfg(AXISR), - mc_make_sid_override_cfg(VICSRD1), - mc_make_sid_override_cfg(TSECSRD), - mc_make_sid_override_cfg(BPMPDMAW), - mc_make_sid_override_cfg(MPCOREW), - mc_make_sid_override_cfg(XUSB_HOSTR), - mc_make_sid_override_cfg(GPUSWR), - mc_make_sid_override_cfg(XUSB_DEVR), - mc_make_sid_override_cfg(UFSHCW), - mc_make_sid_override_cfg(XUSB_HOSTW), - mc_make_sid_override_cfg(SDMMCWAB), - mc_make_sid_override_cfg(SATAW), - mc_make_sid_override_cfg(SCEDMAR), - mc_make_sid_override_cfg(HOST1XDMAR), - mc_make_sid_override_cfg(SDMMCWA), - mc_make_sid_override_cfg(APEDMAW), - mc_make_sid_override_cfg(SESWR), - mc_make_sid_override_cfg(AXISW), - mc_make_sid_override_cfg(AONDMAW), - mc_make_sid_override_cfg(TSECSWRB), - mc_make_sid_override_cfg(MPCORER), - mc_make_sid_override_cfg(ISPWB), - mc_make_sid_override_cfg(AONR), - mc_make_sid_override_cfg(BPMPDMAR), - mc_make_sid_override_cfg(HDAR), - mc_make_sid_override_cfg(SDMMCRA), - mc_make_sid_override_cfg(ETRW), - mc_make_sid_override_cfg(GPUSWR2), - mc_make_sid_override_cfg(EQOSR), - mc_make_sid_override_cfg(TSECSWR), - mc_make_sid_override_cfg(ETRR), - mc_make_sid_override_cfg(NVDECSRD), - mc_make_sid_override_cfg(TSECSRDB), - mc_make_sid_override_cfg(SDMMCRAA), - mc_make_sid_override_cfg(NVDECSRD1), - mc_make_sid_override_cfg(SDMMCR), - mc_make_sid_override_cfg(NVJPGSRD), - mc_make_sid_override_cfg(SCEDMAW), - mc_make_sid_override_cfg(SDMMCWAA), - mc_make_sid_override_cfg(APEW), - mc_make_sid_override_cfg(AONDMAR), - mc_make_sid_override_cfg(PTCR), - mc_make_sid_override_cfg(SCER), - mc_make_sid_override_cfg(ISPRA), - mc_make_sid_override_cfg(ISPWA), - mc_make_sid_override_cfg(VICSWR), - mc_make_sid_override_cfg(SESRD), - mc_make_sid_override_cfg(SDMMCW), - mc_make_sid_override_cfg(SDMMCRAB), - mc_make_sid_override_cfg(EQOSW), - mc_make_sid_override_cfg(GPUSRD2), - mc_make_sid_override_cfg(SCEW), - mc_make_sid_override_cfg(GPUSRD), - mc_make_sid_override_cfg(NVDECSWR), - mc_make_sid_override_cfg(XUSB_DEVW), - mc_make_sid_override_cfg(SATAR), - mc_make_sid_override_cfg(NVDISPLAYR), - mc_make_sid_override_cfg(VIW), - mc_make_sid_override_cfg(UFSHCR), - mc_make_sid_override_cfg(NVENCSWR), - mc_make_sid_override_cfg(AFIW), - smmu_make_cfg(TEGRA_SMMU0_BASE), - smmu_bypass_cfg, /* TBU settings */ - _END_OF_TABLE_, -}; - -/******************************************************************************* - * Handler to return the pointer to the SMMU's context struct - ******************************************************************************/ -smmu_regs_t *plat_get_smmu_ctx(void) -{ - /* index of _END_OF_TABLE_ */ - tegra186_smmu_context[0].val = (uint32_t)(ARRAY_SIZE(tegra186_smmu_context)) - 1U; - - return tegra186_smmu_context; -} - -/******************************************************************************* * Handler to return the support SMMU devices number ******************************************************************************/ uint32_t plat_get_num_smmu_devices(void) diff --git a/plat/nvidia/tegra/soc/t186/plat_trampoline.S b/plat/nvidia/tegra/soc/t186/plat_trampoline.S index db692349e..2fc2046d0 100644 --- a/plat/nvidia/tegra/soc/t186/plat_trampoline.S +++ b/plat/nvidia/tegra/soc/t186/plat_trampoline.S @@ -1,5 +1,6 @@ /* * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,135 +12,30 @@ #include <plat/common/common_def.h> #include <tegra_def.h> -#define TEGRA186_STATE_SYSTEM_SUSPEND 0x5C7 -#define TEGRA186_STATE_SYSTEM_RESUME 0x600D -#define TEGRA186_SMMU_CTX_SIZE 0x420 +#define TEGRA186_MC_CTX_SIZE 0x93 - .globl tegra186_cpu_reset_handler - -/* CPU reset handler routine */ -func tegra186_cpu_reset_handler _align=4 - /* check if we are exiting system suspend state */ - adr x0, __tegra186_system_suspend_state - ldr x1, [x0] - mov x2, #TEGRA186_STATE_SYSTEM_SUSPEND - lsl x2, x2, #16 - add x2, x2, #TEGRA186_STATE_SYSTEM_SUSPEND - cmp x1, x2 - bne boot_cpu - - /* set system resume state */ - mov x1, #TEGRA186_STATE_SYSTEM_RESUME - lsl x1, x1, #16 - mov x2, #TEGRA186_STATE_SYSTEM_RESUME - add x1, x1, x2 - str x1, [x0] - dsb sy - - /* prepare to relocate to TZSRAM */ - mov x0, #BL31_BASE - adr x1, __tegra186_cpu_reset_handler_end - adr x2, __tegra186_cpu_reset_handler_data - ldr x2, [x2, #8] - - /* memcpy16 */ -m_loop16: - cmp x2, #16 - b.lt m_loop1 - ldp x3, x4, [x1], #16 - stp x3, x4, [x0], #16 - sub x2, x2, #16 - b m_loop16 - /* copy byte per byte */ -m_loop1: - cbz x2, boot_cpu - ldrb w3, [x1], #1 - strb w3, [x0], #1 - subs x2, x2, #1 - b.ne m_loop1 - -boot_cpu: - adr x0, __tegra186_cpu_reset_handler_data - ldr x0, [x0] - br x0 -endfunc tegra186_cpu_reset_handler + .globl tegra186_get_mc_ctx_size /* - * Tegra186 reset data (offset 0x0 - 0x430) + * Tegra186 reset data (offset 0x0 - 0x420) * - * 0x000: secure world's entrypoint - * 0x008: BL31 size (RO + RW) - * 0x00C: SMMU context start - * 0x42C: SMMU context end + * 0x000: MC context start + * 0x420: MC context end */ .align 4 - .type __tegra186_cpu_reset_handler_data, %object - .globl __tegra186_cpu_reset_handler_data -__tegra186_cpu_reset_handler_data: - .quad tegra_secure_entrypoint - .quad __BL31_END__ - BL31_BASE - - .globl __tegra186_system_suspend_state -__tegra186_system_suspend_state: - .quad 0 - - .align 4 - .globl __tegra186_smmu_context -__tegra186_smmu_context: - .rept TEGRA186_SMMU_CTX_SIZE +__tegra186_mc_context: + .rept TEGRA186_MC_CTX_SIZE .quad 0 .endr - .size __tegra186_cpu_reset_handler_data, \ - . - __tegra186_cpu_reset_handler_data .align 4 - .globl __tegra186_cpu_reset_handler_end -__tegra186_cpu_reset_handler_end: +__tegra186_mc_context_end: - .globl tegra186_get_cpu_reset_handler_size - .globl tegra186_get_cpu_reset_handler_base - .globl tegra186_get_smmu_ctx_offset - .globl tegra186_set_system_suspend_entry - -/* return size of the CPU reset handler */ -func tegra186_get_cpu_reset_handler_size - adr x0, __tegra186_cpu_reset_handler_end - adr x1, tegra186_cpu_reset_handler - sub x0, x0, x1 - ret -endfunc tegra186_get_cpu_reset_handler_size - -/* return the start address of the CPU reset handler */ -func tegra186_get_cpu_reset_handler_base - adr x0, tegra186_cpu_reset_handler - ret -endfunc tegra186_get_cpu_reset_handler_base - -/* return the size of the SMMU context */ -func tegra186_get_smmu_ctx_offset - adr x0, __tegra186_smmu_context - adr x1, tegra186_cpu_reset_handler +/* return the size of the MC context */ +func tegra186_get_mc_ctx_size + adr x0, __tegra186_mc_context_end + adr x1, __tegra186_mc_context sub x0, x0, x1 ret -endfunc tegra186_get_smmu_ctx_offset - -/* set system suspend state before SC7 entry */ -func tegra186_set_system_suspend_entry - mov x0, #TEGRA_MC_BASE - mov x3, #MC_SECURITY_CFG3_0 - ldr w1, [x0, x3] - lsl x1, x1, #32 - mov x3, #MC_SECURITY_CFG0_0 - ldr w2, [x0, x3] - orr x3, x1, x2 /* TZDRAM base */ - adr x0, __tegra186_system_suspend_state - adr x1, tegra186_cpu_reset_handler - sub x2, x0, x1 /* offset in TZDRAM */ - mov x0, #TEGRA186_STATE_SYSTEM_SUSPEND - lsl x0, x0, #16 - add x0, x0, #TEGRA186_STATE_SYSTEM_SUSPEND - str x0, [x3, x2] /* set value in TZDRAM */ - dsb sy - ret -endfunc tegra186_set_system_suspend_entry +endfunc tegra186_get_mc_ctx_size diff --git a/plat/nvidia/tegra/soc/t186/platform_t186.mk b/plat/nvidia/tegra/soc/t186/platform_t186.mk index d79155f31..c17dab2bd 100644 --- a/plat/nvidia/tegra/soc/t186/platform_t186.mk +++ b/plat/nvidia/tegra/soc/t186/platform_t186.mk @@ -14,7 +14,7 @@ $(eval $(call add_define,ENABLE_CHIP_VERIFICATION_HARNESS)) RESET_TO_BL31 := 1 -PROGRAMMABLE_RESET_ADDRESS := 1 +PROGRAMMABLE_RESET_ADDRESS := 0 COLD_BOOT_SINGLE_CPU := 1 diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/se.h b/plat/nvidia/tegra/soc/t194/drivers/include/se.h index e7cf88d05..7de55a74d 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/include/se.h +++ b/plat/nvidia/tegra/soc/t194/drivers/include/se.h @@ -7,6 +7,8 @@ #ifndef SE_H #define SE_H +int32_t tegra_se_calculate_save_sha256(uint64_t src_addr, + uint32_t src_len_inbyte); int32_t tegra_se_suspend(void); void tegra_se_resume(void); diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h index 9ccb82382..7a68a4303 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h +++ b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h @@ -7,6 +7,8 @@ #ifndef T194_NVG_H #define T194_NVG_H +#include <lib/utils_def.h> + /** * t194_nvg.h - Header for the NVIDIA Generic interface (NVG). * Official documentation for this interface is included as part @@ -20,7 +22,7 @@ */ enum { TEGRA_NVG_VERSION_MAJOR = U(6), - TEGRA_NVG_VERSION_MINOR = U(6) + TEGRA_NVG_VERSION_MINOR = U(7) }; typedef enum { @@ -71,6 +73,9 @@ typedef enum { TEGRA_NVG_CHANNEL_DDA_SNOC_GLOBAL_CTRL = U(77), TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REQ_CTRL = U(78), TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REPLENTISH_CTRL = U(79), + TEGRA_NVG_CHANNEL_RT_SAFE_MASK = U(80), + TEGRA_NVG_CHANNEL_RT_WINDOW_US = U(81), + TEGRA_NVG_CHANNEL_RT_FWD_PROGRESS_US = U(82), TEGRA_NVG_CHANNEL_LAST_INDEX } tegra_nvg_channel_id_t; @@ -153,7 +158,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_power_perf_channel_t { + struct { uint32_t perf_per_watt : U(1); uint32_t reserved_31_1 : U(31); uint32_t reserved_63_32 : U(32); @@ -162,7 +167,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_power_modes_channel_t { + struct { uint32_t low_battery : U(1); uint32_t reserved_1_1 : U(1); uint32_t battery_save : U(1); @@ -182,7 +187,7 @@ typedef union nvg_channel_1_data_u { typedef union { uint64_t flat; - struct nvg_ccplex_cache_control_channel_t { + struct { uint32_t gpu_ways : U(5); uint32_t reserved_7_5 : U(3); uint32_t gpu_only_ways : U(5); @@ -203,7 +208,7 @@ typedef union nvg_channel_2_data_u { typedef union { uint64_t flat; - struct nvg_wake_time_channel_t { + struct { uint32_t wake_time : U(32); uint32_t reserved_63_32 : U(32); } bits; @@ -211,7 +216,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_cstate_info_channel_t { + struct { uint32_t cluster_state : U(3); uint32_t reserved_6_3 : U(4); uint32_t update_cluster : U(1); @@ -242,7 +247,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_lower_bound_channel_t { + struct { uint32_t crossover_value : U(32); uint32_t reserved_63_32 : U(32); } bits; @@ -250,7 +255,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_cstate_stat_query_channel_t { + struct { uint32_t unit_id : U(4); uint32_t reserved_15_4 : U(12); uint32_t stat_id : U(16); @@ -260,7 +265,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_num_cores_channel_t { + struct { uint32_t num_cores : U(4); uint32_t reserved_31_4 : U(28); uint32_t reserved_63_32 : U(32); @@ -269,7 +274,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_unique_logical_id_channel_t { + struct { uint32_t unique_core_id : U(3); uint32_t reserved_31_3 : U(29); uint32_t reserved_63_32 : U(32); @@ -278,7 +283,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_logical_to_physical_mappings_channel_t { + struct { uint32_t lcore0_pcore_id : U(4); uint32_t lcore1_pcore_id : U(4); uint32_t lcore2_pcore_id : U(4); @@ -306,7 +311,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_is_sc7_allowed_channel_t { + struct { uint32_t is_sc7_allowed : U(1); uint32_t reserved_31_1 : U(31); uint32_t reserved_63_32 : U(32); @@ -315,7 +320,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_core_online_channel_t { + struct { uint32_t core_id : U(4); uint32_t reserved_31_4 : U(28); uint32_t reserved_63_32 : U(32); @@ -324,7 +329,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_cc3_control_channel_t { + struct { uint32_t freq_req : U(9); uint32_t reserved_30_9 : U(22); uint32_t enable : U(1); @@ -374,7 +379,7 @@ typedef enum { typedef union { uint64_t flat; - struct nvg_update_ccplex_gsc_channel_t { + struct { uint32_t gsc_enum : U(16); uint32_t reserved_31_16 : U(16); uint32_t reserved_63_32 : U(32); @@ -411,7 +416,7 @@ typedef union { typedef union { uint64_t flat; - struct nvg_hsm_error_ctrl_channel_t { + struct { uint32_t uncorr : U(1); uint32_t corr : U(1); uint32_t reserved_31_2 : U(30); diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se.c b/plat/nvidia/tegra/soc/t194/drivers/se/se.c index a3b338940..ccdc94d13 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/se/se.c +++ b/plat/nvidia/tegra/soc/t194/drivers/se/se.c @@ -28,6 +28,14 @@ #define MAX_TIMEOUT_MS U(100) /* Timeout in 100ms */ #define NUM_SE_REGS_TO_SAVE U(4) +#define SE0_MAX_BUSY_TIMEOUT_MS U(100) /* 100ms Timeout Expired */ +#define BYTES_IN_WORD U(4) +#define SHA256_MAX_HASH_RESULT U(7) +#define SHA256_DST_SIZE U(32) +#define SHA_FIRST_OP U(1) +#define MAX_SHA_ENGINE_CHUNK_SIZE U(0xFFFFFF) +#define SHA256_MSG_LENGTH_ONETIME U(0xFFFF) + /******************************************************************************* * Data structure and global variables ******************************************************************************/ @@ -176,6 +184,270 @@ static int32_t tegra_se_save_context(void) } /* + * Check that SE operation has completed after kickoff + * This function is invoked after an SE operation has been started, + * and it checks the following conditions: + * 1. SE0_INT_STATUS = SE0_OP_DONE + * 2. SE0_STATUS = IDLE + * 3. SE0_ERR_STATUS is clean. + */ +static int32_t tegra_se_sha256_hash_operation_complete(void) +{ + uint32_t val = 0U; + + /* Poll the SE interrupt register to ensure H/W operation complete */ + val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET); + while (SE0_INT_OP_DONE(val) == SE0_INT_OP_DONE_CLEAR) { + val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET); + if (SE0_INT_OP_DONE(val) != SE0_INT_OP_DONE_CLEAR) { + break; + } + } + + /* Poll the SE status idle to ensure H/W operation complete */ + val = tegra_se_read_32(SE0_SHA_STATUS_0); + while (val != SE0_SHA_STATUS_IDLE) { + val = tegra_se_read_32(SE0_SHA_STATUS_0); + if (val == SE0_SHA_STATUS_IDLE) { + break; + } + } + + /* Ensure that no errors are thrown during operation */ + val = tegra_se_read_32(SE0_ERR_STATUS_REG_OFFSET); + if (val != 0U) { + ERROR("%s: error during SE operation! 0x%x", __func__, + val); + return -ENOTSUP; + } + + return 0; +} + +/* + * Security engine primitive normal operations + */ +static int32_t tegra_se_start_normal_operation(uint64_t src_addr, + uint32_t nbytes, uint32_t last_buf, uint32_t src_len_inbytes) +{ + uint32_t val = 0U; + uint32_t src_in_lo; + uint32_t src_in_msb; + uint32_t src_in_hi; + int32_t ret = 0; + + if ((src_addr == 0ULL) || (nbytes == 0U)) + return -EINVAL; + + src_in_lo = (uint32_t)src_addr; + src_in_msb = (uint32_t)((src_addr >> 32U) & 0xFFU); + src_in_hi = ((src_in_msb << SE0_IN_HI_ADDR_HI_0_MSB_SHIFT) | + (nbytes & MAX_SHA_ENGINE_CHUNK_SIZE)); + + /* set SRC_IN_ADDR_LO and SRC_IN_ADDR_HI*/ + tegra_se_write_32(SE0_IN_ADDR, src_in_lo); + tegra_se_write_32(SE0_IN_HI_ADDR_HI, src_in_hi); + + val = tegra_se_read_32(SE0_INT_STATUS_REG_OFFSET); + if (val > 0U) { + tegra_se_write_32(SE0_INT_STATUS_REG_OFFSET, 0x0U); + } + + /* Enable SHA interrupt for SE0 Operation */ + tegra_se_write_32(SE0_SHA_INT_ENABLE, 0x1aU); + + /* flush to DRAM for SE to use the updated contents */ + flush_dcache_range(src_addr, src_len_inbytes); + + /* Start SHA256 operation */ + if (last_buf == 1U) { + tegra_se_write_32(SE0_OPERATION_REG_OFFSET, SE0_OP_START | + SE0_UNIT_OPERATION_PKT_LASTBUF_FIELD); + } else { + tegra_se_write_32(SE0_OPERATION_REG_OFFSET, SE0_OP_START); + } + + return ret; +} + +static int32_t tegra_se_calculate_sha256_hash(uint64_t src_addr, + uint32_t src_len_inbyte) +{ + uint32_t val, last_buf, i; + int32_t ret = 0; + uint32_t operations; + uint64_t src_len_inbits; + uint32_t len_bits_msb; + uint32_t len_bits_lsb; + uint32_t number_of_operations, max_bytes, bytes_left, remaining_bytes; + + if (src_len_inbyte > MAX_SHA_ENGINE_CHUNK_SIZE) { + ERROR("SHA input chunk size too big: 0x%x\n", src_len_inbyte); + return -EINVAL; + } + + if (src_addr == 0ULL) { + return -EINVAL; + } + + /* number of bytes per operation */ + max_bytes = (SHA256_HASH_SIZE_BYTES * SHA256_MSG_LENGTH_ONETIME); + + src_len_inbits = (uint32_t)(src_len_inbyte * 8U); + len_bits_msb = (uint32_t)(src_len_inbits >> 32U); + len_bits_lsb = (uint32_t)src_len_inbits; + + /* program SE0_CONFIG for SHA256 operation */ + val = (uint32_t)(SE0_CONFIG_ENC_ALG_SHA | SE0_CONFIG_ENC_MODE_SHA256 | + SE0_CONFIG_DEC_ALG_NOP | SE0_CONFIG_DST_HASHREG); + tegra_se_write_32(SE0_SHA_CONFIG, val); + + /* set SE0_SHA_MSG_LENGTH registers */ + tegra_se_write_32(SE0_SHA_MSG_LENGTH_0, len_bits_lsb); + tegra_se_write_32(SE0_SHA_MSG_LEFT_0, len_bits_lsb); + tegra_se_write_32(SE0_SHA_MSG_LENGTH_1, len_bits_msb); + + /* zero out unused SE0_SHA_MSG_LENGTH and SE0_SHA_MSG_LEFT */ + tegra_se_write_32(SE0_SHA_MSG_LENGTH_2, 0U); + tegra_se_write_32(SE0_SHA_MSG_LENGTH_3, 0U); + tegra_se_write_32(SE0_SHA_MSG_LEFT_1, 0U); + tegra_se_write_32(SE0_SHA_MSG_LEFT_2, 0U); + tegra_se_write_32(SE0_SHA_MSG_LEFT_3, 0U); + + number_of_operations = (src_len_inbyte / max_bytes); + remaining_bytes = (src_len_inbyte % max_bytes); + if (remaining_bytes > 0U) { + number_of_operations += 1U; + } + + /* + * 1. Operations == 1: program SE0_SHA_TASK register to initiate SHA256 + * hash generation by setting + * 1(SE0_SHA_CONFIG_HW_INIT_HASH) to SE0_SHA_TASK + * and start SHA256-normal operation. + * 2. 1 < Operations < number_of_operations: program SE0_SHA_TASK to + * 0(SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE) to load + * intermediate SHA256 digest result from + * HASH_RESULT register to continue SHA256 + * generation and start SHA256-normal operation. + * 3. Operations == number_of_operations: continue with step 2 and set + * max_bytes to bytes_left to process final + * hash-result generation and start SHA256-normal + * operation. + */ + bytes_left = src_len_inbyte; + for (operations = 1U; operations <= number_of_operations; + operations++) { + if (operations == SHA_FIRST_OP) { + val = SE0_SHA_CONFIG_HW_INIT_HASH; + } else { + /* Load intermediate SHA digest result to + * SHA:HASH_RESULT(0..7) to continue the SHA + * calculation and tell the SHA engine to use it. + */ + for (i = 0U; (i / BYTES_IN_WORD) <= + SHA256_MAX_HASH_RESULT; i += BYTES_IN_WORD) { + val = tegra_se_read_32(SE0_SHA_HASH_RESULT_0 + + i); + tegra_se_write_32(SE0_SHA_HASH_RESULT_0 + i, + val); + } + val = SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE; + if (len_bits_lsb <= (max_bytes * 8U)) { + len_bits_lsb = (remaining_bytes * 8U); + } else { + len_bits_lsb -= (max_bytes * 8U); + } + tegra_se_write_32(SE0_SHA_MSG_LEFT_0, len_bits_lsb); + } + tegra_se_write_32(SE0_SHA_TASK_CONFIG, val); + + max_bytes = (SHA256_HASH_SIZE_BYTES * + SHA256_MSG_LENGTH_ONETIME); + if (bytes_left < max_bytes) { + max_bytes = bytes_left; + last_buf = 1U; + } else { + bytes_left = bytes_left - max_bytes; + last_buf = 0U; + } + /* start operation */ + ret = tegra_se_start_normal_operation(src_addr, max_bytes, + last_buf, src_len_inbyte); + if (ret != 0) { + ERROR("Error during SE operation! 0x%x", ret); + return -EINVAL; + } + } + + return ret; +} + +static int32_t tegra_se_save_sha256_pmc_scratch(void) +{ + uint32_t val = 0U, hash_offset = 0U, scratch_offset = 0U; + int32_t ret; + + /* Check SE0 operation status */ + ret = tegra_se_sha256_hash_operation_complete(); + if (ret != 0) { + ERROR("SE operation complete Failed! 0x%x", ret); + return ret; + } + + for (scratch_offset = SECURE_SCRATCH_TZDRAM_SHA256_HASH_START; + scratch_offset <= SECURE_SCRATCH_TZDRAM_SHA256_HASH_END; + scratch_offset += BYTES_IN_WORD) { + val = tegra_se_read_32(SE0_SHA_HASH_RESULT_0 + hash_offset); + mmio_write_32((uint32_t)(TEGRA_SCRATCH_BASE + scratch_offset), + val); + hash_offset += BYTES_IN_WORD; + } + return 0; +} + +/* + * Handler to generate SHA256 and save HASH-result to pmc-scratch register + */ +int32_t tegra_se_calculate_save_sha256(uint64_t src_addr, + uint32_t src_len_inbyte) +{ + uint32_t security; + int32_t val = 0; + + /* Set SE_SOFT_SETTINGS=SE_SECURE to prevent NS process to change SE + * registers. + */ + security = tegra_se_read_32(SE0_SECURITY); + tegra_se_write_32(SE0_SECURITY, security | SE0_SECURITY_SE_SOFT_SETTING); + + /* Bootrom enable IN_ID bit in SE0_SHA_GSCID_0 register during SC7-exit, causing + * SE0 ignores SE0 operation, and therefore failure of 2nd iteration of SC7 cycle. + */ + tegra_se_write_32(SE0_SHA_GSCID_0, 0x0U); + + /* Calculate SHA256 of BL31 */ + val = tegra_se_calculate_sha256_hash(src_addr, src_len_inbyte); + if (val != 0) { + ERROR("%s: SHA256 generation failed\n", __func__); + return val; + } + + /* + * Reset SE_SECURE to previous value. + */ + tegra_se_write_32(SE0_SECURITY, security); + + /* copy sha256_dst to PMC Scratch register */ + val = tegra_se_save_sha256_pmc_scratch(); + if (val != 0) { + ERROR("%s: SE0 status Error.\n", __func__); + } + + return val; +} + +/* * Handler to power down the SE hardware blocks - SE, RNG1 and PKA1. This * needs to be called only during System Suspend. */ @@ -187,7 +459,7 @@ int32_t tegra_se_suspend(void) assert(tegra_bpmp_ipc_init() == 0); /* Enable SE clock before SE context save */ - ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_enable_clock(TEGRA194_CLK_SE); assert(ret == 0); /* save SE registers */ @@ -203,7 +475,7 @@ int32_t tegra_se_suspend(void) } /* Disable SE clock after SE context save */ - ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_disable_clock(TEGRA194_CLK_SE); assert(ret == 0); return ret; @@ -220,7 +492,7 @@ void tegra_se_resume(void) assert(tegra_bpmp_ipc_init() == 0); /* Enable SE clock before SE context restore */ - ret = tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_enable_clock(TEGRA194_CLK_SE); assert(ret == 0); /* @@ -235,6 +507,6 @@ void tegra_se_resume(void) mmio_write_32(TEGRA_PKA1_BASE + PKA1_MUTEX_WATCHDOG_NS_LIMIT, se_regs[3]); /* Disable SE clock after SE context restore */ - ret = tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE); + ret = tegra_bpmp_ipc_disable_clock(TEGRA194_CLK_SE); assert(ret == 0); } diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h index 577217b8e..fc118aaa1 100644 --- a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h +++ b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h @@ -9,6 +9,86 @@ #define SE_PRIVATE_H #include <lib/utils_def.h> +#include <tegra_def.h> + +/* SE0 security register */ +#define SE0_SECURITY U(0x18) +#define SE0_SECURITY_SE_SOFT_SETTING (((uint32_t)1) << 16U) + +/* SE0 SHA GSCID register */ +#define SE0_SHA_GSCID_0 U(0x100) + +/* SE0 config register */ +#define SE0_SHA_CONFIG U(0x104) +#define SE0_SHA_TASK_CONFIG U(0x108) +#define SE0_SHA_CONFIG_HW_INIT_HASH (((uint32_t)1) << 0U) +#define SE0_SHA_CONFIG_HW_INIT_HASH_DISABLE U(0) + +#define SE0_CONFIG_ENC_ALG_SHIFT U(12) +#define SE0_CONFIG_ENC_ALG_SHA \ + (((uint32_t)3) << SE0_CONFIG_ENC_ALG_SHIFT) +#define SE0_CONFIG_DEC_ALG_SHIFT U(8) +#define SE0_CONFIG_DEC_ALG_NOP \ + (((uint32_t)0) << SE0_CONFIG_DEC_ALG_SHIFT) +#define SE0_CONFIG_DST_SHIFT U(2) +#define SE0_CONFIG_DST_HASHREG \ + (((uint32_t)1) << SE0_CONFIG_DST_SHIFT) +#define SHA256_HASH_SIZE_BYTES U(256) + +#define SE0_CONFIG_ENC_MODE_SHIFT U(24) +#define SE0_CONFIG_ENC_MODE_SHA256 \ + (((uint32_t)5) << SE0_CONFIG_ENC_MODE_SHIFT) + +/* SHA input message length */ +#define SE0_IN_ADDR U(0x10c) +#define SE0_IN_HI_ADDR_HI U(0x110) +#define SE0_IN_HI_ADDR_HI_0_MSB_SHIFT U(24) + +/* SHA input message length */ +#define SE0_SHA_MSG_LENGTH_0 U(0x11c) +#define SE0_SHA_MSG_LENGTH_1 U(0x120) +#define SE0_SHA_MSG_LENGTH_2 U(0x124) +#define SE0_SHA_MSG_LENGTH_3 U(0x128) + +/* SHA input message left */ +#define SE0_SHA_MSG_LEFT_0 U(0x12c) +#define SE0_SHA_MSG_LEFT_1 U(0x130) +#define SE0_SHA_MSG_LEFT_2 U(0x134) +#define SE0_SHA_MSG_LEFT_3 U(0x138) + +/* SE HASH-RESULT */ +#define SE0_SHA_HASH_RESULT_0 U(0x13c) + +/* SE OPERATION */ +#define SE0_OPERATION_REG_OFFSET U(0x17c) +#define SE0_UNIT_OPERATION_PKT_LASTBUF_SHIFT U(16) +#define SE0_UNIT_OPERATION_PKT_LASTBUF_FIELD \ + ((uint32_t)0x1 << SE0_UNIT_OPERATION_PKT_LASTBUF_SHIFT) +#define SE0_OPERATION_SHIFT U(0) +#define SE0_OP_START \ + (((uint32_t)0x1) << SE0_OPERATION_SHIFT) + +/* SE Interrupt */ +#define SE0_SHA_INT_ENABLE U(0x180) + +#define SE0_INT_STATUS_REG_OFFSET U(0x184) +#define SE0_INT_OP_DONE_SHIFT U(4) +#define SE0_INT_OP_DONE_CLEAR \ + (((uint32_t)0U) << SE0_INT_OP_DONE_SHIFT) +#define SE0_INT_OP_DONE(x) \ + ((x) & (((uint32_t)0x1U) << SE0_INT_OP_DONE_SHIFT)) + +/* SE SHA Status */ +#define SE0_SHA_STATUS_0 U(0x188) +#define SE0_SHA_STATUS_IDLE U(0) + +/* SE error status */ +#define SE0_ERR_STATUS_REG_OFFSET U(0x18c) +#define SE0_ERR_STATUS_CLEAR U(0) + +/* SE error status */ +#define SECURE_SCRATCH_TZDRAM_SHA256_HASH_START SECURE_SCRATCH_RSV68_LO +#define SECURE_SCRATCH_TZDRAM_SHA256_HASH_END SECURE_SCRATCH_RSV71_HI /* SE0_INT_ENABLE_0 */ #define SE0_INT_ENABLE U(0x88) @@ -20,7 +100,7 @@ /* SE0_SHA_INT_STATUS_0 */ #define SHA_INT_STATUS U(0x184) -#define SHA_SE_OP_DONE (U(1) << 4) +#define SHA_SE_OP_DONE (U(1) << 4) /* SE0_SHA_ERR_STATUS_0 */ #define SHA_ERR_STATUS U(0x18C) diff --git a/plat/nvidia/tegra/soc/t194/plat_memctrl.c b/plat/nvidia/tegra/soc/t194/plat_memctrl.c index d5f72b614..2d5f8e3c6 100644 --- a/plat/nvidia/tegra/soc/t194/plat_memctrl.c +++ b/plat/nvidia/tegra/soc/t194/plat_memctrl.c @@ -15,12 +15,15 @@ * Array to hold stream_id override config register offsets ******************************************************************************/ const static uint32_t tegra194_streamid_override_regs[] = { + MC_STREAMID_OVERRIDE_CFG_PTCR, MC_STREAMID_OVERRIDE_CFG_HDAR, MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR, MC_STREAMID_OVERRIDE_CFG_NVENCSRD, MC_STREAMID_OVERRIDE_CFG_SATAR, + MC_STREAMID_OVERRIDE_CFG_MPCORER, MC_STREAMID_OVERRIDE_CFG_NVENCSWR, MC_STREAMID_OVERRIDE_CFG_HDAW, + MC_STREAMID_OVERRIDE_CFG_MPCOREW, MC_STREAMID_OVERRIDE_CFG_SATAW, MC_STREAMID_OVERRIDE_CFG_ISPRA, MC_STREAMID_OVERRIDE_CFG_ISPFALR, @@ -131,6 +134,9 @@ const static uint32_t tegra194_streamid_override_regs[] = { MC_STREAMID_OVERRIDE_CFG_NVENC1SRD1, MC_STREAMID_OVERRIDE_CFG_ISPRA1, MC_STREAMID_OVERRIDE_CFG_PCIE0R1, + MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD, + MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD1, + MC_STREAMID_OVERRIDE_CFG_NVDEC1SWR, MC_STREAMID_OVERRIDE_CFG_MIU0R, MC_STREAMID_OVERRIDE_CFG_MIU0W, MC_STREAMID_OVERRIDE_CFG_MIU1R, @@ -142,19 +148,26 @@ const static uint32_t tegra194_streamid_override_regs[] = { MC_STREAMID_OVERRIDE_CFG_MIU4R, MC_STREAMID_OVERRIDE_CFG_MIU4W, MC_STREAMID_OVERRIDE_CFG_MIU5R, - MC_STREAMID_OVERRIDE_CFG_MIU5W + MC_STREAMID_OVERRIDE_CFG_MIU5W, + MC_STREAMID_OVERRIDE_CFG_MIU6R, + MC_STREAMID_OVERRIDE_CFG_MIU6W, + MC_STREAMID_OVERRIDE_CFG_MIU7R, + MC_STREAMID_OVERRIDE_CFG_MIU7W }; /******************************************************************************* * Array to hold the security configs for stream IDs ******************************************************************************/ const static mc_streamid_security_cfg_t tegra194_streamid_sec_cfgs[] = { + mc_make_sec_cfg(PTCR, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MPCORER, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MPCOREW, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(ISPRA, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(ISPFALR, NON_SECURE, NO_OVERRIDE, ENABLE), @@ -265,6 +278,9 @@ const static mc_streamid_security_cfg_t tegra194_streamid_sec_cfgs[] = { mc_make_sec_cfg(NVENC1SRD1, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(ISPRA1, NON_SECURE, NO_OVERRIDE, ENABLE), mc_make_sec_cfg(PCIE0R1, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(NVDEC1SRD, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(NVDEC1SRD1, NON_SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(NVDEC1SWR, NON_SECURE, NO_OVERRIDE, DISABLE), mc_make_sec_cfg(MIU0R, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(MIU0W, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(MIU1R, NON_SECURE, OVERRIDE, DISABLE), @@ -276,17 +292,290 @@ const static mc_streamid_security_cfg_t tegra194_streamid_sec_cfgs[] = { mc_make_sec_cfg(MIU4R, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(MIU4W, NON_SECURE, OVERRIDE, DISABLE), mc_make_sec_cfg(MIU5R, NON_SECURE, OVERRIDE, DISABLE), - mc_make_sec_cfg(MIU5W, NON_SECURE, OVERRIDE, DISABLE) + mc_make_sec_cfg(MIU5W, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU6R, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU6W, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU7R, NON_SECURE, OVERRIDE, DISABLE), + mc_make_sec_cfg(MIU7W, NON_SECURE, OVERRIDE, DISABLE) }; /******************************************************************************* + * Array to hold MC context for Tegra194 + ******************************************************************************/ +static __attribute__((aligned(16))) mc_regs_t tegra194_mc_context[] = { + _START_OF_TABLE_, + mc_make_sid_security_cfg(HDAR), + mc_make_sid_security_cfg(HOST1XDMAR), + mc_make_sid_security_cfg(NVENCSRD), + mc_make_sid_security_cfg(SATAR), + mc_make_sid_security_cfg(NVENCSWR), + mc_make_sid_security_cfg(HDAW), + mc_make_sid_security_cfg(SATAW), + mc_make_sid_security_cfg(ISPRA), + mc_make_sid_security_cfg(ISPFALR), + mc_make_sid_security_cfg(ISPWA), + mc_make_sid_security_cfg(ISPWB), + mc_make_sid_security_cfg(XUSB_HOSTR), + mc_make_sid_security_cfg(XUSB_HOSTW), + mc_make_sid_security_cfg(XUSB_DEVR), + mc_make_sid_security_cfg(XUSB_DEVW), + mc_make_sid_security_cfg(TSECSRD), + mc_make_sid_security_cfg(TSECSWR), + mc_make_sid_security_cfg(SDMMCRA), + mc_make_sid_security_cfg(SDMMCR), + mc_make_sid_security_cfg(SDMMCRAB), + mc_make_sid_security_cfg(SDMMCWA), + mc_make_sid_security_cfg(SDMMCW), + mc_make_sid_security_cfg(SDMMCWAB), + mc_make_sid_security_cfg(VICSRD), + mc_make_sid_security_cfg(VICSWR), + mc_make_sid_security_cfg(VIW), + mc_make_sid_security_cfg(NVDECSRD), + mc_make_sid_security_cfg(NVDECSWR), + mc_make_sid_security_cfg(APER), + mc_make_sid_security_cfg(APEW), + mc_make_sid_security_cfg(NVJPGSRD), + mc_make_sid_security_cfg(NVJPGSWR), + mc_make_sid_security_cfg(SESRD), + mc_make_sid_security_cfg(SESWR), + mc_make_sid_security_cfg(AXIAPR), + mc_make_sid_security_cfg(AXIAPW), + mc_make_sid_security_cfg(ETRR), + mc_make_sid_security_cfg(ETRW), + mc_make_sid_security_cfg(TSECSRDB), + mc_make_sid_security_cfg(TSECSWRB), + mc_make_sid_security_cfg(AXISR), + mc_make_sid_security_cfg(AXISW), + mc_make_sid_security_cfg(EQOSR), + mc_make_sid_security_cfg(EQOSW), + mc_make_sid_security_cfg(UFSHCR), + mc_make_sid_security_cfg(UFSHCW), + mc_make_sid_security_cfg(NVDISPLAYR), + mc_make_sid_security_cfg(BPMPR), + mc_make_sid_security_cfg(BPMPW), + mc_make_sid_security_cfg(BPMPDMAR), + mc_make_sid_security_cfg(BPMPDMAW), + mc_make_sid_security_cfg(AONR), + mc_make_sid_security_cfg(AONW), + mc_make_sid_security_cfg(AONDMAR), + mc_make_sid_security_cfg(AONDMAW), + mc_make_sid_security_cfg(SCER), + mc_make_sid_security_cfg(SCEW), + mc_make_sid_security_cfg(SCEDMAR), + mc_make_sid_security_cfg(SCEDMAW), + mc_make_sid_security_cfg(APEDMAR), + mc_make_sid_security_cfg(APEDMAW), + mc_make_sid_security_cfg(NVDISPLAYR1), + mc_make_sid_security_cfg(VICSRD1), + mc_make_sid_security_cfg(NVDECSRD1), + mc_make_sid_security_cfg(VIFALR), + mc_make_sid_security_cfg(VIFALW), + mc_make_sid_security_cfg(DLA0RDA), + mc_make_sid_security_cfg(DLA0FALRDB), + mc_make_sid_security_cfg(DLA0WRA), + mc_make_sid_security_cfg(DLA0FALWRB), + mc_make_sid_security_cfg(DLA1RDA), + mc_make_sid_security_cfg(DLA1FALRDB), + mc_make_sid_security_cfg(DLA1WRA), + mc_make_sid_security_cfg(DLA1FALWRB), + mc_make_sid_security_cfg(PVA0RDA), + mc_make_sid_security_cfg(PVA0RDB), + mc_make_sid_security_cfg(PVA0RDC), + mc_make_sid_security_cfg(PVA0WRA), + mc_make_sid_security_cfg(PVA0WRB), + mc_make_sid_security_cfg(PVA0WRC), + mc_make_sid_security_cfg(PVA1RDA), + mc_make_sid_security_cfg(PVA1RDB), + mc_make_sid_security_cfg(PVA1RDC), + mc_make_sid_security_cfg(PVA1WRA), + mc_make_sid_security_cfg(PVA1WRB), + mc_make_sid_security_cfg(PVA1WRC), + mc_make_sid_security_cfg(RCER), + mc_make_sid_security_cfg(RCEW), + mc_make_sid_security_cfg(RCEDMAR), + mc_make_sid_security_cfg(RCEDMAW), + mc_make_sid_security_cfg(NVENC1SRD), + mc_make_sid_security_cfg(NVENC1SWR), + mc_make_sid_security_cfg(PCIE0R), + mc_make_sid_security_cfg(PCIE0W), + mc_make_sid_security_cfg(PCIE1R), + mc_make_sid_security_cfg(PCIE1W), + mc_make_sid_security_cfg(PCIE2AR), + mc_make_sid_security_cfg(PCIE2AW), + mc_make_sid_security_cfg(PCIE3R), + mc_make_sid_security_cfg(PCIE3W), + mc_make_sid_security_cfg(PCIE4R), + mc_make_sid_security_cfg(PCIE4W), + mc_make_sid_security_cfg(PCIE5R), + mc_make_sid_security_cfg(PCIE5W), + mc_make_sid_security_cfg(ISPFALW), + mc_make_sid_security_cfg(DLA0RDA1), + mc_make_sid_security_cfg(DLA1RDA1), + mc_make_sid_security_cfg(PVA0RDA1), + mc_make_sid_security_cfg(PVA0RDB1), + mc_make_sid_security_cfg(PVA1RDA1), + mc_make_sid_security_cfg(PVA1RDB1), + mc_make_sid_security_cfg(PCIE5R1), + mc_make_sid_security_cfg(NVENCSRD1), + mc_make_sid_security_cfg(NVENC1SRD1), + mc_make_sid_security_cfg(ISPRA1), + mc_make_sid_security_cfg(PCIE0R1), + mc_make_sid_security_cfg(MIU0R), + mc_make_sid_security_cfg(MIU0W), + mc_make_sid_security_cfg(MIU1R), + mc_make_sid_security_cfg(MIU1W), + mc_make_sid_security_cfg(MIU2R), + mc_make_sid_security_cfg(MIU2W), + mc_make_sid_security_cfg(MIU3R), + mc_make_sid_security_cfg(MIU3W), + mc_make_sid_override_cfg(HDAR), + mc_make_sid_override_cfg(HOST1XDMAR), + mc_make_sid_override_cfg(NVENCSRD), + mc_make_sid_override_cfg(SATAR), + mc_make_sid_override_cfg(NVENCSWR), + mc_make_sid_override_cfg(HDAW), + mc_make_sid_override_cfg(SATAW), + mc_make_sid_override_cfg(ISPRA), + mc_make_sid_override_cfg(ISPFALR), + mc_make_sid_override_cfg(ISPWA), + mc_make_sid_override_cfg(ISPWB), + mc_make_sid_override_cfg(XUSB_HOSTR), + mc_make_sid_override_cfg(XUSB_HOSTW), + mc_make_sid_override_cfg(XUSB_DEVR), + mc_make_sid_override_cfg(XUSB_DEVW), + mc_make_sid_override_cfg(TSECSRD), + mc_make_sid_override_cfg(TSECSWR), + mc_make_sid_override_cfg(SDMMCRA), + mc_make_sid_override_cfg(SDMMCR), + mc_make_sid_override_cfg(SDMMCRAB), + mc_make_sid_override_cfg(SDMMCWA), + mc_make_sid_override_cfg(SDMMCW), + mc_make_sid_override_cfg(SDMMCWAB), + mc_make_sid_override_cfg(VICSRD), + mc_make_sid_override_cfg(VICSWR), + mc_make_sid_override_cfg(VIW), + mc_make_sid_override_cfg(NVDECSRD), + mc_make_sid_override_cfg(NVDECSWR), + mc_make_sid_override_cfg(APER), + mc_make_sid_override_cfg(APEW), + mc_make_sid_override_cfg(NVJPGSRD), + mc_make_sid_override_cfg(NVJPGSWR), + mc_make_sid_override_cfg(SESRD), + mc_make_sid_override_cfg(SESWR), + mc_make_sid_override_cfg(AXIAPR), + mc_make_sid_override_cfg(AXIAPW), + mc_make_sid_override_cfg(ETRR), + mc_make_sid_override_cfg(ETRW), + mc_make_sid_override_cfg(TSECSRDB), + mc_make_sid_override_cfg(TSECSWRB), + mc_make_sid_override_cfg(AXISR), + mc_make_sid_override_cfg(AXISW), + mc_make_sid_override_cfg(EQOSR), + mc_make_sid_override_cfg(EQOSW), + mc_make_sid_override_cfg(UFSHCR), + mc_make_sid_override_cfg(UFSHCW), + mc_make_sid_override_cfg(NVDISPLAYR), + mc_make_sid_override_cfg(BPMPR), + mc_make_sid_override_cfg(BPMPW), + mc_make_sid_override_cfg(BPMPDMAR), + mc_make_sid_override_cfg(BPMPDMAW), + mc_make_sid_override_cfg(AONR), + mc_make_sid_override_cfg(AONW), + mc_make_sid_override_cfg(AONDMAR), + mc_make_sid_override_cfg(AONDMAW), + mc_make_sid_override_cfg(SCER), + mc_make_sid_override_cfg(SCEW), + mc_make_sid_override_cfg(SCEDMAR), + mc_make_sid_override_cfg(SCEDMAW), + mc_make_sid_override_cfg(APEDMAR), + mc_make_sid_override_cfg(APEDMAW), + mc_make_sid_override_cfg(NVDISPLAYR1), + mc_make_sid_override_cfg(VICSRD1), + mc_make_sid_override_cfg(NVDECSRD1), + mc_make_sid_override_cfg(VIFALR), + mc_make_sid_override_cfg(VIFALW), + mc_make_sid_override_cfg(DLA0RDA), + mc_make_sid_override_cfg(DLA0FALRDB), + mc_make_sid_override_cfg(DLA0WRA), + mc_make_sid_override_cfg(DLA0FALWRB), + mc_make_sid_override_cfg(DLA1RDA), + mc_make_sid_override_cfg(DLA1FALRDB), + mc_make_sid_override_cfg(DLA1WRA), + mc_make_sid_override_cfg(DLA1FALWRB), + mc_make_sid_override_cfg(PVA0RDA), + mc_make_sid_override_cfg(PVA0RDB), + mc_make_sid_override_cfg(PVA0RDC), + mc_make_sid_override_cfg(PVA0WRA), + mc_make_sid_override_cfg(PVA0WRB), + mc_make_sid_override_cfg(PVA0WRC), + mc_make_sid_override_cfg(PVA1RDA), + mc_make_sid_override_cfg(PVA1RDB), + mc_make_sid_override_cfg(PVA1RDC), + mc_make_sid_override_cfg(PVA1WRA), + mc_make_sid_override_cfg(PVA1WRB), + mc_make_sid_override_cfg(PVA1WRC), + mc_make_sid_override_cfg(RCER), + mc_make_sid_override_cfg(RCEW), + mc_make_sid_override_cfg(RCEDMAR), + mc_make_sid_override_cfg(RCEDMAW), + mc_make_sid_override_cfg(NVENC1SRD), + mc_make_sid_override_cfg(NVENC1SWR), + mc_make_sid_override_cfg(PCIE0R), + mc_make_sid_override_cfg(PCIE0W), + mc_make_sid_override_cfg(PCIE1R), + mc_make_sid_override_cfg(PCIE1W), + mc_make_sid_override_cfg(PCIE2AR), + mc_make_sid_override_cfg(PCIE2AW), + mc_make_sid_override_cfg(PCIE3R), + mc_make_sid_override_cfg(PCIE3W), + mc_make_sid_override_cfg(PCIE4R), + mc_make_sid_override_cfg(PCIE4W), + mc_make_sid_override_cfg(PCIE5R), + mc_make_sid_override_cfg(PCIE5W), + mc_make_sid_override_cfg(ISPFALW), + mc_make_sid_override_cfg(DLA0RDA1), + mc_make_sid_override_cfg(DLA1RDA1), + mc_make_sid_override_cfg(PVA0RDA1), + mc_make_sid_override_cfg(PVA0RDB1), + mc_make_sid_override_cfg(PVA1RDA1), + mc_make_sid_override_cfg(PVA1RDB1), + mc_make_sid_override_cfg(PCIE5R1), + mc_make_sid_override_cfg(NVENCSRD1), + mc_make_sid_override_cfg(NVENC1SRD1), + mc_make_sid_override_cfg(ISPRA1), + mc_make_sid_override_cfg(PCIE0R1), + mc_make_sid_override_cfg(MIU0R), + mc_make_sid_override_cfg(MIU0W), + mc_make_sid_override_cfg(MIU1R), + mc_make_sid_override_cfg(MIU1W), + mc_make_sid_override_cfg(MIU2R), + mc_make_sid_override_cfg(MIU2W), + mc_make_sid_override_cfg(MIU3R), + mc_make_sid_override_cfg(MIU3W), + mc_smmu_bypass_cfg, /* TBU settings */ + _END_OF_TABLE_, +}; + +/******************************************************************************* + * Handler to return the pointer to the MC's context struct + ******************************************************************************/ +static mc_regs_t *tegra194_get_mc_system_suspend_ctx(void) +{ + /* index of _END_OF_TABLE_ */ + tegra194_mc_context[0].val = (uint32_t)ARRAY_SIZE(tegra194_mc_context) - 1U; + + return tegra194_mc_context; +} + +/******************************************************************************* * Struct to hold the memory controller settings ******************************************************************************/ static tegra_mc_settings_t tegra194_mc_settings = { .streamid_override_cfg = tegra194_streamid_override_regs, .num_streamid_override_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_override_regs), .streamid_security_cfg = tegra194_streamid_sec_cfgs, - .num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_sec_cfgs) + .num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_sec_cfgs), + .get_mc_system_suspend_ctx = tegra194_get_mc_system_suspend_ctx }; /******************************************************************************* diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c index 144e41885..ce5815b46 100644 --- a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c +++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c @@ -10,14 +10,17 @@ #include <string.h> #include <arch_helpers.h> +#include <bpmp_ipc.h> #include <common/bl_common.h> #include <common/debug.h> #include <context.h> +#include <drivers/delay_timer.h> #include <denver.h> #include <lib/el3_runtime/context_mgmt.h> #include <lib/psci/psci.h> #include <mce.h> #include <mce_private.h> +#include <memctrl_v2.h> #include <plat/common/platform.h> #include <se.h> #include <smmu.h> @@ -116,7 +119,7 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) const plat_local_state_t *pwr_domain_state; uint8_t stateid_afflvl0, stateid_afflvl2; plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); - uint64_t smmu_ctx_base; + uint64_t mc_ctx_base; uint32_t val; mce_cstate_info_t sc7_cstate_info = { .cluster = (uint32_t)TEGRA_NVG_CLUSTER_CC6, @@ -135,7 +138,7 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] & TEGRA194_STATE_ID_MASK; - if ((stateid_afflvl0 == PSTATE_ID_CORE_POWERDN)) { + if (stateid_afflvl0 == PSTATE_ID_CORE_POWERDN) { /* Enter CPU powerdown */ (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, @@ -149,10 +152,10 @@ int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG); mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_BOOTP_FCFG, val); - /* save SMMU context */ - smmu_ctx_base = params_from_bl2->tzdram_base + - tegra194_get_smmu_ctx_offset(); - tegra_smmu_save_context((uintptr_t)smmu_ctx_base); + /* save MC context */ + mc_ctx_base = params_from_bl2->tzdram_base + + tegra194_get_mc_ctx_offset(); + tegra_mc_save_context((uintptr_t)mc_ctx_base); /* * Suspend SE, RNG1 and PKA1 only on silcon and fpga, @@ -289,9 +292,34 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); uint8_t stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] & TEGRA194_STATE_ID_MASK; + uint64_t src_len_in_bytes = (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE; uint64_t val; + int32_t ret = PSCI_E_SUCCESS; if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { + val = params_from_bl2->tzdram_base + + tegra194_get_cpu_reset_handler_size(); + + /* initialise communication channel with BPMP */ + ret = tegra_bpmp_ipc_init(); + assert(ret == 0); + + /* Enable SE clock before SE context save */ + ret = tegra_bpmp_ipc_enable_clock(TEGRA194_CLK_SE); + assert(ret == 0); + + /* + * It is very unlikely that the BL31 image would be + * bigger than 2^32 bytes + */ + assert(src_len_in_bytes < UINT32_MAX); + + if (tegra_se_calculate_save_sha256(BL31_BASE, + (uint32_t)src_len_in_bytes) != 0) { + ERROR("Hash calculation failed. Reboot\n"); + (void)tegra_soc_prepare_system_reset(); + } + /* * The TZRAM loses power when we enter system suspend. To * allow graceful exit from system suspend, we need to copy @@ -300,10 +328,14 @@ int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_sta val = params_from_bl2->tzdram_base + tegra194_get_cpu_reset_handler_size(); memcpy((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE, - (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE); + src_len_in_bytes); + + /* Disable SE clock after SE context save */ + ret = tegra_bpmp_ipc_disable_clock(TEGRA194_CLK_SE); + assert(ret == 0); } - return PSCI_E_SUCCESS; + return ret; } int32_t tegra_soc_pwr_domain_suspend_pwrdown_early(const psci_power_state_t *target_state) @@ -336,7 +368,11 @@ int32_t tegra_soc_pwr_domain_on(u_register_t mpidr) int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) { + const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); + uint8_t enable_ccplex_lock_step = params_from_bl2->enable_ccplex_lock_step; uint8_t stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]; + cpu_context_t *ctx = cm_get_context(NON_SECURE); + uint64_t actlr_elx; /* * Reset power state info for CPUs when onlining, we set @@ -345,6 +381,10 @@ int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) * will re-init this info from non-secure software when the * core come online. */ + actlr_elx = read_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1)); + actlr_elx &= ~DENVER_CPU_PMSTATE_MASK; + actlr_elx |= DENVER_CPU_PMSTATE_C1; + write_ctx_reg((get_el1_sysregs_ctx(ctx)), (CTX_ACTLR_EL1), (actlr_elx)); /* * Check if we are exiting from deep sleep and restore SE @@ -414,13 +454,23 @@ int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) mmio_write_32(TEGRA_XUSB_PADCTL_BASE + XUSB_PADCTL_DEV_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_DEV); } + } - /* - * Reset power state info for the last core doing SC7 - * entry and exit, we set deepest power state as CC7 - * and SC7 for SC7 entry which may not be requested by - * non-secure SW which controls idle states. - */ + /* + * Enable dual execution optimized translations for all ELx. + */ + if (enable_ccplex_lock_step != 0U) { + actlr_elx = read_actlr_el3(); + actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL3; + write_actlr_el3(actlr_elx); + + actlr_elx = read_actlr_el2(); + actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL2; + write_actlr_el2(actlr_elx); + + actlr_elx = read_actlr_el1(); + actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL1; + write_actlr_el1(actlr_elx); } return PSCI_E_SUCCESS; diff --git a/plat/nvidia/tegra/soc/t194/plat_secondary.c b/plat/nvidia/tegra/soc/t194/plat_secondary.c index c397c91ba..0882142a1 100644 --- a/plat/nvidia/tegra/soc/t194/plat_secondary.c +++ b/plat/nvidia/tegra/soc/t194/plat_secondary.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -13,6 +13,8 @@ #include <tegra_def.h> #include <tegra_private.h> +extern uint64_t tegra_bl31_phys_base; + #define MISCREG_AA64_RST_LOW 0x2004U #define MISCREG_AA64_RST_HIGH 0x2008U @@ -25,10 +27,14 @@ void plat_secondary_setup(void) { uint32_t addr_low, addr_high; plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); - uint64_t cpu_reset_handler_base, cpu_reset_handler_size; + uint64_t cpu_reset_handler_base, cpu_reset_handler_size, tzdram_addr; + uint64_t src_len_bytes = BL_END - tegra_bl31_phys_base; INFO("Setting up secondary CPU boot\n"); + tzdram_addr = params_from_bl2->tzdram_base + + tegra194_get_cpu_reset_handler_size(); + /* * The BL31 code resides in the TZSRAM which loses state * when we enter System Suspend. Copy the wakeup trampoline @@ -53,4 +59,8 @@ void plat_secondary_setup(void) addr_low); mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI, addr_high); + mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_LO, + (uint32_t)tzdram_addr); + mmio_write_32(TEGRA_SCRATCH_BASE + SECURE_SCRATCH_RSV72_HI, + (uint32_t)src_len_bytes); } diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c index 235fba43c..82555403e 100644 --- a/plat/nvidia/tegra/soc/t194/plat_setup.c +++ b/plat/nvidia/tegra/soc/t194/plat_setup.c @@ -201,6 +201,10 @@ void plat_enable_console(int32_t id) ******************************************************************************/ void plat_early_platform_setup(void) { + const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); + uint8_t enable_ccplex_lock_step = params_from_bl2->enable_ccplex_lock_step; + uint64_t actlr_elx; + /* sanity check MCE firmware compatibility */ mce_verify_firmware_version(); @@ -250,6 +254,23 @@ void plat_early_platform_setup(void) mmio_write_32(TEGRA_XUSB_PADCTL_BASE + XUSB_PADCTL_DEV_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_DEV); } + + /* + * Enable dual execution optimized translations for all ELx. + */ + if (enable_ccplex_lock_step != 0U) { + actlr_elx = read_actlr_el3(); + actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL3; + write_actlr_el3(actlr_elx); + + actlr_elx = read_actlr_el2(); + actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL2; + write_actlr_el2(actlr_elx); + + actlr_elx = read_actlr_el1(); + actlr_elx |= DENVER_CPU_ENABLE_DUAL_EXEC_EL1; + write_actlr_el1(actlr_elx); + } } /* Secure IRQs for Tegra194 */ diff --git a/plat/nvidia/tegra/soc/t194/plat_smmu.c b/plat/nvidia/tegra/soc/t194/plat_smmu.c index 3b4a3803c..310e95104 100644 --- a/plat/nvidia/tegra/soc/t194/plat_smmu.c +++ b/plat/nvidia/tegra/soc/t194/plat_smmu.c @@ -8,7 +8,6 @@ #include <common/debug.h> #include <smmu.h> #include <tegra_def.h> -#include <tegra_mc_def.h> #define BOARD_SYSTEM_FPGA_BASE U(1) #define BASE_CONFIG_SMMU_DEVICES U(2) @@ -20,276 +19,6 @@ static uint32_t tegra_misc_read_32(uint32_t off) } /******************************************************************************* - * Array to hold SMMU context for Tegra194 - ******************************************************************************/ -static __attribute__((aligned(16))) smmu_regs_t tegra194_smmu_context[] = { - _START_OF_TABLE_, - mc_make_sid_security_cfg(HDAR), - mc_make_sid_security_cfg(HOST1XDMAR), - mc_make_sid_security_cfg(NVENCSRD), - mc_make_sid_security_cfg(SATAR), - mc_make_sid_security_cfg(NVENCSWR), - mc_make_sid_security_cfg(HDAW), - mc_make_sid_security_cfg(SATAW), - mc_make_sid_security_cfg(ISPRA), - mc_make_sid_security_cfg(ISPFALR), - mc_make_sid_security_cfg(ISPWA), - mc_make_sid_security_cfg(ISPWB), - mc_make_sid_security_cfg(XUSB_HOSTR), - mc_make_sid_security_cfg(XUSB_HOSTW), - mc_make_sid_security_cfg(XUSB_DEVR), - mc_make_sid_security_cfg(XUSB_DEVW), - mc_make_sid_security_cfg(TSECSRD), - mc_make_sid_security_cfg(TSECSWR), - mc_make_sid_security_cfg(SDMMCRA), - mc_make_sid_security_cfg(SDMMCR), - mc_make_sid_security_cfg(SDMMCRAB), - mc_make_sid_security_cfg(SDMMCWA), - mc_make_sid_security_cfg(SDMMCW), - mc_make_sid_security_cfg(SDMMCWAB), - mc_make_sid_security_cfg(VICSRD), - mc_make_sid_security_cfg(VICSWR), - mc_make_sid_security_cfg(VIW), - mc_make_sid_security_cfg(NVDECSRD), - mc_make_sid_security_cfg(NVDECSWR), - mc_make_sid_security_cfg(APER), - mc_make_sid_security_cfg(APEW), - mc_make_sid_security_cfg(NVJPGSRD), - mc_make_sid_security_cfg(NVJPGSWR), - mc_make_sid_security_cfg(SESRD), - mc_make_sid_security_cfg(SESWR), - mc_make_sid_security_cfg(AXIAPR), - mc_make_sid_security_cfg(AXIAPW), - mc_make_sid_security_cfg(ETRR), - mc_make_sid_security_cfg(ETRW), - mc_make_sid_security_cfg(TSECSRDB), - mc_make_sid_security_cfg(TSECSWRB), - mc_make_sid_security_cfg(AXISR), - mc_make_sid_security_cfg(AXISW), - mc_make_sid_security_cfg(EQOSR), - mc_make_sid_security_cfg(EQOSW), - mc_make_sid_security_cfg(UFSHCR), - mc_make_sid_security_cfg(UFSHCW), - mc_make_sid_security_cfg(NVDISPLAYR), - mc_make_sid_security_cfg(BPMPR), - mc_make_sid_security_cfg(BPMPW), - mc_make_sid_security_cfg(BPMPDMAR), - mc_make_sid_security_cfg(BPMPDMAW), - mc_make_sid_security_cfg(AONR), - mc_make_sid_security_cfg(AONW), - mc_make_sid_security_cfg(AONDMAR), - mc_make_sid_security_cfg(AONDMAW), - mc_make_sid_security_cfg(SCER), - mc_make_sid_security_cfg(SCEW), - mc_make_sid_security_cfg(SCEDMAR), - mc_make_sid_security_cfg(SCEDMAW), - mc_make_sid_security_cfg(APEDMAR), - mc_make_sid_security_cfg(APEDMAW), - mc_make_sid_security_cfg(NVDISPLAYR1), - mc_make_sid_security_cfg(VICSRD1), - mc_make_sid_security_cfg(NVDECSRD1), - mc_make_sid_security_cfg(VIFALR), - mc_make_sid_security_cfg(VIFALW), - mc_make_sid_security_cfg(DLA0RDA), - mc_make_sid_security_cfg(DLA0FALRDB), - mc_make_sid_security_cfg(DLA0WRA), - mc_make_sid_security_cfg(DLA0FALWRB), - mc_make_sid_security_cfg(DLA1RDA), - mc_make_sid_security_cfg(DLA1FALRDB), - mc_make_sid_security_cfg(DLA1WRA), - mc_make_sid_security_cfg(DLA1FALWRB), - mc_make_sid_security_cfg(PVA0RDA), - mc_make_sid_security_cfg(PVA0RDB), - mc_make_sid_security_cfg(PVA0RDC), - mc_make_sid_security_cfg(PVA0WRA), - mc_make_sid_security_cfg(PVA0WRB), - mc_make_sid_security_cfg(PVA0WRC), - mc_make_sid_security_cfg(PVA1RDA), - mc_make_sid_security_cfg(PVA1RDB), - mc_make_sid_security_cfg(PVA1RDC), - mc_make_sid_security_cfg(PVA1WRA), - mc_make_sid_security_cfg(PVA1WRB), - mc_make_sid_security_cfg(PVA1WRC), - mc_make_sid_security_cfg(RCER), - mc_make_sid_security_cfg(RCEW), - mc_make_sid_security_cfg(RCEDMAR), - mc_make_sid_security_cfg(RCEDMAW), - mc_make_sid_security_cfg(NVENC1SRD), - mc_make_sid_security_cfg(NVENC1SWR), - mc_make_sid_security_cfg(PCIE0R), - mc_make_sid_security_cfg(PCIE0W), - mc_make_sid_security_cfg(PCIE1R), - mc_make_sid_security_cfg(PCIE1W), - mc_make_sid_security_cfg(PCIE2AR), - mc_make_sid_security_cfg(PCIE2AW), - mc_make_sid_security_cfg(PCIE3R), - mc_make_sid_security_cfg(PCIE3W), - mc_make_sid_security_cfg(PCIE4R), - mc_make_sid_security_cfg(PCIE4W), - mc_make_sid_security_cfg(PCIE5R), - mc_make_sid_security_cfg(PCIE5W), - mc_make_sid_security_cfg(ISPFALW), - mc_make_sid_security_cfg(DLA0RDA1), - mc_make_sid_security_cfg(DLA1RDA1), - mc_make_sid_security_cfg(PVA0RDA1), - mc_make_sid_security_cfg(PVA0RDB1), - mc_make_sid_security_cfg(PVA1RDA1), - mc_make_sid_security_cfg(PVA1RDB1), - mc_make_sid_security_cfg(PCIE5R1), - mc_make_sid_security_cfg(NVENCSRD1), - mc_make_sid_security_cfg(NVENC1SRD1), - mc_make_sid_security_cfg(ISPRA1), - mc_make_sid_security_cfg(PCIE0R1), - mc_make_sid_security_cfg(MIU0R), - mc_make_sid_security_cfg(MIU0W), - mc_make_sid_security_cfg(MIU1R), - mc_make_sid_security_cfg(MIU1W), - mc_make_sid_security_cfg(MIU2R), - mc_make_sid_security_cfg(MIU2W), - mc_make_sid_security_cfg(MIU3R), - mc_make_sid_security_cfg(MIU3W), - mc_make_sid_override_cfg(HDAR), - mc_make_sid_override_cfg(HOST1XDMAR), - mc_make_sid_override_cfg(NVENCSRD), - mc_make_sid_override_cfg(SATAR), - mc_make_sid_override_cfg(NVENCSWR), - mc_make_sid_override_cfg(HDAW), - mc_make_sid_override_cfg(SATAW), - mc_make_sid_override_cfg(ISPRA), - mc_make_sid_override_cfg(ISPFALR), - mc_make_sid_override_cfg(ISPWA), - mc_make_sid_override_cfg(ISPWB), - mc_make_sid_override_cfg(XUSB_HOSTR), - mc_make_sid_override_cfg(XUSB_HOSTW), - mc_make_sid_override_cfg(XUSB_DEVR), - mc_make_sid_override_cfg(XUSB_DEVW), - mc_make_sid_override_cfg(TSECSRD), - mc_make_sid_override_cfg(TSECSWR), - mc_make_sid_override_cfg(SDMMCRA), - mc_make_sid_override_cfg(SDMMCR), - mc_make_sid_override_cfg(SDMMCRAB), - mc_make_sid_override_cfg(SDMMCWA), - mc_make_sid_override_cfg(SDMMCW), - mc_make_sid_override_cfg(SDMMCWAB), - mc_make_sid_override_cfg(VICSRD), - mc_make_sid_override_cfg(VICSWR), - mc_make_sid_override_cfg(VIW), - mc_make_sid_override_cfg(NVDECSRD), - mc_make_sid_override_cfg(NVDECSWR), - mc_make_sid_override_cfg(APER), - mc_make_sid_override_cfg(APEW), - mc_make_sid_override_cfg(NVJPGSRD), - mc_make_sid_override_cfg(NVJPGSWR), - mc_make_sid_override_cfg(SESRD), - mc_make_sid_override_cfg(SESWR), - mc_make_sid_override_cfg(AXIAPR), - mc_make_sid_override_cfg(AXIAPW), - mc_make_sid_override_cfg(ETRR), - mc_make_sid_override_cfg(ETRW), - mc_make_sid_override_cfg(TSECSRDB), - mc_make_sid_override_cfg(TSECSWRB), - mc_make_sid_override_cfg(AXISR), - mc_make_sid_override_cfg(AXISW), - mc_make_sid_override_cfg(EQOSR), - mc_make_sid_override_cfg(EQOSW), - mc_make_sid_override_cfg(UFSHCR), - mc_make_sid_override_cfg(UFSHCW), - mc_make_sid_override_cfg(NVDISPLAYR), - mc_make_sid_override_cfg(BPMPR), - mc_make_sid_override_cfg(BPMPW), - mc_make_sid_override_cfg(BPMPDMAR), - mc_make_sid_override_cfg(BPMPDMAW), - mc_make_sid_override_cfg(AONR), - mc_make_sid_override_cfg(AONW), - mc_make_sid_override_cfg(AONDMAR), - mc_make_sid_override_cfg(AONDMAW), - mc_make_sid_override_cfg(SCER), - mc_make_sid_override_cfg(SCEW), - mc_make_sid_override_cfg(SCEDMAR), - mc_make_sid_override_cfg(SCEDMAW), - mc_make_sid_override_cfg(APEDMAR), - mc_make_sid_override_cfg(APEDMAW), - mc_make_sid_override_cfg(NVDISPLAYR1), - mc_make_sid_override_cfg(VICSRD1), - mc_make_sid_override_cfg(NVDECSRD1), - mc_make_sid_override_cfg(VIFALR), - mc_make_sid_override_cfg(VIFALW), - mc_make_sid_override_cfg(DLA0RDA), - mc_make_sid_override_cfg(DLA0FALRDB), - mc_make_sid_override_cfg(DLA0WRA), - mc_make_sid_override_cfg(DLA0FALWRB), - mc_make_sid_override_cfg(DLA1RDA), - mc_make_sid_override_cfg(DLA1FALRDB), - mc_make_sid_override_cfg(DLA1WRA), - mc_make_sid_override_cfg(DLA1FALWRB), - mc_make_sid_override_cfg(PVA0RDA), - mc_make_sid_override_cfg(PVA0RDB), - mc_make_sid_override_cfg(PVA0RDC), - mc_make_sid_override_cfg(PVA0WRA), - mc_make_sid_override_cfg(PVA0WRB), - mc_make_sid_override_cfg(PVA0WRC), - mc_make_sid_override_cfg(PVA1RDA), - mc_make_sid_override_cfg(PVA1RDB), - mc_make_sid_override_cfg(PVA1RDC), - mc_make_sid_override_cfg(PVA1WRA), - mc_make_sid_override_cfg(PVA1WRB), - mc_make_sid_override_cfg(PVA1WRC), - mc_make_sid_override_cfg(RCER), - mc_make_sid_override_cfg(RCEW), - mc_make_sid_override_cfg(RCEDMAR), - mc_make_sid_override_cfg(RCEDMAW), - mc_make_sid_override_cfg(NVENC1SRD), - mc_make_sid_override_cfg(NVENC1SWR), - mc_make_sid_override_cfg(PCIE0R), - mc_make_sid_override_cfg(PCIE0W), - mc_make_sid_override_cfg(PCIE1R), - mc_make_sid_override_cfg(PCIE1W), - mc_make_sid_override_cfg(PCIE2AR), - mc_make_sid_override_cfg(PCIE2AW), - mc_make_sid_override_cfg(PCIE3R), - mc_make_sid_override_cfg(PCIE3W), - mc_make_sid_override_cfg(PCIE4R), - mc_make_sid_override_cfg(PCIE4W), - mc_make_sid_override_cfg(PCIE5R), - mc_make_sid_override_cfg(PCIE5W), - mc_make_sid_override_cfg(ISPFALW), - mc_make_sid_override_cfg(DLA0RDA1), - mc_make_sid_override_cfg(DLA1RDA1), - mc_make_sid_override_cfg(PVA0RDA1), - mc_make_sid_override_cfg(PVA0RDB1), - mc_make_sid_override_cfg(PVA1RDA1), - mc_make_sid_override_cfg(PVA1RDB1), - mc_make_sid_override_cfg(PCIE5R1), - mc_make_sid_override_cfg(NVENCSRD1), - mc_make_sid_override_cfg(NVENC1SRD1), - mc_make_sid_override_cfg(ISPRA1), - mc_make_sid_override_cfg(PCIE0R1), - mc_make_sid_override_cfg(MIU0R), - mc_make_sid_override_cfg(MIU0W), - mc_make_sid_override_cfg(MIU1R), - mc_make_sid_override_cfg(MIU1W), - mc_make_sid_override_cfg(MIU2R), - mc_make_sid_override_cfg(MIU2W), - mc_make_sid_override_cfg(MIU3R), - mc_make_sid_override_cfg(MIU3W), - smmu_make_cfg(TEGRA_SMMU0_BASE), - smmu_make_cfg(TEGRA_SMMU2_BASE), - smmu_bypass_cfg, /* TBU settings */ - _END_OF_TABLE_, -}; - -/******************************************************************************* - * Handler to return the pointer to the SMMU's context struct - ******************************************************************************/ -smmu_regs_t *plat_get_smmu_ctx(void) -{ - /* index of _END_OF_TABLE_ */ - tegra194_smmu_context[0].val = (uint32_t)ARRAY_SIZE(tegra194_smmu_context) - 1U; - - return tegra194_smmu_context; -} - -/******************************************************************************* * Handler to return the support SMMU devices number ******************************************************************************/ uint32_t plat_get_num_smmu_devices(void) diff --git a/plat/nvidia/tegra/soc/t194/plat_trampoline.S b/plat/nvidia/tegra/soc/t194/plat_trampoline.S index 540c2019c..819920f02 100644 --- a/plat/nvidia/tegra/soc/t194/plat_trampoline.S +++ b/plat/nvidia/tegra/soc/t194/plat_trampoline.S @@ -12,7 +12,7 @@ #define TEGRA194_STATE_SYSTEM_SUSPEND 0x5C7 #define TEGRA194_STATE_SYSTEM_RESUME 0x600D -#define TEGRA194_SMMU_CTX_SIZE 0x80D +#define TEGRA194_MC_CTX_SIZE 0xFB .align 4 .globl tegra194_cpu_reset_handler @@ -69,8 +69,8 @@ endfunc tegra194_cpu_reset_handler * * 0x0000: secure world's entrypoint * 0x0008: BL31 size (RO + RW) - * 0x0010: SMMU context start - * 0x2490: SMMU context end + * 0x0010: MC context start + * 0x2490: MC context end */ .align 4 @@ -79,14 +79,13 @@ endfunc tegra194_cpu_reset_handler __tegra194_cpu_reset_handler_data: .quad tegra_secure_entrypoint .quad __BL31_END__ - BL31_BASE - .globl __tegra194_system_suspend_state __tegra194_system_suspend_state: .quad 0 .align 4 -__tegra194_smmu_context: - .rept TEGRA194_SMMU_CTX_SIZE +__tegra194_mc_context: + .rept TEGRA194_MC_CTX_SIZE .quad 0 .endr .size __tegra194_cpu_reset_handler_data, \ @@ -98,7 +97,7 @@ __tegra194_cpu_reset_handler_end: .globl tegra194_get_cpu_reset_handler_size .globl tegra194_get_cpu_reset_handler_base - .globl tegra194_get_smmu_ctx_offset + .globl tegra194_get_mc_ctx_offset .globl tegra194_set_system_suspend_entry /* return size of the CPU reset handler */ @@ -115,13 +114,13 @@ func tegra194_get_cpu_reset_handler_base ret endfunc tegra194_get_cpu_reset_handler_base -/* return the size of the SMMU context */ -func tegra194_get_smmu_ctx_offset - adr x0, __tegra194_smmu_context +/* return the size of the MC context */ +func tegra194_get_mc_ctx_offset + adr x0, __tegra194_mc_context adr x1, tegra194_cpu_reset_handler sub x0, x0, x1 ret -endfunc tegra194_get_smmu_ctx_offset +endfunc tegra194_get_mc_ctx_offset /* set system suspend state before SC7 entry */ func tegra194_set_system_suspend_entry diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c index 635018dbc..48608583d 100644 --- a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c +++ b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c @@ -927,17 +927,12 @@ static void tegra_se_enable_clocks(void) val &= ~ENTROPY_RESET_BIT; mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_RST_DEVICES_W, val); - if (!tegra_chipid_is_t210_b01()) { - - /* - * T210 SE clock source is turned off in kernel, to simplify - * SE clock source setting, we switch SE clock source to - * CLK_M, SE_CLK_DIVISOR = 0. T210 B01 SE clock source is - * always on, so don't need this setting. - */ - mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_RST_CTL_CLK_SRC_SE, - SE_CLK_SRC_CLK_M); - } + /* + * Switch SE clock source to CLK_M, to make sure SE clock + * is on when saving SE context + */ + mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_RST_CTL_CLK_SRC_SE, + SE_CLK_SRC_CLK_M); /* Enable SE clock */ val = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_CLK_OUT_ENB_V); diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c index 933e925ec..6d014bf2c 100644 --- a/plat/nvidia/tegra/soc/t210/plat_setup.c +++ b/plat/nvidia/tegra/soc/t210/plat_setup.c @@ -179,6 +179,8 @@ void plat_early_platform_setup(void) /* Secure IRQs for Tegra186 */ static const interrupt_prop_t tegra210_interrupt_props[] = { + INTR_PROP_DESC(TEGRA210_TIMER1_IRQ, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), INTR_PROP_DESC(TEGRA210_WDT_CPU_LEGACY_FIQ, GIC_HIGHEST_SEC_PRIORITY, GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), }; diff --git a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c index 7d26fe795..904f8d62e 100644 --- a/plat/nvidia/tegra/soc/t210/plat_sip_calls.c +++ b/plat/nvidia/tegra/soc/t210/plat_sip_calls.c @@ -88,7 +88,6 @@ int plat_sip_handler(uint32_t smc_fid, return -EINVAL; } } else { - ERROR("%s: unsupported function ID\n", __func__); return -ENOTSUP; } return 0; diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk index 928d69a71..6aa198c33 100644 --- a/plat/qemu/qemu/platform.mk +++ b/plat/qemu/qemu/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -140,6 +140,8 @@ QEMU_GICV2_SOURCES := drivers/arm/gic/v2/gicv2_helpers.c \ ${PLAT_QEMU_COMMON_PATH}/qemu_gicv2.c QEMU_GICV3_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/common/gic_common.c \ plat/common/plat_gicv3.c \ diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk index 51832d0ff..6ad3d8bbf 100644 --- a/plat/qemu/qemu_sbsa/platform.mk +++ b/plat/qemu/qemu_sbsa/platform.mk @@ -63,6 +63,8 @@ BL2_SOURCES += ${PLAT_QEMU_COMMON_PATH}/qemu_bl2_mem_params_desc.c \ endif QEMU_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/common/gic_common.c \ plat/common/plat_gicv3.c \ diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk index 5a23d3c71..0dc1840c9 100644 --- a/plat/rockchip/rk3399/platform.mk +++ b/plat/rockchip/rk3399/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2016-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -29,6 +29,8 @@ RK_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/gic500.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ plat/common/plat_gicv3.c \ ${RK_PLAT}/common/rockchip_gicv3.c diff --git a/plat/rpi/common/include/rpi_shared.h b/plat/rpi/common/include/rpi_shared.h index de8357162..686343892 100644 --- a/plat/rpi/common/include/rpi_shared.h +++ b/plat/rpi/common/include/rpi_shared.h @@ -14,7 +14,7 @@ ******************************************************************************/ /* Utility functions */ -void rpi3_console_init(unsigned int base_clk_rate); +void rpi3_console_init(void); void rpi3_setup_page_tables(uintptr_t total_base, size_t total_size, uintptr_t code_start, uintptr_t code_limit, uintptr_t rodata_start, uintptr_t rodata_limit diff --git a/plat/rpi/common/rpi3_common.c b/plat/rpi/common/rpi3_common.c index 27281f2ba..ef88bf10e 100644 --- a/plat/rpi/common/rpi3_common.c +++ b/plat/rpi/common/rpi3_common.c @@ -13,7 +13,9 @@ #include <common/debug.h> #include <bl31/interrupt_mgmt.h> #include <drivers/console.h> +#include <drivers/rpi3/gpio/rpi3_gpio.h> #include <drivers/ti/uart/uart_16550.h> +#include <drivers/arm/pl011.h> #include <lib/xlat_tables/xlat_tables_v2.h> #include <rpi_hw.h> @@ -104,16 +106,33 @@ static const mmap_region_t plat_rpi3_mmap[] = { ******************************************************************************/ static console_t rpi3_console; -void rpi3_console_init(unsigned int base_clk_rate) + +static bool rpi3_use_mini_uart(void) +{ + return rpi3_gpio_get_select(14) == RPI3_GPIO_FUNC_ALT5; +} + +void rpi3_console_init(void) { int console_scope = CONSOLE_FLAG_BOOT; -#if RPI3_RUNTIME_UART != -1 - console_scope |= CONSOLE_FLAG_RUNTIME; -#endif - int rc = console_16550_register(PLAT_RPI3_UART_BASE, - base_clk_rate, - PLAT_RPI3_UART_BAUDRATE, - &rpi3_console); + int rc; + + if (RPI3_RUNTIME_UART != -1) + console_scope |= CONSOLE_FLAG_RUNTIME; + + rpi3_gpio_init(); + + if (rpi3_use_mini_uart()) + rc = console_16550_register(PLAT_RPI_MINI_UART_BASE, + 0, + PLAT_RPI_UART_BAUDRATE, + &rpi3_console); + else + rc = console_pl011_register(PLAT_RPI_PL011_UART_BASE, + PLAT_RPI_PL011_UART_CLOCK, + PLAT_RPI_UART_BAUDRATE, + &rpi3_console); + if (rc == 0) { /* * The crash console doesn't use the multi console API, it uses diff --git a/plat/rpi/rpi3/aarch64/plat_helpers.S b/plat/rpi/rpi3/aarch64/plat_helpers.S index 24278bdf6..ab925b6c0 100644 --- a/plat/rpi/rpi3/aarch64/plat_helpers.S +++ b/plat/rpi/rpi3/aarch64/plat_helpers.S @@ -9,8 +9,6 @@ #include <assert_macros.S> #include <platform_def.h> -#include "../include/rpi_hw.h" - .globl plat_crash_console_flush .globl plat_crash_console_init .globl plat_crash_console_putc @@ -133,9 +131,9 @@ endfunc platform_mem_init * --------------------------------------------- */ func plat_crash_console_init - mov_imm x0, PLAT_RPI3_UART_BASE - mov_imm x1, PLAT_RPI3_UART_CLK_IN_HZ - mov_imm x2, PLAT_RPI3_UART_BAUDRATE + mov_imm x0, PLAT_RPI_MINI_UART_BASE + mov x1, xzr + mov x2, xzr b console_16550_core_init endfunc plat_crash_console_init @@ -147,7 +145,7 @@ endfunc plat_crash_console_init * --------------------------------------------- */ func plat_crash_console_putc - mov_imm x1, PLAT_RPI3_UART_BASE + mov_imm x1, PLAT_RPI_MINI_UART_BASE b console_16550_core_putc endfunc plat_crash_console_putc @@ -160,6 +158,6 @@ endfunc plat_crash_console_putc * --------------------------------------------- */ func plat_crash_console_flush - mov_imm x0, PLAT_RPI3_UART_BASE + mov_imm x0, PLAT_RPI_MINI_UART_BASE b console_16550_core_flush endfunc plat_crash_console_flush diff --git a/plat/rpi/rpi3/include/platform_def.h b/plat/rpi/rpi3/include/platform_def.h index e308f70a6..9cacd9915 100644 --- a/plat/rpi/rpi3/include/platform_def.h +++ b/plat/rpi/rpi3/include/platform_def.h @@ -249,9 +249,10 @@ /* * Serial-related constants. */ -#define PLAT_RPI3_UART_BASE RPI3_MINI_UART_BASE -#define PLAT_RPI3_UART_CLK_IN_HZ RPI3_MINI_UART_CLK_IN_HZ -#define PLAT_RPI3_UART_BAUDRATE ULL(115200) +#define PLAT_RPI_MINI_UART_BASE RPI3_MINI_UART_BASE +#define PLAT_RPI_PL011_UART_BASE RPI3_PL011_UART_BASE +#define PLAT_RPI_PL011_UART_CLOCK RPI3_PL011_UART_CLOCK +#define PLAT_RPI_UART_BAUDRATE ULL(115200) /* * System counter diff --git a/plat/rpi/rpi3/include/rpi_hw.h b/plat/rpi/rpi3/include/rpi_hw.h index 01d5b4a0f..2aecab379 100644 --- a/plat/rpi/rpi3/include/rpi_hw.h +++ b/plat/rpi/rpi3/include/rpi_hw.h @@ -77,11 +77,15 @@ #define RPI3_RNG_INT_MASK_DISABLE U(0x1) /* - * Serial port (called 'Mini UART' in the BCM docucmentation). + * Serial ports: + * 'Mini UART' in the BCM docucmentation is the 8250 compatible UART. + * There is also a PL011 UART, multiplexed to the same pins. */ #define RPI3_IO_MINI_UART_OFFSET ULL(0x00215040) #define RPI3_MINI_UART_BASE (RPI_IO_BASE + RPI3_IO_MINI_UART_OFFSET) -#define RPI3_MINI_UART_CLK_IN_HZ ULL(500000000) +#define RPI3_IO_PL011_UART_OFFSET ULL(0x00201000) +#define RPI3_PL011_UART_BASE (RPI_IO_BASE + RPI3_IO_PL011_UART_OFFSET) +#define RPI3_PL011_UART_CLOCK ULL(48000000) /* * GPIO controller diff --git a/plat/rpi/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk index a21a7709a..a5b8904d5 100644 --- a/plat/rpi/rpi3/platform.mk +++ b/plat/rpi/rpi3/platform.mk @@ -11,6 +11,10 @@ PLAT_INCLUDES := -Iplat/rpi/common/include \ -Iplat/rpi/rpi3/include PLAT_BL_COMMON_SOURCES := drivers/ti/uart/aarch64/16550_console.S \ + drivers/arm/pl011/aarch64/pl011_console.S \ + drivers/gpio/gpio.c \ + drivers/delay_timer/delay_timer.c \ + drivers/rpi3/gpio/rpi3_gpio.c \ plat/rpi/common/rpi3_common.c \ ${XLAT_TABLES_LIB_SRCS} @@ -29,10 +33,7 @@ BL2_SOURCES += common/desc_image_load.c \ drivers/io/io_fip.c \ drivers/io/io_memmap.c \ drivers/io/io_storage.c \ - drivers/gpio/gpio.c \ - drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ - drivers/rpi3/gpio/rpi3_gpio.c \ drivers/io/io_block.c \ drivers/mmc/mmc.c \ drivers/rpi3/sdhost/rpi3_sdhost.c \ diff --git a/plat/rpi/rpi3/rpi3_bl1_setup.c b/plat/rpi/rpi3/rpi3_bl1_setup.c index dcce76e47..3ac30e0f0 100644 --- a/plat/rpi/rpi3/rpi3_bl1_setup.c +++ b/plat/rpi/rpi3/rpi3_bl1_setup.c @@ -35,7 +35,7 @@ void bl1_early_platform_setup(void) 0x80000000); /* Initialize the console to provide early debug support */ - rpi3_console_init(PLAT_RPI3_UART_CLK_IN_HZ); + rpi3_console_init(); /* Allow BL1 to see the whole Trusted RAM */ bl1_tzram_layout.total_base = BL_RAM_BASE; diff --git a/plat/rpi/rpi3/rpi3_bl2_setup.c b/plat/rpi/rpi3/rpi3_bl2_setup.c index 44827c63a..db7181794 100644 --- a/plat/rpi/rpi3/rpi3_bl2_setup.c +++ b/plat/rpi/rpi3/rpi3_bl2_setup.c @@ -24,17 +24,6 @@ /* Data structure which holds the extents of the trusted SRAM for BL2 */ static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); -/* rpi3 GPIO setup function. */ -static void rpi3_gpio_setup(void) -{ - struct rpi3_gpio_params params; - - memset(¶ms, 0, sizeof(struct rpi3_gpio_params)); - params.reg_base = RPI3_GPIO_BASE; - - rpi3_gpio_init(¶ms); -} - /* Data structure which holds the MMC info */ static struct mmc_device_info mmc_info; @@ -62,13 +51,13 @@ void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, meminfo_t *mem_layout = (meminfo_t *) arg1; /* Initialize the console to provide early debug support */ - rpi3_console_init(PLAT_RPI3_UART_CLK_IN_HZ); + rpi3_console_init(); /* Enable arch timer */ generic_delay_timer_init(); /* Setup GPIO driver */ - rpi3_gpio_setup(); + rpi3_gpio_init(); /* Setup the BL2 memory layout */ bl2_tzram_layout = *mem_layout; diff --git a/plat/rpi/rpi3/rpi3_bl31_setup.c b/plat/rpi/rpi3/rpi3_bl31_setup.c index 24a56139b..59157536b 100644 --- a/plat/rpi/rpi3/rpi3_bl31_setup.c +++ b/plat/rpi/rpi3/rpi3_bl31_setup.c @@ -72,7 +72,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, { /* Initialize the console to provide early debug support */ - rpi3_console_init(PLAT_RPI3_UART_CLK_IN_HZ); + rpi3_console_init(); /* * In debug builds, a special value is passed in 'arg1' to verify diff --git a/plat/rpi/rpi4/aarch64/plat_helpers.S b/plat/rpi/rpi4/aarch64/plat_helpers.S index 083c30e71..fac1b2075 100644 --- a/plat/rpi/rpi4/aarch64/plat_helpers.S +++ b/plat/rpi/rpi4/aarch64/plat_helpers.S @@ -10,8 +10,6 @@ #include <platform_def.h> #include <cortex_a72.h> -#include "../include/rpi_hw.h" - .globl plat_crash_console_flush .globl plat_crash_console_init .globl plat_crash_console_putc @@ -135,7 +133,7 @@ endfunc platform_mem_init * --------------------------------------------- */ func plat_crash_console_init - mov_imm x0, PLAT_RPI3_UART_BASE + mov_imm x0, PLAT_RPI_MINI_UART_BASE mov x1, xzr mov x2, xzr b console_16550_core_init @@ -149,7 +147,7 @@ endfunc plat_crash_console_init * --------------------------------------------- */ func plat_crash_console_putc - mov_imm x1, PLAT_RPI3_UART_BASE + mov_imm x1, PLAT_RPI_MINI_UART_BASE b console_16550_core_putc endfunc plat_crash_console_putc @@ -162,7 +160,7 @@ endfunc plat_crash_console_putc * --------------------------------------------- */ func plat_crash_console_flush - mov_imm x0, PLAT_RPI3_UART_BASE + mov_imm x0, PLAT_RPI_MINI_UART_BASE b console_16550_core_flush endfunc plat_crash_console_flush diff --git a/plat/rpi/rpi4/include/platform_def.h b/plat/rpi/rpi4/include/platform_def.h index a9ecdba20..6f6bbbe7a 100644 --- a/plat/rpi/rpi4/include/platform_def.h +++ b/plat/rpi/rpi4/include/platform_def.h @@ -126,8 +126,10 @@ /* * Serial-related constants. */ -#define PLAT_RPI3_UART_BASE RPI3_MINI_UART_BASE -#define PLAT_RPI3_UART_BAUDRATE ULL(115200) +#define PLAT_RPI_MINI_UART_BASE RPI4_MINI_UART_BASE +#define PLAT_RPI_PL011_UART_BASE RPI4_PL011_UART_BASE +#define PLAT_RPI_PL011_UART_CLOCK RPI4_PL011_UART_CLOCK +#define PLAT_RPI_UART_BAUDRATE ULL(115200) /* * System counter diff --git a/plat/rpi/rpi4/include/rpi_hw.h b/plat/rpi/rpi4/include/rpi_hw.h index b1dd4e92e..718510610 100644 --- a/plat/rpi/rpi4/include/rpi_hw.h +++ b/plat/rpi/rpi4/include/rpi_hw.h @@ -77,10 +77,15 @@ #define RPI3_RNG_INT_MASK_DISABLE U(0x1) /* - * Serial port (called 'Mini UART' in the Broadcom documentation). + * Serial ports: + * 'Mini UART' in the BCM docucmentation is the 8250 compatible UART. + * There is also a PL011 UART, multiplexed to the same pins. */ -#define RPI3_IO_MINI_UART_OFFSET ULL(0x00215040) -#define RPI3_MINI_UART_BASE (RPI_IO_BASE + RPI3_IO_MINI_UART_OFFSET) +#define RPI4_IO_MINI_UART_OFFSET ULL(0x00215040) +#define RPI4_MINI_UART_BASE (RPI_IO_BASE + RPI4_IO_MINI_UART_OFFSET) +#define RPI4_IO_PL011_UART_OFFSET ULL(0x00201000) +#define RPI4_PL011_UART_BASE (RPI_IO_BASE + RPI4_IO_PL011_UART_OFFSET) +#define RPI4_PL011_UART_CLOCK ULL(48000000) /* * GPIO controller diff --git a/plat/rpi/rpi4/platform.mk b/plat/rpi/rpi4/platform.mk index 2038021a0..49e78dfed 100644 --- a/plat/rpi/rpi4/platform.mk +++ b/plat/rpi/rpi4/platform.mk @@ -11,6 +11,7 @@ PLAT_INCLUDES := -Iplat/rpi/common/include \ -Iplat/rpi/rpi4/include PLAT_BL_COMMON_SOURCES := drivers/ti/uart/aarch64/16550_console.S \ + drivers/arm/pl011/aarch64/pl011_console.S \ plat/rpi/common/rpi3_common.c \ ${XLAT_TABLES_LIB_SRCS} @@ -20,6 +21,9 @@ BL31_SOURCES += lib/cpus/aarch64/cortex_a72.S \ drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v2/gicv2_helpers.c \ drivers/arm/gic/v2/gicv2_main.c \ + drivers/delay_timer/delay_timer.c \ + drivers/gpio/gpio.c \ + drivers/rpi3/gpio/rpi3_gpio.c \ plat/common/plat_gicv2.c \ plat/rpi/rpi4/rpi4_bl31_setup.c \ plat/rpi/common/rpi3_pm.c \ diff --git a/plat/rpi/rpi4/rpi4_bl31_setup.c b/plat/rpi/rpi4/rpi4_bl31_setup.c index 9e3b53979..0a49d81b2 100644 --- a/plat/rpi/rpi4/rpi4_bl31_setup.c +++ b/plat/rpi/rpi4/rpi4_bl31_setup.c @@ -132,14 +132,8 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, /* Early GPU firmware revisions need a little break here. */ ldelay(100000); - /* - * Initialize the console to provide early debug support. - * We rely on the GPU firmware to have initialised the UART correctly, - * as the baud base clock rate differs across GPU firmware revisions. - * Providing a base clock of 0 lets the 16550 UART init routine skip - * the initial enablement and baud rate setup. - */ - rpi3_console_init(0); + /* Initialize the console to provide early debug support. */ + rpi3_console_init(); bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); bl33_image_ep_info.spsr = rpi3_get_spsr_for_bl33_entry(); diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk index ab1f69e68..0d9071b32 100644 --- a/plat/socionext/synquacer/platform.mk +++ b/plat/socionext/synquacer/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -33,6 +33,8 @@ PLAT_BL_COMMON_SOURCES += $(PLAT_PATH)/sq_helpers.S \ BL31_SOURCES += drivers/arm/ccn/ccn.c \ drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/gicv3_main.c \ lib/cpus/aarch64/cortex_a53.S \ plat/common/plat_gicv3.c \ diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk index 8e96b68bb..a014f528f 100644 --- a/plat/socionext/uniphier/platform.mk +++ b/plat/socionext/uniphier/platform.mk @@ -58,6 +58,8 @@ BL2_SOURCES += common/desc_image_load.c \ BL31_SOURCES += drivers/arm/cci/cci.c \ drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/gic/v3/gicv3_main.c \ lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a72.S \ diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk index 7956497ae..587b44bc3 100644 --- a/plat/ti/k3/common/plat_common.mk +++ b/plat/ti/k3/common/plat_common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -57,6 +57,8 @@ K3_GIC_SOURCES += \ drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ plat/common/plat_gicv3.c \ ${PLAT_PATH}/common/k3_gicv3.c \ diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk index 1e231cce8..5d7fd697f 100644 --- a/plat/xilinx/versal/platform.mk +++ b/plat/xilinx/versal/platform.mk @@ -52,6 +52,8 @@ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \ drivers/arm/gic/v3/gic500.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicdv3_helpers.c \ + drivers/arm/gic/v3/gicrv3_helpers.c \ drivers/arm/pl011/aarch64/pl011_console.S \ plat/common/aarch64/crash_console_helpers.S \ plat/arm/common/arm_cci.c \ diff --git a/services/arm_arch_svc/arm_arch_svc_setup.c b/services/arm_arch_svc/arm_arch_svc_setup.c index 6dac56ec8..ba539309d 100644 --- a/services/arm_arch_svc/arm_arch_svc_setup.c +++ b/services/arm_arch_svc/arm_arch_svc_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,18 +12,27 @@ #include <lib/smccc.h> #include <services/arm_arch_svc.h> #include <smccc_helpers.h> +#include <plat/common/platform.h> static int32_t smccc_version(void) { return MAKE_SMCCC_VERSION(SMCCC_MAJOR_VERSION, SMCCC_MINOR_VERSION); } -static int32_t smccc_arch_features(u_register_t arg) +static int32_t smccc_arch_features(u_register_t arg1, u_register_t arg2) { - switch (arg) { + switch (arg1) { case SMCCC_VERSION: case SMCCC_ARCH_FEATURES: return SMC_OK; + case SMCCC_ARCH_SOC_ID: + if (arg2 == SMCCC_GET_SOC_REVISION) { + return plat_get_soc_revision(); + } + if (arg2 == SMCCC_GET_SOC_VERSION) { + return plat_get_soc_version(); + } + return SMC_ARCH_CALL_INVAL_PARAM; #if WORKAROUND_CVE_2017_5715 case SMCCC_ARCH_WORKAROUND_1: if (check_wa_cve_2017_5715() == ERRATA_NOT_APPLIES) @@ -94,7 +103,7 @@ static uintptr_t arm_arch_svc_smc_handler(uint32_t smc_fid, case SMCCC_VERSION: SMC_RET1(handle, smccc_version()); case SMCCC_ARCH_FEATURES: - SMC_RET1(handle, smccc_arch_features(x1)); + SMC_RET1(handle, smccc_arch_features(x1, x2)); #if WORKAROUND_CVE_2017_5715 case SMCCC_ARCH_WORKAROUND_1: /* diff --git a/services/spd/tlkd/tlkd_main.c b/services/spd/tlkd/tlkd_main.c index 3cfc52db4..481bb69e3 100644 --- a/services/spd/tlkd/tlkd_main.c +++ b/services/spd/tlkd/tlkd_main.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,6 +15,7 @@ * responsible for initialising and maintaining communication with the SP. ******************************************************************************/ #include <assert.h> +#include <bl31/interrupt_mgmt.h> #include <errno.h> #include <stddef.h> @@ -49,6 +51,50 @@ DEFINE_SVC_UUID2(tlk_uuid, static int32_t tlkd_init(void); /******************************************************************************* + * Secure Payload Dispatcher's timer interrupt handler + ******************************************************************************/ +static uint64_t tlkd_interrupt_handler(uint32_t id, + uint32_t flags, + void *handle, + void *cookie) +{ + cpu_context_t *s_cpu_context; + int irq = plat_ic_get_pending_interrupt_id(); + + /* acknowledge the interrupt and mark it complete */ + (void)plat_ic_acknowledge_interrupt(); + plat_ic_end_of_interrupt(irq); + + /* + * Disable the routing of NS interrupts from secure world to + * EL3 while interrupted on this core. + */ + disable_intr_rm_local(INTR_TYPE_S_EL1, SECURE); + + /* Check the security state when the exception was generated */ + assert(get_interrupt_src_ss(flags) == NON_SECURE); + assert(handle == cm_get_context(NON_SECURE)); + + /* Save non-secure state */ + cm_el1_sysregs_context_save(NON_SECURE); + + /* Get a reference to the secure context */ + s_cpu_context = cm_get_context(SECURE); + assert(s_cpu_context); + + /* + * Restore non-secure state. There is no need to save the + * secure system register context since the SP was supposed + * to preserve it during S-EL1 interrupt handling. + */ + cm_el1_sysregs_context_restore(SECURE); + cm_set_next_eret_context(SECURE); + + /* Provide the IRQ number to the SPD */ + SMC_RET4(s_cpu_context, (uint32_t)TLK_IRQ_FIRED, 0, (uint32_t)irq, 0); +} + +/******************************************************************************* * Secure Payload Dispatcher setup. The SPD finds out the SP entrypoint and type * (aarch32/aarch64) if not already known and initialises the context for entry * into the SP for its initialisation. @@ -56,6 +102,8 @@ static int32_t tlkd_init(void); static int32_t tlkd_setup(void) { entry_point_info_t *tlk_ep_info; + uint32_t flags; + int32_t ret; /* * Get information about the Secure Payload (BL32) image. Its @@ -86,6 +134,18 @@ static int32_t tlkd_setup(void) tlk_ep_info->pc, &tlk_ctx); + /* get a list of all S-EL1 IRQs from the platform */ + + /* register interrupt handler */ + flags = 0; + set_interrupt_rm_flag(flags, NON_SECURE); + ret = register_interrupt_type_handler(INTR_TYPE_S_EL1, + tlkd_interrupt_handler, + flags); + if (ret != 0) { + ERROR("failed to register tlkd interrupt handler (%d)\n", ret); + } + /* * All TLK SPD initialization done. Now register our init function * with BL31 for deferred invocation @@ -370,7 +430,6 @@ static uintptr_t tlkd_smc_handler(uint32_t smc_fid, */ case TLK_SUSPEND_DONE: case TLK_RESUME_DONE: - case TLK_SYSTEM_OFF_DONE: if (ns) SMC_RET1(handle, SMC_UNK); @@ -385,6 +444,34 @@ static uintptr_t tlkd_smc_handler(uint32_t smc_fid, break; /* + * This function ID is used by SP to indicate that it has completed + * handling the secure interrupt. + */ + case TLK_IRQ_DONE: + + if (ns) + SMC_RET1(handle, SMC_UNK); + + assert(handle == cm_get_context(SECURE)); + + /* save secure world context */ + cm_el1_sysregs_context_save(SECURE); + + /* Get a reference to the non-secure context */ + ns_cpu_context = cm_get_context(NON_SECURE); + assert(ns_cpu_context); + + /* + * Restore non-secure state. There is no need to save the + * secure system register context since the SP was supposed + * to preserve it during S-EL1 interrupt handling. + */ + cm_el1_sysregs_context_restore(NON_SECURE); + cm_set_next_eret_context(NON_SECURE); + + SMC_RET0(ns_cpu_context); + + /* * Return the number of service function IDs implemented to * provide service to non-secure */ diff --git a/services/spd/tlkd/tlkd_pm.c b/services/spd/tlkd/tlkd_pm.c index 7d1959bce..ed5bf7761 100644 --- a/services/spd/tlkd/tlkd_pm.c +++ b/services/spd/tlkd/tlkd_pm.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -98,29 +99,6 @@ static void cpu_resume_handler(u_register_t suspend_level) } /******************************************************************************* - * System is about to be reset. Inform the SP to allow any book-keeping - ******************************************************************************/ -static void system_off_handler(void) -{ - int cpu = read_mpidr() & MPIDR_CPU_MASK; - gp_regs_t *gp_regs; - - /* TLK runs only on CPU0 */ - if (cpu != 0) - return; - - /* pass system off/reset events to TLK */ - gp_regs = get_gpregs_ctx(&tlk_ctx.cpu_ctx); - write_ctx_reg(gp_regs, CTX_GPREG_X0, TLK_SYSTEM_OFF); - - /* - * Enter the SP. We do not care about the return value because we - * must continue with the shutdown anyway. - */ - (void)tlkd_synchronous_sp_entry(&tlk_ctx); -} - -/******************************************************************************* * Structure populated by the Dispatcher to be given a chance to perform any * bookkeeping before PSCI executes a power mgmt. operation. ******************************************************************************/ @@ -128,6 +106,4 @@ const spd_pm_ops_t tlkd_pm_ops = { .svc_migrate_info = cpu_migrate_info, .svc_suspend = cpu_suspend_handler, .svc_suspend_finish = cpu_resume_handler, - .svc_system_off = system_off_handler, - .svc_system_reset = system_off_handler }; diff --git a/services/spd/trusty/trusty.c b/services/spd/trusty/trusty.c index ba2f4a6e4..b10da7679 100644 --- a/services/spd/trusty/trusty.c +++ b/services/spd/trusty/trusty.c @@ -413,7 +413,7 @@ static int32_t trusty_setup(void) /* Get trusty's entry point info */ ep_info = bl31_plat_get_next_image_ep_info(SECURE); if (ep_info == NULL) { - INFO("Trusty image missing.\n"); + VERBOSE("Trusty image missing.\n"); return -1; } @@ -466,7 +466,7 @@ static int32_t trusty_setup(void) trusty_fiq_handler, flags); if (ret != 0) { - ERROR("trusty: failed to register fiq handler, ret = %d\n", ret); + VERBOSE("trusty: failed to register fiq handler, ret = %d\n", ret); } if (aarch32) { diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 2cdf4f5ff..a3e1a2d57 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -162,6 +162,16 @@ static int spmd_spmc_init(void *rd_base, size_t rd_size) INFO("SPM core run time EL%x.\n", SPMD_SPM_AT_SEL2 ? MODE_EL2 : MODE_EL1); + /* Validate the SPMC ID, Ensure high bit is set */ + if (!(spmc_attrs.spmc_id >> SPMC_SECURE_ID_SHIFT) & + SPMC_SECURE_ID_MASK) { + WARN("Invalid ID (0x%x) for SPMC.\n", + spmc_attrs.spmc_id); + return 1; + } + + INFO("SPMC ID %x.\n", spmc_attrs.spmc_id); + /* Validate the SPM core execution state */ if ((spmc_attrs.exec_state != MODE_RW_64) && (spmc_attrs.exec_state != MODE_RW_32)) { @@ -436,6 +446,26 @@ uint64_t spmd_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, break; /* not reached */ + case SPCI_ID_GET: + /* + * Returns the ID of the calling SPCI component. + */ + if (!secure_origin) { + SMC_RET8(handle, SPCI_SUCCESS_SMC32, + SPCI_TARGET_INFO_MBZ, SPCI_NS_ENDPOINT_ID, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ); + } else { + SMC_RET8(handle, SPCI_SUCCESS_SMC32, + SPCI_TARGET_INFO_MBZ, spmc_attrs.spmc_id, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ); + } + + break; /* not reached */ + case SPCI_RX_RELEASE: case SPCI_RXTX_MAP_SMC32: case SPCI_RXTX_MAP_SMC64: diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h index 61b479a8b..0ad35c7c1 100644 --- a/services/std_svc/spmd/spmd_private.h +++ b/services/std_svc/spmd/spmd_private.h @@ -55,6 +55,15 @@ typedef struct spmd_spm_core_context { } spmd_spm_core_context_t; /* + * Reserve ID for NS physical SPCI Endpoint. + */ +#define SPCI_NS_ENDPOINT_ID U(0) + +/* Mask and shift to check valid secure SPCI Endpoint ID. */ +#define SPMC_SECURE_ID_MASK 0x1 +#define SPMC_SECURE_ID_SHIFT 15 + +/* * Data structure used by the SPM dispatcher (SPMD) in EL3 to track sequence of * SPCI calls from lower ELs. * |