~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/xtensa/kernel/setup.c

Version: ~ [ linux-5.4.2 ] ~ [ linux-5.3.15 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.88 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.158 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.206 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.206 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.78 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp