1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * (C) Copyright 2014 - 2022, Xilinx, Inc.
4 * (C) Copyright 2022 - 2025, Advanced Micro Devices, Inc.
5 *
6 * Michal Simek <michal.simek@amd.com>
7 */
8
9 #include <efi.h>
10 #include <efi_loader.h>
11 #include <env.h>
12 #include <image.h>
13 #include <init.h>
14 #include <jffs2/load_kernel.h>
15 #include <log.h>
16 #include <asm/global_data.h>
17 #include <asm/sections.h>
18 #include <dm/uclass.h>
19 #include <i2c.h>
20 #include <linux/sizes.h>
21 #include <malloc.h>
22 #include <memtop.h>
23 #include <mtd_node.h>
24 #include "board.h"
25 #include <dm.h>
26 #include <i2c_eeprom.h>
27 #include <net.h>
28 #include <generated/dt.h>
29 #include <rng.h>
30 #include <slre.h>
31 #include <soc.h>
32 #include <linux/ctype.h>
33 #include <linux/kernel.h>
34 #include <u-boot/uuid.h>
35
36 #include "fru.h"
37
38 #if IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)
39 struct efi_fw_image fw_images[] = {
40 #if defined(XILINX_BOOT_IMAGE_GUID)
41 {
42 .image_type_id = XILINX_BOOT_IMAGE_GUID,
43 .fw_name = u"XILINX-BOOT",
44 .image_index = 1,
45 },
46 #endif
47 #if defined(XILINX_UBOOT_IMAGE_GUID) && defined(CONFIG_SPL_FS_LOAD_PAYLOAD_NAME)
48 {
49 .image_type_id = XILINX_UBOOT_IMAGE_GUID,
50 .fw_name = u"XILINX-UBOOT",
51 .image_index = 2,
52 },
53 #endif
54 };
55
56 struct efi_capsule_update_info update_info = {
57 .num_images = ARRAY_SIZE(fw_images),
58 .images = fw_images,
59 };
60
61 #endif /* EFI_HAVE_CAPSULE_SUPPORT */
62
63 #define EEPROM_HEADER_MAGIC 0xdaaddeed
64 #define EEPROM_HDR_MANUFACTURER_LEN 16
65 #define EEPROM_HDR_NAME_LEN 16
66 #define EEPROM_HDR_REV_LEN 8
67 #define EEPROM_HDR_SERIAL_LEN 20
68 #define EEPROM_HDR_NO_OF_MAC_ADDR 4
69 #define EEPROM_HDR_ETH_ALEN ETH_ALEN
70 #define EEPROM_HDR_UUID_LEN 16
71
72 struct xilinx_board_description {
73 u32 header;
74 char manufacturer[EEPROM_HDR_MANUFACTURER_LEN + 1];
75 char name[EEPROM_HDR_NAME_LEN + 1];
76 char revision[EEPROM_HDR_REV_LEN + 1];
77 char serial[EEPROM_HDR_SERIAL_LEN + 1];
78 u8 mac_addr[EEPROM_HDR_NO_OF_MAC_ADDR][EEPROM_HDR_ETH_ALEN + 1];
79 char uuid[EEPROM_HDR_UUID_LEN + 1];
80 };
81
82 static int highest_id = -1;
83 static struct xilinx_board_description *board_info __section(".data");
84
85 #define XILINX_I2C_DETECTION_BITS sizeof(struct fru_common_hdr)
86
87 /* Variable which stores pointer to array which stores eeprom content */
88 struct xilinx_legacy_format {
89 char board_sn[18]; /* 0x0 */
90 char unused0[14]; /* 0x12 */
91 char eth_mac[ETH_ALEN]; /* 0x20 */
92 char unused1[170]; /* 0x26 */
93 char board_name[11]; /* 0xd0 */
94 char unused2[5]; /* 0xdc */
95 char board_revision[3]; /* 0xe0 */
96 char unused3[29]; /* 0xe3 */
97 };
98
xilinx_eeprom_legacy_cleanup(char * eeprom,int size)99 static void xilinx_eeprom_legacy_cleanup(char *eeprom, int size)
100 {
101 int i;
102 unsigned char byte;
103
104 for (i = 0; i < size; i++) {
105 byte = eeprom[i];
106
107 /* Ignore MAC address */
108 if (i >= offsetof(struct xilinx_legacy_format, eth_mac) &&
109 i < offsetof(struct xilinx_legacy_format, unused1)) {
110 continue;
111 }
112
113 /* Remove all non printable chars */
114 if (byte < '!' || byte > '~') {
115 eeprom[i] = 0;
116 continue;
117 }
118
119 /* Convert strings to lower case */
120 if (byte >= 'A' && byte <= 'Z')
121 eeprom[i] = byte + 'a' - 'A';
122 }
123 }
124
xilinx_read_eeprom_legacy(struct udevice * dev,char * name,struct xilinx_board_description * desc)125 static int xilinx_read_eeprom_legacy(struct udevice *dev, char *name,
126 struct xilinx_board_description *desc)
127 {
128 int ret, size;
129 struct xilinx_legacy_format *eeprom_content;
130 bool eth_valid = false;
131
132 size = sizeof(*eeprom_content);
133
134 eeprom_content = calloc(1, size);
135 if (!eeprom_content)
136 return -ENOMEM;
137
138 debug("%s: I2C EEPROM read pass data at %p\n", __func__,
139 eeprom_content);
140
141 ret = dm_i2c_read(dev, 0, (uchar *)eeprom_content, size);
142 if (ret) {
143 debug("%s: I2C EEPROM read failed\n", __func__);
144 free(eeprom_content);
145 return ret;
146 }
147
148 xilinx_eeprom_legacy_cleanup((char *)eeprom_content, size);
149
150 /* Terminating \0 chars are the part of desc fields already */
151 strlcpy(desc->name, eeprom_content->board_name,
152 sizeof(eeprom_content->board_name) + 1);
153 strlcpy(desc->revision, eeprom_content->board_revision,
154 sizeof(eeprom_content->board_revision) + 1);
155 strlcpy(desc->serial, eeprom_content->board_sn,
156 sizeof(eeprom_content->board_sn) + 1);
157
158 eth_valid = is_valid_ethaddr((const u8 *)eeprom_content->eth_mac);
159 if (eth_valid)
160 memcpy(desc->mac_addr[0], eeprom_content->eth_mac, ETH_ALEN);
161
162 printf("Xilinx I2C Legacy format at %s:\n", name);
163 printf(" Board name:\t%s\n", desc->name);
164 printf(" Board rev:\t%s\n", desc->revision);
165 printf(" Board SN:\t%s\n", desc->serial);
166
167 if (eth_valid)
168 printf(" Ethernet mac:\t%pM\n", desc->mac_addr);
169
170 desc->header = EEPROM_HEADER_MAGIC;
171
172 free(eeprom_content);
173
174 return ret;
175 }
176
xilinx_detect_legacy(u8 * buffer)177 static bool xilinx_detect_legacy(u8 *buffer)
178 {
179 int i;
180 char c;
181
182 for (i = 0; i < XILINX_I2C_DETECTION_BITS; i++) {
183 c = buffer[i];
184
185 if (c < '0' || c > '9')
186 return false;
187 }
188
189 return true;
190 }
191
xilinx_read_eeprom_fru(struct udevice * dev,char * name,struct xilinx_board_description * desc)192 static int xilinx_read_eeprom_fru(struct udevice *dev, char *name,
193 struct xilinx_board_description *desc)
194 {
195 int i, ret, eeprom_size;
196 u8 *fru_content;
197 u8 id = 0;
198
199 /* FIXME this is shortcut - if eeprom type is wrong it will fail */
200 eeprom_size = i2c_eeprom_size(dev);
201
202 fru_content = calloc(1, eeprom_size);
203 if (!fru_content)
204 return -ENOMEM;
205
206 debug("%s: I2C EEPROM read pass data at %p\n", __func__,
207 fru_content);
208
209 ret = dm_i2c_read(dev, 0, (uchar *)fru_content,
210 eeprom_size);
211 if (ret) {
212 debug("%s: I2C EEPROM read failed\n", __func__);
213 goto end;
214 }
215
216 fru_capture((unsigned long)fru_content);
217 if (gd->flags & GD_FLG_RELOC || (_DEBUG && IS_ENABLED(CONFIG_DTB_RESELECT))) {
218 printf("Xilinx I2C FRU format at %s:\n", name);
219 ret = fru_display(0);
220 if (ret) {
221 printf("FRU format decoding failed.\n");
222 goto end;
223 }
224 }
225
226 if (desc->header == EEPROM_HEADER_MAGIC) {
227 debug("Information already filled\n");
228 ret = -EINVAL;
229 goto end;
230 }
231
232 /* It is clear that FRU was captured and structures were filled */
233 strlcpy(desc->manufacturer, (char *)fru_data.brd.manufacturer_name,
234 sizeof(desc->manufacturer));
235 strlcpy(desc->uuid, (char *)fru_data.brd.uuid,
236 sizeof(desc->uuid));
237 strlcpy(desc->name, (char *)fru_data.brd.product_name,
238 sizeof(desc->name));
239 for (i = 0; i < sizeof(desc->name); i++) {
240 if (desc->name[i] == ' ')
241 desc->name[i] = '\0';
242 }
243 strlcpy(desc->revision, (char *)fru_data.brd.rev,
244 sizeof(desc->revision));
245 for (i = 0; i < sizeof(desc->revision); i++) {
246 if (desc->revision[i] == ' ')
247 desc->revision[i] = '\0';
248 }
249 strlcpy(desc->serial, (char *)fru_data.brd.serial_number,
250 sizeof(desc->serial));
251
252 while (id < EEPROM_HDR_NO_OF_MAC_ADDR) {
253 if (is_valid_ethaddr((const u8 *)fru_data.mac.macid[id]))
254 memcpy(&desc->mac_addr[id],
255 (char *)fru_data.mac.macid[id], ETH_ALEN);
256 id++;
257 }
258
259 desc->header = EEPROM_HEADER_MAGIC;
260
261 end:
262 free(fru_content);
263 return ret;
264 }
265
xilinx_detect_fru(u8 * buffer)266 static bool xilinx_detect_fru(u8 *buffer)
267 {
268 u8 checksum = 0;
269 int i;
270
271 checksum = fru_checksum((u8 *)buffer, sizeof(struct fru_common_hdr));
272 if (checksum) {
273 debug("%s Common header CRC FAIL\n", __func__);
274 return false;
275 }
276
277 bool all_zeros = true;
278 /* Checksum over all zeros is also zero that's why detect this case */
279 for (i = 0; i < sizeof(struct fru_common_hdr); i++) {
280 if (buffer[i] != 0)
281 all_zeros = false;
282 }
283
284 if (all_zeros)
285 return false;
286
287 debug("%s Common header CRC PASS\n", __func__);
288 return true;
289 }
290
xilinx_read_eeprom_single(char * name,struct xilinx_board_description * desc)291 static int xilinx_read_eeprom_single(char *name,
292 struct xilinx_board_description *desc)
293 {
294 int ret;
295 struct udevice *dev;
296 ofnode eeprom;
297 u8 buffer[XILINX_I2C_DETECTION_BITS];
298
299 eeprom = ofnode_get_aliases_node(name);
300 if (!ofnode_valid(eeprom))
301 return -ENODEV;
302
303 ret = uclass_get_device_by_ofnode(UCLASS_I2C_EEPROM, eeprom, &dev);
304 if (ret)
305 return ret;
306
307 ret = dm_i2c_read(dev, 0, buffer, sizeof(buffer));
308 if (ret) {
309 debug("%s: I2C EEPROM read failed\n", __func__);
310 return ret;
311 }
312
313 debug("%s: i2c memory detected: %s\n", __func__, name);
314
315 if (IS_ENABLED(CONFIG_CMD_FRU) && xilinx_detect_fru(buffer))
316 return xilinx_read_eeprom_fru(dev, name, desc);
317
318 if (xilinx_detect_legacy(buffer))
319 return xilinx_read_eeprom_legacy(dev, name, desc);
320
321 return -ENODEV;
322 }
323
xilinx_read_eeprom(void)324 __maybe_unused int xilinx_read_eeprom(void)
325 {
326 int id;
327 char name_buf[8]; /* 8 bytes should be enough for nvmem+number */
328 struct xilinx_board_description *desc;
329
330 highest_id = dev_read_alias_highest_id("nvmem");
331 /* No nvmem aliases present */
332 if (highest_id < 0)
333 return -EINVAL;
334
335 board_info = calloc(1, sizeof(*desc) * (highest_id + 1));
336 if (!board_info)
337 return -ENOMEM;
338
339 debug("%s: Highest ID %d, board_info %p\n", __func__,
340 highest_id, board_info);
341
342 for (id = 0; id <= highest_id; id++) {
343 snprintf(name_buf, sizeof(name_buf), "nvmem%d", id);
344
345 /* Alloc structure */
346 desc = &board_info[id];
347
348 /* Ignoring return value for supporting multiple chips */
349 xilinx_read_eeprom_single(name_buf, desc);
350 }
351
352 /*
353 * Consider to clean board_info structure when board/cards are not
354 * detected.
355 */
356
357 return 0;
358 }
359
360 #if defined(CONFIG_OF_BOARD)
board_fdt_blob_setup(void ** fdtp)361 int board_fdt_blob_setup(void **fdtp)
362 {
363 void *fdt_blob;
364
365 if (IS_ENABLED(CONFIG_TARGET_XILINX_MBV)) {
366 fdt_blob = (void *)CONFIG_XILINX_OF_BOARD_DTB_ADDR;
367
368 if (fdt_magic(fdt_blob) == FDT_MAGIC) {
369 *fdtp = fdt_blob;
370 return 0;
371 }
372 }
373
374 if (!IS_ENABLED(CONFIG_XPL_BUILD) &&
375 !IS_ENABLED(CONFIG_VERSAL_NO_DDR) &&
376 !IS_ENABLED(CONFIG_ZYNQMP_NO_DDR)) {
377 fdt_blob = (void *)CONFIG_XILINX_OF_BOARD_DTB_ADDR;
378
379 if (fdt_magic(fdt_blob) == FDT_MAGIC) {
380 *fdtp = fdt_blob;
381 return 0;
382 }
383
384 debug("DTB is not passed via %p\n", fdt_blob);
385 }
386
387 if (IS_ENABLED(CONFIG_XPL_BUILD)) {
388 /*
389 * FDT is at end of BSS unless it is in a different memory
390 * region
391 */
392 if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS))
393 fdt_blob = (ulong *)_image_binary_end;
394 else
395 fdt_blob = (ulong *)__bss_end;
396 } else {
397 /* FDT is at end of image */
398 fdt_blob = (ulong *)_end;
399 }
400
401 if (fdt_magic(fdt_blob) == FDT_MAGIC) {
402 *fdtp = fdt_blob;
403
404 return 0;
405 }
406
407 debug("DTB is also not passed via %p\n", fdt_blob);
408
409 return -EINVAL;
410 }
411 #endif
412
413 #if defined(CONFIG_BOARD_LATE_INIT)
env_set_by_index(const char * name,int index,char * data)414 static int env_set_by_index(const char *name, int index, char *data)
415 {
416 char var[32];
417
418 if (!index)
419 sprintf(var, "board_%s", name);
420 else
421 sprintf(var, "card%d_%s", index, name);
422
423 return env_set(var, data);
424 }
425
board_late_init_xilinx(void)426 int board_late_init_xilinx(void)
427 {
428 u32 ret = 0;
429 int i, id, macid = 0;
430 struct xilinx_board_description *desc;
431 phys_size_t bootm_size = gd->ram_top - gd->ram_base;
432 u64 bootscr_flash_offset, bootscr_flash_size;
433 ulong scriptaddr;
434 u64 bootscr_address;
435 u64 bootscr_offset;
436
437 /* Fetch bootscr_address/bootscr_offset from DT and update */
438 if (!ofnode_read_bootscript_address(&bootscr_address,
439 &bootscr_offset)) {
440 if (bootscr_offset)
441 ret |= env_set_hex("scriptaddr",
442 gd->ram_base +
443 bootscr_offset);
444 else
445 ret |= env_set_hex("scriptaddr",
446 bootscr_address);
447 } else {
448 /* Update scriptaddr(bootscr offset) from env */
449 scriptaddr = env_get_hex("scriptaddr", 0);
450 ret |= env_set_hex("scriptaddr",
451 gd->ram_base + scriptaddr);
452 }
453
454 if (!ofnode_read_bootscript_flash(&bootscr_flash_offset,
455 &bootscr_flash_size)) {
456 ret |= env_set_hex("script_offset_f", bootscr_flash_offset);
457 ret |= env_set_hex("script_size_f", bootscr_flash_size);
458 } else {
459 debug("!!! Please define bootscr-flash-offset via DT !!!\n");
460 ret |= env_set_hex("script_offset_f",
461 CONFIG_BOOT_SCRIPT_OFFSET);
462 }
463
464 if (IS_ENABLED(CONFIG_ARCH_ZYNQ) || IS_ENABLED(CONFIG_MICROBLAZE))
465 bootm_size = min(bootm_size, (phys_size_t)(SZ_512M + SZ_256M));
466
467 ret |= env_set_addr("bootm_low", (void *)gd->ram_base);
468 ret |= env_set_addr("bootm_size", (void *)bootm_size);
469
470 for (id = 0; id <= highest_id; id++) {
471 if (!board_info)
472 break;
473
474 desc = &board_info[id];
475 if (desc && desc->header == EEPROM_HEADER_MAGIC) {
476 if (desc->manufacturer[0])
477 ret |= env_set_by_index("manufacturer", id,
478 desc->manufacturer);
479 if (desc->name[0])
480 ret |= env_set_by_index("name", id,
481 desc->name);
482 if (desc->revision[0])
483 ret |= env_set_by_index("rev", id,
484 desc->revision);
485 if (desc->serial[0])
486 ret |= env_set_by_index("serial", id,
487 desc->serial);
488
489 if (desc->uuid[0]) {
490 unsigned char uuid[UUID_STR_LEN + 1];
491 unsigned char *t = desc->uuid;
492
493 memset(uuid, 0, UUID_STR_LEN + 1);
494
495 sprintf(uuid, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
496 t[0], t[1], t[2], t[3], t[4], t[5],
497 t[6], t[7], t[8], t[9], t[10], t[11],
498 t[12], t[13], t[14], t[15]);
499 ret |= env_set_by_index("uuid", id, uuid);
500 }
501
502 if (!(CONFIG_IS_ENABLED(NET) ||
503 CONFIG_IS_ENABLED(NET_LWIP)))
504 continue;
505
506 for (i = 0; i < EEPROM_HDR_NO_OF_MAC_ADDR; i++) {
507 if (is_valid_ethaddr((const u8 *)desc->mac_addr[i]))
508 ret |= eth_env_set_enetaddr_by_index("eth",
509 macid++, desc->mac_addr[i]);
510 }
511 }
512 }
513
514 if (ret)
515 printf("%s: Saving run time variables FAILED\n", __func__);
516
517 return 0;
518 }
519 #endif
520
521 static char *board_name = DEVICE_TREE;
522
board_fit_config_name_match(const char * name)523 int __maybe_unused board_fit_config_name_match(const char *name)
524 {
525 debug("%s: Check %s, default %s\n", __func__, name, board_name);
526
527 #if !defined(CONFIG_XPL_BUILD)
528 if (IS_ENABLED(CONFIG_REGEX)) {
529 struct slre slre;
530 int ret;
531
532 ret = slre_compile(&slre, name);
533 if (ret) {
534 ret = slre_match(&slre, board_name, strlen(board_name),
535 NULL);
536 debug("%s: name match ret = %d\n", __func__, ret);
537 return !ret;
538 }
539 }
540 #endif
541
542 if (!strcmp(name, board_name))
543 return 0;
544
545 return -1;
546 }
547
548 #if IS_ENABLED(CONFIG_DTB_RESELECT)
549 #define MAX_NAME_LENGTH 50
550
board_name_decode(void)551 char * __maybe_unused __weak board_name_decode(void)
552 {
553 char *board_local_name;
554 struct xilinx_board_description *desc;
555 int i, id;
556
557 board_local_name = calloc(1, MAX_NAME_LENGTH);
558 if (!board_info)
559 return NULL;
560
561 for (id = 0; id <= highest_id; id++) {
562 desc = &board_info[id];
563
564 /* No board description */
565 if (!desc)
566 goto error;
567
568 /* Board is not detected */
569 if (desc->header != EEPROM_HEADER_MAGIC)
570 continue;
571
572 /* The first string should be soc name */
573 if (!id)
574 strcat(board_local_name, CONFIG_SYS_BOARD);
575
576 /*
577 * For two purpose here:
578 * soc_name- eg: zynqmp-
579 * and between base board and CC eg: ..revA-sck...
580 */
581 strcat(board_local_name, "-");
582
583 if (desc->name[0]) {
584 /* For DT composition name needs to be lowercase */
585 for (i = 0; i < sizeof(desc->name); i++)
586 desc->name[i] = tolower(desc->name[i]);
587
588 strcat(board_local_name, desc->name);
589 }
590 if (desc->revision[0]) {
591 strcat(board_local_name, "-rev");
592
593 /* And revision needs to be uppercase */
594 for (i = 0; i < sizeof(desc->revision); i++)
595 desc->revision[i] = toupper(desc->revision[i]);
596
597 strcat(board_local_name, desc->revision);
598 }
599 }
600
601 /*
602 * Longer strings will end up with buffer overflow and potential
603 * attacks that's why check it
604 */
605 if (strlen(board_local_name) >= MAX_NAME_LENGTH)
606 panic("Board name can't be determined\n");
607
608 if (strlen(board_local_name))
609 return board_local_name;
610
611 error:
612 free(board_local_name);
613 return NULL;
614 }
615
board_detection(void)616 bool __maybe_unused __weak board_detection(void)
617 {
618 if (CONFIG_IS_ENABLED(DM_I2C) && CONFIG_IS_ENABLED(I2C_EEPROM)) {
619 int ret;
620
621 ret = xilinx_read_eeprom();
622 return !ret ? true : false;
623 }
624
625 return false;
626 }
627
soc_detection(void)628 bool __maybe_unused __weak soc_detection(void)
629 {
630 return false;
631 }
632
soc_name_decode(void)633 char * __maybe_unused __weak soc_name_decode(void)
634 {
635 return NULL;
636 }
637
embedded_dtb_select(void)638 int embedded_dtb_select(void)
639 {
640 if (soc_detection()) {
641 char *soc_local_name;
642
643 soc_local_name = soc_name_decode();
644 if (soc_local_name) {
645 board_name = soc_local_name;
646 printf("Detected SOC name: %s\n", board_name);
647
648 /* Time to change DTB on fly */
649 /* Both ways should work here */
650 /* fdtdec_resetup(&rescan); */
651 return fdtdec_setup();
652 }
653 }
654
655 if (board_detection()) {
656 char *board_local_name;
657
658 board_local_name = board_name_decode();
659 if (board_local_name) {
660 board_name = board_local_name;
661 printf("Detected name: %s\n", board_name);
662
663 /* Time to change DTB on fly */
664 /* Both ways should work here */
665 /* fdtdec_resetup(&rescan); */
666 fdtdec_setup();
667 }
668 }
669 return 0;
670 }
671 #endif
672
673 #ifdef CONFIG_OF_BOARD_SETUP
674 #define MAX_RAND_SIZE 8
ft_board_setup(void * blob,struct bd_info * bd)675 int ft_board_setup(void *blob, struct bd_info *bd)
676 {
677 static const struct node_info nodes[] = {
678 { "arm,pl353-nand-r2p1", MTD_DEV_TYPE_NAND, },
679 };
680
681 if (IS_ENABLED(CONFIG_FDT_FIXUP_PARTITIONS) && IS_ENABLED(CONFIG_NAND_ZYNQ))
682 fdt_fixup_mtdparts(blob, nodes, ARRAY_SIZE(nodes));
683
684 return 0;
685 }
686 #endif
687
688 #ifndef CONFIG_XILINX_MINI
689
690 #ifndef MMU_SECTION_SIZE
691 #define MMU_SECTION_SIZE (1 * 1024 * 1024)
692 #endif
693
board_get_usable_ram_top(phys_size_t total_size)694 phys_addr_t board_get_usable_ram_top(phys_size_t total_size)
695 {
696 phys_size_t size;
697 phys_addr_t reg;
698
699 if (!total_size)
700 return gd->ram_top;
701
702 if (!IS_ALIGNED((ulong)gd->fdt_blob, 0x8))
703 panic("Not 64bit aligned DT location: %p\n", gd->fdt_blob);
704
705 size = ALIGN(CONFIG_SYS_MALLOC_LEN + total_size, MMU_SECTION_SIZE);
706 reg = get_mem_top(gd->ram_base, gd->ram_size, size,
707 (void *)gd->fdt_blob);
708 if (!reg)
709 reg = gd->ram_top - size;
710
711 return reg + size;
712 }
713
714 #endif
715
716 #if IS_ENABLED(CONFIG_BOARD_RNG_SEED)
717 /* Use hardware rng to seed Linux random. */
board_rng_seed(struct abuf * buf)718 __weak int board_rng_seed(struct abuf *buf)
719 {
720 struct udevice *dev;
721 ulong len = 64;
722 u64 *data;
723
724 if (uclass_get_device(UCLASS_RNG, 0, &dev) || !dev) {
725 printf("No RNG device\n");
726 return -ENODEV;
727 }
728
729 data = malloc(len);
730 if (!data) {
731 printf("Out of memory\n");
732 return -ENOMEM;
733 }
734
735 if (dm_rng_read(dev, data, len)) {
736 printf("Reading RNG failed\n");
737 free(data);
738 return -EIO;
739 }
740
741 abuf_init_set(buf, data, len);
742
743 return 0;
744 }
745 #endif
746