Tegra: lib: library for profiling the cold boot path
The non secure world would like to profile the boot path for
the EL3 and S-EL1 firmwares. To allow it to do that, a non-secure
DRAM region (4K) is allocated and the base address is passed to
the EL3 firmware.
This patch adds a library to allow the platform code to store the
tag:timestamp pair to the shared memory. The tegra platform code
then uses the `record` method to add timestamps.
Original change by Akshay Sharan <asharan@nvidia.com>
Change-Id: Idbbef9c83ed84a508b04d85a6637775960dc94ba
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c
index e92960c..80cc712 100644
--- a/plat/nvidia/tegra/common/tegra_bl31_setup.c
+++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c
@@ -26,6 +26,7 @@
#include <plat/common/platform.h>
#include <memctrl.h>
+#include <profiler.h>
#include <tegra_def.h>
#include <tegra_platform.h>
#include <tegra_private.h>
@@ -125,6 +126,7 @@
image_info_t bl32_img_info = { {0} };
uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end;
uint32_t console_clock;
+ int32_t ret;
/*
* For RESET_TO_BL31 systems, BL31 is the first bootloader to run so
@@ -195,6 +197,32 @@
}
/*
+ * The previous bootloader passes the base address of the shared memory
+ * location to store the boot profiler logs. Sanity check the
+ * address and initilise the profiler library, if it looks ok.
+ */
+ if (plat_params->boot_profiler_shmem_base != 0ULL) {
+
+ ret = bl31_check_ns_address(plat_params->boot_profiler_shmem_base,
+ PROFILER_SIZE_BYTES);
+ if (ret == (int32_t)0) {
+
+ /* store the membase for the profiler lib */
+ plat_bl31_params_from_bl2.boot_profiler_shmem_base =
+ plat_params->boot_profiler_shmem_base;
+
+ /* initialise the profiler library */
+ boot_profiler_init(plat_params->boot_profiler_shmem_base,
+ TEGRA_TMRUS_BASE);
+ }
+ }
+
+ /*
+ * Add timestamp for platform early setup entry.
+ */
+ boot_profiler_add_record("[TF] early setup entry");
+
+ /*
* Initialize delay timer
*/
tegra_delay_timer_init();
@@ -244,6 +272,11 @@
/* Early platform setup for Tegra SoCs */
plat_early_platform_setup();
+ /*
+ * Add timestamp for platform early setup exit.
+ */
+ boot_profiler_add_record("[TF] early setup exit");
+
INFO("BL3-1: Boot CPU: %s Processor [%lx]\n",
(((read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK)
== DENVER_IMPL) ? "Denver" : "ARM", read_mpidr());
@@ -268,6 +301,11 @@
******************************************************************************/
void bl31_platform_setup(void)
{
+ /*
+ * Add timestamp for platform setup entry.
+ */
+ boot_profiler_add_record("[TF] plat setup entry");
+
/* Initialize the gic cpu and distributor interfaces */
plat_gic_setup();
@@ -287,6 +325,11 @@
*/
tegra_memctrl_tzram_setup(TEGRA_TZRAM_BASE, TEGRA_TZRAM_SIZE);
+ /*
+ * Add timestamp for platform setup exit.
+ */
+ boot_profiler_add_record("[TF] plat setup exit");
+
INFO("BL3-1: Tegra platform setup complete\n");
}
@@ -305,6 +348,12 @@
* disabled before we jump to the non-secure world.
*/
tegra_memctrl_disable_ahb_redirection();
+
+ /*
+ * Add final timestamp before exiting BL31.
+ */
+ boot_profiler_add_record("[TF] bl31 exit");
+ boot_profiler_deinit();
}
/*******************************************************************************
@@ -325,6 +374,11 @@
#endif
const plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params();
+ /*
+ * Add timestamp for arch setup entry.
+ */
+ boot_profiler_add_record("[TF] arch setup entry");
+
/* add memory regions */
mmap_add_region(rw_start, rw_start,
rw_size,
@@ -373,6 +427,11 @@
/* enable the MMU */
enable_mmu_el3(0);
+ /*
+ * Add timestamp for arch setup exit.
+ */
+ boot_profiler_add_record("[TF] arch setup exit");
+
INFO("BL3-1: Tegra: MMU enabled\n");
}