Merge pull request #919 from davidcunado-arm/dc/smc_yielding_generic
Update terminology: standard SMC to yielding SMC
diff --git a/bl1/bl1_fwu.c b/bl1/bl1_fwu.c
index f7fae68..e2ede68 100644
--- a/bl1/bl1_fwu.c
+++ b/bl1/bl1_fwu.c
@@ -109,7 +109,7 @@
break;
}
- SMC_RET0(handle);
+ SMC_RET1(handle, SMC_UNK);
}
/*******************************************************************************
diff --git a/drivers/ti/uart/aarch64/16550_console.S b/drivers/ti/uart/aarch64/16550_console.S
index 489fcbe..1b9cab8 100644
--- a/drivers/ti/uart/aarch64/16550_console.S
+++ b/drivers/ti/uart/aarch64/16550_console.S
@@ -115,9 +115,6 @@
b.ne 1b
mov w2, #0xD /* '\r' */
str w2, [x1, #UARTTX]
- ldr w2, [x1, #UARTFCR]
- orr w2, w2, #UARTFCR_TXCLR
- str w2, [x1, #UARTFCR]
/* Check if the transmit FIFO is full */
2: ldr w2, [x1, #UARTLSR]
@@ -125,9 +122,6 @@
cmp w2, #(UARTLSR_TEMT | UARTLSR_THRE)
b.ne 2b
str w0, [x1, #UARTTX]
- ldr w2, [x1, #UARTFCR]
- orr w2, w2, #UARTFCR_TXCLR
- str w2, [x1, #UARTFCR]
ret
putc_error:
mov w0, #-1
diff --git a/include/bl32/payloads/tlk.h b/include/bl32/payloads/tlk.h
index d355313..1a83b1f 100644
--- a/include/bl32/payloads/tlk.h
+++ b/include/bl32/payloads/tlk.h
@@ -31,7 +31,7 @@
#ifndef __TLK_H__
#define __TLK_H__
-#include <utils.h>
+#include <utils_def.h>
/*
* Generate function IDs for the Trusted OS/Apps
diff --git a/include/common/bl_common.h b/include/common/bl_common.h
index 38be628..2a026b8 100644
--- a/include/common/bl_common.h
+++ b/include/common/bl_common.h
@@ -85,7 +85,7 @@
#include <stddef.h>
#include <stdint.h>
#include <types.h>
-#include <utils.h> /* To retain compatibility */
+#include <utils_def.h> /* To retain compatibility */
/*
* Declarations of linker defined symbols to help determine memory layout of
diff --git a/include/lib/aarch64/arch.h b/include/lib/aarch64/arch.h
index 4b323d3..ef7241d 100644
--- a/include/lib/aarch64/arch.h
+++ b/include/lib/aarch64/arch.h
@@ -31,7 +31,7 @@
#ifndef __ARCH_H__
#define __ARCH_H__
-#include <utils.h>
+#include <utils_def.h>
/*******************************************************************************
* MIDR bit definitions
diff --git a/include/lib/cpus/errata_report.h b/include/lib/cpus/errata_report.h
index 6c6a844..228ffea 100644
--- a/include/lib/cpus/errata_report.h
+++ b/include/lib/cpus/errata_report.h
@@ -36,7 +36,7 @@
#include <arch.h>
#include <arch_helpers.h>
#include <spinlock.h>
-#include <utils.h>
+#include <utils_def.h>
#if DEBUG
void print_errata_status(void);
diff --git a/include/lib/smcc.h b/include/lib/smcc.h
index 708805f..5fad7b8 100644
--- a/include/lib/smcc.h
+++ b/include/lib/smcc.h
@@ -31,7 +31,7 @@
#ifndef __SMCC_H__
#define __SMCC_H__
-#include <utils.h>
+#include <utils_def.h>
/*******************************************************************************
* Bit definitions inside the function id as per the SMC calling convention
@@ -58,6 +58,7 @@
#define SMC_64 1
#define SMC_32 0
+#define SMC_OK 0
#define SMC_UNK 0xffffffff
#define SMC_TYPE_FAST ULL(1)
#if !ERROR_DEPRECATED
diff --git a/include/lib/utils.h b/include/lib/utils.h
index 279c913..c085b7d 100644
--- a/include/lib/utils.h
+++ b/include/lib/utils.h
@@ -31,67 +31,8 @@
#ifndef __UTILS_H__
#define __UTILS_H__
-/* Compute the number of elements in the given array */
-#define ARRAY_SIZE(a) \
- (sizeof(a) / sizeof((a)[0]))
-
-#define IS_POWER_OF_TWO(x) \
- (((x) & ((x) - 1)) == 0)
-
-#define SIZE_FROM_LOG2_WORDS(n) (4 << (n))
-
-#define BIT(nr) (1UL << (nr))
-
-#define MIN(x, y) __extension__ ({ \
- __typeof__(x) _x = (x); \
- __typeof__(y) _y = (y); \
- (void)(&_x == &_y); \
- _x < _y ? _x : _y; \
-})
-
-#define MAX(x, y) __extension__ ({ \
- __typeof__(x) _x = (x); \
- __typeof__(y) _y = (y); \
- (void)(&_x == &_y); \
- _x > _y ? _x : _y; \
-})
-
-/*
- * The round_up() macro rounds up a value to the given boundary in a
- * type-agnostic yet type-safe manner. The boundary must be a power of two.
- * In other words, it computes the smallest multiple of boundary which is
- * greater than or equal to value.
- *
- * round_down() is similar but rounds the value down instead.
- */
-#define round_boundary(value, boundary) \
- ((__typeof__(value))((boundary) - 1))
-
-#define round_up(value, boundary) \
- ((((value) - 1) | round_boundary(value, boundary)) + 1)
-
-#define round_down(value, boundary) \
- ((value) & ~round_boundary(value, boundary))
-
-/*
- * Evaluates to 1 if (ptr + inc) overflows, 0 otherwise.
- * Both arguments must be unsigned pointer values (i.e. uintptr_t).
- */
-#define check_uptr_overflow(ptr, inc) \
- (((ptr) > UINTPTR_MAX - (inc)) ? 1 : 0)
-
-/*
- * For those constants to be shared between C and other sources, apply a 'ull'
- * suffix to the argument only in C, to avoid undefined or unintended behaviour.
- *
- * The GNU assembler and linker do not support the 'ull' suffix (it causes the
- * build process to fail) therefore the suffix is omitted when used in linker
- * scripts and assembler files.
-*/
-#if defined(__LINKER__) || defined(__ASSEMBLY__)
-# define ULL(_x) (_x)
-#else
-# define ULL(_x) (_x##ull)
+#if !ERROR_DEPRECATED
+#include <utils_def.h>
#endif
/*
diff --git a/include/lib/utils_def.h b/include/lib/utils_def.h
new file mode 100644
index 0000000..202f050
--- /dev/null
+++ b/include/lib/utils_def.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __UTILS_DEF_H__
+#define __UTILS_DEF_H__
+
+/* Compute the number of elements in the given array */
+#define ARRAY_SIZE(a) \
+ (sizeof(a) / sizeof((a)[0]))
+
+#define IS_POWER_OF_TWO(x) \
+ (((x) & ((x) - 1)) == 0)
+
+#define SIZE_FROM_LOG2_WORDS(n) (4 << (n))
+
+#define BIT(nr) (1UL << (nr))
+
+#define MIN(x, y) __extension__ ({ \
+ __typeof__(x) _x = (x); \
+ __typeof__(y) _y = (y); \
+ (void)(&_x == &_y); \
+ _x < _y ? _x : _y; \
+})
+
+#define MAX(x, y) __extension__ ({ \
+ __typeof__(x) _x = (x); \
+ __typeof__(y) _y = (y); \
+ (void)(&_x == &_y); \
+ _x > _y ? _x : _y; \
+})
+
+/*
+ * The round_up() macro rounds up a value to the given boundary in a
+ * type-agnostic yet type-safe manner. The boundary must be a power of two.
+ * In other words, it computes the smallest multiple of boundary which is
+ * greater than or equal to value.
+ *
+ * round_down() is similar but rounds the value down instead.
+ */
+#define round_boundary(value, boundary) \
+ ((__typeof__(value))((boundary) - 1))
+
+#define round_up(value, boundary) \
+ ((((value) - 1) | round_boundary(value, boundary)) + 1)
+
+#define round_down(value, boundary) \
+ ((value) & ~round_boundary(value, boundary))
+
+/*
+ * Evaluates to 1 if (ptr + inc) overflows, 0 otherwise.
+ * Both arguments must be unsigned pointer values (i.e. uintptr_t).
+ */
+#define check_uptr_overflow(ptr, inc) \
+ (((ptr) > UINTPTR_MAX - (inc)) ? 1 : 0)
+
+/*
+ * For those constants to be shared between C and other sources, apply a 'ull'
+ * suffix to the argument only in C, to avoid undefined or unintended behaviour.
+ *
+ * The GNU assembler and linker do not support the 'ull' suffix (it causes the
+ * build process to fail) therefore the suffix is omitted when used in linker
+ * scripts and assembler files.
+*/
+#if defined(__LINKER__) || defined(__ASSEMBLY__)
+# define ULL(_x) (_x)
+#else
+# define ULL(_x) (_x##ull)
+#endif
+
+#endif /* __UTILS_DEF_H__ */
diff --git a/include/lib/xlat_tables/xlat_tables_defs.h b/include/lib/xlat_tables/xlat_tables_defs.h
index 3105d7a..032ce92 100644
--- a/include/lib/xlat_tables/xlat_tables_defs.h
+++ b/include/lib/xlat_tables/xlat_tables_defs.h
@@ -31,7 +31,7 @@
#ifndef __XLAT_TABLES_DEFS_H__
#define __XLAT_TABLES_DEFS_H__
-#include <utils.h>
+#include <utils_def.h>
/* Miscellaneous MMU related constants */
#define NUM_2MB_IN_GB (1 << 9)
diff --git a/include/plat/arm/board/common/board_css_def.h b/include/plat/arm/board/common/board_css_def.h
index 4b5e84d..88a97d9 100644
--- a/include/plat/arm/board/common/board_css_def.h
+++ b/include/plat/arm/board/common/board_css_def.h
@@ -33,7 +33,7 @@
#include <common_def.h>
#include <soc_css_def.h>
-#include <utils.h>
+#include <utils_def.h>
#include <v2m_def.h>
/*
diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h
index 43e0eb8..f5f8378 100644
--- a/include/plat/arm/common/arm_def.h
+++ b/include/plat/arm/common/arm_def.h
@@ -34,7 +34,7 @@
#include <common_def.h>
#include <platform_def.h>
#include <tbbr_img_def.h>
-#include <utils.h>
+#include <utils_def.h>
#include <xlat_tables_defs.h>
diff --git a/include/plat/arm/common/plat_arm.h b/include/plat/arm/common/plat_arm.h
index 4ba4a84..8ea32b9 100644
--- a/include/plat/arm/common/plat_arm.h
+++ b/include/plat/arm/common/plat_arm.h
@@ -35,7 +35,7 @@
#include <cassert.h>
#include <cpu_data.h>
#include <stdint.h>
-#include <utils.h>
+#include <utils_def.h>
/*******************************************************************************
* Forward declarations
diff --git a/include/plat/arm/css/common/css_pm.h b/include/plat/arm/css/common/css_pm.h
index 489275e..1e1bab7 100644
--- a/include/plat/arm/css/common/css_pm.h
+++ b/include/plat/arm/css/common/css_pm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -35,11 +35,15 @@
#include <psci.h>
#include <types.h>
+/* System power domain at level 2, as currently implemented by CSS platforms */
+#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2
+
/* Macros to read the CSS power domain state */
#define CSS_CORE_PWR_STATE(state) (state)->pwr_domain_state[ARM_PWR_LVL0]
#define CSS_CLUSTER_PWR_STATE(state) (state)->pwr_domain_state[ARM_PWR_LVL1]
-#define CSS_SYSTEM_PWR_STATE(state) ((PLAT_MAX_PWR_LVL > ARM_PWR_LVL1) ?\
- (state)->pwr_domain_state[ARM_PWR_LVL2] : 0)
+#define CSS_SYSTEM_PWR_STATE(state) \
+ ((PLAT_MAX_PWR_LVL == CSS_SYSTEM_PWR_DMN_LVL) ?\
+ (state)->pwr_domain_state[CSS_SYSTEM_PWR_DMN_LVL] : 0)
int css_pwr_domain_on(u_register_t mpidr);
void css_pwr_domain_on_finish(const psci_power_state_t *target_state);
diff --git a/include/plat/arm/soc/common/soc_css_def.h b/include/plat/arm/soc/common/soc_css_def.h
index efd78f0..ecced3d 100644
--- a/include/plat/arm/soc/common/soc_css_def.h
+++ b/include/plat/arm/soc/common/soc_css_def.h
@@ -32,7 +32,7 @@
#define __SOC_CSS_DEF_H__
#include <common_def.h>
-#include <utils.h>
+#include <utils_def.h>
/*
diff --git a/lib/xlat_tables/xlat_tables_common.c b/lib/xlat_tables/xlat_tables_common.c
index 4426cce..23f3daa 100644
--- a/lib/xlat_tables/xlat_tables_common.c
+++ b/lib/xlat_tables/xlat_tables_common.c
@@ -273,15 +273,19 @@
}
/*
- * Returns attributes of area at `base_va` with size `size`. It returns the
- * attributes of the innermost region that contains it. If there are partial
- * overlaps, it returns -1, as a smaller size is needed.
+ * Look for the innermost region that contains the area at `base_va` with size
+ * `size`. Populate *attr with the attributes of this region.
+ *
+ * On success, this function returns 0.
+ * If there are partial overlaps (meaning that a smaller size is needed) or if
+ * the region can't be found in the given area, it returns -1. In this case the
+ * value pointed by attr should be ignored by the caller.
*/
-static mmap_attr_t mmap_region_attr(mmap_region_t *mm, uintptr_t base_va,
- size_t size)
+static int mmap_region_attr(mmap_region_t *mm, uintptr_t base_va,
+ size_t size, mmap_attr_t *attr)
{
/* Don't assume that the area is contained in the first region */
- mmap_attr_t attr = -1;
+ int ret = -1;
/*
* Get attributes from last (innermost) region that contains the
@@ -301,23 +305,25 @@
for (;; ++mm) {
if (!mm->size)
- return attr; /* Reached end of list */
+ return ret; /* Reached end of list */
if (mm->base_va > base_va + size - 1)
- return attr; /* Next region is after area so end */
+ return ret; /* Next region is after area so end */
if (mm->base_va + mm->size - 1 < base_va)
continue; /* Next region has already been overtaken */
- if (mm->attr == attr)
+ if (!ret && mm->attr == *attr)
continue; /* Region doesn't override attribs so skip */
if (mm->base_va > base_va ||
mm->base_va + mm->size - 1 < base_va + size - 1)
return -1; /* Region doesn't fully cover our area */
- attr = mm->attr;
+ *attr = mm->attr;
+ ret = 0;
}
+ return ret;
}
static mmap_region_t *init_xlation_table_inner(mmap_region_t *mm,
@@ -360,9 +366,10 @@
* there are partially overlapping regions. On success,
* it will return the innermost region's attributes.
*/
- mmap_attr_t attr = mmap_region_attr(mm, base_va,
- level_size);
- if (attr >= 0) {
+ mmap_attr_t attr;
+ int r = mmap_region_attr(mm, base_va, level_size, &attr);
+
+ if (!r) {
desc = mmap_desc(attr,
base_va - mm->base_va + mm->base_pa,
level);
diff --git a/lib/xlat_tables/xlat_tables_private.h b/lib/xlat_tables/xlat_tables_private.h
index f0f656b..54ad909 100644
--- a/lib/xlat_tables/xlat_tables_private.h
+++ b/lib/xlat_tables/xlat_tables_private.h
@@ -33,7 +33,7 @@
#include <cassert.h>
#include <platform_def.h>
-#include <utils.h>
+#include <utils_def.h>
/*
* If the platform hasn't defined a physical and a virtual address space size
diff --git a/lib/xlat_tables_v2/xlat_tables_private.h b/lib/xlat_tables_v2/xlat_tables_private.h
index 048c4a8..e79890e 100644
--- a/lib/xlat_tables_v2/xlat_tables_private.h
+++ b/lib/xlat_tables_v2/xlat_tables_private.h
@@ -33,7 +33,7 @@
#include <cassert.h>
#include <platform_def.h>
-#include <utils.h>
+#include <utils_def.h>
/*
* If the platform hasn't defined a physical and a virtual address space size
diff --git a/plat/arm/board/juno/juno_pm.c b/plat/arm/board/juno/juno_pm.c
deleted file mode 100644
index c0fa628..0000000
--- a/plat/arm/board/juno/juno_pm.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this
- * list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of ARM nor the names of its contributors may be used
- * to endorse or promote products derived from this software without specific
- * prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-#include <css_pm.h>
-#include <plat_arm.h>
-
-/*
- * Custom `validate_power_state` handler for Juno. According to PSCI
- * Specification, interrupts targeted to cores in PSCI CPU SUSPEND should
- * be able to resume it. On Juno, when the system power domain is suspended,
- * the GIC is also powered down. The SCP resumes the final core to be suspend
- * when an external wake-up event is received. But the other cores cannot be
- * woken up by a targeted interrupt, because GIC doesn't forward these
- * interrupts to the SCP. Due to this hardware limitation, we down-grade PSCI
- * CPU SUSPEND requests targeted to the system power domain level
- * to cluster power domain level.
- *
- * The system power domain suspend on Juno is only supported only via
- * PSCI SYSTEM SUSPEND API.
- */
-static int juno_validate_power_state(unsigned int power_state,
- psci_power_state_t *req_state)
-{
- int rc;
- rc = arm_validate_power_state(power_state, req_state);
-
- /*
- * Ensure that the system power domain level is never suspended
- * via PSCI CPU SUSPEND API. Currently system suspend is only
- * supported via PSCI SYSTEM SUSPEND API.
- */
- req_state->pwr_domain_state[ARM_PWR_LVL2] = ARM_LOCAL_STATE_RUN;
- return rc;
-}
-
-/*
- * Custom `translate_power_state_by_mpidr` handler for Juno. Unlike in the
- * `juno_validate_power_state`, we do not down-grade the system power
- * domain level request in `power_state` as it will be used to query the
- * PSCI_STAT_COUNT/RESIDENCY at the system power domain level.
- */
-static int juno_translate_power_state_by_mpidr(u_register_t mpidr,
- unsigned int power_state,
- psci_power_state_t *output_state)
-{
- return arm_validate_power_state(power_state, output_state);
-}
-
-/*******************************************************************************
- * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
- * platform will take care of registering the handlers with PSCI.
- ******************************************************************************/
-plat_psci_ops_t plat_arm_psci_pm_ops = {
- .pwr_domain_on = css_pwr_domain_on,
- .pwr_domain_on_finish = css_pwr_domain_on_finish,
- .pwr_domain_off = css_pwr_domain_off,
- .cpu_standby = css_cpu_standby,
- .pwr_domain_suspend = css_pwr_domain_suspend,
- .pwr_domain_suspend_finish = css_pwr_domain_suspend_finish,
- .system_off = css_system_off,
- .system_reset = css_system_reset,
- .validate_power_state = juno_validate_power_state,
- .validate_ns_entrypoint = arm_validate_ns_entrypoint,
- .get_sys_suspend_power_state = css_get_sys_suspend_power_state,
- .translate_power_state_by_mpidr = juno_translate_power_state_by_mpidr,
- .get_node_hw_state = css_node_hw_state
-};
diff --git a/plat/arm/board/juno/juno_trng.c b/plat/arm/board/juno/juno_trng.c
index 2fcddcd..9bb760f 100644
--- a/plat/arm/board/juno/juno_trng.c
+++ b/plat/arm/board/juno/juno_trng.c
@@ -31,7 +31,7 @@
#include <assert.h>
#include <mmio.h>
#include <string.h>
-#include <utils.h>
+#include <utils_def.h>
#include "juno_def.h"
#define NSAMPLE_CLOCKS 1 /* min 1 cycle, max 231 cycles */
diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk
index 0855438..e29f8c8 100644
--- a/plat/arm/board/juno/platform.mk
+++ b/plat/arm/board/juno/platform.mk
@@ -73,7 +73,6 @@
BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \
lib/cpus/aarch64/cortex_a57.S \
lib/cpus/aarch64/cortex_a72.S \
- plat/arm/board/juno/juno_pm.c \
plat/arm/board/juno/juno_topology.c \
${JUNO_GIC_SOURCES} \
${JUNO_INTERCONNECT_SOURCES} \
diff --git a/plat/arm/css/common/css_bl2_setup.c b/plat/arm/css/common/css_bl2_setup.c
index 5361d89..65a98ba 100644
--- a/plat/arm/css/common/css_bl2_setup.c
+++ b/plat/arm/css/common/css_bl2_setup.c
@@ -34,6 +34,7 @@
#include <mmio.h>
#include <plat_arm.h>
#include <string.h>
+#include <utils.h>
#include "css_scp_bootloader.h"
/* Weak definition may be overridden in specific CSS based platform */
diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c
index d4dd0af..21ce865 100644
--- a/plat/arm/css/common/css_pm.c
+++ b/plat/arm/css/common/css_pm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -75,6 +75,13 @@
CASSERT(PLAT_MAX_PWR_LVL >= ARM_PWR_LVL1,
assert_max_pwr_lvl_supported_mismatch);
+/*
+ * Ensure that the PLAT_MAX_PWR_LVL is not greater than CSS_SYSTEM_PWR_DMN_LVL
+ * assumed by the CSS layer.
+ */
+CASSERT(PLAT_MAX_PWR_LVL <= CSS_SYSTEM_PWR_DMN_LVL,
+ assert_max_pwr_lvl_higher_than_css_sys_lvl);
+
/*******************************************************************************
* Handler called when a power domain is about to be turned on. The
* level and mpidr determine the affinity instance.
@@ -243,7 +250,7 @@
* System Suspend is supported only if the system power domain node
* is implemented.
*/
- assert(PLAT_MAX_PWR_LVL >= ARM_PWR_LVL2);
+ assert(PLAT_MAX_PWR_LVL == CSS_SYSTEM_PWR_DMN_LVL);
for (i = ARM_PWR_LVL0; i <= PLAT_MAX_PWR_LVL; i++)
req_state->pwr_domain_state[i] = ARM_LOCAL_STATE_OFF;
@@ -257,6 +264,39 @@
return css_scp_get_power_state(mpidr, power_level);
}
+/*
+ * The system power domain suspend is only supported only via
+ * PSCI SYSTEM_SUSPEND API. PSCI CPU_SUSPEND request to system power domain
+ * will be downgraded to the lower level.
+ */
+static int css_validate_power_state(unsigned int power_state,
+ psci_power_state_t *req_state)
+{
+ int rc;
+ rc = arm_validate_power_state(power_state, req_state);
+
+ /*
+ * Ensure that the system power domain level is never suspended
+ * via PSCI CPU SUSPEND API. Currently system suspend is only
+ * supported via PSCI SYSTEM SUSPEND API.
+ */
+ req_state->pwr_domain_state[CSS_SYSTEM_PWR_DMN_LVL] = ARM_LOCAL_STATE_RUN;
+ return rc;
+}
+
+/*
+ * Custom `translate_power_state_by_mpidr` handler for CSS. Unlike in the
+ * `css_validate_power_state`, we do not downgrade the system power
+ * domain level request in `power_state` as it will be used to query the
+ * PSCI_STAT_COUNT/RESIDENCY at the system power domain level.
+ */
+static int css_translate_power_state_by_mpidr(u_register_t mpidr,
+ unsigned int power_state,
+ psci_power_state_t *output_state)
+{
+ return arm_validate_power_state(power_state, output_state);
+}
+
/*******************************************************************************
* Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard
* platform will take care of registering the handlers with PSCI.
@@ -270,7 +310,9 @@
.pwr_domain_suspend_finish = css_pwr_domain_suspend_finish,
.system_off = css_system_off,
.system_reset = css_system_reset,
- .validate_power_state = arm_validate_power_state,
+ .validate_power_state = css_validate_power_state,
.validate_ns_entrypoint = arm_validate_ns_entrypoint,
- .get_node_hw_state = css_node_hw_state
+ .translate_power_state_by_mpidr = css_translate_power_state_by_mpidr,
+ .get_node_hw_state = css_node_hw_state,
+ .get_sys_suspend_power_state = css_get_sys_suspend_power_state
};
diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
index 41a4ede..87c7ed0 100644
--- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
+++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c
@@ -40,7 +40,8 @@
#include <string.h>
#include <tegra_def.h>
#include <tegra_platform.h>
-#include <xlat_tables.h>
+#include <utils.h>
+#include <xlat_tables_v2.h>
#define TEGRA_GPU_RESET_REG_OFFSET 0x30
#define GPU_RESET_BIT (1 << 0)
@@ -450,7 +451,7 @@
tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size_mb);
/*
- * MCE propogates the VideoMem configuration values across the
+ * MCE propagates the VideoMem configuration values across the
* CCPLEX.
*/
mce_update_gsc_videomem();
@@ -490,7 +491,7 @@
tegra_mc_read_32(MC_SECURITY_CFG1_0));
/*
- * MCE propogates the security configuration values across the
+ * MCE propagates the security configuration values across the
* CCPLEX.
*/
mce_update_gsc_tzdram();
@@ -506,25 +507,28 @@
{
uint32_t index;
uint32_t total_128kb_blocks = size_in_bytes >> 17;
- uint32_t residual_4kb_blocks = (size_in_bytes & 0x1FFFF) >> 12;
+ uint32_t residual_4kb_blocks = (size_in_bytes & (uint32_t)0x1FFFF) >> 12;
uint32_t val;
+ INFO("Configuring TrustZone SRAM Memory Carveout\n");
+
/*
* Reset the access configuration registers to restrict access
* to the TZRAM aperture
*/
- for (index = MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG0;
- index <= MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS5;
- index += 4)
+ for (index = MC_TZRAM_CLIENT_ACCESS_CFG0;
+ index < ((uint32_t)MC_TZRAM_CARVEOUT_CFG + (uint32_t)MC_GSC_CONFIG_REGS_SIZE);
+ index += 4U) {
tegra_mc_write_32(index, 0);
+ }
/*
* Set the TZRAM base. TZRAM base must be 4k aligned, at least.
*/
- assert(!(phys_base & 0xFFF));
+ assert((phys_base & (uint64_t)0xFFF) == 0U);
tegra_mc_write_32(MC_TZRAM_BASE_LO, (uint32_t)phys_base);
tegra_mc_write_32(MC_TZRAM_BASE_HI,
- (uint32_t)(phys_base >> 32) & TZRAM_BASE_HI_MASK);
+ (uint32_t)(phys_base >> 32) & MC_GSC_BASE_HI_MASK);
/*
* Set the TZRAM size
@@ -533,7 +537,7 @@
* blocks)
*
*/
- val = (residual_4kb_blocks << TZRAM_SIZE_RANGE_4KB_SHIFT) |
+ val = (residual_4kb_blocks << MC_GSC_SIZE_RANGE_4KB_SHIFT) |
total_128kb_blocks;
tegra_mc_write_32(MC_TZRAM_SIZE, val);
@@ -543,17 +547,96 @@
* at all.
*/
val = tegra_mc_read_32(MC_TZRAM_CARVEOUT_CFG);
- val &= ~TZRAM_ENABLE_TZ_LOCK_BIT;
- val |= TZRAM_LOCK_CFG_SETTINGS_BIT;
+ val &= ~MC_GSC_ENABLE_TZ_LOCK_BIT;
+ val |= MC_GSC_LOCK_CFG_SETTINGS_BIT;
tegra_mc_write_32(MC_TZRAM_CARVEOUT_CFG, val);
/*
- * MCE propogates the security configuration values across the
+ * MCE propagates the security configuration values across the
* CCPLEX.
*/
mce_update_gsc_tzram();
}
+static void tegra_lock_videomem_nonoverlap(uint64_t phys_base,
+ uint64_t size_in_bytes)
+{
+ uint32_t index;
+ uint64_t total_128kb_blocks = size_in_bytes >> 17;
+ uint64_t residual_4kb_blocks = (size_in_bytes & (uint32_t)0x1FFFF) >> 12;
+ uint64_t val;
+
+ /*
+ * Reset the access configuration registers to restrict access to
+ * old Videomem aperture
+ */
+ for (index = MC_VIDEO_PROTECT_CLEAR_ACCESS_CFG0;
+ index < ((uint32_t)MC_VIDEO_PROTECT_CLEAR_ACCESS_CFG0 + (uint32_t)MC_GSC_CONFIG_REGS_SIZE);
+ index += 4U) {
+ tegra_mc_write_32(index, 0);
+ }
+
+ /*
+ * Set the base. It must be 4k aligned, at least.
+ */
+ assert((phys_base & (uint64_t)0xFFF) == 0U);
+ tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_LO, (uint32_t)phys_base);
+ tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_HI,
+ (uint32_t)(phys_base >> 32) & (uint32_t)MC_GSC_BASE_HI_MASK);
+
+ /*
+ * Set the aperture size
+ *
+ * total size = (number of 128KB blocks) + (number of remaining 4KB
+ * blocks)
+ *
+ */
+ val = (uint32_t)((residual_4kb_blocks << MC_GSC_SIZE_RANGE_4KB_SHIFT) |
+ total_128kb_blocks);
+ tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_SIZE, (uint32_t)val);
+
+ /*
+ * Lock the configuration settings by enabling TZ-only lock and
+ * locking the configuration against any future changes from NS
+ * world.
+ */
+ tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_CFG,
+ (uint32_t)MC_GSC_ENABLE_TZ_LOCK_BIT);
+
+ /*
+ * MCE propagates the GSC configuration values across the
+ * CCPLEX.
+ */
+}
+
+static void tegra_unlock_videomem_nonoverlap(void)
+{
+ /* Clear the base */
+ tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_LO, 0);
+ tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_BASE_HI, 0);
+
+ /* Clear the size */
+ tegra_mc_write_32(MC_VIDEO_PROTECT_CLEAR_SIZE, 0);
+}
+
+static void tegra_clear_videomem(uintptr_t non_overlap_area_start,
+ unsigned long long non_overlap_area_size)
+{
+ /*
+ * Map the NS memory first, clean it and then unmap it.
+ */
+ mmap_add_dynamic_region(non_overlap_area_start, /* PA */
+ non_overlap_area_start, /* VA */
+ non_overlap_area_size, /* size */
+ MT_NS | MT_RW | MT_EXECUTE_NEVER); /* attrs */
+
+ zero_normalmem((void *)non_overlap_area_start, non_overlap_area_size);
+ flush_dcache_range(non_overlap_area_start, non_overlap_area_size);
+
+ mmap_remove_dynamic_region(non_overlap_area_start,
+ non_overlap_area_size);
+}
+
/*
* Program the Video Memory carveout region
*
@@ -562,7 +645,10 @@
*/
void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes)
{
+ uintptr_t vmem_end_old = video_mem_base + (video_mem_size_mb << 20);
+ uintptr_t vmem_end_new = phys_base + size_in_bytes;
uint32_t regval;
+ unsigned long long non_overlap_area_size;
/*
* The GPU is the user of the Video Memory region. In order to
@@ -570,7 +656,7 @@
* new base/size ONLY if the GPU is in reset mode.
*/
regval = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_GPU_RESET_REG_OFFSET);
- if ((regval & GPU_RESET_BIT) == 0) {
+ if ((regval & GPU_RESET_BIT) == 0U) {
ERROR("GPU not in reset! Video Memory setup failed\n");
return;
}
@@ -581,17 +667,61 @@
*/
INFO("Configuring Video Memory Carveout\n");
+ /*
+ * Configure Memory Controller directly for the first time.
+ */
+ if (video_mem_base == 0U)
+ goto done;
+
+ /*
+ * Lock the non overlapping memory being cleared so that other masters
+ * do not accidently write to it. The memory would be unlocked once
+ * the non overlapping region is cleared and the new memory
+ * settings take effect.
+ */
+ tegra_lock_videomem_nonoverlap(video_mem_base,
+ video_mem_size_mb << 20);
+
+ /*
+ * Clear the old regions now being exposed. The following cases
+ * can occur -
+ *
+ * 1. clear whole old region (no overlap with new region)
+ * 2. clear old sub-region below new base
+ * 3. clear old sub-region above new end
+ */
+ INFO("Cleaning previous Video Memory Carveout\n");
+
+ if (phys_base > vmem_end_old || video_mem_base > vmem_end_new) {
+ tegra_clear_videomem(video_mem_base,
+ (uint64_t)video_mem_size_mb << 20);
+ } else {
+ if (video_mem_base < phys_base) {
+ non_overlap_area_size = phys_base - video_mem_base;
+ tegra_clear_videomem(video_mem_base, non_overlap_area_size);
+ }
+ if (vmem_end_old > vmem_end_new) {
+ non_overlap_area_size = vmem_end_old - vmem_end_new;
+ tegra_clear_videomem(vmem_end_new, non_overlap_area_size);
+ }
+ }
+
+done:
+ /* program the Videomem aperture */
tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base);
tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI,
(uint32_t)(phys_base >> 32));
tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20);
+ /* unlock the previous locked nonoverlapping aperture */
+ tegra_unlock_videomem_nonoverlap();
+
/* store new values */
video_mem_base = phys_base;
video_mem_size_mb = size_in_bytes >> 20;
/*
- * MCE propogates the VideoMem configuration values across the
+ * MCE propagates the VideoMem configuration values across the
* CCPLEX.
*/
mce_update_gsc_videomem();
diff --git a/plat/nvidia/tegra/common/drivers/smmu/smmu.c b/plat/nvidia/tegra/common/drivers/smmu/smmu.c
index a985532..60fd300 100644
--- a/plat/nvidia/tegra/common/drivers/smmu/smmu.c
+++ b/plat/nvidia/tegra/common/drivers/smmu/smmu.c
@@ -89,7 +89,6 @@
{
uint32_t i, num_entries = 0;
smmu_regs_t *smmu_ctx_regs;
-#if DEBUG
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;
@@ -102,8 +101,6 @@
(1 << (((reg_id1 >> ID1_NUMPAGENDXB_SHIFT) & ID1_NUMPAGENDXB_MASK) + 1));
assert(!((pgshift != PGSHIFT) || (cb_size != CB_SIZE)));
-#endif
-
assert((smmu_ctx_addr >= tzdram_base) && (smmu_ctx_addr <= tzdram_end));
/* get SMMU context table */
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index 8307af7..1dc8066 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -205,6 +205,11 @@
}
/*
+ * Initialize delay timer
+ */
+ tegra_delay_timer_init();
+
+ /*
* Do initial security configuration to allow DRAM/device access.
*/
tegra_memctrl_tzdram_setup(plat_bl31_params_from_bl2.tzdram_base,
@@ -264,11 +269,6 @@
plat_gic_setup();
/*
- * Initialize delay timer
- */
- tegra_delay_timer_init();
-
- /*
* Setup secondary CPU POR infrastructure.
*/
plat_secondary_setup();
@@ -354,6 +354,12 @@
MT_DEVICE | MT_RW | MT_SECURE);
#endif
+ /* map on-chip free running uS timer */
+ mmap_add_region(page_align((uint64_t)TEGRA_TMRUS_BASE, 0),
+ page_align((uint64_t)TEGRA_TMRUS_BASE, 0),
+ (uint64_t)TEGRA_TMRUS_SIZE,
+ MT_DEVICE | MT_RO | MT_SECURE);
+
/* add MMIO space */
plat_mmio_map = plat_get_mmio_map();
if (plat_mmio_map)
@@ -375,13 +381,12 @@
******************************************************************************/
int bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes)
{
- uint64_t end = base + size_in_bytes - 1;
+ uint64_t end = base + size_in_bytes;
/*
* Check if the NS DRAM address is valid
*/
- if ((base < TEGRA_DRAM_BASE) || (end > TEGRA_DRAM_END) ||
- (base >= end)) {
+ if ((base < TEGRA_DRAM_BASE) || (end > TEGRA_DRAM_END)) {
ERROR("NS address is out-of-bounds!\n");
return -EFAULT;
}
diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk
index e8e25ef..cb4d188 100644
--- a/plat/nvidia/tegra/common/tegra_common.mk
+++ b/plat/nvidia/tegra/common/tegra_common.mk
@@ -28,19 +28,6 @@
# POSSIBILITY OF SUCH DAMAGE.
#
-CRASH_REPORTING := 1
-$(eval $(call add_define,CRASH_REPORTING))
-
-ASM_ASSERTION := 1
-$(eval $(call add_define,ASM_ASSERTION))
-
-USE_COHERENT_MEM := 0
-
-SEPARATE_CODE_AND_RODATA := 1
-
-PLAT_XLAT_TABLES_DYNAMIC := 1
-$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
-
PLAT_INCLUDES := -Iplat/nvidia/tegra/include/drivers \
-Iplat/nvidia/tegra/include \
-Iplat/nvidia/tegra/include/${TARGET_SOC}
diff --git a/plat/nvidia/tegra/include/t132/tegra_def.h b/plat/nvidia/tegra/include/t132/tegra_def.h
index 4ba4f12..e488bd8 100644
--- a/plat/nvidia/tegra/include/t132/tegra_def.h
+++ b/plat/nvidia/tegra/include/t132/tegra_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -58,6 +58,7 @@
* Tegra micro-seconds timer constants
******************************************************************************/
#define TEGRA_TMRUS_BASE 0x60005010
+#define TEGRA_TMRUS_SIZE 0x1000
/*******************************************************************************
* Tegra Clock and Reset Controller constants
diff --git a/plat/nvidia/tegra/include/t186/tegra_def.h b/plat/nvidia/tegra/include/t186/tegra_def.h
index ae11d28..8d7ab6e 100644
--- a/plat/nvidia/tegra/include/t186/tegra_def.h
+++ b/plat/nvidia/tegra/include/t186/tegra_def.h
@@ -157,6 +157,16 @@
#define TEGRA_MC_STREAMID_BASE 0x02C00000
#define TEGRA_MC_BASE 0x02C10000
+/* General Security Carveout register macros */
+#define MC_GSC_CONFIG_REGS_SIZE 0x40UL
+#define MC_GSC_LOCK_CFG_SETTINGS_BIT (1UL << 1)
+#define MC_GSC_ENABLE_TZ_LOCK_BIT (1UL << 0)
+#define MC_GSC_SIZE_RANGE_4KB_SHIFT 27UL
+#define MC_GSC_BASE_LO_SHIFT 12UL
+#define MC_GSC_BASE_LO_MASK 0xFFFFFUL
+#define MC_GSC_BASE_HI_SHIFT 0UL
+#define MC_GSC_BASE_HI_MASK 3UL
+
/* TZDRAM carveout configuration registers */
#define MC_SECURITY_CFG0_0 0x70
#define MC_SECURITY_CFG1_0 0x74
@@ -165,34 +175,24 @@
/* Video Memory carveout configuration registers */
#define MC_VIDEO_PROTECT_BASE_HI 0x978
#define MC_VIDEO_PROTECT_BASE_LO 0x648
-#define MC_VIDEO_PROTECT_SIZE_MB 0x64c
+#define MC_VIDEO_PROTECT_SIZE_MB 0x64C
+
+/*
+ * Carveout (MC_SECURITY_CARVEOUT24) registers used to clear the
+ * non-overlapping Video memory region
+ */
+#define MC_VIDEO_PROTECT_CLEAR_CFG 0x25A0
+#define MC_VIDEO_PROTECT_CLEAR_BASE_LO 0x25A4
+#define MC_VIDEO_PROTECT_CLEAR_BASE_HI 0x25A8
+#define MC_VIDEO_PROTECT_CLEAR_SIZE 0x25AC
+#define MC_VIDEO_PROTECT_CLEAR_ACCESS_CFG0 0x25B0
/* TZRAM carveout (MC_SECURITY_CARVEOUT11) configuration registers */
+#define MC_TZRAM_CARVEOUT_CFG 0x2190
#define MC_TZRAM_BASE_LO 0x2194
-#define TZRAM_BASE_LO_SHIFT 12
-#define TZRAM_BASE_LO_MASK 0xFFFFF
#define MC_TZRAM_BASE_HI 0x2198
-#define TZRAM_BASE_HI_SHIFT 0
-#define TZRAM_BASE_HI_MASK 3
#define MC_TZRAM_SIZE 0x219C
-#define TZRAM_SIZE_RANGE_4KB_SHIFT 27
-
-#define MC_TZRAM_CARVEOUT_CFG 0x2190
-#define TZRAM_LOCK_CFG_SETTINGS_BIT (1 << 1)
-#define TZRAM_ENABLE_TZ_LOCK_BIT (1 << 0)
-#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG0 0x21A0
-#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG1 0x21A4
-#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG2 0x21A8
-#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG3 0x21AC
-#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG4 0x21B0
-#define MC_TZRAM_CARVEOUT_CLIENT_ACCESS_CFG5 0x21B4
-
-#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS0 0x21B8
-#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS1 0x21BC
-#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS2 0x21C0
-#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS3 0x21C4
-#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS4 0x21C8
-#define MC_TZRAM_CARVEOUT_FORCE_INTERNAL_ACCESS5 0x21CC
+#define MC_TZRAM_CLIENT_ACCESS_CFG0 0x21A0
/*******************************************************************************
* Tegra UART Controller constants
@@ -237,6 +237,7 @@
* Tegra micro-seconds timer constants
******************************************************************************/
#define TEGRA_TMRUS_BASE 0x0C2E0000
+#define TEGRA_TMRUS_SIZE 0x1000
/*******************************************************************************
* Tegra Power Mgmt Controller constants
diff --git a/plat/nvidia/tegra/include/t210/tegra_def.h b/plat/nvidia/tegra/include/t210/tegra_def.h
index 0961355..d8ad10c 100644
--- a/plat/nvidia/tegra/include/t210/tegra_def.h
+++ b/plat/nvidia/tegra/include/t210/tegra_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -83,6 +83,7 @@
* Tegra micro-seconds timer constants
******************************************************************************/
#define TEGRA_TMRUS_BASE 0x60005010
+#define TEGRA_TMRUS_SIZE 0x1000
/*******************************************************************************
* Tegra Clock and Reset Controller constants
diff --git a/plat/nvidia/tegra/platform.mk b/plat/nvidia/tegra/platform.mk
index 2eeffca..1f7a4dc 100644
--- a/plat/nvidia/tegra/platform.mk
+++ b/plat/nvidia/tegra/platform.mk
@@ -30,12 +30,29 @@
SOC_DIR := plat/nvidia/tegra/soc/${TARGET_SOC}
-# Enable PSCI v1.0 extended state ID format
-PSCI_EXTENDED_STATE_ID := 1
+# dump the state on crash console
+CRASH_REPORTING := 1
+$(eval $(call add_define,CRASH_REPORTING))
+
+# enable assert() for release/debug builds
+ENABLE_ASSERTIONS := 1
# Disable the PSCI platform compatibility layer
ENABLE_PLAT_COMPAT := 0
+# enable dynamic memory mapping
+PLAT_XLAT_TABLES_DYNAMIC := 1
+$(eval $(call add_define,PLAT_XLAT_TABLES_DYNAMIC))
+
+# Enable PSCI v1.0 extended state ID format
+PSCI_EXTENDED_STATE_ID := 1
+
+# code and read-only data should be put on separate memory pages
+SEPARATE_CODE_AND_RODATA := 1
+
+# do not use coherent memory
+USE_COHERENT_MEM := 0
+
include plat/nvidia/tegra/common/tegra_common.mk
include ${SOC_DIR}/platform_${TARGET_SOC}.mk
diff --git a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
index f05f3d0..af21c28 100644
--- a/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t132/plat_psci_handlers.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -132,7 +132,7 @@
int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
{
-#if DEBUG
+#if ENABLE_ASSERTIONS
int cpu = read_mpidr() & MPIDR_CPU_MASK;
/* SYSTEM_SUSPEND only on CPU0 */
diff --git a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
index 7f711a7..87fadbe 100644
--- a/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
+++ b/plat/nvidia/tegra/soc/t186/drivers/mce/ari.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -30,10 +30,13 @@
#include <arch.h>
#include <arch_helpers.h>
+#include <assert.h>
#include <debug.h>
+#include <delay_timer.h>
#include <denver.h>
#include <mmio.h>
#include <mce_private.h>
+#include <platform.h>
#include <sys/errno.h>
#include <t18x_ari.h>
@@ -49,10 +52,13 @@
#define ARI_RESPONSE_DATA_HI 0x18
/* Status values for the current request */
-#define ARI_REQ_PENDING 1
-#define ARI_REQ_ONGOING 3
-#define ARI_REQUEST_VALID_BIT (1 << 8)
-#define ARI_EVT_MASK_STANDBYWFI_BIT (1 << 7)
+#define ARI_REQ_PENDING 1U
+#define ARI_REQ_ONGOING 3U
+#define ARI_REQUEST_VALID_BIT (1U << 8)
+#define ARI_EVT_MASK_STANDBYWFI_BIT (1U << 7)
+
+/* default timeout (ms) to wait for ARI completion */
+#define ARI_MAX_RETRY_COUNT 2000
/*******************************************************************************
* ARI helper functions
@@ -96,7 +102,8 @@
static int ari_request_wait(uint32_t ari_base, uint32_t evt_mask, uint32_t req,
uint32_t lo, uint32_t hi)
{
- int status;
+ uint32_t retries = ARI_MAX_RETRY_COUNT;
+ uint32_t status;
/* program the request, event_mask, hi and lo registers */
ari_write_32(ari_base, lo, ARI_REQUEST_DATA_LO);
@@ -112,10 +119,36 @@
if (evt_mask)
return 0;
+ /* For shutdown/reboot commands, we dont have to check for timeouts */
+ if ((req == (uint32_t)TEGRA_ARI_MISC_CCPLEX) &&
+ ((lo == (uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF) ||
+ (lo == (uint32_t)TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT))) {
+ return 0;
+ }
+
+ /*
+ * Wait for the command response for not more than the timeout
+ */
+ while (retries != 0U) {
+
- /* NOTE: add timeout check if needed */
- status = ari_read_32(ari_base, ARI_STATUS);
- while (status & (ARI_REQ_ONGOING | ARI_REQ_PENDING))
+ /* read the command status */
status = ari_read_32(ari_base, ARI_STATUS);
+ if ((status & (ARI_REQ_ONGOING | ARI_REQ_PENDING)) == 0U)
+ break;
+
+ /* delay 1 ms */
+ mdelay(1);
+
+ /* decrement the retry count */
+ retries--;
+ }
+
+ /* assert if the command timed out */
+ if (retries == 0U) {
+ ERROR("ARI request timed out: req %d on CPU %d\n",
+ req, plat_my_core_pos());
+ assert(retries != 0U);
+ }
return 0;
}
diff --git a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
index 9790b81..a7f41c1 100644
--- a/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t186/plat_psci_handlers.c
@@ -188,8 +188,11 @@
int core_pos = read_mpidr() & MPIDR_CPU_MASK;
mce_cstate_info_t cstate_info = { 0 };
- /* get the current core's power state */
- target = *(states + core_pos);
+ /* get the power state at this level */
+ if (lvl == MPIDR_AFFLVL1)
+ target = *(states + core_pos);
+ if (lvl == MPIDR_AFFLVL2)
+ target = *(states + cpu);
/* CPU suspend */
if (lvl == MPIDR_AFFLVL1 && target == PSTATE_ID_CORE_POWERDN) {
@@ -242,7 +245,8 @@
}
/* System Suspend */
- if ((lvl == MPIDR_AFFLVL2) || (target == PSTATE_ID_SOC_POWERDN))
+ if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) &&
+ (target == PSTATE_ID_SOC_POWERDN))
return PSTATE_ID_SOC_POWERDN;
/* default state */
diff --git a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
index 05028a1..91a13e8 100644
--- a/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
+++ b/plat/nvidia/tegra/soc/t210/plat_psci_handlers.c
@@ -100,6 +100,39 @@
return PSCI_E_SUCCESS;
}
+/*******************************************************************************
+ * Platform handler to calculate the proper target power level at the
+ * specified affinity level
+ ******************************************************************************/
+plat_local_state_t tegra_soc_get_target_pwr_state(unsigned int lvl,
+ const plat_local_state_t *states,
+ unsigned int ncpu)
+{
+ plat_local_state_t target = *states;
+ int cpu = plat_my_core_pos();
+ int core_pos = read_mpidr() & MPIDR_CPU_MASK;
+
+ /* get the power state at this level */
+ if (lvl == MPIDR_AFFLVL1)
+ target = *(states + core_pos);
+ if (lvl == MPIDR_AFFLVL2)
+ target = *(states + cpu);
+
+ /* Cluster idle/power-down */
+ if ((lvl == MPIDR_AFFLVL1) && ((target == PSTATE_ID_CLUSTER_IDLE) ||
+ (target == PSTATE_ID_CLUSTER_POWERDN))) {
+ return target;
+ }
+
+ /* System Suspend */
+ if (((lvl == MPIDR_AFFLVL2) || (lvl == MPIDR_AFFLVL1)) &&
+ (target == PSTATE_ID_SOC_POWERDN))
+ return PSTATE_ID_SOC_POWERDN;
+
+ /* default state */
+ return PSCI_LOCAL_STATE_RUN;
+}
+
int tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state)
{
u_register_t mpidr = read_mpidr();
@@ -121,14 +154,14 @@
} else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_IDLE) {
- assert(stateid_afflvl0 == PLAT_MAX_OFF_STATE);
+ assert(stateid_afflvl0 == PSTATE_ID_CLUSTER_IDLE);
/* Prepare for cluster idle */
tegra_fc_cluster_idle(mpidr);
} else if (stateid_afflvl1 == PSTATE_ID_CLUSTER_POWERDN) {
- assert(stateid_afflvl0 == PLAT_MAX_OFF_STATE);
+ assert(stateid_afflvl0 == PSTATE_ID_CLUSTER_POWERDN);
/* Prepare for cluster powerdn */
tegra_fc_cluster_powerdn(mpidr);
diff --git a/plat/nvidia/tegra/soc/t210/platform_t210.mk b/plat/nvidia/tegra/soc/t210/platform_t210.mk
index 8946869..cd26e6e 100644
--- a/plat/nvidia/tegra/soc/t210/platform_t210.mk
+++ b/plat/nvidia/tegra/soc/t210/platform_t210.mk
@@ -40,7 +40,7 @@
PLATFORM_MAX_CPUS_PER_CLUSTER := 4
$(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER))
-MAX_XLAT_TABLES := 3
+MAX_XLAT_TABLES := 4
$(eval $(call add_define,MAX_XLAT_TABLES))
MAX_MMAP_REGIONS := 8
diff --git a/services/spd/tspd/tspd_main.c b/services/spd/tspd/tspd_main.c
index f538422..02e1db7 100644
--- a/services/spd/tspd/tspd_main.c
+++ b/services/spd/tspd/tspd_main.c
@@ -632,7 +632,7 @@
cm_el1_sysregs_context_restore(NON_SECURE);
cm_set_next_eret_context(NON_SECURE);
- SMC_RET0(handle);
+ SMC_RET1(handle, SMC_OK);
/*
* Request from non secure world to resume the preempted