julhal01 | 37e1aea | 2021-02-09 15:22:20 +0000 | [diff] [blame] | 1 | // SPDX-License-Identifier: BSD-3-Clause |
| 2 | /* |
| 3 | * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. |
| 4 | */ |
| 5 | |
| 6 | #include <string.h> |
Julian Hall | 7048d30 | 2021-06-03 16:07:28 +0100 | [diff] [blame] | 7 | #include <config/interface/config_store.h> |
| 8 | #include <config/interface/config_blob.h> |
julhal01 | 37e1aea | 2021-02-09 15:22:20 +0000 | [diff] [blame] | 9 | #include <platform/interface/device_region.h> |
Imre Kis | fe6521e | 2021-10-27 20:20:37 +0200 | [diff] [blame^] | 10 | #include "platform/interface/memory_region.h" |
julhal01 | 37e1aea | 2021-02-09 15:22:20 +0000 | [diff] [blame] | 11 | #include "sp_config_loader.h" |
| 12 | |
| 13 | |
Imre Kis | fe6521e | 2021-10-27 20:20:37 +0200 | [diff] [blame^] | 14 | struct sp_param_region { |
julhal01 | 37e1aea | 2021-02-09 15:22:20 +0000 | [diff] [blame] | 15 | char name[16]; |
| 16 | uintptr_t location; |
| 17 | size_t size; |
| 18 | }; |
| 19 | |
Julian Hall | 7048d30 | 2021-06-03 16:07:28 +0100 | [diff] [blame] | 20 | static void load_device_regions(const struct ffa_name_value_pair *value_pair); |
| 21 | static void load_memory_regions(const struct ffa_name_value_pair *value_pair); |
| 22 | static void load_blob(const struct ffa_name_value_pair *value_pair); |
| 23 | |
julhal01 | 37e1aea | 2021-02-09 15:22:20 +0000 | [diff] [blame] | 24 | /** |
Julian Hall | 7048d30 | 2021-06-03 16:07:28 +0100 | [diff] [blame] | 25 | * Loads externally provided configuration data passed into the SP via |
| 26 | * FFA initialisation parameters. Data can originate from |
| 27 | * the SP manifest, an external device tree or a dynamic configuration |
| 28 | * mechanism such as a handover block (HOB). |
julhal01 | 37e1aea | 2021-02-09 15:22:20 +0000 | [diff] [blame] | 29 | */ |
| 30 | void sp_config_load(struct ffa_init_info *init_info) |
| 31 | { |
| 32 | /* Load deployment specific configuration */ |
| 33 | for (size_t param_index = 0; param_index < init_info->count; param_index++) { |
| 34 | |
| 35 | if (!strcmp((const char *)init_info->nvp[param_index].name,"DEVICE_REGIONS")) { |
| 36 | |
Julian Hall | 7048d30 | 2021-06-03 16:07:28 +0100 | [diff] [blame] | 37 | load_device_regions(&init_info->nvp[param_index]); |
| 38 | } |
| 39 | else if (!strcmp((const char *)init_info->nvp[param_index].name,"MEMORY_REGIONS")) { |
julhal01 | 37e1aea | 2021-02-09 15:22:20 +0000 | [diff] [blame] | 40 | |
Julian Hall | 7048d30 | 2021-06-03 16:07:28 +0100 | [diff] [blame] | 41 | load_memory_regions(&init_info->nvp[param_index]); |
| 42 | } |
| 43 | else { |
julhal01 | 37e1aea | 2021-02-09 15:22:20 +0000 | [diff] [blame] | 44 | |
Julian Hall | 7048d30 | 2021-06-03 16:07:28 +0100 | [diff] [blame] | 45 | load_blob(&init_info->nvp[param_index]); |
julhal01 | 37e1aea | 2021-02-09 15:22:20 +0000 | [diff] [blame] | 46 | } |
| 47 | } |
| 48 | } |
Julian Hall | 7048d30 | 2021-06-03 16:07:28 +0100 | [diff] [blame] | 49 | |
| 50 | static void load_device_regions(const struct ffa_name_value_pair *value_pair) |
| 51 | { |
Imre Kis | fe6521e | 2021-10-27 20:20:37 +0200 | [diff] [blame^] | 52 | struct sp_param_region *d = (struct sp_param_region *)value_pair->value; |
Julian Hall | 7048d30 | 2021-06-03 16:07:28 +0100 | [diff] [blame] | 53 | |
| 54 | /* Iterate over the device regions */ |
| 55 | while ((uintptr_t)d < (value_pair->value + value_pair->size)) { |
| 56 | |
| 57 | struct device_region device_region; |
| 58 | |
| 59 | strcpy(device_region.dev_class, d->name); |
| 60 | device_region.dev_instance = 0; |
| 61 | device_region.base_addr = d->location; |
| 62 | device_region.io_region_size = d->size; |
| 63 | |
| 64 | config_store_add(CONFIG_CLASSIFIER_DEVICE_REGION, |
| 65 | device_region.dev_class, device_region.dev_instance, |
| 66 | &device_region, sizeof(device_region)); |
| 67 | |
| 68 | ++d; |
| 69 | } |
| 70 | } |
| 71 | |
| 72 | static void load_memory_regions(const struct ffa_name_value_pair *value_pair) |
| 73 | { |
Imre Kis | fe6521e | 2021-10-27 20:20:37 +0200 | [diff] [blame^] | 74 | struct sp_param_region *d = (struct sp_param_region *)value_pair->value; |
| 75 | |
| 76 | /* Iterate over the device regions */ |
| 77 | while ((uintptr_t)d < (value_pair->value + value_pair->size)) { |
| 78 | |
| 79 | struct memory_region memory_region; |
| 80 | |
| 81 | strcpy(memory_region.region_name, d->name); |
| 82 | memory_region.base_addr = d->location; |
| 83 | memory_region.region_size = d->size; |
| 84 | |
| 85 | config_store_add(CONFIG_CLASSIFIER_MEMORY_REGION, |
| 86 | memory_region.region_name, 0, |
| 87 | &memory_region, sizeof(memory_region)); |
| 88 | |
| 89 | ++d; |
| 90 | } |
Julian Hall | 7048d30 | 2021-06-03 16:07:28 +0100 | [diff] [blame] | 91 | } |
| 92 | |
| 93 | static void load_blob(const struct ffa_name_value_pair *value_pair) |
| 94 | { |
| 95 | struct config_blob blob; |
| 96 | |
| 97 | blob.data = (const void*)value_pair->value; |
| 98 | blob.data_len = value_pair->size; |
| 99 | |
| 100 | config_store_add(CONFIG_CLASSIFIER_BLOB, |
| 101 | (const char *)value_pair->name, 0, |
| 102 | &blob, sizeof(blob)); |
| 103 | } |