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

TOMOYO Linux Cross Reference
Linux/arch/powerpc/kernel/cputable.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-or-later
  2 /*
  3  *  Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org)
  4  *
  5  *  Modifications for ppc64:
  6  *      Copyright (C) 2003 Dave Engebretsen <engebret@us.ibm.com>
  7  */
  8 
  9 #include <linux/string.h>
 10 #include <linux/sched.h>
 11 #include <linux/threads.h>
 12 #include <linux/init.h>
 13 #include <linux/export.h>
 14 #include <linux/jump_label.h>
 15 #include <linux/of.h>
 16 
 17 #include <asm/cputable.h>
 18 #include <asm/mce.h>
 19 #include <asm/mmu.h>
 20 #include <asm/setup.h>
 21 #include <asm/cpu_setup.h>
 22 
 23 static struct cpu_spec the_cpu_spec __ro_after_init;
 24 
 25 struct cpu_spec *cur_cpu_spec __ro_after_init = NULL;
 26 EXPORT_SYMBOL(cur_cpu_spec);
 27 
 28 /* The platform string corresponding to the real PVR */
 29 const char *powerpc_base_platform;
 30 
 31 #include "cpu_specs.h"
 32 
 33 void __init set_cur_cpu_spec(struct cpu_spec *s)
 34 {
 35         struct cpu_spec *t = &the_cpu_spec;
 36 
 37         t = PTRRELOC(t);
 38         /*
 39          * use memcpy() instead of *t = *s so that GCC replaces it
 40          * by __memcpy() when KASAN is active
 41          */
 42         memcpy(t, s, sizeof(*t));
 43 
 44         *PTRRELOC(&cur_cpu_spec) = &the_cpu_spec;
 45 }
 46 
 47 static struct cpu_spec * __init setup_cpu_spec(unsigned long offset,
 48                                                struct cpu_spec *s)
 49 {
 50         struct cpu_spec *t = &the_cpu_spec;
 51         struct cpu_spec old;
 52 
 53         t = PTRRELOC(t);
 54         old = *t;
 55 
 56         /*
 57          * Copy everything, then do fixups. Use memcpy() instead of *t = *s
 58          * so that GCC replaces it by __memcpy() when KASAN is active
 59          */
 60         memcpy(t, s, sizeof(*t));
 61 
 62         /*
 63          * If we are overriding a previous value derived from the real
 64          * PVR with a new value obtained using a logical PVR value,
 65          * don't modify the performance monitor fields.
 66          */
 67         if (old.num_pmcs && !s->num_pmcs) {
 68                 t->num_pmcs = old.num_pmcs;
 69                 t->pmc_type = old.pmc_type;
 70 
 71                 /*
 72                  * Let's ensure that the
 73                  * fix for the PMAO bug is enabled on compatibility mode.
 74                  */
 75                 t->cpu_features |= old.cpu_features & CPU_FTR_PMAO_BUG;
 76         }
 77 
 78         /* Set kuap ON at startup, will be disabled later if cmdline has 'nosmap' */
 79         if (IS_ENABLED(CONFIG_PPC_KUAP) && IS_ENABLED(CONFIG_PPC32))
 80                 t->mmu_features |= MMU_FTR_KUAP;
 81 
 82         *PTRRELOC(&cur_cpu_spec) = &the_cpu_spec;
 83 
 84         /*
 85          * Set the base platform string once; assumes
 86          * we're called with real pvr first.
 87          */
 88         if (*PTRRELOC(&powerpc_base_platform) == NULL)
 89                 *PTRRELOC(&powerpc_base_platform) = t->platform;
 90 
 91 #if defined(CONFIG_PPC64) || defined(CONFIG_BOOKE)
 92         /* ppc64 and booke expect identify_cpu to also call setup_cpu for
 93          * that processor. I will consolidate that at a later time, for now,
 94          * just use #ifdef. We also don't need to PTRRELOC the function
 95          * pointer on ppc64 and booke as we are running at 0 in real mode
 96          * on ppc64 and reloc_offset is always 0 on booke.
 97          */
 98         if (t->cpu_setup) {
 99                 t->cpu_setup(offset, t);
100         }
101 #endif /* CONFIG_PPC64 || CONFIG_BOOKE */
102 
103         return t;
104 }
105 
106 struct cpu_spec * __init identify_cpu(unsigned long offset, unsigned int pvr)
107 {
108         struct cpu_spec *s = cpu_specs;
109         int i;
110 
111         BUILD_BUG_ON(!ARRAY_SIZE(cpu_specs));
112 
113         s = PTRRELOC(s);
114 
115         for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) {
116                 if ((pvr & s->pvr_mask) == s->pvr_value)
117                         return setup_cpu_spec(offset, s);
118         }
119 
120         BUG();
121 
122         return NULL;
123 }
124 
125 /*
126  * Used by cpufeatures to get the name for CPUs with a PVR table.
127  * If they don't hae a PVR table, cpufeatures gets the name from
128  * cpu device-tree node.
129  */
130 void __init identify_cpu_name(unsigned int pvr)
131 {
132         struct cpu_spec *s = cpu_specs;
133         struct cpu_spec *t = &the_cpu_spec;
134         int i;
135 
136         s = PTRRELOC(s);
137         t = PTRRELOC(t);
138 
139         for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) {
140                 if ((pvr & s->pvr_mask) == s->pvr_value) {
141                         t->cpu_name = s->cpu_name;
142                         return;
143                 }
144         }
145 }
146 
147 
148 #ifdef CONFIG_JUMP_LABEL_FEATURE_CHECKS
149 struct static_key_true cpu_feature_keys[NUM_CPU_FTR_KEYS] = {
150                         [0 ... NUM_CPU_FTR_KEYS - 1] = STATIC_KEY_TRUE_INIT
151 };
152 EXPORT_SYMBOL_GPL(cpu_feature_keys);
153 
154 void __init cpu_feature_keys_init(void)
155 {
156         int i;
157 
158         for (i = 0; i < NUM_CPU_FTR_KEYS; i++) {
159                 unsigned long f = 1ul << i;
160 
161                 if (!(cur_cpu_spec->cpu_features & f))
162                         static_branch_disable(&cpu_feature_keys[i]);
163         }
164 }
165 
166 struct static_key_true mmu_feature_keys[NUM_MMU_FTR_KEYS] = {
167                         [0 ... NUM_MMU_FTR_KEYS - 1] = STATIC_KEY_TRUE_INIT
168 };
169 EXPORT_SYMBOL(mmu_feature_keys);
170 
171 void __init mmu_feature_keys_init(void)
172 {
173         int i;
174 
175         for (i = 0; i < NUM_MMU_FTR_KEYS; i++) {
176                 unsigned long f = 1ul << i;
177 
178                 if (!(cur_cpu_spec->mmu_features & f))
179                         static_branch_disable(&mmu_feature_keys[i]);
180         }
181 }
182 #endif
183 

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

kernel.org | git.kernel.org | LWN.net | Project Home | 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.

sflogo.php