aboutsummaryrefslogtreecommitdiffstats
path: root/arch/xtensa/kernel/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/xtensa/kernel/setup.c')
-rw-r--r--arch/xtensa/kernel/setup.c131
1 files changed, 94 insertions, 37 deletions
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c
index 6e2b6638122d..7d12af1317f1 100644
--- a/arch/xtensa/kernel/setup.c
+++ b/arch/xtensa/kernel/setup.c
@@ -21,6 +21,8 @@
21#include <linux/screen_info.h> 21#include <linux/screen_info.h>
22#include <linux/bootmem.h> 22#include <linux/bootmem.h>
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/percpu.h>
25#include <linux/cpu.h>
24#include <linux/of_fdt.h> 26#include <linux/of_fdt.h>
25#include <linux/of_platform.h> 27#include <linux/of_platform.h>
26 28
@@ -37,6 +39,7 @@
37#endif 39#endif
38 40
39#include <asm/bootparam.h> 41#include <asm/bootparam.h>
42#include <asm/mmu_context.h>
40#include <asm/pgtable.h> 43#include <asm/pgtable.h>
41#include <asm/processor.h> 44#include <asm/processor.h>
42#include <asm/timex.h> 45#include <asm/timex.h>
@@ -45,6 +48,7 @@
45#include <asm/setup.h> 48#include <asm/setup.h>
46#include <asm/param.h> 49#include <asm/param.h>
47#include <asm/traps.h> 50#include <asm/traps.h>
51#include <asm/smp.h>
48 52
49#include <platform/hardware.h> 53#include <platform/hardware.h>
50 54
@@ -85,12 +89,6 @@ static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
85 89
86sysmem_info_t __initdata sysmem; 90sysmem_info_t __initdata sysmem;
87 91
88#ifdef CONFIG_MMU
89extern void init_mmu(void);
90#else
91static inline void init_mmu(void) { }
92#endif
93
94extern int mem_reserve(unsigned long, unsigned long, int); 92extern int mem_reserve(unsigned long, unsigned long, int);
95extern void bootmem_init(void); 93extern void bootmem_init(void);
96extern void zones_init(void); 94extern void zones_init(void);
@@ -214,6 +212,42 @@ static int __init parse_bootparam(const bp_tag_t* tag)
214#ifdef CONFIG_OF 212#ifdef CONFIG_OF
215bool __initdata dt_memory_scan = false; 213bool __initdata dt_memory_scan = false;
216 214
215#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY
216unsigned long xtensa_kio_paddr = XCHAL_KIO_DEFAULT_PADDR;
217EXPORT_SYMBOL(xtensa_kio_paddr);
218
219static int __init xtensa_dt_io_area(unsigned long node, const char *uname,
220 int depth, void *data)
221{
222 const __be32 *ranges;
223 unsigned long len;
224
225 if (depth > 1)
226 return 0;
227
228 if (!of_flat_dt_is_compatible(node, "simple-bus"))
229 return 0;
230
231 ranges = of_get_flat_dt_prop(node, "ranges", &len);
232 if (!ranges)
233 return 1;
234 if (len == 0)
235 return 1;
236
237 xtensa_kio_paddr = of_read_ulong(ranges+1, 1);
238 /* round down to nearest 256MB boundary */
239 xtensa_kio_paddr &= 0xf0000000;
240
241 return 1;
242}
243#else
244static int __init xtensa_dt_io_area(unsigned long node, const char *uname,
245 int depth, void *data)
246{
247 return 1;
248}
249#endif
250
217void __init early_init_dt_add_memory_arch(u64 base, u64 size) 251void __init early_init_dt_add_memory_arch(u64 base, u64 size)
218{ 252{
219 if (!dt_memory_scan) 253 if (!dt_memory_scan)
@@ -234,6 +268,7 @@ void __init early_init_devtree(void *params)
234 dt_memory_scan = true; 268 dt_memory_scan = true;
235 269
236 early_init_dt_scan(params); 270 early_init_dt_scan(params);
271 of_scan_flat_dt(xtensa_dt_io_area, NULL);
237 272
238 if (!command_line[0]) 273 if (!command_line[0])
239 strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); 274 strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
@@ -241,7 +276,7 @@ void __init early_init_devtree(void *params)
241 276
242static int __init xtensa_device_probe(void) 277static int __init xtensa_device_probe(void)
243{ 278{
244 of_platform_populate(NULL, NULL, NULL, NULL); 279 of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
245 return 0; 280 return 0;
246} 281}
247 282
@@ -354,7 +389,8 @@ static inline int probed_compare_swap(int *v, int cmp, int set)
354 389
355/* Handle probed exception */ 390/* Handle probed exception */
356 391
357void __init do_probed_exception(struct pt_regs *regs, unsigned long exccause) 392static void __init do_probed_exception(struct pt_regs *regs,
393 unsigned long exccause)
358{ 394{
359 if (regs->pc == rcw_probe_pc) { /* exception on s32c1i ? */ 395 if (regs->pc == rcw_probe_pc) { /* exception on s32c1i ? */
360 regs->pc += 3; /* skip the s32c1i instruction */ 396 regs->pc += 3; /* skip the s32c1i instruction */
@@ -366,7 +402,7 @@ void __init do_probed_exception(struct pt_regs *regs, unsigned long exccause)
366 402
367/* Simple test of S32C1I (soc bringup assist) */ 403/* Simple test of S32C1I (soc bringup assist) */
368 404
369void __init check_s32c1i(void) 405static int __init check_s32c1i(void)
370{ 406{
371 int n, cause1, cause2; 407 int n, cause1, cause2;
372 void *handbus, *handdata, *handaddr; /* temporarily saved handlers */ 408 void *handbus, *handdata, *handaddr; /* temporarily saved handlers */
@@ -421,24 +457,21 @@ void __init check_s32c1i(void)
421 trap_set_handler(EXCCAUSE_LOAD_STORE_ERROR, handbus); 457 trap_set_handler(EXCCAUSE_LOAD_STORE_ERROR, handbus);
422 trap_set_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, handdata); 458 trap_set_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, handdata);
423 trap_set_handler(EXCCAUSE_LOAD_STORE_ADDR_ERROR, handaddr); 459 trap_set_handler(EXCCAUSE_LOAD_STORE_ADDR_ERROR, handaddr);
460 return 0;
424} 461}
425 462
426#else /* XCHAL_HAVE_S32C1I */ 463#else /* XCHAL_HAVE_S32C1I */
427 464
428/* This condition should not occur with a commercially deployed processor. 465/* This condition should not occur with a commercially deployed processor.
429 Display reminder for early engr test or demo chips / FPGA bitstreams */ 466 Display reminder for early engr test or demo chips / FPGA bitstreams */
430void __init check_s32c1i(void) 467static int __init check_s32c1i(void)
431{ 468{
432 pr_warn("Processor configuration lacks atomic compare-and-swap support!\n"); 469 pr_warn("Processor configuration lacks atomic compare-and-swap support!\n");
470 return 0;
433} 471}
434 472
435#endif /* XCHAL_HAVE_S32C1I */ 473#endif /* XCHAL_HAVE_S32C1I */
436#else /* CONFIG_S32C1I_SELFTEST */ 474early_initcall(check_s32c1i);
437
438void __init check_s32c1i(void)
439{
440}
441
442#endif /* CONFIG_S32C1I_SELFTEST */ 475#endif /* CONFIG_S32C1I_SELFTEST */
443 476
444 477
@@ -447,8 +480,6 @@ void __init setup_arch(char **cmdline_p)
447 strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); 480 strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
448 *cmdline_p = command_line; 481 *cmdline_p = command_line;
449 482
450 check_s32c1i();
451
452 /* Reserve some memory regions */ 483 /* Reserve some memory regions */
453 484
454#ifdef CONFIG_BLK_DEV_INITRD 485#ifdef CONFIG_BLK_DEV_INITRD
@@ -505,6 +536,10 @@ void __init setup_arch(char **cmdline_p)
505 536
506 platform_setup(cmdline_p); 537 platform_setup(cmdline_p);
507 538
539#ifdef CONFIG_SMP
540 smp_init_cpus();
541#endif
542
508 paging_init(); 543 paging_init();
509 zones_init(); 544 zones_init();
510 545
@@ -521,6 +556,22 @@ void __init setup_arch(char **cmdline_p)
521#endif 556#endif
522} 557}
523 558
559static DEFINE_PER_CPU(struct cpu, cpu_data);
560
561static int __init topology_init(void)
562{
563 int i;
564
565 for_each_possible_cpu(i) {
566 struct cpu *cpu = &per_cpu(cpu_data, i);
567 cpu->hotpluggable = !!i;
568 register_cpu(cpu, i);
569 }
570
571 return 0;
572}
573subsys_initcall(topology_init);
574
524void machine_restart(char * cmd) 575void machine_restart(char * cmd)
525{ 576{
526 platform_restart(); 577 platform_restart();
@@ -546,21 +597,27 @@ void machine_power_off(void)
546static int 597static int
547c_show(struct seq_file *f, void *slot) 598c_show(struct seq_file *f, void *slot)
548{ 599{
600 char buf[NR_CPUS * 5];
601
602 cpulist_scnprintf(buf, sizeof(buf), cpu_online_mask);
549 /* high-level stuff */ 603 /* high-level stuff */
550 seq_printf(f,"processor\t: 0\n" 604 seq_printf(f, "CPU count\t: %u\n"
551 "vendor_id\t: Tensilica\n" 605 "CPU list\t: %s\n"
552 "model\t\t: Xtensa " XCHAL_HW_VERSION_NAME "\n" 606 "vendor_id\t: Tensilica\n"
553 "core ID\t\t: " XCHAL_CORE_ID "\n" 607 "model\t\t: Xtensa " XCHAL_HW_VERSION_NAME "\n"
554 "build ID\t: 0x%x\n" 608 "core ID\t\t: " XCHAL_CORE_ID "\n"
555 "byte order\t: %s\n" 609 "build ID\t: 0x%x\n"
556 "cpu MHz\t\t: %lu.%02lu\n" 610 "byte order\t: %s\n"
557 "bogomips\t: %lu.%02lu\n", 611 "cpu MHz\t\t: %lu.%02lu\n"
558 XCHAL_BUILD_UNIQUE_ID, 612 "bogomips\t: %lu.%02lu\n",
559 XCHAL_HAVE_BE ? "big" : "little", 613 num_online_cpus(),
560 ccount_freq/1000000, 614 buf,
561 (ccount_freq/10000) % 100, 615 XCHAL_BUILD_UNIQUE_ID,
562 loops_per_jiffy/(500000/HZ), 616 XCHAL_HAVE_BE ? "big" : "little",
563 (loops_per_jiffy/(5000/HZ)) % 100); 617 ccount_freq/1000000,
618 (ccount_freq/10000) % 100,
619 loops_per_jiffy/(500000/HZ),
620 (loops_per_jiffy/(5000/HZ)) % 100);
564 621
565 seq_printf(f,"flags\t\t: " 622 seq_printf(f,"flags\t\t: "
566#if XCHAL_HAVE_NMI 623#if XCHAL_HAVE_NMI
@@ -672,7 +729,7 @@ c_show(struct seq_file *f, void *slot)
672static void * 729static void *
673c_start(struct seq_file *f, loff_t *pos) 730c_start(struct seq_file *f, loff_t *pos)
674{ 731{
675 return (void *) ((*pos == 0) ? (void *)1 : NULL); 732 return (*pos == 0) ? (void *)1 : NULL;
676} 733}
677 734
678static void * 735static void *
@@ -688,10 +745,10 @@ c_stop(struct seq_file *f, void *v)
688 745
689const struct seq_operations cpuinfo_op = 746const struct seq_operations cpuinfo_op =
690{ 747{
691 start: c_start, 748 .start = c_start,
692 next: c_next, 749 .next = c_next,
693 stop: c_stop, 750 .stop = c_stop,
694 show: c_show 751 .show = c_show,
695}; 752};
696 753
697#endif /* CONFIG_PROC_FS */ 754#endif /* CONFIG_PROC_FS */