diff options
author | Amit Daniel Kachhap <amit.kachhap@arm.com> | 2018-07-20 15:05:06 +0530 |
---|---|---|
committer | ronald-cron-arm <39518861+ronald-cron-arm@users.noreply.github.com> | 2018-10-18 17:22:34 +0000 |
commit | 8d3a72d2c34a149c1ba8267ea13b8b5cad6fc38c (patch) | |
tree | 620b7a04d112cc627bc91ac3fbacde4acabb7db6 /product/sgi575 | |
parent | 24ec64db5b5df1eb54873a87952378cdba8aae41 (diff) |
sgi575/module: Add ROM support
Change-Id: I93384f96dbd5c194a8dedf9d37931cd240f2be94
Signed-off-by: Amit Daniel Kachhap <amit.kachhap@arm.com>
Diffstat (limited to 'product/sgi575')
-rw-r--r-- | product/sgi575/module/sgi575_rom/include/mod_sgi575_rom.h | 45 | ||||
-rw-r--r-- | product/sgi575/module/sgi575_rom/src/Makefile | 11 | ||||
-rw-r--r-- | product/sgi575/module/sgi575_rom/src/mod_sgi575_rom.c | 118 |
3 files changed, 174 insertions, 0 deletions
diff --git a/product/sgi575/module/sgi575_rom/include/mod_sgi575_rom.h b/product/sgi575/module/sgi575_rom/include/mod_sgi575_rom.h new file mode 100644 index 00000000..cd4a0661 --- /dev/null +++ b/product/sgi575/module/sgi575_rom/include/mod_sgi575_rom.h @@ -0,0 +1,45 @@ +/* + * Arm SCP/MCP Software + * Copyright (c) 2018, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MOD_SGI575_ROM_H +#define MOD_SGI575_ROM_H + +#include <stdint.h> + +/*! + * \addtogroup GroupSGI575Module SGI575 Product Modules + * @{ + */ + +/*! + * \defgroup GroupSGI575 ROM Support + * @{ + */ + +/*! + * \brief Module configuration data. + */ +struct sgi575_rom_config { + /*! Base address of the RAM firmware image */ + const uintptr_t ramfw_base; + + /*! Base address of the NOR flash memory */ + const uintptr_t nor_base; + + /*! The RAM size to load */ + const unsigned int load_ram_size; +}; + +/*! + * @} + */ + +/*! + * @} + */ + +#endif /* MOD_SGI575_ROM_H */ diff --git a/product/sgi575/module/sgi575_rom/src/Makefile b/product/sgi575/module/sgi575_rom/src/Makefile new file mode 100644 index 00000000..4e1226e4 --- /dev/null +++ b/product/sgi575/module/sgi575_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 := sgi575 ROM +BS_LIB_SOURCES := mod_sgi575_rom.c + +include $(BS_DIR)/lib.mk diff --git a/product/sgi575/module/sgi575_rom/src/mod_sgi575_rom.c b/product/sgi575/module/sgi575_rom/src/mod_sgi575_rom.c new file mode 100644 index 00000000..8375b9c4 --- /dev/null +++ b/product/sgi575/module/sgi575_rom/src/mod_sgi575_rom.c @@ -0,0 +1,118 @@ +/* + * 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_log.h> +#include <mod_sgi575_rom.h> + +static const struct sgi575_rom_config *rom_config; +static struct mod_log_api *log_api; + +enum rom_event { + ROM_EVENT_RUN, + ROM_EVENT_COUNT +}; + +/* + * This function assumes that the RAM firmware image is located at the beginning + * of the SCP SRAM. The reset handler will be at offset 0x4 (the second entry of + * the vector table). + */ +static void jump_to_ramfw(void) +{ + uintptr_t const *reset_base = (uintptr_t *)(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 API + */ +static int sgi575_rom_init(fwk_id_t module_id, unsigned int element_count, + const void *data) +{ + rom_config = data; + + return FWK_SUCCESS; +} + +static int sgi575_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), + &log_api); + + if (status != FWK_SUCCESS) + return FWK_E_PANIC; + } + + return FWK_SUCCESS; +} + +static int sgi575_rom_start(fwk_id_t id) +{ + int status; + struct fwk_event event = { + .source_id = FWK_ID_MODULE(FWK_MODULE_IDX_SGI575_ROM), + .target_id = FWK_ID_MODULE(FWK_MODULE_IDX_SGI575_ROM), + .id = FWK_ID_EVENT(FWK_MODULE_IDX_SGI575_ROM, ROM_EVENT_RUN), + }; + + status = fwk_thread_put_event(&event); + + return status; +} + +static int sgi575_rom_process_event(const struct fwk_event *event, + struct fwk_event *resp) +{ + log_api->log(MOD_LOG_GROUP_INFO, "[ROM] Launch RAM\n"); + + if (rom_config->load_ram_size != 0) { + memcpy((void *)rom_config->ramfw_base, + (uint8_t *)rom_config->nor_base, rom_config->load_ram_size); + } + + jump_to_ramfw(); + + return FWK_SUCCESS; +} + +/* Module descriptor */ +const struct fwk_module module_sgi575_rom = { + .name = "SGI575_ROM", + .type = FWK_MODULE_TYPE_SERVICE, + .event_count = ROM_EVENT_COUNT, + .init = sgi575_rom_init, + .bind = sgi575_rom_bind, + .start = sgi575_rom_start, + .process_event = sgi575_rom_process_event, +}; |