diff options
author | Deepak Pandey <Deepak.Pandey@arm.com> | 2018-12-13 10:54:14 +0530 |
---|---|---|
committer | ronald-cron-arm <39518861+ronald-cron-arm@users.noreply.github.com> | 2018-12-21 12:39:56 +0000 |
commit | 30e205ea9fbbe795fe4889ccaa7ac629a51d87c2 (patch) | |
tree | 2dfc7e3d0df485902b64130d5c029818366ae180 | |
parent | 649bc5ebb5a045e8ee59fef6d92e81ddcb207bab (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.h | 42 | ||||
-rw-r--r-- | product/n1sdp/module/n1sdp_rom/src/Makefile | 11 | ||||
-rw-r--r-- | product/n1sdp/module/n1sdp_rom/src/mod_n1sdp_rom.c | 185 |
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, +}; |