1 /*
2 * Copyright (c) 2018-2022, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <libfdt.h>
8
9 #include <arch_helpers.h>
10 #include <common/debug.h>
11 #include <common/desc_image_load.h>
12 #include <drivers/arm/css/sds.h>
13 #include <plat/arm/common/plat_arm.h>
14 #include <plat/common/platform.h>
15
16 #include <platform_def.h>
17 #include <sgi_base_platform_def.h>
18 #include <sgi_variant.h>
19
20 /*
21 * Information about the isolated CPUs obtained from SDS.
22 */
23 struct isolated_cpu_mpid_list {
24 uint64_t num_entries; /* Number of entries in the list */
25 uint64_t mpid_list[PLATFORM_CORE_COUNT]; /* List of isolated CPU MPIDs */
26 };
27
28 /* Function to read isolated CPU MPID list from SDS. */
plat_arm_sgi_get_isolated_cpu_list(struct isolated_cpu_mpid_list * list)29 void plat_arm_sgi_get_isolated_cpu_list(struct isolated_cpu_mpid_list *list)
30 {
31 int ret;
32
33 ret = sds_init();
34 if (ret != SDS_OK) {
35 ERROR("SDS initialization failed, error: %d\n", ret);
36 panic();
37 }
38
39 ret = sds_struct_read(SDS_ISOLATED_CPU_LIST_ID, 0, &list->num_entries,
40 sizeof(list->num_entries), SDS_ACCESS_MODE_CACHED);
41 if (ret != SDS_OK) {
42 INFO("SDS CPU num elements read failed, error: %d\n", ret);
43 list->num_entries = 0;
44 return;
45 }
46
47 if (list->num_entries > PLATFORM_CORE_COUNT) {
48 ERROR("Isolated CPU list count %ld greater than max"
49 " number supported %d\n",
50 list->num_entries, PLATFORM_CORE_COUNT);
51 panic();
52 } else if (list->num_entries == 0) {
53 INFO("SDS isolated CPU list is empty\n");
54 return;
55 }
56
57 ret = sds_struct_read(SDS_ISOLATED_CPU_LIST_ID,
58 sizeof(list->num_entries),
59 &list->mpid_list,
60 sizeof(list->mpid_list[0]) * list->num_entries,
61 SDS_ACCESS_MODE_CACHED);
62 if (ret != SDS_OK) {
63 ERROR("SDS CPU list read failed. error: %d\n", ret);
64 panic();
65 }
66 }
67
68 /*******************************************************************************
69 * This function inserts Platform information via device tree nodes as,
70 * system-id {
71 * platform-id = <0>;
72 * config-id = <0>;
73 * isolated-cpu-list = <0>
74 * }
75 ******************************************************************************/
plat_sgi_append_config_node(void)76 static int plat_sgi_append_config_node(void)
77 {
78 bl_mem_params_node_t *mem_params;
79 void *fdt;
80 int nodeoffset, err;
81 unsigned int platid = 0, platcfg = 0;
82 struct isolated_cpu_mpid_list cpu_mpid_list = {0};
83
84 mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
85 if (mem_params == NULL) {
86 ERROR("NT_FW CONFIG base address is NULL");
87 return -1;
88 }
89
90 fdt = (void *)(mem_params->image_info.image_base);
91
92 /* Check the validity of the fdt */
93 if (fdt_check_header(fdt) != 0) {
94 ERROR("Invalid NT_FW_CONFIG DTB passed\n");
95 return -1;
96 }
97
98 nodeoffset = fdt_subnode_offset(fdt, 0, "system-id");
99 if (nodeoffset < 0) {
100 ERROR("Failed to get system-id node offset\n");
101 return -1;
102 }
103
104 platid = plat_arm_sgi_get_platform_id();
105 err = fdt_setprop_u32(fdt, nodeoffset, "platform-id", platid);
106 if (err < 0) {
107 ERROR("Failed to set platform-id\n");
108 return -1;
109 }
110
111 platcfg = plat_arm_sgi_get_config_id();
112 err = fdt_setprop_u32(fdt, nodeoffset, "config-id", platcfg);
113 if (err < 0) {
114 ERROR("Failed to set config-id\n");
115 return -1;
116 }
117
118 platcfg = plat_arm_sgi_get_multi_chip_mode();
119 err = fdt_setprop_u32(fdt, nodeoffset, "multi-chip-mode", platcfg);
120 if (err < 0) {
121 ERROR("Failed to set multi-chip-mode\n");
122 return -1;
123 }
124
125 plat_arm_sgi_get_isolated_cpu_list(&cpu_mpid_list);
126 if (cpu_mpid_list.num_entries > 0) {
127 err = fdt_setprop(fdt, nodeoffset, "isolated-cpu-list",
128 &cpu_mpid_list,
129 (sizeof(cpu_mpid_list.num_entries) *
130 (cpu_mpid_list.num_entries + 1)));
131 if (err < 0) {
132 ERROR("Failed to set isolated-cpu-list, error: %d\n",
133 err);
134 }
135 }
136
137 flush_dcache_range((uintptr_t)fdt, mem_params->image_info.image_size);
138
139 return 0;
140 }
141
142 /*******************************************************************************
143 * This function returns the list of executable images.
144 ******************************************************************************/
plat_get_next_bl_params(void)145 bl_params_t *plat_get_next_bl_params(void)
146 {
147 int ret;
148
149 ret = plat_sgi_append_config_node();
150 if (ret != 0)
151 panic();
152
153 return arm_get_next_bl_params();
154 }
155
156