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