fdt_loader_cmd.c (273927) | fdt_loader_cmd.c (273934) |
---|---|
1/*- 2 * Copyright (c) 2009-2010 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Semihalf under sponsorship from 6 * the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 14 unchanged lines hidden (view full) --- 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 2009-2010 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Semihalf under sponsorship from 6 * the FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 14 unchanged lines hidden (view full) --- 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> |
31__FBSDID("$FreeBSD: head/sys/boot/fdt/fdt_loader_cmd.c 273927 2014-11-01 10:50:18Z andrew $"); | 31__FBSDID("$FreeBSD: head/sys/boot/fdt/fdt_loader_cmd.c 273934 2014-11-01 17:12:44Z andrew $"); |
32 33#include <stand.h> 34#include <fdt.h> 35#include <libfdt.h> 36#include <sys/param.h> 37#include <sys/linker.h> 38#include <machine/elf.h> 39 40#include "bootstrap.h" 41#include "fdt_platform.h" | 32 33#include <stand.h> 34#include <fdt.h> 35#include <libfdt.h> 36#include <sys/param.h> 37#include <sys/linker.h> 38#include <machine/elf.h> 39 40#include "bootstrap.h" 41#include "fdt_platform.h" |
42#include "glue.h" | |
43 44#ifdef DEBUG 45#define debugf(fmt, args...) do { printf("%s(): ", __func__); \ 46 printf(fmt,##args); } while (0) 47#else 48#define debugf(fmt, args...) 49#endif 50 51#define FDT_CWD_LEN 256 52#define FDT_MAX_DEPTH 6 53 54#define FDT_PROP_SEP " = " 55 | 42 43#ifdef DEBUG 44#define debugf(fmt, args...) do { printf("%s(): ", __func__); \ 45 printf(fmt,##args); } while (0) 46#else 47#define debugf(fmt, args...) 48#endif 49 50#define FDT_CWD_LEN 256 51#define FDT_MAX_DEPTH 6 52 53#define FDT_PROP_SEP " = " 54 |
56#define STR(number) #number 57#define STRINGIFY(number) STR(number) 58 | |
59#define COPYOUT(s,d,l) archsw.arch_copyout(s, d, l) 60#define COPYIN(s,d,l) archsw.arch_copyin(s, d, l) 61 62#define FDT_STATIC_DTB_SYMBOL "fdt_static_dtb" 63 64#define CMD_REQUIRES_BLOB 0x01 65 66/* Location of FDT yet to be loaded. */ --- 157 unchanged lines hidden (view full) --- 224 225 fdtp_va = va; 226 COPYOUT(va, fdtp, fdtp_size); 227 debugf("DTB blob found at 0x%jx, size: 0x%jx\n", (uintmax_t)va, (uintmax_t)fdtp_size); 228 229 return (0); 230} 231 | 55#define COPYOUT(s,d,l) archsw.arch_copyout(s, d, l) 56#define COPYIN(s,d,l) archsw.arch_copyin(s, d, l) 57 58#define FDT_STATIC_DTB_SYMBOL "fdt_static_dtb" 59 60#define CMD_REQUIRES_BLOB 0x01 61 62/* Location of FDT yet to be loaded. */ --- 157 unchanged lines hidden (view full) --- 220 221 fdtp_va = va; 222 COPYOUT(va, fdtp, fdtp_size); 223 debugf("DTB blob found at 0x%jx, size: 0x%jx\n", (uintmax_t)va, (uintmax_t)fdtp_size); 224 225 return (0); 226} 227 |
232static int | 228int |
233fdt_load_dtb_addr(struct fdt_header *header) 234{ 235 int err; 236 237 debugf("fdt_load_dtb_addr(%p)\n", header); 238 239 fdtp_size = fdt_totalsize(header); 240 err = fdt_check_header(header); --- 8 unchanged lines hidden (view full) --- 249 return (1); 250 } 251 252 fdtp_va = 0; // Don't write this back into module or kernel. 253 bcopy(header, fdtp, fdtp_size); 254 return (0); 255} 256 | 229fdt_load_dtb_addr(struct fdt_header *header) 230{ 231 int err; 232 233 debugf("fdt_load_dtb_addr(%p)\n", header); 234 235 fdtp_size = fdt_totalsize(header); 236 err = fdt_check_header(header); --- 8 unchanged lines hidden (view full) --- 245 return (1); 246 } 247 248 fdtp_va = 0; // Don't write this back into module or kernel. 249 bcopy(header, fdtp, fdtp_size); 250 return (0); 251} 252 |
257static int | 253int |
258fdt_load_dtb_file(const char * filename) 259{ 260 struct preloaded_file *bfp, *oldbfp; 261 int err; 262 263 debugf("fdt_load_dtb_file(%s)\n", filename); 264 265 oldbfp = file_findfile(NULL, "dtb"); --- 13 unchanged lines hidden (view full) --- 279 file_discard(oldbfp); 280 return (0); 281} 282 283int 284fdt_setup_fdtp() 285{ 286 struct preloaded_file *bfp; | 254fdt_load_dtb_file(const char * filename) 255{ 256 struct preloaded_file *bfp, *oldbfp; 257 int err; 258 259 debugf("fdt_load_dtb_file(%s)\n", filename); 260 261 oldbfp = file_findfile(NULL, "dtb"); --- 13 unchanged lines hidden (view full) --- 275 file_discard(oldbfp); 276 return (0); 277} 278 279int 280fdt_setup_fdtp() 281{ 282 struct preloaded_file *bfp; |
287 struct fdt_header *hdr; 288 const char *s; 289 char *p; | |
290 vm_offset_t va; 291 292 debugf("fdt_setup_fdtp()\n"); 293 294 /* If we already loaded a file, use it. */ 295 if ((bfp = file_findfile(NULL, "dtb")) != NULL) { 296 if (fdt_load_dtb(bfp->f_addr) == 0) { 297 printf("Using DTB from loaded file '%s'.\n", --- 6 unchanged lines hidden (view full) --- 304 if (fdt_to_load != NULL) { 305 if (fdt_load_dtb_addr(fdt_to_load) == 0) { 306 printf("Using DTB from memory address 0x%08X.\n", 307 (unsigned int)fdt_to_load); 308 return (0); 309 } 310 } 311 | 283 vm_offset_t va; 284 285 debugf("fdt_setup_fdtp()\n"); 286 287 /* If we already loaded a file, use it. */ 288 if ((bfp = file_findfile(NULL, "dtb")) != NULL) { 289 if (fdt_load_dtb(bfp->f_addr) == 0) { 290 printf("Using DTB from loaded file '%s'.\n", --- 6 unchanged lines hidden (view full) --- 297 if (fdt_to_load != NULL) { 298 if (fdt_load_dtb_addr(fdt_to_load) == 0) { 299 printf("Using DTB from memory address 0x%08X.\n", 300 (unsigned int)fdt_to_load); 301 return (0); 302 } 303 } 304 |
312 /* 313 * If the U-boot environment contains a variable giving the address of a 314 * valid blob in memory, use it. The U-boot README says the right 315 * variable for fdt data loaded into ram is fdt_addr_r, so try that 316 * first. Board vendors also use both fdtaddr and fdt_addr names. 317 */ 318 s = ub_env_get("fdt_addr_r"); 319 if (s == NULL) 320 s = ub_env_get("fdtaddr"); 321 if (s == NULL) 322 s = ub_env_get("fdt_addr"); 323 if (s != NULL && *s != '\0') { 324 hdr = (struct fdt_header *)strtoul(s, &p, 16); 325 if (*p == '\0') { 326 if (fdt_load_dtb_addr(hdr) == 0) { 327 printf("Using DTB provided by U-Boot at " 328 "address %p.\n", hdr); 329 return (0); 330 } 331 } 332 } | 305 if (fdt_platform_load_dtb() == 0) 306 return (0); |
333 | 307 |
334 /* 335 * If the U-boot environment contains a variable giving the name of a 336 * file, use it if we can load and validate it. 337 */ 338 s = ub_env_get("fdtfile"); 339 if (s == NULL) 340 s = ub_env_get("fdt_file"); 341 if (s != NULL && *s != '\0') { 342 if (fdt_load_dtb_file(s) == 0) { 343 printf("Loaded DTB from file '%s'.\n", s); 344 return (0); 345 } 346 } 347 | |
348 /* If there is a dtb compiled into the kernel, use it. */ 349 if ((va = fdt_find_static_dtb()) != 0) { 350 if (fdt_load_dtb(va) == 0) { 351 printf("Using DTB compiled into kernel.\n"); 352 return (0); 353 } 354 } 355 --- 46 unchanged lines hidden (view full) --- 402 buf++; 403 /* Find another number */ 404 while ((isxdigit(*buf) || *buf == 'x') && buf < end) 405 buf++; 406 } 407 return (cnt); 408} 409 | 308 /* If there is a dtb compiled into the kernel, use it. */ 309 if ((va = fdt_find_static_dtb()) != 0) { 310 if (fdt_load_dtb(va) == 0) { 311 printf("Using DTB compiled into kernel.\n"); 312 return (0); 313 } 314 } 315 --- 46 unchanged lines hidden (view full) --- 362 buf++; 363 /* Find another number */ 364 while ((isxdigit(*buf) || *buf == 'x') && buf < end) 365 buf++; 366 } 367 return (cnt); 368} 369 |
410#define TMP_MAX_ETH 8 411 412static void 413fixup_ethernet(const char *env, char *ethstr, int *eth_no, int len) | 370void 371fdt_fixup_ethernet(const char *str, char *ethstr, int len) |
414{ | 372{ |
415 const char *str; 416 char *end; | |
417 uint8_t tmp_addr[6]; | 373 uint8_t tmp_addr[6]; |
418 int i, n; | |
419 | 374 |
420 /* Extract interface number */ 421 i = strtol(env + 3, &end, 10); 422 if (end == (env + 3)) 423 /* 'ethaddr' means interface 0 address */ 424 n = 0; 425 else 426 n = i; 427 428 if (n > TMP_MAX_ETH) 429 return; 430 431 str = ub_env_get(env); 432 | |
433 /* Convert macaddr string into a vector of uints */ 434 fdt_strtovectx(str, &tmp_addr, 6, sizeof(uint8_t)); | 375 /* Convert macaddr string into a vector of uints */ 376 fdt_strtovectx(str, &tmp_addr, 6, sizeof(uint8_t)); |
435 if (n != 0) { 436 i = strlen(env) - 7; 437 strncpy(ethstr + 8, env + 3, i); 438 } | |
439 /* Set actual property to a value from vect */ 440 fdt_setprop(fdtp, fdt_path_offset(fdtp, ethstr), 441 "local-mac-address", &tmp_addr, 6 * sizeof(uint8_t)); | 377 /* Set actual property to a value from vect */ 378 fdt_setprop(fdtp, fdt_path_offset(fdtp, ethstr), 379 "local-mac-address", &tmp_addr, 6 * sizeof(uint8_t)); |
442 443 /* Clear ethernet..XXXX.. string */ 444 bzero(ethstr + 8, len - 8); 445 446 if (n + 1 > *eth_no) 447 *eth_no = n + 1; | |
448} 449 | 380} 381 |
450static void 451fixup_cpubusfreqs(unsigned long cpufreq, unsigned long busfreq) | 382void 383fdt_fixup_cpubusfreqs(unsigned long cpufreq, unsigned long busfreq) |
452{ 453 int lo, o = 0, o2, maxo = 0, depth; 454 const uint32_t zero = 0; 455 456 /* We want to modify every subnode of /cpus */ 457 o = fdt_path_offset(fdtp, "/cpus"); 458 if (o < 0) 459 return; --- 62 unchanged lines hidden (view full) --- 522 return (EINVAL); 523 524 debugf(" reg#%d (start: 0x%0x size: 0x%0x) valid!\n", 525 i, cur_start, cur_size); 526 } 527 return (0); 528} 529 | 384{ 385 int lo, o = 0, o2, maxo = 0, depth; 386 const uint32_t zero = 0; 387 388 /* We want to modify every subnode of /cpus */ 389 o = fdt_path_offset(fdtp, "/cpus"); 390 if (o < 0) 391 return; --- 62 unchanged lines hidden (view full) --- 454 return (EINVAL); 455 456 debugf(" reg#%d (start: 0x%0x size: 0x%0x) valid!\n", 457 i, cur_start, cur_size); 458 } 459 return (0); 460} 461 |
530static void 531fixup_memory(struct sys_info *si) | 462void 463fdt_fixup_memory(struct fdt_mem_region *region, size_t num) |
532{ | 464{ |
533 struct mem_region *curmr; | 465 struct fdt_mem_region *curmr; |
534 uint32_t addr_cells, size_cells; 535 uint32_t *addr_cellsp, *reg, *size_cellsp; | 466 uint32_t addr_cells, size_cells; 467 uint32_t *addr_cellsp, *reg, *size_cellsp; |
536 int err, i, len, memory, realmrno, root; | 468 int err, i, len, memory, root; 469 size_t realmrno; |
537 uint8_t *buf, *sb; 538 uint64_t rstart, rsize; 539 int reserved; 540 541 root = fdt_path_offset(fdtp, "/"); 542 if (root < 0) { 543 sprintf(command_errbuf, "Could not find root node !"); 544 return; --- 41 unchanged lines hidden (view full) --- 586 len = (addr_cells + size_cells) * reserved * sizeof(uint32_t); 587 sb = buf = (uint8_t *)malloc(len); 588 if (!buf) 589 return; 590 591 bzero(buf, len); 592 593 for (i = 0; i < reserved; i++) { | 470 uint8_t *buf, *sb; 471 uint64_t rstart, rsize; 472 int reserved; 473 474 root = fdt_path_offset(fdtp, "/"); 475 if (root < 0) { 476 sprintf(command_errbuf, "Could not find root node !"); 477 return; --- 41 unchanged lines hidden (view full) --- 519 len = (addr_cells + size_cells) * reserved * sizeof(uint32_t); 520 sb = buf = (uint8_t *)malloc(len); 521 if (!buf) 522 return; 523 524 bzero(buf, len); 525 526 for (i = 0; i < reserved; i++) { |
594 curmr = &si->mr[i]; | |
595 if (fdt_get_mem_rsv(fdtp, i, &rstart, &rsize)) 596 break; 597 if (rsize) { 598 /* Ensure endianess, and put cells into a buffer */ 599 if (addr_cells == 2) 600 *(uint64_t *)buf = 601 cpu_to_fdt64(rstart); 602 else --- 15 unchanged lines hidden (view full) --- 618 /* Set property */ 619 if ((err = fdt_setprop(fdtp, root, "memreserve", sb, len)) < 0) 620 printf("Could not fixup 'memreserve' property.\n"); 621 622 free(sb); 623 } 624 625 /* Count valid memory regions entries in sysinfo. */ | 527 if (fdt_get_mem_rsv(fdtp, i, &rstart, &rsize)) 528 break; 529 if (rsize) { 530 /* Ensure endianess, and put cells into a buffer */ 531 if (addr_cells == 2) 532 *(uint64_t *)buf = 533 cpu_to_fdt64(rstart); 534 else --- 15 unchanged lines hidden (view full) --- 550 /* Set property */ 551 if ((err = fdt_setprop(fdtp, root, "memreserve", sb, len)) < 0) 552 printf("Could not fixup 'memreserve' property.\n"); 553 554 free(sb); 555 } 556 557 /* Count valid memory regions entries in sysinfo. */ |
626 realmrno = si->mr_no; 627 for (i = 0; i < si->mr_no; i++) 628 if (si->mr[i].start == 0 && si->mr[i].size == 0) | 558 realmrno = num; 559 for (i = 0; i < num; i++) 560 if (region[i].start == 0 && region[i].size == 0) |
629 realmrno--; 630 631 if (realmrno == 0) { 632 sprintf(command_errbuf, "Could not fixup '/memory' node : " 633 "sysinfo doesn't contain valid memory regions info!\n"); 634 return; 635 } 636 --- 10 unchanged lines hidden (view full) --- 647 648 len = (addr_cells + size_cells) * realmrno * sizeof(uint32_t); 649 sb = buf = (uint8_t *)malloc(len); 650 if (!buf) 651 return; 652 653 bzero(buf, len); 654 | 561 realmrno--; 562 563 if (realmrno == 0) { 564 sprintf(command_errbuf, "Could not fixup '/memory' node : " 565 "sysinfo doesn't contain valid memory regions info!\n"); 566 return; 567 } 568 --- 10 unchanged lines hidden (view full) --- 579 580 len = (addr_cells + size_cells) * realmrno * sizeof(uint32_t); 581 sb = buf = (uint8_t *)malloc(len); 582 if (!buf) 583 return; 584 585 bzero(buf, len); 586 |
655 for (i = 0; i < si->mr_no; i++) { 656 curmr = &si->mr[i]; | 587 for (i = 0; i < num; i++) { 588 curmr = ®ion[i]; |
657 if (curmr->size != 0) { 658 /* Ensure endianess, and put cells into a buffer */ 659 if (addr_cells == 2) 660 *(uint64_t *)buf = 661 cpu_to_fdt64(curmr->start); 662 else 663 *(uint32_t *)buf = 664 cpu_to_fdt32(curmr->start); --- 12 unchanged lines hidden (view full) --- 677 678 /* Set property */ 679 if ((err = fdt_setprop(fdtp, memory, "reg", sb, len)) < 0) 680 sprintf(command_errbuf, "Could not fixup '/memory' node.\n"); 681 682 free(sb); 683} 684 | 589 if (curmr->size != 0) { 590 /* Ensure endianess, and put cells into a buffer */ 591 if (addr_cells == 2) 592 *(uint64_t *)buf = 593 cpu_to_fdt64(curmr->start); 594 else 595 *(uint32_t *)buf = 596 cpu_to_fdt32(curmr->start); --- 12 unchanged lines hidden (view full) --- 609 610 /* Set property */ 611 if ((err = fdt_setprop(fdtp, memory, "reg", sb, len)) < 0) 612 sprintf(command_errbuf, "Could not fixup '/memory' node.\n"); 613 614 free(sb); 615} 616 |
685static void 686fixup_stdout(const char *env) | 617void 618fdt_fixup_stdout(const char *str) |
687{ | 619{ |
688 const char *str; | |
689 char *ptr; 690 int serialno; 691 int len, no, sero; 692 const struct fdt_property *prop; 693 char *tmp[10]; 694 | 620 char *ptr; 621 int serialno; 622 int len, no, sero; 623 const struct fdt_property *prop; 624 char *tmp[10]; 625 |
695 str = ub_env_get(env); | |
696 ptr = (char *)str + strlen(str) - 1; 697 while (ptr > str && isdigit(*(str - 1))) 698 str--; 699 700 if (ptr == str) 701 return; 702 703 serialno = (int)strtol(ptr, NULL, 0); --- 29 unchanged lines hidden (view full) --- 733} 734 735/* 736 * Locate the blob, fix it up and return its location. 737 */ 738static int 739fdt_fixup(void) 740{ | 626 ptr = (char *)str + strlen(str) - 1; 627 while (ptr > str && isdigit(*(str - 1))) 628 str--; 629 630 if (ptr == str) 631 return; 632 633 serialno = (int)strtol(ptr, NULL, 0); --- 29 unchanged lines hidden (view full) --- 663} 664 665/* 666 * Locate the blob, fix it up and return its location. 667 */ 668static int 669fdt_fixup(void) 670{ |
741 const char *env; 742 char *ethstr; 743 int chosen, eth_no, len; 744 struct sys_info *si; | 671 int chosen, len; |
745 | 672 |
746 env = NULL; 747 eth_no = 0; 748 ethstr = NULL; | |
749 len = 0; 750 751 debugf("fdt_fixup()\n"); 752 753 if (fdtp == NULL && fdt_setup_fdtp() != 0) 754 return (0); 755 756 /* Create /chosen node (if not exists) */ 757 if ((chosen = fdt_subnode_offset(fdtp, 0, "chosen")) == 758 -FDT_ERR_NOTFOUND) 759 chosen = fdt_add_subnode(fdtp, 0, "chosen"); 760 761 /* Value assigned to fixup-applied does not matter. */ 762 if (fdt_getprop(fdtp, chosen, "fixup-applied", NULL)) 763 return (1); 764 | 673 len = 0; 674 675 debugf("fdt_fixup()\n"); 676 677 if (fdtp == NULL && fdt_setup_fdtp() != 0) 678 return (0); 679 680 /* Create /chosen node (if not exists) */ 681 if ((chosen = fdt_subnode_offset(fdtp, 0, "chosen")) == 682 -FDT_ERR_NOTFOUND) 683 chosen = fdt_add_subnode(fdtp, 0, "chosen"); 684 685 /* Value assigned to fixup-applied does not matter. */ 686 if (fdt_getprop(fdtp, chosen, "fixup-applied", NULL)) 687 return (1); 688 |
765 /* Acquire sys_info */ 766 si = ub_get_sys_info(); | 689 fdt_platform_fixups(); |
767 | 690 |
768 while ((env = ub_env_enum(env)) != NULL) { 769 if (strncmp(env, "eth", 3) == 0 && 770 strncmp(env + (strlen(env) - 4), "addr", 4) == 0) { 771 /* 772 * Handle Ethernet addrs: parse uboot env eth%daddr 773 */ 774 775 if (!eth_no) { 776 /* 777 * Check how many chars we will need to store 778 * maximal eth iface number. 779 */ 780 len = strlen(STRINGIFY(TMP_MAX_ETH)) + 781 strlen("ethernet"); 782 783 /* 784 * Reserve mem for string "ethernet" and len 785 * chars for iface no. 786 */ 787 ethstr = (char *)malloc(len * sizeof(char)); 788 bzero(ethstr, len * sizeof(char)); 789 strcpy(ethstr, "ethernet0"); 790 } 791 792 /* Modify blob */ 793 fixup_ethernet(env, ethstr, ð_no, len); 794 795 } else if (strcmp(env, "consoledev") == 0) 796 fixup_stdout(env); 797 } 798 799 /* Modify cpu(s) and bus clock frequenties in /cpus node [Hz] */ 800 fixup_cpubusfreqs(si->clk_cpu, si->clk_bus); 801 802 /* Fixup memory regions */ 803 fixup_memory(si); 804 | |
805 fdt_setprop(fdtp, chosen, "fixup-applied", NULL, 0); 806 return (1); 807} 808 809/* 810 * Copy DTB blob to specified location and return size 811 */ 812int --- 890 unchanged lines hidden --- | 691 fdt_setprop(fdtp, chosen, "fixup-applied", NULL, 0); 692 return (1); 693} 694 695/* 696 * Copy DTB blob to specified location and return size 697 */ 698int --- 890 unchanged lines hidden --- |