This source file includes following definitions.
- omap4_get_scu_base
- omap5_erratum_workaround_801819
- omap5_erratum_workaround_801819
- omap5_secondary_harden_predictor
- omap5_secondary_harden_predictor
- omap4_secondary_init
- omap4_boot_secondary
- omap4_smp_init_cpus
- omap4_smp_cpu1_startup_valid
- omap4_smp_maybe_reset_cpu1
- omap4_smp_prepare_cpus
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 #include <linux/init.h>
  16 #include <linux/device.h>
  17 #include <linux/smp.h>
  18 #include <linux/io.h>
  19 #include <linux/irqchip/arm-gic.h>
  20 
  21 #include <asm/sections.h>
  22 #include <asm/smp_scu.h>
  23 #include <asm/virt.h>
  24 
  25 #include "omap-secure.h"
  26 #include "omap-wakeupgen.h"
  27 #include <asm/cputype.h>
  28 
  29 #include "soc.h"
  30 #include "iomap.h"
  31 #include "common.h"
  32 #include "clockdomain.h"
  33 #include "pm.h"
  34 
  35 #define CPU_MASK                0xff0ffff0
  36 #define CPU_CORTEX_A9           0x410FC090
  37 #define CPU_CORTEX_A15          0x410FC0F0
  38 
  39 #define OMAP5_CORE_COUNT        0x2
  40 
  41 #define AUX_CORE_BOOT0_GP_RELEASE       0x020
  42 #define AUX_CORE_BOOT0_HS_RELEASE       0x200
  43 
  44 struct omap_smp_config {
  45         unsigned long cpu1_rstctrl_pa;
  46         void __iomem *cpu1_rstctrl_va;
  47         void __iomem *scu_base;
  48         void __iomem *wakeupgen_base;
  49         void *startup_addr;
  50 };
  51 
  52 static struct omap_smp_config cfg;
  53 
  54 static const struct omap_smp_config omap443x_cfg __initconst = {
  55         .cpu1_rstctrl_pa = 0x4824380c,
  56         .startup_addr = omap4_secondary_startup,
  57 };
  58 
  59 static const struct omap_smp_config omap446x_cfg __initconst = {
  60         .cpu1_rstctrl_pa = 0x4824380c,
  61         .startup_addr = omap4460_secondary_startup,
  62 };
  63 
  64 static const struct omap_smp_config omap5_cfg __initconst = {
  65         .cpu1_rstctrl_pa = 0x48243810,
  66         .startup_addr = omap5_secondary_startup,
  67 };
  68 
  69 void __iomem *omap4_get_scu_base(void)
  70 {
  71         return cfg.scu_base;
  72 }
  73 
  74 #ifdef CONFIG_OMAP5_ERRATA_801819
  75 void omap5_erratum_workaround_801819(void)
  76 {
  77         u32 acr, revidr;
  78         u32 acr_mask;
  79 
  80         
  81         asm volatile ("mrc p15, 0, %0, c0, c0, 6" : "=r" (revidr));
  82         if (revidr & (0x1 << 3))
  83                 return;
  84 
  85         asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr));
  86         
  87 
  88 
  89 
  90 
  91 
  92         acr_mask = (0x3 << 25) | (0x3 << 27);
  93         
  94         if ((acr & acr_mask) == acr_mask)
  95                 return;
  96 
  97         acr |= acr_mask;
  98         omap_smc1(OMAP5_DRA7_MON_SET_ACR_INDEX, acr);
  99 
 100         pr_debug("%s: ARM erratum workaround 801819 applied on CPU%d\n",
 101                  __func__, smp_processor_id());
 102 }
 103 #else
 104 static inline void omap5_erratum_workaround_801819(void) { }
 105 #endif
 106 
 107 #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
 108 
 109 
 110 
 111 
 112 
 113 
 114 
 115 
 116 
 117 
 118 
 119 
 120 
 121 static void omap5_secondary_harden_predictor(void)
 122 {
 123         u32 acr, acr_mask;
 124 
 125         asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (acr));
 126 
 127         
 128 
 129 
 130         acr_mask = BIT(0);
 131 
 132         
 133         if ((acr & acr_mask) == acr_mask)
 134                 return;
 135 
 136         acr |= acr_mask;
 137         omap_smc1(OMAP5_DRA7_MON_SET_ACR_INDEX, acr);
 138 
 139         pr_debug("%s: ARM ACR setup for CVE_2017_5715 applied on CPU%d\n",
 140                  __func__, smp_processor_id());
 141 }
 142 #else
 143 static inline void omap5_secondary_harden_predictor(void) { }
 144 #endif
 145 
 146 static void omap4_secondary_init(unsigned int cpu)
 147 {
 148         
 149 
 150 
 151 
 152 
 153 
 154 
 155 
 156         if (soc_is_omap443x() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
 157                 omap_secure_dispatcher(OMAP4_PPA_CPU_ACTRL_SMP_INDEX,
 158                                                         4, 0, 0, 0, 0, 0);
 159 
 160         if (soc_is_omap54xx() || soc_is_dra7xx()) {
 161                 
 162 
 163 
 164 
 165                 set_cntfreq();
 166                 
 167                 omap5_erratum_workaround_801819();
 168                 
 169                 omap5_secondary_harden_predictor();
 170         }
 171 }
 172 
 173 static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle)
 174 {
 175         static struct clockdomain *cpu1_clkdm;
 176         static bool booted;
 177         static struct powerdomain *cpu1_pwrdm;
 178 
 179         
 180 
 181 
 182 
 183 
 184 
 185         if (omap_secure_apis_support())
 186                 omap_modify_auxcoreboot0(AUX_CORE_BOOT0_HS_RELEASE,
 187                                          0xfffffdff);
 188         else
 189                 writel_relaxed(AUX_CORE_BOOT0_GP_RELEASE,
 190                                cfg.wakeupgen_base + OMAP_AUX_CORE_BOOT_0);
 191 
 192         if (!cpu1_clkdm && !cpu1_pwrdm) {
 193                 cpu1_clkdm = clkdm_lookup("mpu1_clkdm");
 194                 cpu1_pwrdm = pwrdm_lookup("cpu1_pwrdm");
 195         }
 196 
 197         
 198 
 199 
 200 
 201 
 202 
 203 
 204 
 205 
 206 
 207 
 208         if (booted && cpu1_pwrdm && cpu1_clkdm) {
 209                 
 210 
 211 
 212 
 213 
 214 
 215 
 216 
 217 
 218 
 219 
 220 
 221 
 222 
 223 
 224                 if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) {
 225                         local_irq_disable();
 226                         gic_dist_disable();
 227                 }
 228 
 229                 
 230 
 231 
 232 
 233                 clkdm_deny_idle_nolock(cpu1_clkdm);
 234                 pwrdm_set_next_pwrst(cpu1_pwrdm, PWRDM_POWER_ON);
 235                 clkdm_allow_idle_nolock(cpu1_clkdm);
 236 
 237                 if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) {
 238                         while (gic_dist_disabled()) {
 239                                 udelay(1);
 240                                 cpu_relax();
 241                         }
 242                         gic_timer_retrigger();
 243                         local_irq_enable();
 244                 }
 245         } else {
 246                 dsb_sev();
 247                 booted = true;
 248         }
 249 
 250         arch_send_wakeup_ipi_mask(cpumask_of(cpu));
 251 
 252         return 0;
 253 }
 254 
 255 
 256 
 257 
 258 
 259 static void __init omap4_smp_init_cpus(void)
 260 {
 261         unsigned int i = 0, ncores = 1, cpu_id;
 262 
 263         
 264         cpu_id = read_cpuid_id() & CPU_MASK;
 265         if (cpu_id == CPU_CORTEX_A9) {
 266                 
 267 
 268 
 269 
 270                 cfg.scu_base =  OMAP2_L4_IO_ADDRESS(scu_a9_get_base());
 271                 BUG_ON(!cfg.scu_base);
 272                 ncores = scu_get_core_count(cfg.scu_base);
 273         } else if (cpu_id == CPU_CORTEX_A15) {
 274                 ncores = OMAP5_CORE_COUNT;
 275         }
 276 
 277         
 278         if (ncores > nr_cpu_ids) {
 279                 pr_warn("SMP: %u cores greater than maximum (%u), clipping\n",
 280                         ncores, nr_cpu_ids);
 281                 ncores = nr_cpu_ids;
 282         }
 283 
 284         for (i = 0; i < ncores; i++)
 285                 set_cpu_possible(i, true);
 286 }
 287 
 288 
 289 
 290 
 291 
 292 
 293 static bool __init omap4_smp_cpu1_startup_valid(unsigned long addr)
 294 {
 295         if ((addr >= __pa(PAGE_OFFSET)) && (addr <= __pa(__bss_start)))
 296                 return false;
 297 
 298         return true;
 299 }
 300 
 301 
 302 
 303 
 304 
 305 
 306 
 307 static void __init omap4_smp_maybe_reset_cpu1(struct omap_smp_config *c)
 308 {
 309         unsigned long cpu1_startup_pa, cpu1_ns_pa_addr;
 310         bool needs_reset = false;
 311         u32 released;
 312 
 313         if (omap_secure_apis_support())
 314                 released = omap_read_auxcoreboot0() & AUX_CORE_BOOT0_HS_RELEASE;
 315         else
 316                 released = readl_relaxed(cfg.wakeupgen_base +
 317                                          OMAP_AUX_CORE_BOOT_0) &
 318                                                 AUX_CORE_BOOT0_GP_RELEASE;
 319         if (released) {
 320                 pr_warn("smp: CPU1 not parked?\n");
 321 
 322                 return;
 323         }
 324 
 325         cpu1_startup_pa = readl_relaxed(cfg.wakeupgen_base +
 326                                         OMAP_AUX_CORE_BOOT_1);
 327 
 328         
 329         if (!omap4_smp_cpu1_startup_valid(cpu1_startup_pa))
 330                 needs_reset = true;
 331 
 332         
 333 
 334 
 335 
 336         if ((soc_is_omap44xx() || soc_is_omap54xx())) {
 337                 cpu1_ns_pa_addr = omap4_get_cpu1_ns_pa_addr();
 338                 if (!omap4_smp_cpu1_startup_valid(cpu1_ns_pa_addr))
 339                         needs_reset = true;
 340         } else {
 341                 cpu1_ns_pa_addr = 0;
 342         }
 343 
 344         if (!needs_reset || !c->cpu1_rstctrl_va)
 345                 return;
 346 
 347         pr_info("smp: CPU1 parked within kernel, needs reset (0x%lx 0x%lx)\n",
 348                 cpu1_startup_pa, cpu1_ns_pa_addr);
 349 
 350         writel_relaxed(1, c->cpu1_rstctrl_va);
 351         readl_relaxed(c->cpu1_rstctrl_va);
 352         writel_relaxed(0, c->cpu1_rstctrl_va);
 353 }
 354 
 355 static void __init omap4_smp_prepare_cpus(unsigned int max_cpus)
 356 {
 357         const struct omap_smp_config *c = NULL;
 358 
 359         if (soc_is_omap443x())
 360                 c = &omap443x_cfg;
 361         else if (soc_is_omap446x())
 362                 c = &omap446x_cfg;
 363         else if (soc_is_dra74x() || soc_is_omap54xx() || soc_is_dra76x())
 364                 c = &omap5_cfg;
 365 
 366         if (!c) {
 367                 pr_err("%s Unknown SMP SoC?\n", __func__);
 368                 return;
 369         }
 370 
 371         
 372         cfg.cpu1_rstctrl_pa = c->cpu1_rstctrl_pa;
 373         cfg.startup_addr = c->startup_addr;
 374         cfg.wakeupgen_base = omap_get_wakeupgen_base();
 375 
 376         if (soc_is_dra74x() || soc_is_omap54xx() || soc_is_dra76x()) {
 377                 if ((__boot_cpu_mode & MODE_MASK) == HYP_MODE)
 378                         cfg.startup_addr = omap5_secondary_hyp_startup;
 379                 omap5_erratum_workaround_801819();
 380         }
 381 
 382         cfg.cpu1_rstctrl_va = ioremap(cfg.cpu1_rstctrl_pa, 4);
 383         if (!cfg.cpu1_rstctrl_va)
 384                 return;
 385 
 386         
 387 
 388 
 389 
 390         if (cfg.scu_base)
 391                 scu_enable(cfg.scu_base);
 392 
 393         omap4_smp_maybe_reset_cpu1(&cfg);
 394 
 395         
 396 
 397 
 398 
 399 
 400 
 401         if (omap_secure_apis_support())
 402                 omap_auxcoreboot_addr(__pa_symbol(cfg.startup_addr));
 403         else
 404                 writel_relaxed(__pa_symbol(cfg.startup_addr),
 405                                cfg.wakeupgen_base + OMAP_AUX_CORE_BOOT_1);
 406 }
 407 
 408 const struct smp_operations omap4_smp_ops __initconst = {
 409         .smp_init_cpus          = omap4_smp_init_cpus,
 410         .smp_prepare_cpus       = omap4_smp_prepare_cpus,
 411         .smp_secondary_init     = omap4_secondary_init,
 412         .smp_boot_secondary     = omap4_boot_secondary,
 413 #ifdef CONFIG_HOTPLUG_CPU
 414         .cpu_die                = omap4_cpu_die,
 415         .cpu_kill               = omap4_cpu_kill,
 416 #endif
 417 };