aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeepak Pandey <Deepak.Pandey@arm.com>2018-12-13 10:54:14 +0530
committerronald-cron-arm <39518861+ronald-cron-arm@users.noreply.github.com>2018-12-21 12:39:56 +0000
commit30e205ea9fbbe795fe4889ccaa7ac629a51d87c2 (patch)
tree2dfc7e3d0df485902b64130d5c029818366ae180
parent649bc5ebb5a045e8ee59fef6d92e81ddcb207bab (diff)
n1sdp/scp_rom: add n1sdp_rom module.
This code is responsible for the first level of the capsule firmware parsing to fetch the ramfw and load to the respective location and jump to it. Change-Id: Id1dbc3fc80784370a5f0726bb63de61f63e5ca7c Signed-off-by: Deepak Pandey <Deepak.Pandey@arm.com>
-rw-r--r--product/n1sdp/module/n1sdp_rom/include/mod_n1sdp_rom.h42
-rw-r--r--product/n1sdp/module/n1sdp_rom/src/Makefile11
-rw-r--r--product/n1sdp/module/n1sdp_rom/src/mod_n1sdp_rom.c185
3 files changed, 238 insertions, 0 deletions
diff --git a/product/n1sdp/module/n1sdp_rom/include/mod_n1sdp_rom.h b/product/n1sdp/module/n1sdp_rom/include/mod_n1sdp_rom.h
new file mode 100644
index 00000000..b2793289
--- /dev/null
+++ b/product/n1sdp/module/n1sdp_rom/include/mod_n1sdp_rom.h
@@ -0,0 +1,42 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef MOD_N1SDP_ROM_H
+#define MOD_N1SDP_ROM_H
+
+#include <stdint.h>
+
+/*!
+ * \addtogroup GroupN1SDPModule N1SDP Product Modules
+ * @{
+ */
+
+/*!
+ * \defgroup GroupN1SDPRom N1SDP SCP ROM Support
+ * @{
+ */
+
+/*!
+ * \brief Module configuration data.
+ */
+struct n1sdp_rom_config {
+ /*! Base address of the RAM to which SCP BL2 will be copied to */
+ const uintptr_t ramfw_base;
+
+ /*! Type of RAM Firmware to load */
+ const uint8_t image_type;
+};
+
+/*!
+ * @}
+ */
+
+/*!
+ * @}
+ */
+
+#endif /* MOD_N1SDP_ROM_H */
diff --git a/product/n1sdp/module/n1sdp_rom/src/Makefile b/product/n1sdp/module/n1sdp_rom/src/Makefile
new file mode 100644
index 00000000..343170f8
--- /dev/null
+++ b/product/n1sdp/module/n1sdp_rom/src/Makefile
@@ -0,0 +1,11 @@
+#
+# Arm SCP/MCP Software
+# Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+BS_LIB_NAME := N1SDP ROM
+BS_LIB_SOURCES := mod_n1sdp_rom.c
+
+include $(BS_DIR)/lib.mk
diff --git a/product/n1sdp/module/n1sdp_rom/src/mod_n1sdp_rom.c b/product/n1sdp/module/n1sdp_rom/src/mod_n1sdp_rom.c
new file mode 100644
index 00000000..f7a198d3
--- /dev/null
+++ b/product/n1sdp/module/n1sdp_rom/src/mod_n1sdp_rom.c
@@ -0,0 +1,185 @@
+/*
+ * Arm SCP/MCP Software
+ * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <fwk_errno.h>
+#include <fwk_interrupt.h>
+#include <fwk_module.h>
+#include <fwk_module_idx.h>
+#include <fwk_thread.h>
+#include <mod_n1sdp_flash.h>
+#include <mod_n1sdp_rom.h>
+#include <mod_log.h>
+
+/*
+ * Module context
+ */
+struct mod_n1sdp_rom_ctx {
+ /* ROM configuration structure */
+ const struct n1sdp_rom_config *rom_config;
+
+ /* Pointer to log API */
+ struct mod_log_api *log_api;
+
+ /* Pointer to n1sdp_flash API */
+ struct mod_n1sdp_flash_api *flash_api;
+};
+
+enum rom_event {
+ ROM_EVENT_RUN,
+ ROM_EVENT_COUNT
+};
+
+static struct mod_n1sdp_rom_ctx n1sdp_rom_ctx;
+
+static void jump_to_ramfw(void)
+{
+ uintptr_t const *reset_base =
+ (uintptr_t *)(n1sdp_rom_ctx.rom_config->ramfw_base + 0x4);
+ void (*ramfw_reset_handler)(void);
+
+ /*
+ * Disable interrupts for the duration of the ROM firmware to RAM firmware
+ * transition.
+ */
+ fwk_interrupt_global_disable();
+
+ ramfw_reset_handler = (void (*)(void))*reset_base;
+
+ /*
+ * Execute the RAM firmware's reset handler to pass control from ROM
+ * firmware to the RAM firmware.
+ */
+ ramfw_reset_handler();
+}
+
+/*
+ * Framework handlers
+ */
+static int n1sdp_rom_init(fwk_id_t module_id, unsigned int element_count,
+ const void *data)
+{
+ if ((data == NULL) || (element_count > 0))
+ return FWK_E_PANIC;
+
+ n1sdp_rom_ctx.rom_config = data;
+
+ return FWK_SUCCESS;
+}
+
+static int n1sdp_rom_bind(fwk_id_t id, unsigned int round)
+{
+ int status;
+
+ /* Use second round only (round numbering is zero-indexed) */
+ if (round == 1) {
+ /* Bind to the log component */
+ status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_LOG),
+ FWK_ID_API(FWK_MODULE_IDX_LOG, 0),
+ &n1sdp_rom_ctx.log_api);
+
+ if (status != FWK_SUCCESS)
+ return FWK_E_PANIC;
+
+ /* Bind to the n1sdp_flash component */
+ status = fwk_module_bind(FWK_ID_MODULE(FWK_MODULE_IDX_N1SDP_FLASH),
+ FWK_ID_API(FWK_MODULE_IDX_N1SDP_FLASH, 0),
+ &n1sdp_rom_ctx.flash_api);
+ if (status != FWK_SUCCESS)
+ return FWK_E_PANIC;
+ }
+
+ return FWK_SUCCESS;
+}
+
+static int n1sdp_rom_start(fwk_id_t id)
+{
+ struct fwk_event event = {
+ .source_id = FWK_ID_MODULE(FWK_MODULE_IDX_N1SDP_ROM),
+ .target_id = FWK_ID_MODULE(FWK_MODULE_IDX_N1SDP_ROM),
+ .id = FWK_ID_EVENT(FWK_MODULE_IDX_N1SDP_ROM, ROM_EVENT_RUN),
+ };
+
+ return fwk_thread_put_event(&event);
+}
+
+static int n1sdp_rom_process_event(const struct fwk_event *event,
+ struct fwk_event *resp)
+{
+ struct mod_n1sdp_fip_descriptor *fip_desc_table = NULL;
+ struct mod_n1sdp_fip_descriptor *fip_desc = NULL;
+ unsigned int fip_count = 0;
+ unsigned int i;
+ int status;
+
+ status = n1sdp_rom_ctx.flash_api->get_n1sdp_fip_descriptor_count(
+ FWK_ID_MODULE(FWK_MODULE_IDX_N1SDP_ROM),
+ &fip_count);
+ if (status != FWK_SUCCESS)
+ return status;
+ status = n1sdp_rom_ctx.flash_api->get_n1sdp_fip_descriptor_table(
+ FWK_ID_MODULE(FWK_MODULE_IDX_N1SDP_ROM),
+ &fip_desc_table);
+ if (status != FWK_SUCCESS)
+ return status;
+
+ for (i = 0; i < fip_count; i++) {
+ fip_desc = &fip_desc_table[i];
+ if (fip_desc->type != n1sdp_rom_ctx.rom_config->image_type)
+ continue;
+
+ if (fip_desc->size == 0)
+ return FWK_E_DATA;
+
+ if (fip_desc->type == MOD_N1SDP_FIP_TYPE_MCP_BL2) {
+ n1sdp_rom_ctx.log_api->log(MOD_LOG_GROUP_INFO,
+ "[ROM] Found MCP RAM Firmware at address: 0x%x,"
+ " size: %d bytes, flags: 0x%x\n",
+ fip_desc->address,
+ fip_desc->size,
+ fip_desc->flags);
+ n1sdp_rom_ctx.log_api->log(MOD_LOG_GROUP_INFO,
+ "[ROM] Copying MCP RAM Firmware to ITCRAM...!\n");
+ } else {
+ n1sdp_rom_ctx.log_api->log(MOD_LOG_GROUP_INFO,
+ "[ROM] Found SCP BL2 RAM Firmware at address: 0x%x,"
+ " size: %d bytes, flags: 0x%x\n",
+ fip_desc->address,
+ fip_desc->size,
+ fip_desc->flags);
+ n1sdp_rom_ctx.log_api->log(MOD_LOG_GROUP_INFO,
+ "[ROM] Copying SCP RAM Firmware to ITCRAM...!\n");
+ }
+ break;
+ }
+
+ if (i >= fip_count)
+ return FWK_E_DATA;
+
+ memcpy((void *)n1sdp_rom_ctx.rom_config->ramfw_base,
+ (uint8_t *)fip_desc->address, fip_desc->size);
+ n1sdp_rom_ctx.log_api->log(MOD_LOG_GROUP_INFO, "[ROM] Done!\n");
+
+ n1sdp_rom_ctx.log_api->log(MOD_LOG_GROUP_INFO,
+ "[ROM] Jumping to RAM Firmware\n");
+
+ jump_to_ramfw();
+
+ return FWK_SUCCESS;
+}
+
+/* Module descriptor */
+const struct fwk_module module_n1sdp_rom = {
+ .name = "N1SDP SCP ROM",
+ .type = FWK_MODULE_TYPE_SERVICE,
+ .event_count = ROM_EVENT_COUNT,
+ .init = n1sdp_rom_init,
+ .bind = n1sdp_rom_bind,
+ .start = n1sdp_rom_start,
+ .process_event = n1sdp_rom_process_event,
+};