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