^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <asm/machvec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) static const char *cpu_name[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) [CPU_SH7201] = "SH7201",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) [CPU_SH7203] = "SH7203", [CPU_SH7263] = "SH7263",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) [CPU_SH7264] = "SH7264", [CPU_SH7269] = "SH7269",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) [CPU_SH7206] = "SH7206", [CPU_SH7619] = "SH7619",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) [CPU_SH7705] = "SH7705", [CPU_SH7706] = "SH7706",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) [CPU_SH7707] = "SH7707", [CPU_SH7708] = "SH7708",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) [CPU_SH7709] = "SH7709", [CPU_SH7710] = "SH7710",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) [CPU_SH7712] = "SH7712", [CPU_SH7720] = "SH7720",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) [CPU_SH7721] = "SH7721", [CPU_SH7729] = "SH7729",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) [CPU_SH7750] = "SH7750", [CPU_SH7750S] = "SH7750S",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) [CPU_SH7750R] = "SH7750R", [CPU_SH7751] = "SH7751",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) [CPU_SH7751R] = "SH7751R", [CPU_SH7760] = "SH7760",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) [CPU_SH4_202] = "SH4-202", [CPU_SH4_501] = "SH4-501",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) [CPU_SH7763] = "SH7763", [CPU_SH7770] = "SH7770",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) [CPU_SH7780] = "SH7780", [CPU_SH7781] = "SH7781",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) [CPU_SH7343] = "SH7343", [CPU_SH7785] = "SH7785",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) [CPU_SH7786] = "SH7786", [CPU_SH7757] = "SH7757",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) [CPU_SH7722] = "SH7722", [CPU_SHX3] = "SH-X3",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) [CPU_MXG] = "MX-G", [CPU_SH7723] = "SH7723",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) [CPU_SH7366] = "SH7366", [CPU_SH7724] = "SH7724",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) [CPU_SH7372] = "SH7372", [CPU_SH7734] = "SH7734",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) [CPU_J2] = "J2",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) [CPU_SH_NONE] = "Unknown"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) const char *get_cpu_subtype(struct sh_cpuinfo *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) return cpu_name[c->type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) EXPORT_SYMBOL(get_cpu_subtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #ifdef CONFIG_PROC_FS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* Symbolic CPU flags, keep in sync with asm/cpu-features.h */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static const char *cpu_flags[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) "none", "fpu", "p2flush", "mmuassoc", "dsp", "perfctr",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) "ptea", "llsc", "l2", "op32", "pteaex", NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static void show_cpuflags(struct seq_file *m, struct sh_cpuinfo *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) unsigned long i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) seq_printf(m, "cpu flags\t:");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) if (!c->flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) seq_printf(m, " %s\n", cpu_flags[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) for (i = 0; cpu_flags[i]; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if ((c->flags & (1 << i)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) seq_printf(m, " %s", cpu_flags[i+1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) seq_printf(m, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static void show_cacheinfo(struct seq_file *m, const char *type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) struct cache_info info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned int cache_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) cache_size = info.ways * info.sets * info.linesz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) seq_printf(m, "%s size\t: %2dKiB (%d-way)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) type, cache_size >> 10, info.ways);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * Get CPU information for use by the procfs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static int show_cpuinfo(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct sh_cpuinfo *c = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) unsigned int cpu = c - cpu_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (!cpu_online(cpu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (cpu == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) seq_printf(m, "machine\t\t: %s\n", get_system_type());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) seq_printf(m, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) seq_printf(m, "processor\t: %d\n", cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) seq_printf(m, "cpu family\t: %s\n", init_utsname()->machine);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) seq_printf(m, "cpu type\t: %s\n", get_cpu_subtype(c));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (c->cut_major == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) seq_printf(m, "cut\t\t: unknown\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) else if (c->cut_minor == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) seq_printf(m, "cut\t\t: %d.x\n", c->cut_major);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) seq_printf(m, "cut\t\t: %d.%d\n", c->cut_major, c->cut_minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) show_cpuflags(m, c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) seq_printf(m, "cache type\t: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * Check for what type of cache we have, we support both the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * unified cache on the SH-2 and SH-3, as well as the harvard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * style cache on the SH-4.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (c->icache.flags & SH_CACHE_COMBINED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) seq_printf(m, "unified\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) show_cacheinfo(m, "cache", c->icache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) seq_printf(m, "split (harvard)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) show_cacheinfo(m, "icache", c->icache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) show_cacheinfo(m, "dcache", c->dcache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* Optional secondary cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (c->flags & CPU_HAS_L2_CACHE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) show_cacheinfo(m, "scache", c->scache);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) seq_printf(m, "address sizes\t: %u bits physical\n", c->phys_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) seq_printf(m, "bogomips\t: %lu.%02lu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) c->loops_per_jiffy/(500000/HZ),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) (c->loops_per_jiffy/(5000/HZ)) % 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static void *c_start(struct seq_file *m, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return *pos < NR_CPUS ? cpu_data + *pos : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static void *c_next(struct seq_file *m, void *v, loff_t *pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ++*pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return c_start(m, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static void c_stop(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) const struct seq_operations cpuinfo_op = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) .start = c_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) .next = c_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) .stop = c_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .show = show_cpuinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #endif /* CONFIG_PROC_FS */