aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arc/kernel/head.S4
-rw-r--r--arch/arc/kernel/setup.c87
2 files changed, 64 insertions, 27 deletions
diff --git a/arch/arc/kernel/head.S b/arch/arc/kernel/head.S
index 26e33a8b2d18..1f945d0f40da 100644
--- a/arch/arc/kernel/head.S
+++ b/arch/arc/kernel/head.S
@@ -103,9 +103,9 @@ ENTRY(stext)
103#ifdef CONFIG_ARC_UBOOT_SUPPORT 103#ifdef CONFIG_ARC_UBOOT_SUPPORT
104 ; Uboot - kernel ABI 104 ; Uboot - kernel ABI
105 ; r0 = [0] No uboot interaction, [1] cmdline in r2, [2] DTB in r2 105 ; r0 = [0] No uboot interaction, [1] cmdline in r2, [2] DTB in r2
106 ; r1 = magic number (board identity, unused as of now 106 ; r1 = magic number (always zero as of now)
107 ; r2 = pointer to uboot provided cmdline or external DTB in mem 107 ; r2 = pointer to uboot provided cmdline or external DTB in mem
108 ; These are handled later in setup_arch() 108 ; These are handled later in handle_uboot_args()
109 st r0, [@uboot_tag] 109 st r0, [@uboot_tag]
110 st r2, [@uboot_arg] 110 st r2, [@uboot_arg]
111#endif 111#endif
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index def19b0ef8c6..8bb156164556 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -462,43 +462,80 @@ void setup_processor(void)
462 arc_chk_core_config(); 462 arc_chk_core_config();
463} 463}
464 464
465static inline int is_kernel(unsigned long addr) 465static inline bool uboot_arg_invalid(unsigned long addr)
466{ 466{
467 if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end) 467 /*
468 return 1; 468 * Check that it is a untranslated address (although MMU is not enabled
469 return 0; 469 * yet, it being a high address ensures this is not by fluke)
470 */
471 if (addr < PAGE_OFFSET)
472 return true;
473
474 /* Check that address doesn't clobber resident kernel image */
475 return addr >= (unsigned long)_stext && addr <= (unsigned long)_end;
470} 476}
471 477
472void __init setup_arch(char **cmdline_p) 478#define IGNORE_ARGS "Ignore U-boot args: "
479
480/* uboot_tag values for U-boot - kernel ABI revision 0; see head.S */
481#define UBOOT_TAG_NONE 0
482#define UBOOT_TAG_CMDLINE 1
483#define UBOOT_TAG_DTB 2
484
485void __init handle_uboot_args(void)
473{ 486{
487 bool use_embedded_dtb = true;
488 bool append_cmdline = false;
489
474#ifdef CONFIG_ARC_UBOOT_SUPPORT 490#ifdef CONFIG_ARC_UBOOT_SUPPORT
475 /* make sure that uboot passed pointer to cmdline/dtb is valid */ 491 /* check that we know this tag */
476 if (uboot_tag && is_kernel((unsigned long)uboot_arg)) 492 if (uboot_tag != UBOOT_TAG_NONE &&
477 panic("Invalid uboot arg\n"); 493 uboot_tag != UBOOT_TAG_CMDLINE &&
494 uboot_tag != UBOOT_TAG_DTB) {
495 pr_warn(IGNORE_ARGS "invalid uboot tag: '%08x'\n", uboot_tag);
496 goto ignore_uboot_args;
497 }
498
499 if (uboot_tag != UBOOT_TAG_NONE &&
500 uboot_arg_invalid((unsigned long)uboot_arg)) {
501 pr_warn(IGNORE_ARGS "invalid uboot arg: '%px'\n", uboot_arg);
502 goto ignore_uboot_args;
503 }
504
505 /* see if U-boot passed an external Device Tree blob */
506 if (uboot_tag == UBOOT_TAG_DTB) {
507 machine_desc = setup_machine_fdt((void *)uboot_arg);
478 508
479 /* See if u-boot passed an external Device Tree blob */ 509 /* external Device Tree blob is invalid - use embedded one */
480 machine_desc = setup_machine_fdt(uboot_arg); /* uboot_tag == 2 */ 510 use_embedded_dtb = !machine_desc;
481 if (!machine_desc) 511 }
512
513 if (uboot_tag == UBOOT_TAG_CMDLINE)
514 append_cmdline = true;
515
516ignore_uboot_args:
482#endif 517#endif
483 { 518
484 /* No, so try the embedded one */ 519 if (use_embedded_dtb) {
485 machine_desc = setup_machine_fdt(__dtb_start); 520 machine_desc = setup_machine_fdt(__dtb_start);
486 if (!machine_desc) 521 if (!machine_desc)
487 panic("Embedded DT invalid\n"); 522 panic("Embedded DT invalid\n");
523 }
488 524
489 /* 525 /*
490 * If we are here, it is established that @uboot_arg didn't 526 * NOTE: @boot_command_line is populated by setup_machine_fdt() so this
491 * point to DT blob. Instead if u-boot says it is cmdline, 527 * append processing can only happen after.
492 * append to embedded DT cmdline. 528 */
493 * setup_machine_fdt() would have populated @boot_command_line 529 if (append_cmdline) {
494 */ 530 /* Ensure a whitespace between the 2 cmdlines */
495 if (uboot_tag == 1) { 531 strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
496 /* Ensure a whitespace between the 2 cmdlines */ 532 strlcat(boot_command_line, uboot_arg, COMMAND_LINE_SIZE);
497 strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
498 strlcat(boot_command_line, uboot_arg,
499 COMMAND_LINE_SIZE);
500 }
501 } 533 }
534}
535
536void __init setup_arch(char **cmdline_p)
537{
538 handle_uboot_args();
502 539
503 /* Save unparsed command line copy for /proc/cmdline */ 540 /* Save unparsed command line copy for /proc/cmdline */
504 *cmdline_p = boot_command_line; 541 *cmdline_p = boot_command_line;