arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / arch / xtensa / kernel / setup.c
1 /*
2  * arch/xtensa/kernel/setup.c
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.
10  * Copyright (C) 2014 - 2016  Cadence Design Systems Inc.
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
18 #include <linux/errno.h>
19 #include <linux/init.h>
20 #include <linux/mm.h>
21 #include <linux/proc_fs.h>
22 #include <linux/kernel.h>
23 #include <linux/percpu.h>
24 #include <linux/reboot.h>
25 #include <linux/cpu.h>
26 #include <linux/of.h>
27 #include <linux/of_fdt.h>
28
29 #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
30 # include <linux/console.h>
31 #endif
32
33 #ifdef CONFIG_PROC_FS
34 # include <linux/seq_file.h>
35 #endif
36
37 #include <asm/bootparam.h>
38 #include <asm/kasan.h>
39 #include <asm/mmu_context.h>
40 #include <asm/page.h>
41 #include <asm/param.h>
42 #include <asm/platform.h>
43 #include <asm/processor.h>
44 #include <asm/sections.h>
45 #include <asm/setup.h>
46 #include <asm/smp.h>
47 #include <asm/sysmem.h>
48 #include <asm/timex.h>
49 #include <asm/traps.h>
50
51 #ifdef CONFIG_BLK_DEV_INITRD
52 extern unsigned long initrd_start;
53 extern unsigned long initrd_end;
54 extern int initrd_below_start_ok;
55 #endif
56
57 #ifdef CONFIG_USE_OF
58 void *dtb_start = __dtb_start;
59 #endif
60
61 extern unsigned long loops_per_jiffy;
62
63 /* Command line specified as configuration option. */
64
65 static char __initdata command_line[COMMAND_LINE_SIZE];
66
67 #ifdef CONFIG_CMDLINE_BOOL
68 static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
69 #endif
70
71 #ifdef CONFIG_PARSE_BOOTPARAM
72 /*
73  * Boot parameter parsing.
74  *
75  * The Xtensa port uses a list of variable-sized tags to pass data to
76  * the kernel. The first tag must be a BP_TAG_FIRST tag for the list
77  * to be recognised. The list is terminated with a zero-sized
78  * BP_TAG_LAST tag.
79  */
80
81 typedef struct tagtable {
82         u32 tag;
83         int (*parse)(const bp_tag_t*);
84 } tagtable_t;
85
86 #define __tagtable(tag, fn) static tagtable_t __tagtable_##fn           \
87         __section(".taglist") __attribute__((used)) = { tag, fn }
88
89 /* parse current tag */
90
91 static int __init parse_tag_mem(const bp_tag_t *tag)
92 {
93         struct bp_meminfo *mi = (struct bp_meminfo *)(tag->data);
94
95         if (mi->type != MEMORY_TYPE_CONVENTIONAL)
96                 return -1;
97
98         return memblock_add(mi->start, mi->end - mi->start);
99 }
100
101 __tagtable(BP_TAG_MEMORY, parse_tag_mem);
102
103 #ifdef CONFIG_BLK_DEV_INITRD
104
105 static int __init parse_tag_initrd(const bp_tag_t* tag)
106 {
107         struct bp_meminfo *mi = (struct bp_meminfo *)(tag->data);
108
109         initrd_start = (unsigned long)__va(mi->start);
110         initrd_end = (unsigned long)__va(mi->end);
111
112         return 0;
113 }
114
115 __tagtable(BP_TAG_INITRD, parse_tag_initrd);
116
117 #endif /* CONFIG_BLK_DEV_INITRD */
118
119 #ifdef CONFIG_USE_OF
120
121 static int __init parse_tag_fdt(const bp_tag_t *tag)
122 {
123         dtb_start = __va(tag->data[0]);
124         return 0;
125 }
126
127 __tagtable(BP_TAG_FDT, parse_tag_fdt);
128
129 #endif /* CONFIG_USE_OF */
130
131 static int __init parse_tag_cmdline(const bp_tag_t* tag)
132 {
133         strscpy(command_line, (char *)(tag->data), COMMAND_LINE_SIZE);
134         return 0;
135 }
136
137 __tagtable(BP_TAG_COMMAND_LINE, parse_tag_cmdline);
138
139 static int __init parse_bootparam(const bp_tag_t* tag)
140 {
141         extern tagtable_t __tagtable_begin, __tagtable_end;
142         tagtable_t *t;
143
144         /* Boot parameters must start with a BP_TAG_FIRST tag. */
145
146         if (tag->id != BP_TAG_FIRST) {
147                 pr_warn("Invalid boot parameters!\n");
148                 return 0;
149         }
150
151         tag = (bp_tag_t*)((unsigned long)tag + sizeof(bp_tag_t) + tag->size);
152
153         /* Parse all tags. */
154
155         while (tag != NULL && tag->id != BP_TAG_LAST) {
156                 for (t = &__tagtable_begin; t < &__tagtable_end; t++) {
157                         if (tag->id == t->tag) {
158                                 t->parse(tag);
159                                 break;
160                         }
161                 }
162                 if (t == &__tagtable_end)
163                         pr_warn("Ignoring tag 0x%08x\n", tag->id);
164                 tag = (bp_tag_t*)((unsigned long)(tag + 1) + tag->size);
165         }
166
167         return 0;
168 }
169 #else
170 static int __init parse_bootparam(const bp_tag_t *tag)
171 {
172         pr_info("Ignoring boot parameters at %p\n", tag);
173         return 0;
174 }
175 #endif
176
177 #ifdef CONFIG_USE_OF
178
179 #if !XCHAL_HAVE_PTP_MMU || XCHAL_HAVE_SPANNING_WAY
180 unsigned long xtensa_kio_paddr = XCHAL_KIO_DEFAULT_PADDR;
181 EXPORT_SYMBOL(xtensa_kio_paddr);
182
183 static int __init xtensa_dt_io_area(unsigned long node, const char *uname,
184                 int depth, void *data)
185 {
186         const __be32 *ranges;
187         int len;
188
189         if (depth > 1)
190                 return 0;
191
192         if (!of_flat_dt_is_compatible(node, "simple-bus"))
193                 return 0;
194
195         ranges = of_get_flat_dt_prop(node, "ranges", &len);
196         if (!ranges)
197                 return 1;
198         if (len == 0)
199                 return 1;
200
201         xtensa_kio_paddr = of_read_ulong(ranges+1, 1);
202         /* round down to nearest 256MB boundary */
203         xtensa_kio_paddr &= 0xf0000000;
204
205         init_kio();
206
207         return 1;
208 }
209 #else
210 static int __init xtensa_dt_io_area(unsigned long node, const char *uname,
211                 int depth, void *data)
212 {
213         return 1;
214 }
215 #endif
216
217 void __init early_init_devtree(void *params)
218 {
219         early_init_dt_scan(params);
220         of_scan_flat_dt(xtensa_dt_io_area, NULL);
221
222         if (!command_line[0])
223                 strscpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
224 }
225
226 #endif /* CONFIG_USE_OF */
227
228 /*
229  * Initialize architecture. (Early stage)
230  */
231
232 void __init init_arch(bp_tag_t *bp_start)
233 {
234         /* Initialize basic exception handling if configuration may need it */
235
236         if (IS_ENABLED(CONFIG_KASAN) ||
237             IS_ENABLED(CONFIG_XTENSA_LOAD_STORE))
238                 early_trap_init();
239
240         /* Initialize MMU. */
241
242         init_mmu();
243
244         /* Initialize initial KASAN shadow map */
245
246         kasan_early_init();
247
248         /* Parse boot parameters */
249
250         if (bp_start)
251                 parse_bootparam(bp_start);
252
253 #ifdef CONFIG_USE_OF
254         early_init_devtree(dtb_start);
255 #endif
256
257 #ifdef CONFIG_CMDLINE_BOOL
258         if (!command_line[0])
259                 strscpy(command_line, default_command_line, COMMAND_LINE_SIZE);
260 #endif
261
262         /* Early hook for platforms */
263
264         platform_init(bp_start);
265 }
266
267 /*
268  * Initialize system. Setup memory and reserve regions.
269  */
270
271 static inline int __init_memblock mem_reserve(unsigned long start,
272                                               unsigned long end)
273 {
274         return memblock_reserve(start, end - start);
275 }
276
277 void __init setup_arch(char **cmdline_p)
278 {
279         pr_info("config ID: %08x:%08x\n",
280                 xtensa_get_sr(SREG_EPC), xtensa_get_sr(SREG_EXCSAVE));
281         if (xtensa_get_sr(SREG_EPC) != XCHAL_HW_CONFIGID0 ||
282             xtensa_get_sr(SREG_EXCSAVE) != XCHAL_HW_CONFIGID1)
283                 pr_info("built for config ID: %08x:%08x\n",
284                         XCHAL_HW_CONFIGID0, XCHAL_HW_CONFIGID1);
285
286         *cmdline_p = command_line;
287         platform_setup(cmdline_p);
288         strscpy(boot_command_line, *cmdline_p, COMMAND_LINE_SIZE);
289
290         /* Reserve some memory regions */
291
292 #ifdef CONFIG_BLK_DEV_INITRD
293         if (initrd_start < initrd_end &&
294             !mem_reserve(__pa(initrd_start), __pa(initrd_end)))
295                 initrd_below_start_ok = 1;
296         else
297                 initrd_start = 0;
298 #endif
299
300         mem_reserve(__pa(_stext), __pa(_end));
301 #ifdef CONFIG_XIP_KERNEL
302 #ifdef CONFIG_VECTORS_ADDR
303         mem_reserve(__pa(_xip_text_start), __pa(_xip_text_end));
304 #endif
305         mem_reserve(__pa(_xip_start), __pa(_xip_end));
306 #endif
307
308 #ifdef CONFIG_VECTORS_ADDR
309 #ifdef SUPPORT_WINDOWED
310         mem_reserve(__pa(_WindowVectors_text_start),
311                     __pa(_WindowVectors_text_end));
312 #endif
313
314         mem_reserve(__pa(_DebugInterruptVector_text_start),
315                     __pa(_DebugInterruptVector_text_end));
316
317         mem_reserve(__pa(_KernelExceptionVector_text_start),
318                     __pa(_KernelExceptionVector_text_end));
319
320         mem_reserve(__pa(_UserExceptionVector_text_start),
321                     __pa(_UserExceptionVector_text_end));
322
323         mem_reserve(__pa(_DoubleExceptionVector_text_start),
324                     __pa(_DoubleExceptionVector_text_end));
325
326         mem_reserve(__pa(_exception_text_start),
327                     __pa(_exception_text_end));
328 #if XCHAL_EXCM_LEVEL >= 2
329         mem_reserve(__pa(_Level2InterruptVector_text_start),
330                     __pa(_Level2InterruptVector_text_end));
331 #endif
332 #if XCHAL_EXCM_LEVEL >= 3
333         mem_reserve(__pa(_Level3InterruptVector_text_start),
334                     __pa(_Level3InterruptVector_text_end));
335 #endif
336 #if XCHAL_EXCM_LEVEL >= 4
337         mem_reserve(__pa(_Level4InterruptVector_text_start),
338                     __pa(_Level4InterruptVector_text_end));
339 #endif
340 #if XCHAL_EXCM_LEVEL >= 5
341         mem_reserve(__pa(_Level5InterruptVector_text_start),
342                     __pa(_Level5InterruptVector_text_end));
343 #endif
344 #if XCHAL_EXCM_LEVEL >= 6
345         mem_reserve(__pa(_Level6InterruptVector_text_start),
346                     __pa(_Level6InterruptVector_text_end));
347 #endif
348
349 #endif /* CONFIG_VECTORS_ADDR */
350
351 #ifdef CONFIG_SECONDARY_RESET_VECTOR
352         mem_reserve(__pa(_SecondaryResetVector_text_start),
353                     __pa(_SecondaryResetVector_text_end));
354 #endif
355         parse_early_param();
356         bootmem_init();
357         kasan_init();
358         unflatten_and_copy_device_tree();
359
360 #ifdef CONFIG_SMP
361         smp_init_cpus();
362 #endif
363
364         paging_init();
365         zones_init();
366
367 #ifdef CONFIG_VT
368 # if defined(CONFIG_VGA_CONSOLE)
369         conswitchp = &vga_con;
370 # endif
371 #endif
372 }
373
374 static DEFINE_PER_CPU(struct cpu, cpu_data);
375
376 static int __init topology_init(void)
377 {
378         int i;
379
380         for_each_possible_cpu(i) {
381                 struct cpu *cpu = &per_cpu(cpu_data, i);
382                 cpu->hotpluggable = !!i;
383                 register_cpu(cpu, i);
384         }
385
386         return 0;
387 }
388 subsys_initcall(topology_init);
389
390 void cpu_reset(void)
391 {
392 #if XCHAL_HAVE_PTP_MMU && IS_ENABLED(CONFIG_MMU)
393         local_irq_disable();
394         /*
395          * We have full MMU: all autoload ways, ways 7, 8 and 9 of DTLB must
396          * be flushed.
397          * Way 4 is not currently used by linux.
398          * Ways 5 and 6 shall not be touched on MMUv2 as they are hardwired.
399          * Way 5 shall be flushed and way 6 shall be set to identity mapping
400          * on MMUv3.
401          */
402         local_flush_tlb_all();
403         invalidate_page_directory();
404 #if XCHAL_HAVE_SPANNING_WAY
405         /* MMU v3 */
406         {
407                 unsigned long vaddr = (unsigned long)cpu_reset;
408                 unsigned long paddr = __pa(vaddr);
409                 unsigned long tmpaddr = vaddr + SZ_512M;
410                 unsigned long tmp0, tmp1, tmp2, tmp3;
411
412                 /*
413                  * Find a place for the temporary mapping. It must not be
414                  * in the same 512MB region with vaddr or paddr, otherwise
415                  * there may be multihit exception either on entry to the
416                  * temporary mapping, or on entry to the identity mapping.
417                  * (512MB is the biggest page size supported by TLB.)
418                  */
419                 while (((tmpaddr ^ paddr) & -SZ_512M) == 0)
420                         tmpaddr += SZ_512M;
421
422                 /* Invalidate mapping in the selected temporary area */
423                 if (itlb_probe(tmpaddr) & BIT(ITLB_HIT_BIT))
424                         invalidate_itlb_entry(itlb_probe(tmpaddr));
425                 if (itlb_probe(tmpaddr + PAGE_SIZE) & BIT(ITLB_HIT_BIT))
426                         invalidate_itlb_entry(itlb_probe(tmpaddr + PAGE_SIZE));
427
428                 /*
429                  * Map two consecutive pages starting at the physical address
430                  * of this function to the temporary mapping area.
431                  */
432                 write_itlb_entry(__pte((paddr & PAGE_MASK) |
433                                        _PAGE_HW_VALID |
434                                        _PAGE_HW_EXEC |
435                                        _PAGE_CA_BYPASS),
436                                  tmpaddr & PAGE_MASK);
437                 write_itlb_entry(__pte(((paddr & PAGE_MASK) + PAGE_SIZE) |
438                                        _PAGE_HW_VALID |
439                                        _PAGE_HW_EXEC |
440                                        _PAGE_CA_BYPASS),
441                                  (tmpaddr & PAGE_MASK) + PAGE_SIZE);
442
443                 /* Reinitialize TLB */
444                 __asm__ __volatile__ ("movi     %0, 1f\n\t"
445                                       "movi     %3, 2f\n\t"
446                                       "add      %0, %0, %4\n\t"
447                                       "add      %3, %3, %5\n\t"
448                                       "jx       %0\n"
449                                       /*
450                                        * No literal, data or stack access
451                                        * below this point
452                                        */
453                                       "1:\n\t"
454                                       /* Initialize *tlbcfg */
455                                       "movi     %0, 0\n\t"
456                                       "wsr      %0, itlbcfg\n\t"
457                                       "wsr      %0, dtlbcfg\n\t"
458                                       /* Invalidate TLB way 5 */
459                                       "movi     %0, 4\n\t"
460                                       "movi     %1, 5\n"
461                                       "1:\n\t"
462                                       "iitlb    %1\n\t"
463                                       "idtlb    %1\n\t"
464                                       "add      %1, %1, %6\n\t"
465                                       "addi     %0, %0, -1\n\t"
466                                       "bnez     %0, 1b\n\t"
467                                       /* Initialize TLB way 6 */
468                                       "movi     %0, 7\n\t"
469                                       "addi     %1, %9, 3\n\t"
470                                       "addi     %2, %9, 6\n"
471                                       "1:\n\t"
472                                       "witlb    %1, %2\n\t"
473                                       "wdtlb    %1, %2\n\t"
474                                       "add      %1, %1, %7\n\t"
475                                       "add      %2, %2, %7\n\t"
476                                       "addi     %0, %0, -1\n\t"
477                                       "bnez     %0, 1b\n\t"
478                                       "isync\n\t"
479                                       /* Jump to identity mapping */
480                                       "jx       %3\n"
481                                       "2:\n\t"
482                                       /* Complete way 6 initialization */
483                                       "witlb    %1, %2\n\t"
484                                       "wdtlb    %1, %2\n\t"
485                                       /* Invalidate temporary mapping */
486                                       "sub      %0, %9, %7\n\t"
487                                       "iitlb    %0\n\t"
488                                       "add      %0, %0, %8\n\t"
489                                       "iitlb    %0"
490                                       : "=&a"(tmp0), "=&a"(tmp1), "=&a"(tmp2),
491                                         "=&a"(tmp3)
492                                       : "a"(tmpaddr - vaddr),
493                                         "a"(paddr - vaddr),
494                                         "a"(SZ_128M), "a"(SZ_512M),
495                                         "a"(PAGE_SIZE),
496                                         "a"((tmpaddr + SZ_512M) & PAGE_MASK)
497                                       : "memory");
498         }
499 #endif
500 #endif
501         __asm__ __volatile__ ("movi     a2, 0\n\t"
502                               "wsr      a2, icountlevel\n\t"
503                               "movi     a2, 0\n\t"
504                               "wsr      a2, icount\n\t"
505 #if XCHAL_NUM_IBREAK > 0
506                               "wsr      a2, ibreakenable\n\t"
507 #endif
508 #if XCHAL_HAVE_LOOPS
509                               "wsr      a2, lcount\n\t"
510 #endif
511                               "movi     a2, 0x1f\n\t"
512                               "wsr      a2, ps\n\t"
513                               "isync\n\t"
514                               "jx       %0\n\t"
515                               :
516                               : "a" (XCHAL_RESET_VECTOR_VADDR)
517                               : "a2");
518         for (;;)
519                 ;
520 }
521
522 void machine_restart(char * cmd)
523 {
524         local_irq_disable();
525         smp_send_stop();
526         do_kernel_restart(cmd);
527         pr_err("Reboot failed -- System halted\n");
528         while (1)
529                 cpu_relax();
530 }
531
532 void machine_halt(void)
533 {
534         local_irq_disable();
535         smp_send_stop();
536         do_kernel_power_off();
537         while (1)
538                 cpu_relax();
539 }
540
541 void machine_power_off(void)
542 {
543         local_irq_disable();
544         smp_send_stop();
545         do_kernel_power_off();
546         while (1)
547                 cpu_relax();
548 }
549 #ifdef CONFIG_PROC_FS
550
551 /*
552  * Display some core information through /proc/cpuinfo.
553  */
554
555 static int
556 c_show(struct seq_file *f, void *slot)
557 {
558         /* high-level stuff */
559         seq_printf(f, "CPU count\t: %u\n"
560                       "CPU list\t: %*pbl\n"
561                       "vendor_id\t: Tensilica\n"
562                       "model\t\t: Xtensa " XCHAL_HW_VERSION_NAME "\n"
563                       "core ID\t\t: " XCHAL_CORE_ID "\n"
564                       "build ID\t: 0x%x\n"
565                       "config ID\t: %08x:%08x\n"
566                       "byte order\t: %s\n"
567                       "cpu MHz\t\t: %lu.%02lu\n"
568                       "bogomips\t: %lu.%02lu\n",
569                       num_online_cpus(),
570                       cpumask_pr_args(cpu_online_mask),
571                       XCHAL_BUILD_UNIQUE_ID,
572                       xtensa_get_sr(SREG_EPC), xtensa_get_sr(SREG_EXCSAVE),
573                       XCHAL_HAVE_BE ?  "big" : "little",
574                       ccount_freq/1000000,
575                       (ccount_freq/10000) % 100,
576                       loops_per_jiffy/(500000/HZ),
577                       (loops_per_jiffy/(5000/HZ)) % 100);
578         seq_puts(f, "flags\t\t: "
579 #if XCHAL_HAVE_NMI
580                      "nmi "
581 #endif
582 #if XCHAL_HAVE_DEBUG
583                      "debug "
584 # if XCHAL_HAVE_OCD
585                      "ocd "
586 # endif
587 #if XCHAL_HAVE_TRAX
588                      "trax "
589 #endif
590 #if XCHAL_NUM_PERF_COUNTERS
591                      "perf "
592 #endif
593 #endif
594 #if XCHAL_HAVE_DENSITY
595                      "density "
596 #endif
597 #if XCHAL_HAVE_BOOLEANS
598                      "boolean "
599 #endif
600 #if XCHAL_HAVE_LOOPS
601                      "loop "
602 #endif
603 #if XCHAL_HAVE_NSA
604                      "nsa "
605 #endif
606 #if XCHAL_HAVE_MINMAX
607                      "minmax "
608 #endif
609 #if XCHAL_HAVE_SEXT
610                      "sext "
611 #endif
612 #if XCHAL_HAVE_CLAMPS
613                      "clamps "
614 #endif
615 #if XCHAL_HAVE_MAC16
616                      "mac16 "
617 #endif
618 #if XCHAL_HAVE_MUL16
619                      "mul16 "
620 #endif
621 #if XCHAL_HAVE_MUL32
622                      "mul32 "
623 #endif
624 #if XCHAL_HAVE_MUL32_HIGH
625                      "mul32h "
626 #endif
627 #if XCHAL_HAVE_FP
628                      "fpu "
629 #endif
630 #if XCHAL_HAVE_S32C1I
631                      "s32c1i "
632 #endif
633 #if XCHAL_HAVE_EXCLUSIVE
634                      "exclusive "
635 #endif
636                      "\n");
637
638         /* Registers. */
639         seq_printf(f,"physical aregs\t: %d\n"
640                      "misc regs\t: %d\n"
641                      "ibreak\t\t: %d\n"
642                      "dbreak\t\t: %d\n"
643                      "perf counters\t: %d\n",
644                      XCHAL_NUM_AREGS,
645                      XCHAL_NUM_MISC_REGS,
646                      XCHAL_NUM_IBREAK,
647                      XCHAL_NUM_DBREAK,
648                      XCHAL_NUM_PERF_COUNTERS);
649
650
651         /* Interrupt. */
652         seq_printf(f,"num ints\t: %d\n"
653                      "ext ints\t: %d\n"
654                      "int levels\t: %d\n"
655                      "timers\t\t: %d\n"
656                      "debug level\t: %d\n",
657                      XCHAL_NUM_INTERRUPTS,
658                      XCHAL_NUM_EXTINTERRUPTS,
659                      XCHAL_NUM_INTLEVELS,
660                      XCHAL_NUM_TIMERS,
661                      XCHAL_DEBUGLEVEL);
662
663         /* Cache */
664         seq_printf(f,"icache line size: %d\n"
665                      "icache ways\t: %d\n"
666                      "icache size\t: %d\n"
667                      "icache flags\t: "
668 #if XCHAL_ICACHE_LINE_LOCKABLE
669                      "lock "
670 #endif
671                      "\n"
672                      "dcache line size: %d\n"
673                      "dcache ways\t: %d\n"
674                      "dcache size\t: %d\n"
675                      "dcache flags\t: "
676 #if XCHAL_DCACHE_IS_WRITEBACK
677                      "writeback "
678 #endif
679 #if XCHAL_DCACHE_LINE_LOCKABLE
680                      "lock "
681 #endif
682                      "\n",
683                      XCHAL_ICACHE_LINESIZE,
684                      XCHAL_ICACHE_WAYS,
685                      XCHAL_ICACHE_SIZE,
686                      XCHAL_DCACHE_LINESIZE,
687                      XCHAL_DCACHE_WAYS,
688                      XCHAL_DCACHE_SIZE);
689
690         return 0;
691 }
692
693 /*
694  * We show only CPU #0 info.
695  */
696 static void *
697 c_start(struct seq_file *f, loff_t *pos)
698 {
699         return (*pos == 0) ? (void *)1 : NULL;
700 }
701
702 static void *
703 c_next(struct seq_file *f, void *v, loff_t *pos)
704 {
705         ++*pos;
706         return c_start(f, pos);
707 }
708
709 static void
710 c_stop(struct seq_file *f, void *v)
711 {
712 }
713
714 const struct seq_operations cpuinfo_op =
715 {
716         .start  = c_start,
717         .next   = c_next,
718         .stop   = c_stop,
719         .show   = c_show,
720 };
721
722 #endif /* CONFIG_PROC_FS */