aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/kernel/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arc/kernel/setup.c')
-rw-r--r--arch/arc/kernel/setup.c144
1 files changed, 102 insertions, 42 deletions
diff --git a/arch/arc/kernel/setup.c b/arch/arc/kernel/setup.c
index 2e018b8c2e19..7b2340996cf8 100644
--- a/arch/arc/kernel/setup.c
+++ b/arch/arc/kernel/setup.c
@@ -123,6 +123,7 @@ static void read_arc_build_cfg_regs(void)
123 struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; 123 struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()];
124 const struct id_to_str *tbl; 124 const struct id_to_str *tbl;
125 struct bcr_isa_arcv2 isa; 125 struct bcr_isa_arcv2 isa;
126 struct bcr_actionpoint ap;
126 127
127 FIX_PTR(cpu); 128 FIX_PTR(cpu);
128 129
@@ -195,20 +196,40 @@ static void read_arc_build_cfg_regs(void)
195 cpu->bpu.full = bpu.ft; 196 cpu->bpu.full = bpu.ft;
196 cpu->bpu.num_cache = 256 << bpu.bce; 197 cpu->bpu.num_cache = 256 << bpu.bce;
197 cpu->bpu.num_pred = 2048 << bpu.pte; 198 cpu->bpu.num_pred = 2048 << bpu.pte;
199 cpu->bpu.ret_stk = 4 << bpu.rse;
198 200
199 if (cpu->core.family >= 0x54) { 201 if (cpu->core.family >= 0x54) {
200 unsigned int exec_ctrl;
201 202
202 READ_BCR(AUX_EXEC_CTRL, exec_ctrl); 203 struct bcr_uarch_build_arcv2 uarch;
203 cpu->extn.dual_enb = !(exec_ctrl & 1);
204 204
205 /* dual issue always present for this core */ 205 /*
206 cpu->extn.dual = 1; 206 * The first 0x54 core (uarch maj:min 0:1 or 0:2) was
207 * dual issue only (HS4x). But next uarch rev (1:0)
208 * allows it be configured for single issue (HS3x)
209 * Ensure we fiddle with dual issue only on HS4x
210 */
211 READ_BCR(ARC_REG_MICRO_ARCH_BCR, uarch);
212
213 if (uarch.prod == 4) {
214 unsigned int exec_ctrl;
215
216 /* dual issue hardware always present */
217 cpu->extn.dual = 1;
218
219 READ_BCR(AUX_EXEC_CTRL, exec_ctrl);
220
221 /* dual issue hardware enabled ? */
222 cpu->extn.dual_enb = !(exec_ctrl & 1);
223
224 }
207 } 225 }
208 } 226 }
209 227
210 READ_BCR(ARC_REG_AP_BCR, bcr); 228 READ_BCR(ARC_REG_AP_BCR, ap);
211 cpu->extn.ap = bcr.ver ? 1 : 0; 229 if (ap.ver) {
230 cpu->extn.ap_num = 2 << ap.num;
231 cpu->extn.ap_full = !ap.min;
232 }
212 233
213 READ_BCR(ARC_REG_SMART_BCR, bcr); 234 READ_BCR(ARC_REG_SMART_BCR, bcr);
214 cpu->extn.smart = bcr.ver ? 1 : 0; 235 cpu->extn.smart = bcr.ver ? 1 : 0;
@@ -216,8 +237,6 @@ static void read_arc_build_cfg_regs(void)
216 READ_BCR(ARC_REG_RTT_BCR, bcr); 237 READ_BCR(ARC_REG_RTT_BCR, bcr);
217 cpu->extn.rtt = bcr.ver ? 1 : 0; 238 cpu->extn.rtt = bcr.ver ? 1 : 0;
218 239
219 cpu->extn.debug = cpu->extn.ap | cpu->extn.smart | cpu->extn.rtt;
220
221 READ_BCR(ARC_REG_ISA_CFG_BCR, isa); 240 READ_BCR(ARC_REG_ISA_CFG_BCR, isa);
222 241
223 /* some hacks for lack of feature BCR info in old ARC700 cores */ 242 /* some hacks for lack of feature BCR info in old ARC700 cores */
@@ -299,10 +318,10 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len)
299 318
300 if (cpu->bpu.ver) 319 if (cpu->bpu.ver)
301 n += scnprintf(buf + n, len - n, 320 n += scnprintf(buf + n, len - n,
302 "BPU\t\t: %s%s match, cache:%d, Predict Table:%d", 321 "BPU\t\t: %s%s match, cache:%d, Predict Table:%d Return stk: %d",
303 IS_AVAIL1(cpu->bpu.full, "full"), 322 IS_AVAIL1(cpu->bpu.full, "full"),
304 IS_AVAIL1(!cpu->bpu.full, "partial"), 323 IS_AVAIL1(!cpu->bpu.full, "partial"),
305 cpu->bpu.num_cache, cpu->bpu.num_pred); 324 cpu->bpu.num_cache, cpu->bpu.num_pred, cpu->bpu.ret_stk);
306 325
307 if (is_isa_arcv2()) { 326 if (is_isa_arcv2()) {
308 struct bcr_lpb lpb; 327 struct bcr_lpb lpb;
@@ -336,11 +355,17 @@ static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len)
336 IS_AVAIL1(cpu->extn.fpu_sp, "SP "), 355 IS_AVAIL1(cpu->extn.fpu_sp, "SP "),
337 IS_AVAIL1(cpu->extn.fpu_dp, "DP ")); 356 IS_AVAIL1(cpu->extn.fpu_dp, "DP "));
338 357
339 if (cpu->extn.debug) 358 if (cpu->extn.ap_num | cpu->extn.smart | cpu->extn.rtt) {
340 n += scnprintf(buf + n, len - n, "DEBUG\t\t: %s%s%s\n", 359 n += scnprintf(buf + n, len - n, "DEBUG\t\t: %s%s",
341 IS_AVAIL1(cpu->extn.ap, "ActionPoint "),
342 IS_AVAIL1(cpu->extn.smart, "smaRT "), 360 IS_AVAIL1(cpu->extn.smart, "smaRT "),
343 IS_AVAIL1(cpu->extn.rtt, "RTT ")); 361 IS_AVAIL1(cpu->extn.rtt, "RTT "));
362 if (cpu->extn.ap_num) {
363 n += scnprintf(buf + n, len - n, "ActionPoint %d/%s",
364 cpu->extn.ap_num,
365 cpu->extn.ap_full ? "full":"min");
366 }
367 n += scnprintf(buf + n, len - n, "\n");
368 }
344 369
345 if (cpu->dccm.sz || cpu->iccm.sz) 370 if (cpu->dccm.sz || cpu->iccm.sz)
346 n += scnprintf(buf + n, len - n, "Extn [CCM]\t: DCCM @ %x, %d KB / ICCM: @ %x, %d KB\n", 371 n += scnprintf(buf + n, len - n, "Extn [CCM]\t: DCCM @ %x, %d KB / ICCM: @ %x, %d KB\n",
@@ -453,43 +478,78 @@ void setup_processor(void)
453 arc_chk_core_config(); 478 arc_chk_core_config();
454} 479}
455 480
456static inline int is_kernel(unsigned long addr) 481static inline bool uboot_arg_invalid(unsigned long addr)
457{ 482{
458 if (addr >= (unsigned long)_stext && addr <= (unsigned long)_end) 483 /*
459 return 1; 484 * Check that it is a untranslated address (although MMU is not enabled
460 return 0; 485 * yet, it being a high address ensures this is not by fluke)
486 */
487 if (addr < PAGE_OFFSET)
488 return true;
489
490 /* Check that address doesn't clobber resident kernel image */
491 return addr >= (unsigned long)_stext && addr <= (unsigned long)_end;
461} 492}
462 493
463void __init setup_arch(char **cmdline_p) 494#define IGNORE_ARGS "Ignore U-boot args: "
495
496/* uboot_tag values for U-boot - kernel ABI revision 0; see head.S */
497#define UBOOT_TAG_NONE 0
498#define UBOOT_TAG_CMDLINE 1
499#define UBOOT_TAG_DTB 2
500
501void __init handle_uboot_args(void)
464{ 502{
465#ifdef CONFIG_ARC_UBOOT_SUPPORT 503 bool use_embedded_dtb = true;
466 /* make sure that uboot passed pointer to cmdline/dtb is valid */ 504 bool append_cmdline = false;
467 if (uboot_tag && is_kernel((unsigned long)uboot_arg)) 505
468 panic("Invalid uboot arg\n"); 506 /* check that we know this tag */
469 507 if (uboot_tag != UBOOT_TAG_NONE &&
470 /* See if u-boot passed an external Device Tree blob */ 508 uboot_tag != UBOOT_TAG_CMDLINE &&
471 machine_desc = setup_machine_fdt(uboot_arg); /* uboot_tag == 2 */ 509 uboot_tag != UBOOT_TAG_DTB) {
472 if (!machine_desc) 510 pr_warn(IGNORE_ARGS "invalid uboot tag: '%08x'\n", uboot_tag);
473#endif 511 goto ignore_uboot_args;
474 { 512 }
475 /* No, so try the embedded one */ 513
514 if (uboot_tag != UBOOT_TAG_NONE &&
515 uboot_arg_invalid((unsigned long)uboot_arg)) {
516 pr_warn(IGNORE_ARGS "invalid uboot arg: '%px'\n", uboot_arg);
517 goto ignore_uboot_args;
518 }
519
520 /* see if U-boot passed an external Device Tree blob */
521 if (uboot_tag == UBOOT_TAG_DTB) {
522 machine_desc = setup_machine_fdt((void *)uboot_arg);
523
524 /* external Device Tree blob is invalid - use embedded one */
525 use_embedded_dtb = !machine_desc;
526 }
527
528 if (uboot_tag == UBOOT_TAG_CMDLINE)
529 append_cmdline = true;
530
531ignore_uboot_args:
532
533 if (use_embedded_dtb) {
476 machine_desc = setup_machine_fdt(__dtb_start); 534 machine_desc = setup_machine_fdt(__dtb_start);
477 if (!machine_desc) 535 if (!machine_desc)
478 panic("Embedded DT invalid\n"); 536 panic("Embedded DT invalid\n");
537 }
479 538
480 /* 539 /*
481 * If we are here, it is established that @uboot_arg didn't 540 * NOTE: @boot_command_line is populated by setup_machine_fdt() so this
482 * point to DT blob. Instead if u-boot says it is cmdline, 541 * append processing can only happen after.
483 * append to embedded DT cmdline. 542 */
484 * setup_machine_fdt() would have populated @boot_command_line 543 if (append_cmdline) {
485 */ 544 /* Ensure a whitespace between the 2 cmdlines */
486 if (uboot_tag == 1) { 545 strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
487 /* Ensure a whitespace between the 2 cmdlines */ 546 strlcat(boot_command_line, uboot_arg, COMMAND_LINE_SIZE);
488 strlcat(boot_command_line, " ", COMMAND_LINE_SIZE);
489 strlcat(boot_command_line, uboot_arg,
490 COMMAND_LINE_SIZE);
491 }
492 } 547 }
548}
549
550void __init setup_arch(char **cmdline_p)
551{
552 handle_uboot_args();
493 553
494 /* Save unparsed command line copy for /proc/cmdline */ 554 /* Save unparsed command line copy for /proc/cmdline */
495 *cmdline_p = boot_command_line; 555 *cmdline_p = boot_command_line;