1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2008-2012 Semihalf. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "opt_platform.h" 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/kernel.h> 36 #include <sys/bus.h> 37 #include <sys/pcpu.h> 38 #include <sys/proc.h> 39 #include <sys/smp.h> 40 41 #include <machine/bus.h> 42 #include <machine/cpu.h> 43 #include <machine/hid.h> 44 #include <machine/_inttypes.h> 45 #include <machine/machdep.h> 46 #include <machine/md_var.h> 47 #include <machine/platform.h> 48 #include <machine/platformvar.h> 49 #include <machine/smp.h> 50 #include <machine/spr.h> 51 #include <machine/vmparam.h> 52 53 #include <dev/fdt/fdt_common.h> 54 #include <dev/ofw/ofw_bus.h> 55 #include <dev/ofw/ofw_bus_subr.h> 56 #include <dev/ofw/openfirm.h> 57 58 #include <vm/vm.h> 59 #include <vm/pmap.h> 60 #include <vm/vm_extern.h> 61 62 #include <powerpc/mpc85xx/mpc85xx.h> 63 64 #include "platform_if.h" 65 66 #ifdef SMP 67 extern void *ap_pcpu; 68 extern vm_paddr_t kernload; /* Kernel physical load address */ 69 extern uint8_t __boot_page[]; /* Boot page body */ 70 extern uint32_t bp_kernload; 71 72 struct cpu_release { 73 uint32_t entry_h; 74 uint32_t entry_l; 75 uint32_t r3_h; 76 uint32_t r3_l; 77 uint32_t reserved; 78 uint32_t pir; 79 }; 80 #endif 81 82 extern uint32_t *bootinfo; 83 vm_paddr_t ccsrbar_pa; 84 vm_offset_t ccsrbar_va; 85 vm_size_t ccsrbar_size; 86 87 static int cpu, maxcpu; 88 89 static int mpc85xx_probe(platform_t); 90 static void mpc85xx_mem_regions(platform_t, struct mem_region *phys, 91 int *physsz, struct mem_region *avail, int *availsz); 92 static u_long mpc85xx_timebase_freq(platform_t, struct cpuref *cpuref); 93 static int mpc85xx_smp_first_cpu(platform_t, struct cpuref *cpuref); 94 static int mpc85xx_smp_next_cpu(platform_t, struct cpuref *cpuref); 95 static int mpc85xx_smp_get_bsp(platform_t, struct cpuref *cpuref); 96 static int mpc85xx_smp_start_cpu(platform_t, struct pcpu *cpu); 97 static void mpc85xx_smp_timebase_sync(platform_t, u_long tb, int ap); 98 static void mpc85xx_idle(platform_t, int cpu); 99 static int mpc85xx_idle_wakeup(platform_t plat, int cpu); 100 101 static void mpc85xx_reset(platform_t); 102 103 static platform_method_t mpc85xx_methods[] = { 104 PLATFORMMETHOD(platform_probe, mpc85xx_probe), 105 PLATFORMMETHOD(platform_attach, mpc85xx_attach), 106 PLATFORMMETHOD(platform_mem_regions, mpc85xx_mem_regions), 107 PLATFORMMETHOD(platform_timebase_freq, mpc85xx_timebase_freq), 108 109 PLATFORMMETHOD(platform_smp_first_cpu, mpc85xx_smp_first_cpu), 110 PLATFORMMETHOD(platform_smp_next_cpu, mpc85xx_smp_next_cpu), 111 PLATFORMMETHOD(platform_smp_get_bsp, mpc85xx_smp_get_bsp), 112 PLATFORMMETHOD(platform_smp_start_cpu, mpc85xx_smp_start_cpu), 113 PLATFORMMETHOD(platform_smp_timebase_sync, mpc85xx_smp_timebase_sync), 114 115 PLATFORMMETHOD(platform_reset, mpc85xx_reset), 116 PLATFORMMETHOD(platform_idle, mpc85xx_idle), 117 PLATFORMMETHOD(platform_idle_wakeup, mpc85xx_idle_wakeup), 118 119 PLATFORMMETHOD_END 120 }; 121 122 DEFINE_CLASS_0(mpc85xx, mpc85xx_platform, mpc85xx_methods, 0); 123 124 PLATFORM_DEF(mpc85xx_platform); 125 126 static int 127 mpc85xx_probe(platform_t plat) 128 { 129 u_int pvr = (mfpvr() >> 16) & 0xFFFF; 130 131 switch (pvr) { 132 case FSL_E500v1: 133 case FSL_E500v2: 134 case FSL_E500mc: 135 case FSL_E5500: 136 case FSL_E6500: 137 return (BUS_PROBE_DEFAULT); 138 } 139 return (ENXIO); 140 } 141 142 int 143 mpc85xx_attach(platform_t plat) 144 { 145 phandle_t cpus, child, ccsr; 146 const char *soc_name_guesses[] = {"/soc", "soc", NULL}; 147 const char **name; 148 pcell_t ranges[6], acells, pacells, scells; 149 uint64_t ccsrbar, ccsrsize; 150 int i; 151 152 if ((cpus = OF_finddevice("/cpus")) != -1) { 153 for (maxcpu = 0, child = OF_child(cpus); child != 0; 154 child = OF_peer(child), maxcpu++) 155 ; 156 } else 157 maxcpu = 1; 158 159 /* 160 * Locate CCSR region. Irritatingly, there is no way to find it 161 * unless you already know where it is. Try to infer its location 162 * from the device tree. 163 */ 164 165 ccsr = -1; 166 for (name = soc_name_guesses; *name != NULL && ccsr == -1; name++) 167 ccsr = OF_finddevice(*name); 168 if (ccsr == -1) { 169 char type[64]; 170 171 /* That didn't work. Search for devices of type "soc" */ 172 child = OF_child(OF_peer(0)); 173 for (OF_child(child); child != 0; child = OF_peer(child)) { 174 if (OF_getprop(child, "device_type", type, sizeof(type)) 175 <= 0) 176 continue; 177 178 if (strcmp(type, "soc") == 0) { 179 ccsr = child; 180 break; 181 } 182 } 183 } 184 185 if (ccsr == -1) 186 panic("Could not locate CCSR window!"); 187 188 OF_getprop(ccsr, "#size-cells", &scells, sizeof(scells)); 189 OF_getprop(ccsr, "#address-cells", &acells, sizeof(acells)); 190 OF_searchprop(OF_parent(ccsr), "#address-cells", &pacells, 191 sizeof(pacells)); 192 OF_getprop(ccsr, "ranges", ranges, sizeof(ranges)); 193 ccsrbar = ccsrsize = 0; 194 for (i = acells; i < acells + pacells; i++) { 195 ccsrbar <<= 32; 196 ccsrbar |= ranges[i]; 197 } 198 for (i = acells + pacells; i < acells + pacells + scells; i++) { 199 ccsrsize <<= 32; 200 ccsrsize |= ranges[i]; 201 } 202 ccsrbar_va = pmap_early_io_map(ccsrbar, ccsrsize); 203 ccsrbar_pa = ccsrbar; 204 ccsrbar_size = ccsrsize; 205 206 #if 0 207 mpc85xx_fix_errata(ccsrbar_va); 208 #endif 209 mpc85xx_enable_l3_cache(); 210 211 return (0); 212 } 213 214 void 215 mpc85xx_mem_regions(platform_t plat, struct mem_region *phys, int *physsz, 216 struct mem_region *avail, int *availsz) 217 { 218 219 ofw_mem_regions(phys, physsz, avail, availsz); 220 } 221 222 static u_long 223 mpc85xx_timebase_freq(platform_t plat, struct cpuref *cpuref) 224 { 225 u_long ticks; 226 phandle_t cpus, child; 227 pcell_t freq; 228 229 if (bootinfo != NULL) { 230 if (bootinfo[0] == 1) { 231 /* Backward compatibility. See 8-STABLE. */ 232 ticks = bootinfo[3] >> 3; 233 } else { 234 /* Compatibility with Juniper's loader. */ 235 ticks = bootinfo[5] >> 3; 236 } 237 } else 238 ticks = 0; 239 240 if ((cpus = OF_finddevice("/cpus")) == -1) 241 goto out; 242 243 if ((child = OF_child(cpus)) == 0) 244 goto out; 245 246 switch (OF_getproplen(child, "timebase-frequency")) { 247 case 4: 248 { 249 uint32_t tbase; 250 OF_getprop(child, "timebase-frequency", &tbase, sizeof(tbase)); 251 ticks = tbase; 252 return (ticks); 253 } 254 case 8: 255 { 256 uint64_t tbase; 257 OF_getprop(child, "timebase-frequency", &tbase, sizeof(tbase)); 258 ticks = tbase; 259 return (ticks); 260 } 261 default: 262 break; 263 } 264 265 freq = 0; 266 if (OF_getprop(child, "bus-frequency", (void *)&freq, 267 sizeof(freq)) <= 0) 268 goto out; 269 270 if (freq == 0) 271 goto out; 272 273 /* 274 * Time Base and Decrementer are updated every 8 CCB bus clocks. 275 * HID0[SEL_TBCLK] = 0 276 */ 277 if (mpc85xx_is_qoriq()) 278 ticks = freq / 32; 279 else 280 ticks = freq / 8; 281 282 out: 283 if (ticks <= 0) 284 panic("Unable to determine timebase frequency!"); 285 286 return (ticks); 287 } 288 289 static int 290 mpc85xx_smp_first_cpu(platform_t plat, struct cpuref *cpuref) 291 { 292 293 cpu = 0; 294 cpuref->cr_cpuid = cpu; 295 cpuref->cr_hwref = cpuref->cr_cpuid; 296 if (bootverbose) 297 printf("powerpc_smp_first_cpu: cpuid %d\n", cpuref->cr_cpuid); 298 cpu++; 299 300 return (0); 301 } 302 303 static int 304 mpc85xx_smp_next_cpu(platform_t plat, struct cpuref *cpuref) 305 { 306 307 if (cpu >= maxcpu) 308 return (ENOENT); 309 310 cpuref->cr_cpuid = cpu++; 311 cpuref->cr_hwref = cpuref->cr_cpuid; 312 if (bootverbose) 313 printf("powerpc_smp_next_cpu: cpuid %d\n", cpuref->cr_cpuid); 314 315 return (0); 316 } 317 318 static int 319 mpc85xx_smp_get_bsp(platform_t plat, struct cpuref *cpuref) 320 { 321 322 cpuref->cr_cpuid = mfspr(SPR_PIR); 323 cpuref->cr_hwref = cpuref->cr_cpuid; 324 325 return (0); 326 } 327 328 #ifdef SMP 329 static int 330 mpc85xx_smp_start_cpu_epapr(platform_t plat, struct pcpu *pc) 331 { 332 vm_paddr_t rel_pa, bptr; 333 volatile struct cpu_release *rel; 334 vm_offset_t rel_va, rel_page; 335 phandle_t node; 336 int i; 337 338 /* If we're calling this, the node already exists. */ 339 node = OF_finddevice("/cpus"); 340 for (i = 0, node = OF_child(node); i < pc->pc_cpuid; 341 i++, node = OF_peer(node)) 342 ; 343 if (OF_getencprop(node, "cpu-release-addr", (pcell_t *)&rel_pa, 344 sizeof(rel_pa)) == -1) { 345 return (ENOENT); 346 } 347 348 rel_page = kva_alloc(PAGE_SIZE); 349 if (rel_page == 0) 350 return (ENOMEM); 351 352 critical_enter(); 353 rel_va = rel_page + (rel_pa & PAGE_MASK); 354 pmap_kenter(rel_page, rel_pa & ~PAGE_MASK); 355 rel = (struct cpu_release *)rel_va; 356 bptr = ((vm_paddr_t)(uintptr_t)__boot_page - KERNBASE) + kernload; 357 cpu_flush_dcache(__DEVOLATILE(struct cpu_release *,rel), sizeof(*rel)); 358 rel->pir = pc->pc_cpuid; __asm __volatile("sync"); 359 rel->entry_h = (bptr >> 32); 360 rel->entry_l = bptr; __asm __volatile("sync"); 361 cpu_flush_dcache(__DEVOLATILE(struct cpu_release *,rel), sizeof(*rel)); 362 if (bootverbose) 363 printf("Waking up CPU %d via CPU release page %p\n", 364 pc->pc_cpuid, rel); 365 critical_exit(); 366 pmap_kremove(rel_page); 367 kva_free(rel_page, PAGE_SIZE); 368 369 return (0); 370 } 371 #endif 372 373 static int 374 mpc85xx_smp_start_cpu(platform_t plat, struct pcpu *pc) 375 { 376 #ifdef SMP 377 vm_paddr_t bptr; 378 uint32_t reg; 379 int timeout; 380 uintptr_t brr; 381 int cpuid; 382 int epapr_boot = 0; 383 uint32_t tgt; 384 385 if (mpc85xx_is_qoriq()) { 386 reg = ccsr_read4(OCP85XX_COREDISR); 387 cpuid = pc->pc_cpuid; 388 389 if ((reg & (1 << cpuid)) != 0) { 390 printf("%s: CPU %d is disabled!\n", __func__, pc->pc_cpuid); 391 return (-1); 392 } 393 394 brr = OCP85XX_BRR; 395 } else { 396 brr = OCP85XX_EEBPCR; 397 cpuid = pc->pc_cpuid + 24; 398 } 399 bp_kernload = kernload; 400 /* 401 * bp_kernload is in the boot page. Sync the cache because ePAPR 402 * booting has the other core(s) already running. 403 */ 404 cpu_flush_dcache(&bp_kernload, sizeof(bp_kernload)); 405 406 ap_pcpu = pc; 407 __asm __volatile("msync; isync"); 408 409 /* First try the ePAPR way. */ 410 if (mpc85xx_smp_start_cpu_epapr(plat, pc) == 0) { 411 epapr_boot = 1; 412 goto spin_wait; 413 } 414 415 reg = ccsr_read4(brr); 416 if ((reg & (1 << cpuid)) != 0) { 417 printf("SMP: CPU %d already out of hold-off state!\n", 418 pc->pc_cpuid); 419 return (ENXIO); 420 } 421 422 /* Flush caches to have our changes hit DRAM. */ 423 cpu_flush_dcache(__boot_page, 4096); 424 425 bptr = ((vm_paddr_t)(uintptr_t)__boot_page - KERNBASE) + kernload; 426 KASSERT((bptr & 0xfff) == 0, 427 ("%s: boot page is not aligned (%#jx)", __func__, (uintmax_t)bptr)); 428 if (mpc85xx_is_qoriq()) { 429 /* 430 * Read DDR controller configuration to select proper BPTR target ID. 431 * 432 * On P5020 bit 29 of DDR1_CS0_CONFIG enables DDR controllers 433 * interleaving. If this bit is set, we have to use 434 * OCP85XX_TGTIF_RAM_INTL as BPTR target ID. On other QorIQ DPAA SoCs, 435 * this bit is reserved and always 0. 436 */ 437 438 reg = ccsr_read4(OCP85XX_DDR1_CS0_CONFIG); 439 if (reg & (1 << 29)) 440 tgt = OCP85XX_TGTIF_RAM_INTL; 441 else 442 tgt = OCP85XX_TGTIF_RAM1; 443 444 /* 445 * Set BSTR to the physical address of the boot page 446 */ 447 ccsr_write4(OCP85XX_BSTRH, bptr >> 32); 448 ccsr_write4(OCP85XX_BSTRL, bptr); 449 ccsr_write4(OCP85XX_BSTAR, OCP85XX_ENA_MASK | 450 (tgt << OCP85XX_TRGT_SHIFT_QORIQ) | (ffsl(PAGE_SIZE) - 2)); 451 452 /* Read back OCP85XX_BSTAR to synchronize write */ 453 ccsr_read4(OCP85XX_BSTAR); 454 455 /* 456 * Enable and configure time base on new CPU. 457 */ 458 459 /* Set TB clock source to platform clock / 32 */ 460 reg = ccsr_read4(CCSR_CTBCKSELR); 461 ccsr_write4(CCSR_CTBCKSELR, reg & ~(1 << pc->pc_cpuid)); 462 463 /* Enable TB */ 464 reg = ccsr_read4(CCSR_CTBENR); 465 ccsr_write4(CCSR_CTBENR, reg | (1 << pc->pc_cpuid)); 466 } else { 467 /* 468 * Set BPTR to the physical address of the boot page 469 */ 470 bptr = (bptr >> 12) | 0x80000000u; 471 ccsr_write4(OCP85XX_BPTR, bptr); 472 __asm __volatile("isync; msync"); 473 } 474 475 /* 476 * Release AP from hold-off state 477 */ 478 reg = ccsr_read4(brr); 479 ccsr_write4(brr, reg | (1 << cpuid)); 480 __asm __volatile("isync; msync"); 481 482 spin_wait: 483 timeout = 500; 484 while (!pc->pc_awake && timeout--) 485 DELAY(1000); /* wait 1ms */ 486 487 /* 488 * Disable boot page translation so that the 4K page at the default 489 * address (= 0xfffff000) isn't permanently remapped and thus not 490 * usable otherwise. 491 */ 492 if (!epapr_boot) { 493 if (mpc85xx_is_qoriq()) 494 ccsr_write4(OCP85XX_BSTAR, 0); 495 else 496 ccsr_write4(OCP85XX_BPTR, 0); 497 __asm __volatile("isync; msync"); 498 } 499 500 if (!pc->pc_awake) 501 panic("SMP: CPU %d didn't wake up.\n", pc->pc_cpuid); 502 return ((pc->pc_awake) ? 0 : EBUSY); 503 #else 504 /* No SMP support */ 505 return (ENXIO); 506 #endif 507 } 508 509 static void 510 mpc85xx_reset(platform_t plat) 511 { 512 513 /* 514 * Try the dedicated reset register first. 515 * If the SoC doesn't have one, we'll fall 516 * back to using the debug control register. 517 */ 518 ccsr_write4(OCP85XX_RSTCR, 2); 519 520 /* Clear DBCR0, disables debug interrupts and events. */ 521 mtspr(SPR_DBCR0, 0); 522 __asm __volatile("isync"); 523 524 /* Enable Debug Interrupts in MSR. */ 525 mtmsr(mfmsr() | PSL_DE); 526 527 /* Enable debug interrupts and issue reset. */ 528 mtspr(SPR_DBCR0, mfspr(SPR_DBCR0) | DBCR0_IDM | DBCR0_RST_SYSTEM); 529 530 printf("Reset failed...\n"); 531 while (1) 532 ; 533 } 534 535 static void 536 mpc85xx_smp_timebase_sync(platform_t plat, u_long tb, int ap) 537 { 538 539 mttb(tb); 540 } 541 542 static void 543 mpc85xx_idle(platform_t plat, int cpu) 544 { 545 uint32_t reg; 546 547 if (mpc85xx_is_qoriq()) { 548 /* 549 * Base binutils doesn't know what the 'wait' instruction is, so 550 * use the opcode encoding here. 551 */ 552 __asm __volatile("wrteei 1; .long 0x7c00007c"); 553 } else { 554 reg = mfmsr(); 555 /* Freescale E500 core RM section 6.4.1. */ 556 __asm __volatile("msync; mtmsr %0; isync" :: 557 "r" (reg | PSL_WE)); 558 } 559 } 560 561 static int 562 mpc85xx_idle_wakeup(platform_t plat, int cpu) 563 { 564 565 return (0); 566 } 567