1b2a237beSNathan Whitehorn /*- 2*71e3c308SPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3*71e3c308SPedro F. Giffuni * 4b2a237beSNathan Whitehorn * Copyright (c) 2008 Marcel Moolenaar 5b2a237beSNathan Whitehorn * Copyright (c) 2009 Nathan Whitehorn 6b2a237beSNathan Whitehorn * All rights reserved. 7b2a237beSNathan Whitehorn * 8b2a237beSNathan Whitehorn * Redistribution and use in source and binary forms, with or without 9b2a237beSNathan Whitehorn * modification, are permitted provided that the following conditions 10b2a237beSNathan Whitehorn * are met: 11b2a237beSNathan Whitehorn * 12b2a237beSNathan Whitehorn * 1. Redistributions of source code must retain the above copyright 13b2a237beSNathan Whitehorn * notice, this list of conditions and the following disclaimer. 14b2a237beSNathan Whitehorn * 2. Redistributions in binary form must reproduce the above copyright 15b2a237beSNathan Whitehorn * notice, this list of conditions and the following disclaimer in the 16b2a237beSNathan Whitehorn * documentation and/or other materials provided with the distribution. 17b2a237beSNathan Whitehorn * 18b2a237beSNathan Whitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19b2a237beSNathan Whitehorn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20b2a237beSNathan Whitehorn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21b2a237beSNathan Whitehorn * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22b2a237beSNathan Whitehorn * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23b2a237beSNathan Whitehorn * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24b2a237beSNathan Whitehorn * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25b2a237beSNathan Whitehorn * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26b2a237beSNathan Whitehorn * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27b2a237beSNathan Whitehorn * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28b2a237beSNathan Whitehorn */ 29b2a237beSNathan Whitehorn 30b2a237beSNathan Whitehorn #include <sys/cdefs.h> 31b2a237beSNathan Whitehorn __FBSDID("$FreeBSD$"); 32b2a237beSNathan Whitehorn 33b2a237beSNathan Whitehorn #include <sys/param.h> 34b2a237beSNathan Whitehorn #include <sys/systm.h> 35b2a237beSNathan Whitehorn #include <sys/kernel.h> 36b2a237beSNathan Whitehorn #include <sys/bus.h> 37b2a237beSNathan Whitehorn #include <sys/pcpu.h> 38b2a237beSNathan Whitehorn #include <sys/proc.h> 39b2a237beSNathan Whitehorn #include <sys/smp.h> 40b2a237beSNathan Whitehorn #include <vm/vm.h> 41b2a237beSNathan Whitehorn #include <vm/pmap.h> 42b2a237beSNathan Whitehorn 43e1c161e7SJustin Hibbits #include <machine/altivec.h> /* For save_vec() */ 44b2a237beSNathan Whitehorn #include <machine/bus.h> 45b2a237beSNathan Whitehorn #include <machine/cpu.h> 46e1c161e7SJustin Hibbits #include <machine/fpu.h> /* For save_fpu() */ 47b2a237beSNathan Whitehorn #include <machine/hid.h> 48b2a237beSNathan Whitehorn #include <machine/platformvar.h> 49e1c161e7SJustin Hibbits #include <machine/setjmp.h> 50b2a237beSNathan Whitehorn #include <machine/smp.h> 51b2a237beSNathan Whitehorn #include <machine/spr.h> 52b2a237beSNathan Whitehorn 53b2a237beSNathan Whitehorn #include <dev/ofw/openfirm.h> 54b2a237beSNathan Whitehorn #include <machine/ofw_machdep.h> 55b2a237beSNathan Whitehorn 56b2a237beSNathan Whitehorn #include "platform_if.h" 57b2a237beSNathan Whitehorn 58b2a237beSNathan Whitehorn extern void *ap_pcpu; 59b2a237beSNathan Whitehorn 60b2a237beSNathan Whitehorn static int powermac_probe(platform_t); 619f706727SNathan Whitehorn static int powermac_attach(platform_t); 62c1cb22d7SNathan Whitehorn void powermac_mem_regions(platform_t, struct mem_region *phys, int *physsz, 63c1cb22d7SNathan Whitehorn struct mem_region *avail, int *availsz); 64b2a237beSNathan Whitehorn static u_long powermac_timebase_freq(platform_t, struct cpuref *cpuref); 65b2a237beSNathan Whitehorn static int powermac_smp_first_cpu(platform_t, struct cpuref *cpuref); 66b2a237beSNathan Whitehorn static int powermac_smp_next_cpu(platform_t, struct cpuref *cpuref); 67b2a237beSNathan Whitehorn static int powermac_smp_get_bsp(platform_t, struct cpuref *cpuref); 68b2a237beSNathan Whitehorn static int powermac_smp_start_cpu(platform_t, struct pcpu *cpu); 69de2dd83fSNathan Whitehorn static void powermac_smp_timebase_sync(platform_t, u_long tb, int ap); 70b2a237beSNathan Whitehorn static void powermac_reset(platform_t); 71e1c161e7SJustin Hibbits static void powermac_sleep(platform_t); 72b2a237beSNathan Whitehorn 73b2a237beSNathan Whitehorn static platform_method_t powermac_methods[] = { 74b2a237beSNathan Whitehorn PLATFORMMETHOD(platform_probe, powermac_probe), 759f706727SNathan Whitehorn PLATFORMMETHOD(platform_attach, powermac_attach), 76b2a237beSNathan Whitehorn PLATFORMMETHOD(platform_mem_regions, powermac_mem_regions), 77b2a237beSNathan Whitehorn PLATFORMMETHOD(platform_timebase_freq, powermac_timebase_freq), 78b2a237beSNathan Whitehorn 79b2a237beSNathan Whitehorn PLATFORMMETHOD(platform_smp_first_cpu, powermac_smp_first_cpu), 80b2a237beSNathan Whitehorn PLATFORMMETHOD(platform_smp_next_cpu, powermac_smp_next_cpu), 81b2a237beSNathan Whitehorn PLATFORMMETHOD(platform_smp_get_bsp, powermac_smp_get_bsp), 82b2a237beSNathan Whitehorn PLATFORMMETHOD(platform_smp_start_cpu, powermac_smp_start_cpu), 83de2dd83fSNathan Whitehorn PLATFORMMETHOD(platform_smp_timebase_sync, powermac_smp_timebase_sync), 84b2a237beSNathan Whitehorn 85b2a237beSNathan Whitehorn PLATFORMMETHOD(platform_reset, powermac_reset), 86e1c161e7SJustin Hibbits PLATFORMMETHOD(platform_sleep, powermac_sleep), 87b2a237beSNathan Whitehorn 88eaba9848SRui Paulo PLATFORMMETHOD_END 89b2a237beSNathan Whitehorn }; 90b2a237beSNathan Whitehorn 91b2a237beSNathan Whitehorn static platform_def_t powermac_platform = { 92b2a237beSNathan Whitehorn "powermac", 93b2a237beSNathan Whitehorn powermac_methods, 94b2a237beSNathan Whitehorn 0 95b2a237beSNathan Whitehorn }; 96b2a237beSNathan Whitehorn 97b2a237beSNathan Whitehorn PLATFORM_DEF(powermac_platform); 98b2a237beSNathan Whitehorn 99b2a237beSNathan Whitehorn static int 100b2a237beSNathan Whitehorn powermac_probe(platform_t plat) 101b2a237beSNathan Whitehorn { 1025d46492dSNathan Whitehorn char compat[255]; 1035d46492dSNathan Whitehorn ssize_t compatlen; 1045d46492dSNathan Whitehorn char *curstr; 1055d46492dSNathan Whitehorn phandle_t root; 1065d46492dSNathan Whitehorn 1075d46492dSNathan Whitehorn root = OF_peer(0); 1085d46492dSNathan Whitehorn if (root == 0) 1095d46492dSNathan Whitehorn return (ENXIO); 1105d46492dSNathan Whitehorn 1115d46492dSNathan Whitehorn compatlen = OF_getprop(root, "compatible", compat, sizeof(compat)); 1125d46492dSNathan Whitehorn 1135d46492dSNathan Whitehorn for (curstr = compat; curstr < compat + compatlen; 1145d46492dSNathan Whitehorn curstr += strlen(curstr) + 1) { 1155d46492dSNathan Whitehorn if (strncmp(curstr, "MacRISC", 7) == 0) 1165d46492dSNathan Whitehorn return (BUS_PROBE_SPECIFIC); 1175d46492dSNathan Whitehorn } 118b2a237beSNathan Whitehorn 119b2a237beSNathan Whitehorn return (ENXIO); 120b2a237beSNathan Whitehorn } 121b2a237beSNathan Whitehorn 122b2a237beSNathan Whitehorn void 123c1cb22d7SNathan Whitehorn powermac_mem_regions(platform_t plat, struct mem_region *phys, int *physsz, 124c1cb22d7SNathan Whitehorn struct mem_region *avail, int *availsz) 125b2a237beSNathan Whitehorn { 126c1cb22d7SNathan Whitehorn phandle_t memory; 127c1cb22d7SNathan Whitehorn cell_t memoryprop[PHYS_AVAIL_SZ * 2]; 128c1cb22d7SNathan Whitehorn ssize_t propsize, i, j; 129c1cb22d7SNathan Whitehorn int physacells = 1; 130c1cb22d7SNathan Whitehorn 131c1cb22d7SNathan Whitehorn memory = OF_finddevice("/memory"); 132276df218SNathan Whitehorn if (memory == -1) 133276df218SNathan Whitehorn memory = OF_finddevice("/memory@0"); 134c1cb22d7SNathan Whitehorn 135c1cb22d7SNathan Whitehorn /* "reg" has variable #address-cells, but #size-cells is always 1 */ 136c1cb22d7SNathan Whitehorn OF_getprop(OF_parent(memory), "#address-cells", &physacells, 137c1cb22d7SNathan Whitehorn sizeof(physacells)); 138c1cb22d7SNathan Whitehorn 139c1cb22d7SNathan Whitehorn propsize = OF_getprop(memory, "reg", memoryprop, sizeof(memoryprop)); 140c1cb22d7SNathan Whitehorn propsize /= sizeof(cell_t); 141c1cb22d7SNathan Whitehorn for (i = 0, j = 0; i < propsize; i += physacells+1, j++) { 142c1cb22d7SNathan Whitehorn phys[j].mr_start = memoryprop[i]; 143c1cb22d7SNathan Whitehorn if (physacells == 2) { 144c1cb22d7SNathan Whitehorn #ifndef __powerpc64__ 145c1cb22d7SNathan Whitehorn /* On 32-bit PPC, ignore regions starting above 4 GB */ 146c1cb22d7SNathan Whitehorn if (memoryprop[i] != 0) { 147c1cb22d7SNathan Whitehorn j--; 148c1cb22d7SNathan Whitehorn continue; 149c1cb22d7SNathan Whitehorn } 150c1cb22d7SNathan Whitehorn #else 151c1cb22d7SNathan Whitehorn phys[j].mr_start <<= 32; 152c1cb22d7SNathan Whitehorn #endif 153c1cb22d7SNathan Whitehorn phys[j].mr_start |= memoryprop[i+1]; 154c1cb22d7SNathan Whitehorn } 155c1cb22d7SNathan Whitehorn phys[j].mr_size = memoryprop[i + physacells]; 156c1cb22d7SNathan Whitehorn } 157c1cb22d7SNathan Whitehorn *physsz = j; 158c1cb22d7SNathan Whitehorn 159c1cb22d7SNathan Whitehorn /* "available" always has #address-cells = 1 */ 160c1cb22d7SNathan Whitehorn propsize = OF_getprop(memory, "available", memoryprop, 161c1cb22d7SNathan Whitehorn sizeof(memoryprop)); 162276df218SNathan Whitehorn if (propsize <= 0) { 163276df218SNathan Whitehorn for (i = 0; i < *physsz; i++) { 164276df218SNathan Whitehorn avail[i].mr_start = phys[i].mr_start; 165276df218SNathan Whitehorn avail[i].mr_size = phys[i].mr_size; 166276df218SNathan Whitehorn } 167276df218SNathan Whitehorn 168276df218SNathan Whitehorn *availsz = *physsz; 169276df218SNathan Whitehorn } else { 170c1cb22d7SNathan Whitehorn propsize /= sizeof(cell_t); 171c1cb22d7SNathan Whitehorn for (i = 0, j = 0; i < propsize; i += 2, j++) { 172c1cb22d7SNathan Whitehorn avail[j].mr_start = memoryprop[i]; 173c1cb22d7SNathan Whitehorn avail[j].mr_size = memoryprop[i + 1]; 174c1cb22d7SNathan Whitehorn } 175c1cb22d7SNathan Whitehorn 176c1cb22d7SNathan Whitehorn #ifdef __powerpc64__ 177c1cb22d7SNathan Whitehorn /* Add in regions above 4 GB to the available list */ 178c1cb22d7SNathan Whitehorn for (i = 0; i < *physsz; i++) { 179c1cb22d7SNathan Whitehorn if (phys[i].mr_start > BUS_SPACE_MAXADDR_32BIT) { 180c1cb22d7SNathan Whitehorn avail[j].mr_start = phys[i].mr_start; 181c1cb22d7SNathan Whitehorn avail[j].mr_size = phys[i].mr_size; 182c1cb22d7SNathan Whitehorn j++; 183c1cb22d7SNathan Whitehorn } 184c1cb22d7SNathan Whitehorn } 185c1cb22d7SNathan Whitehorn #endif 186c1cb22d7SNathan Whitehorn *availsz = j; 187b2a237beSNathan Whitehorn } 188276df218SNathan Whitehorn } 189b2a237beSNathan Whitehorn 1909f706727SNathan Whitehorn static int 1919f706727SNathan Whitehorn powermac_attach(platform_t plat) 1929f706727SNathan Whitehorn { 1939f706727SNathan Whitehorn phandle_t rootnode; 1949f706727SNathan Whitehorn char model[32]; 1959f706727SNathan Whitehorn 1969f706727SNathan Whitehorn 1979f706727SNathan Whitehorn /* 1989f706727SNathan Whitehorn * Quiesce Open Firmware on PowerMac11,2 and 12,1. It is 1999f706727SNathan Whitehorn * necessary there to shut down a background thread doing fan 2009f706727SNathan Whitehorn * management, and is harmful on other machines (it will make OF 2019f706727SNathan Whitehorn * shut off power to various system components it had turned on). 2029f706727SNathan Whitehorn * 2039f706727SNathan Whitehorn * Note: we don't need to worry about which OF module we are 2049f706727SNathan Whitehorn * using since this is called only from very early boot, within 2059f706727SNathan Whitehorn * OF's boot context. 2069f706727SNathan Whitehorn */ 2079f706727SNathan Whitehorn 2089f706727SNathan Whitehorn rootnode = OF_finddevice("/"); 2099f706727SNathan Whitehorn if (OF_getprop(rootnode, "model", model, sizeof(model)) > 0) { 2109f706727SNathan Whitehorn if (strcmp(model, "PowerMac11,2") == 0 || 2119f706727SNathan Whitehorn strcmp(model, "PowerMac12,1") == 0) { 2129f706727SNathan Whitehorn ofw_quiesce(); 2139f706727SNathan Whitehorn } 2149f706727SNathan Whitehorn } 2159f706727SNathan Whitehorn 2169f706727SNathan Whitehorn return (0); 2179f706727SNathan Whitehorn } 2189f706727SNathan Whitehorn 219b2a237beSNathan Whitehorn static u_long 220b2a237beSNathan Whitehorn powermac_timebase_freq(platform_t plat, struct cpuref *cpuref) 221b2a237beSNathan Whitehorn { 222b2a237beSNathan Whitehorn phandle_t phandle; 223b2a237beSNathan Whitehorn int32_t ticks = -1; 224b2a237beSNathan Whitehorn 225b2a237beSNathan Whitehorn phandle = cpuref->cr_hwref; 226b2a237beSNathan Whitehorn 227b2a237beSNathan Whitehorn OF_getprop(phandle, "timebase-frequency", &ticks, sizeof(ticks)); 228b2a237beSNathan Whitehorn 229b2a237beSNathan Whitehorn if (ticks <= 0) 230b2a237beSNathan Whitehorn panic("Unable to determine timebase frequency!"); 231b2a237beSNathan Whitehorn 232b2a237beSNathan Whitehorn return (ticks); 233b2a237beSNathan Whitehorn } 234b2a237beSNathan Whitehorn 235b2a237beSNathan Whitehorn 236b2a237beSNathan Whitehorn static int 237b2a237beSNathan Whitehorn powermac_smp_fill_cpuref(struct cpuref *cpuref, phandle_t cpu) 238b2a237beSNathan Whitehorn { 239e17bec91SJustin Hibbits cell_t cpuid; 240e17bec91SJustin Hibbits int res; 241b2a237beSNathan Whitehorn 242b2a237beSNathan Whitehorn cpuref->cr_hwref = cpu; 243b2a237beSNathan Whitehorn res = OF_getprop(cpu, "reg", &cpuid, sizeof(cpuid)); 244b2a237beSNathan Whitehorn 245b2a237beSNathan Whitehorn /* 246b2a237beSNathan Whitehorn * psim doesn't have a reg property, so assume 0 as for the 247b2a237beSNathan Whitehorn * uniprocessor case in the CHRP spec. 248b2a237beSNathan Whitehorn */ 249b2a237beSNathan Whitehorn if (res < 0) { 250b2a237beSNathan Whitehorn cpuid = 0; 251b2a237beSNathan Whitehorn } 252b2a237beSNathan Whitehorn 253b2a237beSNathan Whitehorn cpuref->cr_cpuid = cpuid & 0xff; 254b2a237beSNathan Whitehorn return (0); 255b2a237beSNathan Whitehorn } 256b2a237beSNathan Whitehorn 257b2a237beSNathan Whitehorn static int 258b2a237beSNathan Whitehorn powermac_smp_first_cpu(platform_t plat, struct cpuref *cpuref) 259b2a237beSNathan Whitehorn { 260b2a237beSNathan Whitehorn char buf[8]; 261b2a237beSNathan Whitehorn phandle_t cpu, dev, root; 262b2a237beSNathan Whitehorn int res; 263b2a237beSNathan Whitehorn 264b2a237beSNathan Whitehorn root = OF_peer(0); 265b2a237beSNathan Whitehorn 266b2a237beSNathan Whitehorn dev = OF_child(root); 267b2a237beSNathan Whitehorn while (dev != 0) { 268b2a237beSNathan Whitehorn res = OF_getprop(dev, "name", buf, sizeof(buf)); 269b2a237beSNathan Whitehorn if (res > 0 && strcmp(buf, "cpus") == 0) 270b2a237beSNathan Whitehorn break; 271b2a237beSNathan Whitehorn dev = OF_peer(dev); 272b2a237beSNathan Whitehorn } 273b2a237beSNathan Whitehorn if (dev == 0) { 274b2a237beSNathan Whitehorn /* 275b2a237beSNathan Whitehorn * psim doesn't have a name property on the /cpus node, 276b2a237beSNathan Whitehorn * but it can be found directly 277b2a237beSNathan Whitehorn */ 278b2a237beSNathan Whitehorn dev = OF_finddevice("/cpus"); 27907042befSJayachandran C. if (dev == -1) 280b2a237beSNathan Whitehorn return (ENOENT); 281b2a237beSNathan Whitehorn } 282b2a237beSNathan Whitehorn 283b2a237beSNathan Whitehorn cpu = OF_child(dev); 284b2a237beSNathan Whitehorn 285b2a237beSNathan Whitehorn while (cpu != 0) { 286b2a237beSNathan Whitehorn res = OF_getprop(cpu, "device_type", buf, sizeof(buf)); 287b2a237beSNathan Whitehorn if (res > 0 && strcmp(buf, "cpu") == 0) 288b2a237beSNathan Whitehorn break; 289b2a237beSNathan Whitehorn cpu = OF_peer(cpu); 290b2a237beSNathan Whitehorn } 291b2a237beSNathan Whitehorn if (cpu == 0) 292b2a237beSNathan Whitehorn return (ENOENT); 293b2a237beSNathan Whitehorn 294b2a237beSNathan Whitehorn return (powermac_smp_fill_cpuref(cpuref, cpu)); 295b2a237beSNathan Whitehorn } 296b2a237beSNathan Whitehorn 297b2a237beSNathan Whitehorn static int 298b2a237beSNathan Whitehorn powermac_smp_next_cpu(platform_t plat, struct cpuref *cpuref) 299b2a237beSNathan Whitehorn { 300b2a237beSNathan Whitehorn char buf[8]; 301b2a237beSNathan Whitehorn phandle_t cpu; 302b2a237beSNathan Whitehorn int res; 303b2a237beSNathan Whitehorn 304b2a237beSNathan Whitehorn cpu = OF_peer(cpuref->cr_hwref); 305b2a237beSNathan Whitehorn while (cpu != 0) { 306b2a237beSNathan Whitehorn res = OF_getprop(cpu, "device_type", buf, sizeof(buf)); 307b2a237beSNathan Whitehorn if (res > 0 && strcmp(buf, "cpu") == 0) 308b2a237beSNathan Whitehorn break; 309b2a237beSNathan Whitehorn cpu = OF_peer(cpu); 310b2a237beSNathan Whitehorn } 311b2a237beSNathan Whitehorn if (cpu == 0) 312b2a237beSNathan Whitehorn return (ENOENT); 313b2a237beSNathan Whitehorn 314b2a237beSNathan Whitehorn return (powermac_smp_fill_cpuref(cpuref, cpu)); 315b2a237beSNathan Whitehorn } 316b2a237beSNathan Whitehorn 317b2a237beSNathan Whitehorn static int 318b2a237beSNathan Whitehorn powermac_smp_get_bsp(platform_t plat, struct cpuref *cpuref) 319b2a237beSNathan Whitehorn { 320b2a237beSNathan Whitehorn ihandle_t inst; 321b2a237beSNathan Whitehorn phandle_t bsp, chosen; 322b2a237beSNathan Whitehorn int res; 323b2a237beSNathan Whitehorn 324b2a237beSNathan Whitehorn chosen = OF_finddevice("/chosen"); 32507042befSJayachandran C. if (chosen == -1) 326b2a237beSNathan Whitehorn return (ENXIO); 327b2a237beSNathan Whitehorn 328b2a237beSNathan Whitehorn res = OF_getprop(chosen, "cpu", &inst, sizeof(inst)); 329b2a237beSNathan Whitehorn if (res < 0) 330b2a237beSNathan Whitehorn return (ENXIO); 331b2a237beSNathan Whitehorn 332b2a237beSNathan Whitehorn bsp = OF_instance_to_package(inst); 333b2a237beSNathan Whitehorn return (powermac_smp_fill_cpuref(cpuref, bsp)); 334b2a237beSNathan Whitehorn } 335b2a237beSNathan Whitehorn 336b2a237beSNathan Whitehorn static int 337b2a237beSNathan Whitehorn powermac_smp_start_cpu(platform_t plat, struct pcpu *pc) 338b2a237beSNathan Whitehorn { 339b2a237beSNathan Whitehorn #ifdef SMP 340b2a237beSNathan Whitehorn phandle_t cpu; 341b2a237beSNathan Whitehorn volatile uint8_t *rstvec; 342b2a237beSNathan Whitehorn static volatile uint8_t *rstvec_virtbase = NULL; 343b2a237beSNathan Whitehorn int res, reset, timeout; 344b2a237beSNathan Whitehorn 345b2a237beSNathan Whitehorn cpu = pc->pc_hwref; 346b2a237beSNathan Whitehorn res = OF_getprop(cpu, "soft-reset", &reset, sizeof(reset)); 347b2a237beSNathan Whitehorn if (res < 0) { 348b2a237beSNathan Whitehorn reset = 0x58; 349b2a237beSNathan Whitehorn 350b2a237beSNathan Whitehorn switch (pc->pc_cpuid) { 351b2a237beSNathan Whitehorn case 0: 352b2a237beSNathan Whitehorn reset += 0x03; 353b2a237beSNathan Whitehorn break; 354b2a237beSNathan Whitehorn case 1: 355b2a237beSNathan Whitehorn reset += 0x04; 356b2a237beSNathan Whitehorn break; 357b2a237beSNathan Whitehorn case 2: 358b2a237beSNathan Whitehorn reset += 0x0f; 359b2a237beSNathan Whitehorn break; 360b2a237beSNathan Whitehorn case 3: 361b2a237beSNathan Whitehorn reset += 0x10; 362b2a237beSNathan Whitehorn break; 363b2a237beSNathan Whitehorn default: 364b2a237beSNathan Whitehorn return (ENXIO); 365b2a237beSNathan Whitehorn } 366b2a237beSNathan Whitehorn } 367b2a237beSNathan Whitehorn 368b2a237beSNathan Whitehorn ap_pcpu = pc; 369b2a237beSNathan Whitehorn 370b2a237beSNathan Whitehorn if (rstvec_virtbase == NULL) 371b2a237beSNathan Whitehorn rstvec_virtbase = pmap_mapdev(0x80000000, PAGE_SIZE); 372b2a237beSNathan Whitehorn 373b2a237beSNathan Whitehorn rstvec = rstvec_virtbase + reset; 374b2a237beSNathan Whitehorn 375b2a237beSNathan Whitehorn *rstvec = 4; 376b2a237beSNathan Whitehorn powerpc_sync(); 377b2a237beSNathan Whitehorn (void)(*rstvec); 378b2a237beSNathan Whitehorn powerpc_sync(); 379b2a237beSNathan Whitehorn DELAY(1); 380b2a237beSNathan Whitehorn *rstvec = 0; 381b2a237beSNathan Whitehorn powerpc_sync(); 382b2a237beSNathan Whitehorn (void)(*rstvec); 383b2a237beSNathan Whitehorn powerpc_sync(); 384b2a237beSNathan Whitehorn 385b2a237beSNathan Whitehorn timeout = 10000; 386b2a237beSNathan Whitehorn while (!pc->pc_awake && timeout--) 387b2a237beSNathan Whitehorn DELAY(100); 388b2a237beSNathan Whitehorn 389b2a237beSNathan Whitehorn return ((pc->pc_awake) ? 0 : EBUSY); 390b2a237beSNathan Whitehorn #else 391b2a237beSNathan Whitehorn /* No SMP support */ 392b2a237beSNathan Whitehorn return (ENXIO); 393b2a237beSNathan Whitehorn #endif 394b2a237beSNathan Whitehorn } 395b2a237beSNathan Whitehorn 396b2a237beSNathan Whitehorn static void 397de2dd83fSNathan Whitehorn powermac_smp_timebase_sync(platform_t plat, u_long tb, int ap) 398de2dd83fSNathan Whitehorn { 399de2dd83fSNathan Whitehorn 400de2dd83fSNathan Whitehorn mttb(tb); 401de2dd83fSNathan Whitehorn } 402de2dd83fSNathan Whitehorn 403de2dd83fSNathan Whitehorn static void 404b2a237beSNathan Whitehorn powermac_reset(platform_t platform) 405b2a237beSNathan Whitehorn { 406b2a237beSNathan Whitehorn OF_reboot(); 407b2a237beSNathan Whitehorn } 408b2a237beSNathan Whitehorn 409e1c161e7SJustin Hibbits void 410e1c161e7SJustin Hibbits powermac_sleep(platform_t platform) 411e1c161e7SJustin Hibbits { 412e1c161e7SJustin Hibbits 413e1c161e7SJustin Hibbits *(unsigned long *)0x80 = 0x100; 414e1c161e7SJustin Hibbits cpu_sleep(); 415e1c161e7SJustin Hibbits } 416e1c161e7SJustin Hibbits 417