xref: /arm-trusted-firmware/plat/arm/common/fconf/fconf_ethosn_getter.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2021-2023, Arm Limited. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <assert.h>
8*91f16700Schasinglulu #include <string.h>
9*91f16700Schasinglulu 
10*91f16700Schasinglulu #include <common/debug.h>
11*91f16700Schasinglulu #include <common/fdt_wrappers.h>
12*91f16700Schasinglulu #include <libfdt.h>
13*91f16700Schasinglulu #include <plat/arm/common/fconf_ethosn_getter.h>
14*91f16700Schasinglulu 
15*91f16700Schasinglulu struct ethosn_config_t ethosn_config = {0};
16*91f16700Schasinglulu 
17*91f16700Schasinglulu struct ethosn_sub_allocator_t {
18*91f16700Schasinglulu 	const char *name;
19*91f16700Schasinglulu 	size_t name_len;
20*91f16700Schasinglulu 	uint32_t stream_id;
21*91f16700Schasinglulu };
22*91f16700Schasinglulu 
23*91f16700Schasinglulu static int fdt_node_read_reserved_memory_addr(const void *fdt,
24*91f16700Schasinglulu 					      int dev_node,
25*91f16700Schasinglulu 					      uint64_t *reserved_mem_addrs)
26*91f16700Schasinglulu {
27*91f16700Schasinglulu 	uintptr_t addr;
28*91f16700Schasinglulu 	uint32_t phandle;
29*91f16700Schasinglulu 	int err;
30*91f16700Schasinglulu 	int mem_node;
31*91f16700Schasinglulu 
32*91f16700Schasinglulu 	err = fdt_read_uint32(fdt, dev_node, "memory-region", &phandle);
33*91f16700Schasinglulu 	if (err != 0) {
34*91f16700Schasinglulu 		ERROR("FCONF: Failed to get reserved memory phandle\n");
35*91f16700Schasinglulu 		return err;
36*91f16700Schasinglulu 	}
37*91f16700Schasinglulu 
38*91f16700Schasinglulu 	mem_node = fdt_node_offset_by_phandle(fdt, phandle);
39*91f16700Schasinglulu 	if (mem_node < 0) {
40*91f16700Schasinglulu 		ERROR("FCONF: Failed to find reserved memory node from phandle\n");
41*91f16700Schasinglulu 		return mem_node;
42*91f16700Schasinglulu 	}
43*91f16700Schasinglulu 
44*91f16700Schasinglulu 	err = fdt_get_reg_props_by_index(fdt, mem_node, 0U, &addr, NULL);
45*91f16700Schasinglulu 	if (err != 0) {
46*91f16700Schasinglulu 		ERROR("FCONF: Failed to read reserved memory address\n");
47*91f16700Schasinglulu 		return err;
48*91f16700Schasinglulu 	}
49*91f16700Schasinglulu 
50*91f16700Schasinglulu 	*reserved_mem_addrs = addr;
51*91f16700Schasinglulu 
52*91f16700Schasinglulu 	return 0;
53*91f16700Schasinglulu }
54*91f16700Schasinglulu 
55*91f16700Schasinglulu static bool fdt_node_has_reserved_memory(const void *fdt, int dev_node)
56*91f16700Schasinglulu {
57*91f16700Schasinglulu 	return fdt_get_property(fdt, dev_node, "memory-region", NULL) != NULL;
58*91f16700Schasinglulu }
59*91f16700Schasinglulu 
60*91f16700Schasinglulu static int fdt_node_get_iommus_stream_id(const void *fdt, int node, uint32_t *stream_id)
61*91f16700Schasinglulu {
62*91f16700Schasinglulu 	int err;
63*91f16700Schasinglulu 	uint32_t iommus_array[2] = {0U};
64*91f16700Schasinglulu 
65*91f16700Schasinglulu 	err = fdt_read_uint32_array(fdt, node, "iommus", 2U, iommus_array);
66*91f16700Schasinglulu 	if (err) {
67*91f16700Schasinglulu 		return err;
68*91f16700Schasinglulu 	}
69*91f16700Schasinglulu 
70*91f16700Schasinglulu 	*stream_id = iommus_array[1];
71*91f16700Schasinglulu 	return 0;
72*91f16700Schasinglulu }
73*91f16700Schasinglulu 
74*91f16700Schasinglulu static int fdt_node_populate_sub_allocators(const void *fdt,
75*91f16700Schasinglulu 					    int alloc_node,
76*91f16700Schasinglulu 					    struct ethosn_sub_allocator_t *sub_allocators,
77*91f16700Schasinglulu 					    size_t num_allocs)
78*91f16700Schasinglulu {
79*91f16700Schasinglulu 	int sub_node;
80*91f16700Schasinglulu 	size_t i;
81*91f16700Schasinglulu 	int err = -FDT_ERR_NOTFOUND;
82*91f16700Schasinglulu 	uint32_t found_sub_allocators = 0U;
83*91f16700Schasinglulu 
84*91f16700Schasinglulu 	fdt_for_each_subnode(sub_node, fdt, alloc_node) {
85*91f16700Schasinglulu 		const char *node_name;
86*91f16700Schasinglulu 
87*91f16700Schasinglulu 		if (!fdt_node_is_enabled(fdt, sub_node)) {
88*91f16700Schasinglulu 			/* Ignore disabled node */
89*91f16700Schasinglulu 			continue;
90*91f16700Schasinglulu 		}
91*91f16700Schasinglulu 
92*91f16700Schasinglulu 		if (fdt_node_check_compatible(fdt, sub_node, "ethosn-memory") != 0) {
93*91f16700Schasinglulu 			continue;
94*91f16700Schasinglulu 		}
95*91f16700Schasinglulu 
96*91f16700Schasinglulu 		node_name = fdt_get_name(fdt, sub_node, NULL);
97*91f16700Schasinglulu 		for (i = 0U; i < num_allocs; ++i) {
98*91f16700Schasinglulu 			if (strncmp(node_name, sub_allocators[i].name,
99*91f16700Schasinglulu 				    sub_allocators[i].name_len) != 0) {
100*91f16700Schasinglulu 				continue;
101*91f16700Schasinglulu 			}
102*91f16700Schasinglulu 
103*91f16700Schasinglulu 			err = fdt_node_get_iommus_stream_id(fdt, sub_node,
104*91f16700Schasinglulu 							    &sub_allocators[i].stream_id);
105*91f16700Schasinglulu 			if (err) {
106*91f16700Schasinglulu 				ERROR("FCONF: Failed to get stream ID from sub-allocator %s\n",
107*91f16700Schasinglulu 				      node_name);
108*91f16700Schasinglulu 				return err;
109*91f16700Schasinglulu 			}
110*91f16700Schasinglulu 
111*91f16700Schasinglulu 			++found_sub_allocators;
112*91f16700Schasinglulu 			/* Nothing more to do for this node */
113*91f16700Schasinglulu 			break;
114*91f16700Schasinglulu 		}
115*91f16700Schasinglulu 
116*91f16700Schasinglulu 		/* Check that at least one of the sub-allocators matched */
117*91f16700Schasinglulu 		if (i == num_allocs) {
118*91f16700Schasinglulu 			ERROR("FCONF: Unknown sub-allocator %s\n", node_name);
119*91f16700Schasinglulu 			return -FDT_ERR_BADSTRUCTURE;
120*91f16700Schasinglulu 		}
121*91f16700Schasinglulu 	}
122*91f16700Schasinglulu 
123*91f16700Schasinglulu 	if ((sub_node < 0) && (sub_node != -FDT_ERR_NOTFOUND)) {
124*91f16700Schasinglulu 		ERROR("FCONF: Failed to parse sub-allocators\n");
125*91f16700Schasinglulu 		return -FDT_ERR_BADSTRUCTURE;
126*91f16700Schasinglulu 	}
127*91f16700Schasinglulu 
128*91f16700Schasinglulu 	if (err == -FDT_ERR_NOTFOUND) {
129*91f16700Schasinglulu 		ERROR("FCONF: No matching sub-allocator found\n");
130*91f16700Schasinglulu 		return err;
131*91f16700Schasinglulu 	}
132*91f16700Schasinglulu 
133*91f16700Schasinglulu 	if (found_sub_allocators != num_allocs) {
134*91f16700Schasinglulu 		ERROR("FCONF: Not all sub-allocators were found\n");
135*91f16700Schasinglulu 		return -FDT_ERR_BADSTRUCTURE;
136*91f16700Schasinglulu 	}
137*91f16700Schasinglulu 
138*91f16700Schasinglulu 	return 0;
139*91f16700Schasinglulu }
140*91f16700Schasinglulu 
141*91f16700Schasinglulu static int fdt_node_populate_main_allocator(const void *fdt,
142*91f16700Schasinglulu 					    int alloc_node,
143*91f16700Schasinglulu 					    struct ethosn_main_allocator_t *allocator)
144*91f16700Schasinglulu {
145*91f16700Schasinglulu 	int err;
146*91f16700Schasinglulu 	struct ethosn_sub_allocator_t sub_allocators[] = {
147*91f16700Schasinglulu 		{.name = "firmware", .name_len = 8U},
148*91f16700Schasinglulu 		{.name = "working_data", .name_len = 12U}
149*91f16700Schasinglulu 	};
150*91f16700Schasinglulu 
151*91f16700Schasinglulu 	err = fdt_node_populate_sub_allocators(fdt, alloc_node, sub_allocators,
152*91f16700Schasinglulu 					       ARRAY_SIZE(sub_allocators));
153*91f16700Schasinglulu 	if (err) {
154*91f16700Schasinglulu 		return err;
155*91f16700Schasinglulu 	}
156*91f16700Schasinglulu 
157*91f16700Schasinglulu 	allocator->firmware.stream_id = sub_allocators[0].stream_id;
158*91f16700Schasinglulu 	allocator->working_data.stream_id = sub_allocators[1].stream_id;
159*91f16700Schasinglulu 
160*91f16700Schasinglulu 	return 0;
161*91f16700Schasinglulu }
162*91f16700Schasinglulu 
163*91f16700Schasinglulu static int fdt_node_populate_asset_allocator(const void *fdt,
164*91f16700Schasinglulu 					    int alloc_node,
165*91f16700Schasinglulu 					    struct ethosn_asset_allocator_t *allocator)
166*91f16700Schasinglulu {
167*91f16700Schasinglulu 	int err;
168*91f16700Schasinglulu 	struct ethosn_sub_allocator_t sub_allocators[] = {
169*91f16700Schasinglulu 		{.name = "command_stream", .name_len = 14U},
170*91f16700Schasinglulu 		{.name = "weight_data", .name_len = 11U},
171*91f16700Schasinglulu 		{.name = "buffer_data", .name_len = 11U},
172*91f16700Schasinglulu 		{.name = "intermediate_data", .name_len = 17U}
173*91f16700Schasinglulu 	};
174*91f16700Schasinglulu 
175*91f16700Schasinglulu 	err = fdt_node_populate_sub_allocators(fdt, alloc_node, sub_allocators,
176*91f16700Schasinglulu 					       ARRAY_SIZE(sub_allocators));
177*91f16700Schasinglulu 	if (err) {
178*91f16700Schasinglulu 		return err;
179*91f16700Schasinglulu 	}
180*91f16700Schasinglulu 
181*91f16700Schasinglulu 
182*91f16700Schasinglulu 	allocator->command_stream.stream_id = sub_allocators[0].stream_id;
183*91f16700Schasinglulu 	allocator->weight_data.stream_id = sub_allocators[1].stream_id;
184*91f16700Schasinglulu 	allocator->buffer_data.stream_id = sub_allocators[2].stream_id;
185*91f16700Schasinglulu 	allocator->intermediate_data.stream_id = sub_allocators[3].stream_id;
186*91f16700Schasinglulu 	return 0;
187*91f16700Schasinglulu }
188*91f16700Schasinglulu 
189*91f16700Schasinglulu static int fdt_node_populate_core(const void *fdt,
190*91f16700Schasinglulu 				  int device_node,
191*91f16700Schasinglulu 				  int core_node,
192*91f16700Schasinglulu 				  bool has_reserved_memory,
193*91f16700Schasinglulu 				  uint32_t core_index,
194*91f16700Schasinglulu 				  struct ethosn_core_t *core)
195*91f16700Schasinglulu {
196*91f16700Schasinglulu 	int err;
197*91f16700Schasinglulu 	int sub_node;
198*91f16700Schasinglulu 	uintptr_t core_addr;
199*91f16700Schasinglulu 
200*91f16700Schasinglulu 	err = fdt_get_reg_props_by_index(fdt, device_node, core_index,
201*91f16700Schasinglulu 					 &core_addr, NULL);
202*91f16700Schasinglulu 	if (err < 0) {
203*91f16700Schasinglulu 		ERROR("FCONF: Failed to read reg property for NPU core %u\n",
204*91f16700Schasinglulu 		      core_index);
205*91f16700Schasinglulu 		return err;
206*91f16700Schasinglulu 	}
207*91f16700Schasinglulu 
208*91f16700Schasinglulu 	err = -FDT_ERR_NOTFOUND;
209*91f16700Schasinglulu 	fdt_for_each_subnode(sub_node, fdt, core_node) {
210*91f16700Schasinglulu 
211*91f16700Schasinglulu 		if (!fdt_node_is_enabled(fdt, sub_node)) {
212*91f16700Schasinglulu 			continue;
213*91f16700Schasinglulu 		}
214*91f16700Schasinglulu 
215*91f16700Schasinglulu 		if (fdt_node_check_compatible(fdt,
216*91f16700Schasinglulu 					      sub_node,
217*91f16700Schasinglulu 					      "ethosn-main_allocator") != 0) {
218*91f16700Schasinglulu 			continue;
219*91f16700Schasinglulu 		}
220*91f16700Schasinglulu 
221*91f16700Schasinglulu 		if (has_reserved_memory) {
222*91f16700Schasinglulu 			ERROR("FCONF: Main allocator not supported when using reserved memory\n");
223*91f16700Schasinglulu 			return -FDT_ERR_BADSTRUCTURE;
224*91f16700Schasinglulu 		}
225*91f16700Schasinglulu 
226*91f16700Schasinglulu 		if (err != -FDT_ERR_NOTFOUND) {
227*91f16700Schasinglulu 			ERROR("FCONF: NPU core 0x%lx has more than one main allocator\n",
228*91f16700Schasinglulu 			      core_addr);
229*91f16700Schasinglulu 			return -FDT_ERR_BADSTRUCTURE;
230*91f16700Schasinglulu 		}
231*91f16700Schasinglulu 
232*91f16700Schasinglulu 		err = fdt_node_populate_main_allocator(fdt, sub_node, &core->main_allocator);
233*91f16700Schasinglulu 		if (err) {
234*91f16700Schasinglulu 			ERROR("FCONF: Failed to parse main allocator for NPU core 0x%lx\n",
235*91f16700Schasinglulu 			      core_addr);
236*91f16700Schasinglulu 			return err;
237*91f16700Schasinglulu 		}
238*91f16700Schasinglulu 	}
239*91f16700Schasinglulu 
240*91f16700Schasinglulu 	if ((sub_node < 0) && (sub_node != -FDT_ERR_NOTFOUND)) {
241*91f16700Schasinglulu 		ERROR("FCONF: Failed to parse core sub nodes\n");
242*91f16700Schasinglulu 		return -FDT_ERR_BADSTRUCTURE;
243*91f16700Schasinglulu 	}
244*91f16700Schasinglulu 
245*91f16700Schasinglulu 	if (!has_reserved_memory && err) {
246*91f16700Schasinglulu 		ERROR("FCONF: Main allocator not found for NPU core 0x%lx\n",
247*91f16700Schasinglulu 		      core_addr);
248*91f16700Schasinglulu 		return err;
249*91f16700Schasinglulu 	}
250*91f16700Schasinglulu 
251*91f16700Schasinglulu 	core->addr = core_addr;
252*91f16700Schasinglulu 
253*91f16700Schasinglulu 	return 0;
254*91f16700Schasinglulu }
255*91f16700Schasinglulu 
256*91f16700Schasinglulu int fconf_populate_ethosn_config(uintptr_t config)
257*91f16700Schasinglulu {
258*91f16700Schasinglulu 	int ethosn_node;
259*91f16700Schasinglulu 	uint32_t dev_count = 0U;
260*91f16700Schasinglulu 	const void *hw_conf_dtb = (const void *)config;
261*91f16700Schasinglulu 
262*91f16700Schasinglulu 	INFO("Probing Arm(R) Ethos(TM)-N NPU\n");
263*91f16700Schasinglulu 
264*91f16700Schasinglulu 	fdt_for_each_compatible_node(hw_conf_dtb, ethosn_node, "ethosn") {
265*91f16700Schasinglulu 		struct ethosn_device_t *dev = &ethosn_config.devices[dev_count];
266*91f16700Schasinglulu 		uint32_t dev_asset_alloc_count = 0U;
267*91f16700Schasinglulu 		uint32_t dev_core_count = 0U;
268*91f16700Schasinglulu 		uint64_t reserved_memory_addr = 0U;
269*91f16700Schasinglulu 		bool has_reserved_memory;
270*91f16700Schasinglulu 		int sub_node;
271*91f16700Schasinglulu 		int err;
272*91f16700Schasinglulu 
273*91f16700Schasinglulu 		if (!fdt_node_is_enabled(hw_conf_dtb, ethosn_node)) {
274*91f16700Schasinglulu 			continue;
275*91f16700Schasinglulu 		}
276*91f16700Schasinglulu 
277*91f16700Schasinglulu 		if (dev_count >= ETHOSN_DEV_NUM_MAX) {
278*91f16700Schasinglulu 			ERROR("FCONF: Reached max number of NPUs\n");
279*91f16700Schasinglulu 			return -FDT_ERR_BADSTRUCTURE;
280*91f16700Schasinglulu 		}
281*91f16700Schasinglulu 
282*91f16700Schasinglulu 		has_reserved_memory = fdt_node_has_reserved_memory(hw_conf_dtb, ethosn_node);
283*91f16700Schasinglulu 		if (has_reserved_memory) {
284*91f16700Schasinglulu 			err = fdt_node_read_reserved_memory_addr(hw_conf_dtb,
285*91f16700Schasinglulu 								 ethosn_node,
286*91f16700Schasinglulu 								 &reserved_memory_addr);
287*91f16700Schasinglulu 			if (err != 0) {
288*91f16700Schasinglulu 				return err;
289*91f16700Schasinglulu 			}
290*91f16700Schasinglulu 		}
291*91f16700Schasinglulu 
292*91f16700Schasinglulu 		fdt_for_each_subnode(sub_node, hw_conf_dtb, ethosn_node) {
293*91f16700Schasinglulu 
294*91f16700Schasinglulu 			if (!fdt_node_is_enabled(hw_conf_dtb, sub_node)) {
295*91f16700Schasinglulu 				/* Ignore disabled sub node */
296*91f16700Schasinglulu 				continue;
297*91f16700Schasinglulu 			}
298*91f16700Schasinglulu 
299*91f16700Schasinglulu 			if (fdt_node_check_compatible(hw_conf_dtb,
300*91f16700Schasinglulu 						      sub_node,
301*91f16700Schasinglulu 						      "ethosn-core") == 0) {
302*91f16700Schasinglulu 
303*91f16700Schasinglulu 				if (dev_core_count >= ETHOSN_DEV_CORE_NUM_MAX) {
304*91f16700Schasinglulu 					ERROR("FCONF: Reached max number of NPU cores for NPU %u\n",
305*91f16700Schasinglulu 					      dev_count);
306*91f16700Schasinglulu 					return -FDT_ERR_BADSTRUCTURE;
307*91f16700Schasinglulu 				}
308*91f16700Schasinglulu 
309*91f16700Schasinglulu 				err = fdt_node_populate_core(hw_conf_dtb,
310*91f16700Schasinglulu 							     ethosn_node,
311*91f16700Schasinglulu 							     sub_node,
312*91f16700Schasinglulu 							     has_reserved_memory,
313*91f16700Schasinglulu 							     dev_core_count,
314*91f16700Schasinglulu 							     &(dev->cores[dev_core_count]));
315*91f16700Schasinglulu 				if (err) {
316*91f16700Schasinglulu 					return err;
317*91f16700Schasinglulu 				}
318*91f16700Schasinglulu 				++dev_core_count;
319*91f16700Schasinglulu 			} else if (fdt_node_check_compatible(hw_conf_dtb,
320*91f16700Schasinglulu 							     sub_node,
321*91f16700Schasinglulu 							     "ethosn-asset_allocator") == 0) {
322*91f16700Schasinglulu 
323*91f16700Schasinglulu 				if (dev_asset_alloc_count >=
324*91f16700Schasinglulu 				    ETHOSN_DEV_ASSET_ALLOCATOR_NUM_MAX) {
325*91f16700Schasinglulu 					ERROR("FCONF: Reached max number of asset allocators for NPU %u\n",
326*91f16700Schasinglulu 					      dev_count);
327*91f16700Schasinglulu 					return -FDT_ERR_BADSTRUCTURE;
328*91f16700Schasinglulu 				}
329*91f16700Schasinglulu 
330*91f16700Schasinglulu 				if (has_reserved_memory) {
331*91f16700Schasinglulu 					ERROR("FCONF: Asset allocator not supported when using reserved memory\n");
332*91f16700Schasinglulu 					return -FDT_ERR_BADSTRUCTURE;
333*91f16700Schasinglulu 				}
334*91f16700Schasinglulu 
335*91f16700Schasinglulu 				err = fdt_node_populate_asset_allocator(hw_conf_dtb,
336*91f16700Schasinglulu 									sub_node,
337*91f16700Schasinglulu 									&(dev->asset_allocators[dev_asset_alloc_count]));
338*91f16700Schasinglulu 				if (err) {
339*91f16700Schasinglulu 					ERROR("FCONF: Failed to parse asset allocator for NPU %u\n",
340*91f16700Schasinglulu 					      dev_count);
341*91f16700Schasinglulu 					return err;
342*91f16700Schasinglulu 				}
343*91f16700Schasinglulu 				++dev_asset_alloc_count;
344*91f16700Schasinglulu 			}
345*91f16700Schasinglulu 		}
346*91f16700Schasinglulu 
347*91f16700Schasinglulu 		if ((sub_node < 0) && (sub_node != -FDT_ERR_NOTFOUND)) {
348*91f16700Schasinglulu 			ERROR("FCONF: Failed to parse sub nodes for NPU %u\n",
349*91f16700Schasinglulu 			      dev_count);
350*91f16700Schasinglulu 			return -FDT_ERR_BADSTRUCTURE;
351*91f16700Schasinglulu 		}
352*91f16700Schasinglulu 
353*91f16700Schasinglulu 		if (dev_core_count == 0U) {
354*91f16700Schasinglulu 			ERROR("FCONF: NPU %u must have at least one enabled core\n",
355*91f16700Schasinglulu 			      dev_count);
356*91f16700Schasinglulu 			return -FDT_ERR_BADSTRUCTURE;
357*91f16700Schasinglulu 		}
358*91f16700Schasinglulu 
359*91f16700Schasinglulu 		if (!has_reserved_memory && dev_asset_alloc_count == 0U) {
360*91f16700Schasinglulu 			ERROR("FCONF: NPU %u must have at least one asset allocator\n",
361*91f16700Schasinglulu 			      dev_count);
362*91f16700Schasinglulu 			return -FDT_ERR_BADSTRUCTURE;
363*91f16700Schasinglulu 		}
364*91f16700Schasinglulu 
365*91f16700Schasinglulu 		dev->num_cores = dev_core_count;
366*91f16700Schasinglulu 		dev->num_allocators = dev_asset_alloc_count;
367*91f16700Schasinglulu 		dev->has_reserved_memory = has_reserved_memory;
368*91f16700Schasinglulu 		dev->reserved_memory_addr = reserved_memory_addr;
369*91f16700Schasinglulu 		++dev_count;
370*91f16700Schasinglulu 	}
371*91f16700Schasinglulu 
372*91f16700Schasinglulu 	if (dev_count == 0U) {
373*91f16700Schasinglulu 		ERROR("FCONF: Can't find 'ethosn' compatible node in dtb\n");
374*91f16700Schasinglulu 		return -FDT_ERR_BADSTRUCTURE;
375*91f16700Schasinglulu 	}
376*91f16700Schasinglulu 
377*91f16700Schasinglulu 	ethosn_config.num_devices = dev_count;
378*91f16700Schasinglulu 
379*91f16700Schasinglulu 	return 0;
380*91f16700Schasinglulu }
381*91f16700Schasinglulu 
382*91f16700Schasinglulu FCONF_REGISTER_POPULATOR(HW_CONFIG, ethosn_config, fconf_populate_ethosn_config);
383