xref: /rk3399_ARM-atf/plat/arm/board/neoverse_rd/common/nrd_image_load.c (revision 584052c7f80b406666b9597447eeccef4d6deca4)
1 /*
2  * Copyright (c) 2018-2024, 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 #include <platform_def.h>
16 
17 #include <nrd_base_platform_def.h>
18 #include <nrd_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. */
29 void plat_arm_nrd_get_isolated_cpu_list(struct isolated_cpu_mpid_list *list)
30 {
31 	int ret;
32 
33 	ret = sds_init(SDS_SCP_AP_REGION_ID);
34 	if (ret != SDS_OK) {
35 		ERROR("SDS initialization failed, error: %d\n", ret);
36 		panic();
37 	}
38 
39 	ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
40 			SDS_ISOLATED_CPU_LIST_ID, 0, &list->num_entries,
41 			sizeof(list->num_entries), SDS_ACCESS_MODE_CACHED);
42 	if (ret != SDS_OK) {
43 		INFO("SDS CPU num elements read failed, error: %d\n", ret);
44 		list->num_entries = 0;
45 		return;
46 	}
47 
48 	if (list->num_entries > PLATFORM_CORE_COUNT) {
49 		ERROR("Isolated CPU list count %ld greater than max"
50 		      " number supported %d\n",
51 		      list->num_entries, PLATFORM_CORE_COUNT);
52 		panic();
53 	} else if (list->num_entries == 0) {
54 		INFO("SDS isolated CPU list is empty\n");
55 		return;
56 	}
57 
58 	ret = sds_struct_read(SDS_SCP_AP_REGION_ID,
59 			SDS_ISOLATED_CPU_LIST_ID,
60 			sizeof(list->num_entries),
61 			&list->mpid_list,
62 			sizeof(list->mpid_list[0]) * list->num_entries,
63 			SDS_ACCESS_MODE_CACHED);
64 	if (ret != SDS_OK) {
65 		ERROR("SDS CPU list read failed. error: %d\n", ret);
66 		panic();
67 	}
68 }
69 
70 /*******************************************************************************
71  * This function inserts Platform information via device tree nodes as,
72  * system-id {
73  *    platform-id = <0>;
74  *    config-id = <0>;
75  *    isolated-cpu-list = <0>
76  * }
77  ******************************************************************************/
78 static int plat_nrd_append_config_node(void)
79 {
80 	bl_mem_params_node_t *mem_params;
81 	void *fdt;
82 	int nodeoffset, err;
83 	unsigned int platid = 0, platcfg = 0;
84 	struct isolated_cpu_mpid_list cpu_mpid_list = {0};
85 
86 	mem_params = get_bl_mem_params_node(NT_FW_CONFIG_ID);
87 	if (mem_params == NULL) {
88 		ERROR("NT_FW CONFIG base address is NULL");
89 		return -1;
90 	}
91 
92 	fdt = (void *)(mem_params->image_info.image_base);
93 
94 	/* Check the validity of the fdt */
95 	if (fdt_check_header(fdt) != 0) {
96 		ERROR("Invalid NT_FW_CONFIG DTB passed\n");
97 		return -1;
98 	}
99 
100 	nodeoffset = fdt_subnode_offset(fdt, 0, "system-id");
101 	if (nodeoffset < 0) {
102 		ERROR("Failed to get system-id node offset\n");
103 		return -1;
104 	}
105 
106 	platid = plat_arm_nrd_get_platform_id();
107 	err = fdt_setprop_u32(fdt, nodeoffset, "platform-id", platid);
108 	if (err < 0) {
109 		ERROR("Failed to set platform-id\n");
110 		return -1;
111 	}
112 
113 	platcfg = plat_arm_nrd_get_config_id();
114 	err = fdt_setprop_u32(fdt, nodeoffset, "config-id", platcfg);
115 	if (err < 0) {
116 		ERROR("Failed to set config-id\n");
117 		return -1;
118 	}
119 
120 	platcfg = plat_arm_nrd_get_multi_chip_mode();
121 	err = fdt_setprop_u32(fdt, nodeoffset, "multi-chip-mode", platcfg);
122 	if (err < 0) {
123 		ERROR("Failed to set multi-chip-mode\n");
124 		return -1;
125 	}
126 
127 	plat_arm_nrd_get_isolated_cpu_list(&cpu_mpid_list);
128 	if (cpu_mpid_list.num_entries > 0) {
129 		err = fdt_setprop(fdt, nodeoffset, "isolated-cpu-list",
130 				&cpu_mpid_list,
131 				(sizeof(cpu_mpid_list.num_entries) *
132 				(cpu_mpid_list.num_entries + 1)));
133 		if (err < 0) {
134 			ERROR("Failed to set isolated-cpu-list, error: %d\n",
135 			      err);
136 		}
137 	}
138 
139 	flush_dcache_range((uintptr_t)fdt, mem_params->image_info.image_size);
140 
141 	return 0;
142 }
143 
144 /*******************************************************************************
145  * This function returns the list of executable images.
146  ******************************************************************************/
147 bl_params_t *plat_get_next_bl_params(void)
148 {
149 	int ret;
150 
151 	ret = plat_nrd_append_config_node();
152 	if (ret != 0)
153 		panic();
154 
155 	return arm_get_next_bl_params();
156 }
157