Merge remote-tracking branch 'block/for-next'
[deliverable/linux.git] / arch / xtensa / kernel / setup.c
CommitLineData
5a0015d6 1/*
f30c2269 2 * arch/xtensa/kernel/setup.c
5a0015d6
CZ
3 *
4 * This file is subject to the terms and conditions of the GNU General Public
5 * License. See the file "COPYING" in the main directory of this archive
6 * for more details.
7 *
8 * Copyright (C) 1995 Linus Torvalds
9 * Copyright (C) 2001 - 2005 Tensilica Inc.
0e46c111 10 * Copyright (C) 2014 - 2016 Cadence Design Systems Inc.
5a0015d6
CZ
11 *
12 * Chris Zankel <chris@zankel.net>
13 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
14 * Kevin Chea
15 * Marc Gauthier<marc@tensilica.com> <marc@alumni.uwaterloo.ca>
16 */
17
5a0015d6
CZ
18#include <linux/errno.h>
19#include <linux/init.h>
27ac792c 20#include <linux/mm.h>
5a0015d6 21#include <linux/proc_fs.h>
894673ee 22#include <linux/screen_info.h>
5a0015d6
CZ
23#include <linux/bootmem.h>
24#include <linux/kernel.h>
f615136c 25#include <linux/percpu.h>
e973f4ec 26#include <linux/clk-provider.h>
f615136c 27#include <linux/cpu.h>
d02014b2 28#include <linux/of.h>
da844a81 29#include <linux/of_fdt.h>
da844a81 30
5a0015d6
CZ
31#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
32# include <linux/console.h>
33#endif
34
35#ifdef CONFIG_RTC
36# include <linux/timex.h>
37#endif
38
39#ifdef CONFIG_PROC_FS
40# include <linux/seq_file.h>
41#endif
42
5a0015d6 43#include <asm/bootparam.h>
c8f3a7dc 44#include <asm/mmu_context.h>
5a0015d6
CZ
45#include <asm/pgtable.h>
46#include <asm/processor.h>
47#include <asm/timex.h>
48#include <asm/platform.h>
49#include <asm/page.h>
50#include <asm/setup.h>
de4f6e5b 51#include <asm/param.h>
00273125 52#include <asm/traps.h>
f615136c 53#include <asm/smp.h>
9ba067f9 54#include <asm/sysmem.h>
5a0015d6 55
5a891ed5
AD
56#include <platform/hardware.h>
57
5a0015d6
CZ
58#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
59struct screen_info screen_info = { 0, 24, 0, 0, 0, 80, 0, 0, 0, 24, 1, 16};
60#endif
61
62#ifdef CONFIG_BLK_DEV_FD
63extern struct fd_ops no_fd_ops;
64struct fd_ops *fd_ops;
65#endif
66
5a0015d6
CZ
67extern struct rtc_ops no_rtc_ops;
68struct rtc_ops *rtc_ops;
69
5a0015d6 70#ifdef CONFIG_BLK_DEV_INITRD
29eb45a9
RH
71extern unsigned long initrd_start;
72extern unsigned long initrd_end;
5a0015d6
CZ
73int initrd_is_mapped = 0;
74extern int initrd_below_start_ok;
75#endif
76
da844a81 77#ifdef CONFIG_OF
da844a81
MF
78void *dtb_start = __dtb_start;
79#endif
80
5a0015d6
CZ
81unsigned char aux_device_present;
82extern unsigned long loops_per_jiffy;
83
84/* Command line specified as configuration option. */
85
d3e9ccea 86static char __initdata command_line[COMMAND_LINE_SIZE];
5a0015d6
CZ
87
88#ifdef CONFIG_CMDLINE_BOOL
89static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
90#endif
91
5a0015d6
CZ
92/*
93 * Boot parameter parsing.
94 *
95 * The Xtensa port uses a list of variable-sized tags to pass data to
96 * the kernel. The first tag must be a BP_TAG_FIRST tag for the list
97 * to be recognised. The list is terminated with a zero-sized
98 * BP_TAG_LAST tag.
99 */
100
101typedef struct tagtable {
102 u32 tag;
103 int (*parse)(const bp_tag_t*);
104} tagtable_t;
105
106#define __tagtable(tag, fn) static tagtable_t __tagtable_##fn \
f4349b6e 107 __attribute__((used, section(".taglist"))) = { tag, fn }
5a0015d6
CZ
108
109/* parse current tag */
110
da844a81
MF
111static int __init parse_tag_mem(const bp_tag_t *tag)
112{
9ba067f9 113 struct bp_meminfo *mi = (struct bp_meminfo *)(tag->data);
da844a81
MF
114
115 if (mi->type != MEMORY_TYPE_CONVENTIONAL)
116 return -1;
117
0e46c111 118 return memblock_add(mi->start, mi->end - mi->start);
da844a81
MF
119}
120
5a0015d6
CZ
121__tagtable(BP_TAG_MEMORY, parse_tag_mem);
122
123#ifdef CONFIG_BLK_DEV_INITRD
124
125static int __init parse_tag_initrd(const bp_tag_t* tag)
126{
9ba067f9
MF
127 struct bp_meminfo *mi = (struct bp_meminfo *)(tag->data);
128
29eb45a9
RH
129 initrd_start = (unsigned long)__va(mi->start);
130 initrd_end = (unsigned long)__va(mi->end);
5a0015d6
CZ
131
132 return 0;
133}
134
135__tagtable(BP_TAG_INITRD, parse_tag_initrd);
136
da844a81
MF
137#ifdef CONFIG_OF
138
139static int __init parse_tag_fdt(const bp_tag_t *tag)
140{
c5a771d0 141 dtb_start = __va(tag->data[0]);
da844a81
MF
142 return 0;
143}
144
145__tagtable(BP_TAG_FDT, parse_tag_fdt);
146
da844a81
MF
147#endif /* CONFIG_OF */
148
5a0015d6
CZ
149#endif /* CONFIG_BLK_DEV_INITRD */
150
151static int __init parse_tag_cmdline(const bp_tag_t* tag)
152{
da844a81 153 strlcpy(command_line, (char *)(tag->data), COMMAND_LINE_SIZE);
5a0015d6
CZ
154 return 0;
155}
156
157__tagtable(BP_TAG_COMMAND_LINE, parse_tag_cmdline);
158
159static int __init parse_bootparam(const bp_tag_t* tag)
160{
161 extern tagtable_t __tagtable_begin, __tagtable_end;
162 tagtable_t *t;
163
164 /* Boot parameters must start with a BP_TAG_FIRST tag. */
165
166 if (tag->id != BP_TAG_FIRST) {
167 printk(KERN_WARNING "Invalid boot parameters!\n");
168 return 0;
169 }
170
171 tag = (bp_tag_t*)((unsigned long)tag + sizeof(bp_tag_t) + tag->size);
172
173 /* Parse all tags. */
174
175 while (tag != NULL && tag->id != BP_TAG_LAST) {
176 for (t = &__tagtable_begin; t < &__tagtable_end; t++) {
177 if (tag->id == t->tag) {
178 t->parse(tag);
179 break;
180 }
181 }
182 if (t == &__tagtable_end)
183 printk(KERN_WARNING "Ignoring tag "
184 "0x%08x\n", tag->id);
185 tag = (bp_tag_t*)((unsigned long)(tag + 1) + tag->size);
186 }
187
188 return 0;
189}
190
da844a81
MF
191#ifdef CONFIG_OF
192
260c64bb 193#if !XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY
6cb97111
BS
194unsigned long xtensa_kio_paddr = XCHAL_KIO_DEFAULT_PADDR;
195EXPORT_SYMBOL(xtensa_kio_paddr);
196
197static int __init xtensa_dt_io_area(unsigned long node, const char *uname,
198 int depth, void *data)
199{
200 const __be32 *ranges;
9d0c4dfe 201 int len;
6cb97111
BS
202
203 if (depth > 1)
204 return 0;
205
206 if (!of_flat_dt_is_compatible(node, "simple-bus"))
207 return 0;
208
209 ranges = of_get_flat_dt_prop(node, "ranges", &len);
210 if (!ranges)
211 return 1;
212 if (len == 0)
213 return 1;
214
215 xtensa_kio_paddr = of_read_ulong(ranges+1, 1);
216 /* round down to nearest 256MB boundary */
217 xtensa_kio_paddr &= 0xf0000000;
218
219 return 1;
220}
221#else
222static int __init xtensa_dt_io_area(unsigned long node, const char *uname,
223 int depth, void *data)
224{
225 return 1;
226}
227#endif
228
da844a81
MF
229void __init early_init_dt_add_memory_arch(u64 base, u64 size)
230{
231 size &= PAGE_MASK;
0e46c111 232 memblock_add(base, size);
da844a81
MF
233}
234
235void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
236{
237 return __alloc_bootmem(size, align, 0);
238}
239
240void __init early_init_devtree(void *params)
241{
7745fc1f 242 early_init_dt_scan(params);
6cb97111 243 of_scan_flat_dt(xtensa_dt_io_area, NULL);
da844a81 244
7745fc1f
RH
245 if (!command_line[0])
246 strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
da844a81
MF
247}
248
e973f4ec
RH
249static int __init xtensa_device_probe(void)
250{
251 of_clk_init(NULL);
252 return 0;
253}
254
255device_initcall(xtensa_device_probe);
256
da844a81
MF
257#endif /* CONFIG_OF */
258
5a0015d6
CZ
259/*
260 * Initialize architecture. (Early stage)
261 */
262
263void __init init_arch(bp_tag_t *bp_start)
264{
5a0015d6
CZ
265 /* Parse boot parameters */
266
c4c4594b 267 if (bp_start)
da844a81
MF
268 parse_bootparam(bp_start);
269
270#ifdef CONFIG_OF
271 early_init_devtree(dtb_start);
272#endif
5a0015d6 273
da844a81
MF
274#ifdef CONFIG_CMDLINE_BOOL
275 if (!command_line[0])
276 strlcpy(command_line, default_command_line, COMMAND_LINE_SIZE);
277#endif
278
5a0015d6
CZ
279 /* Early hook for platforms */
280
281 platform_init(bp_start);
282
283 /* Initialize MMU. */
284
285 init_mmu();
286}
287
288/*
289 * Initialize system. Setup memory and reserve regions.
290 */
291
292extern char _end;
293extern char _stext;
294extern char _WindowVectors_text_start;
295extern char _WindowVectors_text_end;
296extern char _DebugInterruptVector_literal_start;
297extern char _DebugInterruptVector_text_end;
298extern char _KernelExceptionVector_literal_start;
299extern char _KernelExceptionVector_text_end;
300extern char _UserExceptionVector_literal_start;
301extern char _UserExceptionVector_text_end;
302extern char _DoubleExceptionVector_literal_start;
303extern char _DoubleExceptionVector_text_end;
2d1c645c
MG
304#if XCHAL_EXCM_LEVEL >= 2
305extern char _Level2InterruptVector_text_start;
306extern char _Level2InterruptVector_text_end;
307#endif
308#if XCHAL_EXCM_LEVEL >= 3
309extern char _Level3InterruptVector_text_start;
310extern char _Level3InterruptVector_text_end;
311#endif
312#if XCHAL_EXCM_LEVEL >= 4
313extern char _Level4InterruptVector_text_start;
314extern char _Level4InterruptVector_text_end;
315#endif
316#if XCHAL_EXCM_LEVEL >= 5
317extern char _Level5InterruptVector_text_start;
318extern char _Level5InterruptVector_text_end;
319#endif
320#if XCHAL_EXCM_LEVEL >= 6
321extern char _Level6InterruptVector_text_start;
322extern char _Level6InterruptVector_text_end;
323#endif
ab45fb14
MF
324#ifdef CONFIG_SMP
325extern char _SecondaryResetVector_text_start;
326extern char _SecondaryResetVector_text_end;
327#endif
5a0015d6 328
00273125
MF
329
330#ifdef CONFIG_S32C1I_SELFTEST
331#if XCHAL_HAVE_S32C1I
332
333static int __initdata rcw_word, rcw_probe_pc, rcw_exc;
334
335/*
336 * Basic atomic compare-and-swap, that records PC of S32C1I for probing.
337 *
338 * If *v == cmp, set *v = set. Return previous *v.
339 */
340static inline int probed_compare_swap(int *v, int cmp, int set)
341{
342 int tmp;
343
344 __asm__ __volatile__(
345 " movi %1, 1f\n"
346 " s32i %1, %4, 0\n"
347 " wsr %2, scompare1\n"
348 "1: s32c1i %0, %3, 0\n"
349 : "=a" (set), "=&a" (tmp)
350 : "a" (cmp), "a" (v), "a" (&rcw_probe_pc), "0" (set)
351 : "memory"
352 );
353 return set;
354}
355
356/* Handle probed exception */
357
59970753
MF
358static void __init do_probed_exception(struct pt_regs *regs,
359 unsigned long exccause)
00273125
MF
360{
361 if (regs->pc == rcw_probe_pc) { /* exception on s32c1i ? */
362 regs->pc += 3; /* skip the s32c1i instruction */
363 rcw_exc = exccause;
364 } else {
365 do_unhandled(regs, exccause);
366 }
367}
368
369/* Simple test of S32C1I (soc bringup assist) */
370
59970753 371static int __init check_s32c1i(void)
00273125
MF
372{
373 int n, cause1, cause2;
374 void *handbus, *handdata, *handaddr; /* temporarily saved handlers */
375
376 rcw_probe_pc = 0;
377 handbus = trap_set_handler(EXCCAUSE_LOAD_STORE_ERROR,
378 do_probed_exception);
379 handdata = trap_set_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR,
380 do_probed_exception);
381 handaddr = trap_set_handler(EXCCAUSE_LOAD_STORE_ADDR_ERROR,
382 do_probed_exception);
383
384 /* First try an S32C1I that does not store: */
385 rcw_exc = 0;
386 rcw_word = 1;
387 n = probed_compare_swap(&rcw_word, 0, 2);
388 cause1 = rcw_exc;
389
390 /* took exception? */
391 if (cause1 != 0) {
392 /* unclean exception? */
393 if (n != 2 || rcw_word != 1)
394 panic("S32C1I exception error");
395 } else if (rcw_word != 1 || n != 1) {
396 panic("S32C1I compare error");
397 }
398
399 /* Then an S32C1I that stores: */
400 rcw_exc = 0;
401 rcw_word = 0x1234567;
402 n = probed_compare_swap(&rcw_word, 0x1234567, 0xabcde);
403 cause2 = rcw_exc;
404
405 if (cause2 != 0) {
406 /* unclean exception? */
407 if (n != 0xabcde || rcw_word != 0x1234567)
408 panic("S32C1I exception error (b)");
409 } else if (rcw_word != 0xabcde || n != 0x1234567) {
410 panic("S32C1I store error");
411 }
412
413 /* Verify consistency of exceptions: */
414 if (cause1 || cause2) {
415 pr_warn("S32C1I took exception %d, %d\n", cause1, cause2);
416 /* If emulation of S32C1I upon bus error gets implemented,
417 we can get rid of this panic for single core (not SMP) */
418 panic("S32C1I exceptions not currently supported");
419 }
420 if (cause1 != cause2)
421 panic("inconsistent S32C1I exceptions");
422
423 trap_set_handler(EXCCAUSE_LOAD_STORE_ERROR, handbus);
424 trap_set_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, handdata);
425 trap_set_handler(EXCCAUSE_LOAD_STORE_ADDR_ERROR, handaddr);
59970753 426 return 0;
00273125
MF
427}
428
429#else /* XCHAL_HAVE_S32C1I */
430
431/* This condition should not occur with a commercially deployed processor.
432 Display reminder for early engr test or demo chips / FPGA bitstreams */
59970753 433static int __init check_s32c1i(void)
00273125
MF
434{
435 pr_warn("Processor configuration lacks atomic compare-and-swap support!\n");
59970753 436 return 0;
00273125
MF
437}
438
439#endif /* XCHAL_HAVE_S32C1I */
59970753 440early_initcall(check_s32c1i);
00273125
MF
441#endif /* CONFIG_S32C1I_SELFTEST */
442
0e46c111
MF
443static inline int mem_reserve(unsigned long start, unsigned long end)
444{
445 return memblock_reserve(start, end - start);
446}
00273125 447
5a0015d6
CZ
448void __init setup_arch(char **cmdline_p)
449{
da844a81 450 strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
5a0015d6
CZ
451 *cmdline_p = command_line;
452
453 /* Reserve some memory regions */
454
455#ifdef CONFIG_BLK_DEV_INITRD
456 if (initrd_start < initrd_end) {
457 initrd_is_mapped = mem_reserve(__pa(initrd_start),
0e46c111 458 __pa(initrd_end)) == 0;
5a0015d6 459 initrd_below_start_ok = 1;
c4c4594b 460 } else {
5a0015d6
CZ
461 initrd_start = 0;
462 }
463#endif
464
0e46c111 465 mem_reserve(__pa(&_stext), __pa(&_end));
5a0015d6
CZ
466
467 mem_reserve(__pa(&_WindowVectors_text_start),
0e46c111 468 __pa(&_WindowVectors_text_end));
5a0015d6
CZ
469
470 mem_reserve(__pa(&_DebugInterruptVector_literal_start),
0e46c111 471 __pa(&_DebugInterruptVector_text_end));
5a0015d6
CZ
472
473 mem_reserve(__pa(&_KernelExceptionVector_literal_start),
0e46c111 474 __pa(&_KernelExceptionVector_text_end));
5a0015d6
CZ
475
476 mem_reserve(__pa(&_UserExceptionVector_literal_start),
0e46c111 477 __pa(&_UserExceptionVector_text_end));
5a0015d6
CZ
478
479 mem_reserve(__pa(&_DoubleExceptionVector_literal_start),
0e46c111 480 __pa(&_DoubleExceptionVector_text_end));
5a0015d6 481
2d1c645c
MG
482#if XCHAL_EXCM_LEVEL >= 2
483 mem_reserve(__pa(&_Level2InterruptVector_text_start),
0e46c111 484 __pa(&_Level2InterruptVector_text_end));
2d1c645c
MG
485#endif
486#if XCHAL_EXCM_LEVEL >= 3
487 mem_reserve(__pa(&_Level3InterruptVector_text_start),
0e46c111 488 __pa(&_Level3InterruptVector_text_end));
2d1c645c
MG
489#endif
490#if XCHAL_EXCM_LEVEL >= 4
491 mem_reserve(__pa(&_Level4InterruptVector_text_start),
0e46c111 492 __pa(&_Level4InterruptVector_text_end));
2d1c645c
MG
493#endif
494#if XCHAL_EXCM_LEVEL >= 5
495 mem_reserve(__pa(&_Level5InterruptVector_text_start),
0e46c111 496 __pa(&_Level5InterruptVector_text_end));
2d1c645c
MG
497#endif
498#if XCHAL_EXCM_LEVEL >= 6
499 mem_reserve(__pa(&_Level6InterruptVector_text_start),
0e46c111 500 __pa(&_Level6InterruptVector_text_end));
2d1c645c
MG
501#endif
502
ab45fb14
MF
503#ifdef CONFIG_SMP
504 mem_reserve(__pa(&_SecondaryResetVector_text_start),
0e46c111 505 __pa(&_SecondaryResetVector_text_end));
ab45fb14 506#endif
06bd2824 507 parse_early_param();
5a0015d6
CZ
508 bootmem_init();
509
3104021c 510 unflatten_and_copy_device_tree();
5a0015d6 511
da844a81 512 platform_setup(cmdline_p);
5a0015d6 513
f615136c
MF
514#ifdef CONFIG_SMP
515 smp_init_cpus();
516#endif
517
5a0015d6 518 paging_init();
e5083a63 519 zones_init();
5a0015d6
CZ
520
521#ifdef CONFIG_VT
522# if defined(CONFIG_VGA_CONSOLE)
523 conswitchp = &vga_con;
524# elif defined(CONFIG_DUMMY_CONSOLE)
525 conswitchp = &dummy_con;
526# endif
527#endif
528
288a60cf 529#ifdef CONFIG_PCI
5a0015d6
CZ
530 platform_pcibios_init();
531#endif
532}
533
f615136c
MF
534static DEFINE_PER_CPU(struct cpu, cpu_data);
535
536static int __init topology_init(void)
537{
538 int i;
539
540 for_each_possible_cpu(i) {
541 struct cpu *cpu = &per_cpu(cpu_data, i);
49b424fe 542 cpu->hotpluggable = !!i;
f615136c
MF
543 register_cpu(cpu, i);
544 }
545
546 return 0;
547}
548subsys_initcall(topology_init);
549
5a0015d6
CZ
550void machine_restart(char * cmd)
551{
552 platform_restart();
553}
554
555void machine_halt(void)
556{
557 platform_halt();
558 while (1);
559}
560
561void machine_power_off(void)
562{
563 platform_power_off();
564 while (1);
565}
566#ifdef CONFIG_PROC_FS
567
568/*
569 * Display some core information through /proc/cpuinfo.
570 */
571
572static int
573c_show(struct seq_file *f, void *slot)
574{
575 /* high-level stuff */
f615136c 576 seq_printf(f, "CPU count\t: %u\n"
62518994 577 "CPU list\t: %*pbl\n"
f615136c
MF
578 "vendor_id\t: Tensilica\n"
579 "model\t\t: Xtensa " XCHAL_HW_VERSION_NAME "\n"
580 "core ID\t\t: " XCHAL_CORE_ID "\n"
581 "build ID\t: 0x%x\n"
582 "byte order\t: %s\n"
583 "cpu MHz\t\t: %lu.%02lu\n"
584 "bogomips\t: %lu.%02lu\n",
585 num_online_cpus(),
62518994 586 cpumask_pr_args(cpu_online_mask),
f615136c
MF
587 XCHAL_BUILD_UNIQUE_ID,
588 XCHAL_HAVE_BE ? "big" : "little",
589 ccount_freq/1000000,
590 (ccount_freq/10000) % 100,
591 loops_per_jiffy/(500000/HZ),
592 (loops_per_jiffy/(5000/HZ)) % 100);
5a0015d6
CZ
593
594 seq_printf(f,"flags\t\t: "
595#if XCHAL_HAVE_NMI
596 "nmi "
597#endif
598#if XCHAL_HAVE_DEBUG
599 "debug "
600# if XCHAL_HAVE_OCD
601 "ocd "
602# endif
603#endif
604#if XCHAL_HAVE_DENSITY
605 "density "
606#endif
607#if XCHAL_HAVE_BOOLEANS
608 "boolean "
609#endif
610#if XCHAL_HAVE_LOOPS
611 "loop "
612#endif
613#if XCHAL_HAVE_NSA
614 "nsa "
615#endif
616#if XCHAL_HAVE_MINMAX
617 "minmax "
618#endif
619#if XCHAL_HAVE_SEXT
620 "sext "
621#endif
622#if XCHAL_HAVE_CLAMPS
623 "clamps "
624#endif
625#if XCHAL_HAVE_MAC16
626 "mac16 "
627#endif
628#if XCHAL_HAVE_MUL16
629 "mul16 "
630#endif
631#if XCHAL_HAVE_MUL32
632 "mul32 "
633#endif
634#if XCHAL_HAVE_MUL32_HIGH
635 "mul32h "
636#endif
637#if XCHAL_HAVE_FP
638 "fpu "
2f6ea6a7
MF
639#endif
640#if XCHAL_HAVE_S32C1I
641 "s32c1i "
5a0015d6
CZ
642#endif
643 "\n");
644
645 /* Registers. */
646 seq_printf(f,"physical aregs\t: %d\n"
647 "misc regs\t: %d\n"
648 "ibreak\t\t: %d\n"
649 "dbreak\t\t: %d\n",
650 XCHAL_NUM_AREGS,
651 XCHAL_NUM_MISC_REGS,
652 XCHAL_NUM_IBREAK,
653 XCHAL_NUM_DBREAK);
654
655
656 /* Interrupt. */
657 seq_printf(f,"num ints\t: %d\n"
658 "ext ints\t: %d\n"
659 "int levels\t: %d\n"
660 "timers\t\t: %d\n"
661 "debug level\t: %d\n",
662 XCHAL_NUM_INTERRUPTS,
663 XCHAL_NUM_EXTINTERRUPTS,
664 XCHAL_NUM_INTLEVELS,
665 XCHAL_NUM_TIMERS,
666 XCHAL_DEBUGLEVEL);
667
5a0015d6
CZ
668 /* Cache */
669 seq_printf(f,"icache line size: %d\n"
670 "icache ways\t: %d\n"
671 "icache size\t: %d\n"
672 "icache flags\t: "
673#if XCHAL_ICACHE_LINE_LOCKABLE
415217ef 674 "lock "
5a0015d6
CZ
675#endif
676 "\n"
677 "dcache line size: %d\n"
678 "dcache ways\t: %d\n"
679 "dcache size\t: %d\n"
680 "dcache flags\t: "
681#if XCHAL_DCACHE_IS_WRITEBACK
415217ef 682 "writeback "
5a0015d6
CZ
683#endif
684#if XCHAL_DCACHE_LINE_LOCKABLE
415217ef 685 "lock "
5a0015d6
CZ
686#endif
687 "\n",
688 XCHAL_ICACHE_LINESIZE,
689 XCHAL_ICACHE_WAYS,
690 XCHAL_ICACHE_SIZE,
691 XCHAL_DCACHE_LINESIZE,
692 XCHAL_DCACHE_WAYS,
693 XCHAL_DCACHE_SIZE);
694
5a0015d6
CZ
695 return 0;
696}
697
698/*
699 * We show only CPU #0 info.
700 */
701static void *
702c_start(struct seq_file *f, loff_t *pos)
703{
f615136c 704 return (*pos == 0) ? (void *)1 : NULL;
5a0015d6
CZ
705}
706
707static void *
708c_next(struct seq_file *f, void *v, loff_t *pos)
709{
710 return NULL;
711}
712
713static void
714c_stop(struct seq_file *f, void *v)
715{
716}
717
03a44825 718const struct seq_operations cpuinfo_op =
5a0015d6 719{
f615136c
MF
720 .start = c_start,
721 .next = c_next,
722 .stop = c_stop,
723 .show = c_show,
5a0015d6
CZ
724};
725
726#endif /* CONFIG_PROC_FS */
This page took 0.826254 seconds and 5 git commands to generate.