root/arch/xtensa/kernel/setup.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. parse_tag_mem
  2. parse_tag_initrd
  3. parse_tag_fdt
  4. parse_tag_cmdline
  5. parse_bootparam
  6. parse_bootparam
  7. xtensa_dt_io_area
  8. xtensa_dt_io_area
  9. early_init_devtree
  10. init_arch
  11. mem_reserve
  12. setup_arch
  13. topology_init
  14. cpu_reset
  15. machine_restart
  16. machine_halt
  17. machine_power_off
  18. c_show
  19. c_start
  20. c_next
  21. c_stop

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

/* [<][>][^][v][top][bottom][index][help] */