xref: /freebsd/sys/powerpc/mpc85xx/platform_mpc85xx.c (revision 302acc2e5f017a6b5c25595e98051cbafacfaca3)
1*302acc2eSNathan Whitehorn /*-
2*302acc2eSNathan Whitehorn  * Copyright (c) 2008-2012 Semihalf.
3*302acc2eSNathan Whitehorn  * All rights reserved.
4*302acc2eSNathan Whitehorn  *
5*302acc2eSNathan Whitehorn  * Redistribution and use in source and binary forms, with or without
6*302acc2eSNathan Whitehorn  * modification, are permitted provided that the following conditions
7*302acc2eSNathan Whitehorn  * are met:
8*302acc2eSNathan Whitehorn  *
9*302acc2eSNathan Whitehorn  * 1. Redistributions of source code must retain the above copyright
10*302acc2eSNathan Whitehorn  *    notice, this list of conditions and the following disclaimer.
11*302acc2eSNathan Whitehorn  * 2. Redistributions in binary form must reproduce the above copyright
12*302acc2eSNathan Whitehorn  *    notice, this list of conditions and the following disclaimer in the
13*302acc2eSNathan Whitehorn  *    documentation and/or other materials provided with the distribution.
14*302acc2eSNathan Whitehorn  *
15*302acc2eSNathan Whitehorn  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16*302acc2eSNathan Whitehorn  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17*302acc2eSNathan Whitehorn  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18*302acc2eSNathan Whitehorn  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19*302acc2eSNathan Whitehorn  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20*302acc2eSNathan Whitehorn  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21*302acc2eSNathan Whitehorn  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22*302acc2eSNathan Whitehorn  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23*302acc2eSNathan Whitehorn  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24*302acc2eSNathan Whitehorn  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*302acc2eSNathan Whitehorn  */
26*302acc2eSNathan Whitehorn 
27*302acc2eSNathan Whitehorn #include <sys/cdefs.h>
28*302acc2eSNathan Whitehorn __FBSDID("$FreeBSD$");
29*302acc2eSNathan Whitehorn 
30*302acc2eSNathan Whitehorn #include <sys/param.h>
31*302acc2eSNathan Whitehorn #include <sys/systm.h>
32*302acc2eSNathan Whitehorn #include <sys/kernel.h>
33*302acc2eSNathan Whitehorn #include <sys/bus.h>
34*302acc2eSNathan Whitehorn #include <sys/pcpu.h>
35*302acc2eSNathan Whitehorn #include <sys/proc.h>
36*302acc2eSNathan Whitehorn #include <sys/smp.h>
37*302acc2eSNathan Whitehorn 
38*302acc2eSNathan Whitehorn #include <machine/bus.h>
39*302acc2eSNathan Whitehorn #include <machine/cpu.h>
40*302acc2eSNathan Whitehorn #include <machine/hid.h>
41*302acc2eSNathan Whitehorn #include <machine/platform.h>
42*302acc2eSNathan Whitehorn #include <machine/platformvar.h>
43*302acc2eSNathan Whitehorn #include <machine/smp.h>
44*302acc2eSNathan Whitehorn #include <machine/spr.h>
45*302acc2eSNathan Whitehorn #include <machine/vmparam.h>
46*302acc2eSNathan Whitehorn 
47*302acc2eSNathan Whitehorn #include <dev/fdt/fdt_common.h>
48*302acc2eSNathan Whitehorn #include <dev/ofw/ofw_bus.h>
49*302acc2eSNathan Whitehorn #include <dev/ofw/ofw_bus_subr.h>
50*302acc2eSNathan Whitehorn #include <dev/ofw/openfirm.h>
51*302acc2eSNathan Whitehorn 
52*302acc2eSNathan Whitehorn #include <powerpc/mpc85xx/mpc85xx.h>
53*302acc2eSNathan Whitehorn 
54*302acc2eSNathan Whitehorn #include "platform_if.h"
55*302acc2eSNathan Whitehorn 
56*302acc2eSNathan Whitehorn #ifdef SMP
57*302acc2eSNathan Whitehorn extern void *ap_pcpu;
58*302acc2eSNathan Whitehorn extern vm_paddr_t kernload;		/* Kernel physical load address */
59*302acc2eSNathan Whitehorn extern uint8_t __boot_page[];		/* Boot page body */
60*302acc2eSNathan Whitehorn extern uint32_t bp_ntlb1s;
61*302acc2eSNathan Whitehorn extern uint32_t bp_tlb1[];
62*302acc2eSNathan Whitehorn extern uint32_t bp_tlb1_end[];
63*302acc2eSNathan Whitehorn #endif
64*302acc2eSNathan Whitehorn 
65*302acc2eSNathan Whitehorn extern uint32_t *bootinfo;
66*302acc2eSNathan Whitehorn 
67*302acc2eSNathan Whitehorn static int cpu, maxcpu;
68*302acc2eSNathan Whitehorn 
69*302acc2eSNathan Whitehorn static int mpc85xx_probe(platform_t);
70*302acc2eSNathan Whitehorn static int mpc85xx_attach(platform_t);
71*302acc2eSNathan Whitehorn static void mpc85xx_mem_regions(platform_t, struct mem_region **phys,
72*302acc2eSNathan Whitehorn     int *physsz, struct mem_region **avail, int *availsz);
73*302acc2eSNathan Whitehorn static u_long mpc85xx_timebase_freq(platform_t, struct cpuref *cpuref);
74*302acc2eSNathan Whitehorn static int mpc85xx_smp_first_cpu(platform_t, struct cpuref *cpuref);
75*302acc2eSNathan Whitehorn static int mpc85xx_smp_next_cpu(platform_t, struct cpuref *cpuref);
76*302acc2eSNathan Whitehorn static int mpc85xx_smp_get_bsp(platform_t, struct cpuref *cpuref);
77*302acc2eSNathan Whitehorn static int mpc85xx_smp_start_cpu(platform_t, struct pcpu *cpu);
78*302acc2eSNathan Whitehorn 
79*302acc2eSNathan Whitehorn static void mpc85xx_reset(platform_t);
80*302acc2eSNathan Whitehorn 
81*302acc2eSNathan Whitehorn static platform_method_t mpc85xx_methods[] = {
82*302acc2eSNathan Whitehorn 	PLATFORMMETHOD(platform_probe,		mpc85xx_probe),
83*302acc2eSNathan Whitehorn 	PLATFORMMETHOD(platform_attach,		mpc85xx_attach),
84*302acc2eSNathan Whitehorn 	PLATFORMMETHOD(platform_mem_regions,	mpc85xx_mem_regions),
85*302acc2eSNathan Whitehorn 	PLATFORMMETHOD(platform_timebase_freq,	mpc85xx_timebase_freq),
86*302acc2eSNathan Whitehorn 
87*302acc2eSNathan Whitehorn 	PLATFORMMETHOD(platform_smp_first_cpu,	mpc85xx_smp_first_cpu),
88*302acc2eSNathan Whitehorn 	PLATFORMMETHOD(platform_smp_next_cpu,	mpc85xx_smp_next_cpu),
89*302acc2eSNathan Whitehorn 	PLATFORMMETHOD(platform_smp_get_bsp,	mpc85xx_smp_get_bsp),
90*302acc2eSNathan Whitehorn 	PLATFORMMETHOD(platform_smp_start_cpu,	mpc85xx_smp_start_cpu),
91*302acc2eSNathan Whitehorn 
92*302acc2eSNathan Whitehorn 	PLATFORMMETHOD(platform_reset,		mpc85xx_reset),
93*302acc2eSNathan Whitehorn 
94*302acc2eSNathan Whitehorn 	PLATFORMMETHOD_END
95*302acc2eSNathan Whitehorn };
96*302acc2eSNathan Whitehorn 
97*302acc2eSNathan Whitehorn static platform_def_t mpc85xx_platform = {
98*302acc2eSNathan Whitehorn 	"mpc85xx",
99*302acc2eSNathan Whitehorn 	mpc85xx_methods,
100*302acc2eSNathan Whitehorn 	0
101*302acc2eSNathan Whitehorn };
102*302acc2eSNathan Whitehorn 
103*302acc2eSNathan Whitehorn PLATFORM_DEF(mpc85xx_platform);
104*302acc2eSNathan Whitehorn 
105*302acc2eSNathan Whitehorn static int
106*302acc2eSNathan Whitehorn mpc85xx_probe(platform_t plat)
107*302acc2eSNathan Whitehorn {
108*302acc2eSNathan Whitehorn 	u_int pvr = mfpvr() >> 16;
109*302acc2eSNathan Whitehorn 
110*302acc2eSNathan Whitehorn 	if ((pvr & 0xfff0) == FSL_E500v1)
111*302acc2eSNathan Whitehorn 		return (BUS_PROBE_DEFAULT);
112*302acc2eSNathan Whitehorn 
113*302acc2eSNathan Whitehorn 	return (ENXIO);
114*302acc2eSNathan Whitehorn }
115*302acc2eSNathan Whitehorn 
116*302acc2eSNathan Whitehorn static int
117*302acc2eSNathan Whitehorn mpc85xx_attach(platform_t plat)
118*302acc2eSNathan Whitehorn {
119*302acc2eSNathan Whitehorn 	phandle_t cpus, child;
120*302acc2eSNathan Whitehorn 	uint32_t sr;
121*302acc2eSNathan Whitehorn 	int i, law_max, tgt;
122*302acc2eSNathan Whitehorn 
123*302acc2eSNathan Whitehorn 	if ((cpus = OF_finddevice("/cpus")) != -1) {
124*302acc2eSNathan Whitehorn 		for (maxcpu = 0, child = OF_child(cpus); child != 0;
125*302acc2eSNathan Whitehorn 		    child = OF_peer(child), maxcpu++)
126*302acc2eSNathan Whitehorn 			;
127*302acc2eSNathan Whitehorn 	} else
128*302acc2eSNathan Whitehorn 		maxcpu = 1;
129*302acc2eSNathan Whitehorn 
130*302acc2eSNathan Whitehorn 	/*
131*302acc2eSNathan Whitehorn 	 * Clear local access windows. Skip DRAM entries, so we don't shoot
132*302acc2eSNathan Whitehorn 	 * ourselves in the foot.
133*302acc2eSNathan Whitehorn 	 */
134*302acc2eSNathan Whitehorn 	law_max = law_getmax();
135*302acc2eSNathan Whitehorn 	for (i = 0; i < law_max; i++) {
136*302acc2eSNathan Whitehorn 		sr = ccsr_read4(OCP85XX_LAWSR(i));
137*302acc2eSNathan Whitehorn 		if ((sr & 0x80000000) == 0)
138*302acc2eSNathan Whitehorn 			continue;
139*302acc2eSNathan Whitehorn 		tgt = (sr & 0x01f00000) >> 20;
140*302acc2eSNathan Whitehorn 		if (tgt == OCP85XX_TGTIF_RAM1 || tgt == OCP85XX_TGTIF_RAM2 ||
141*302acc2eSNathan Whitehorn 		    tgt == OCP85XX_TGTIF_RAM_INTL)
142*302acc2eSNathan Whitehorn 			continue;
143*302acc2eSNathan Whitehorn 
144*302acc2eSNathan Whitehorn 		ccsr_write4(OCP85XX_LAWSR(i), sr & 0x7fffffff);
145*302acc2eSNathan Whitehorn 	}
146*302acc2eSNathan Whitehorn 
147*302acc2eSNathan Whitehorn 	return (0);
148*302acc2eSNathan Whitehorn }
149*302acc2eSNathan Whitehorn 
150*302acc2eSNathan Whitehorn void
151*302acc2eSNathan Whitehorn mpc85xx_mem_regions(platform_t plat, struct mem_region **phys, int *physsz,
152*302acc2eSNathan Whitehorn     struct mem_region **avail, int *availsz)
153*302acc2eSNathan Whitehorn {
154*302acc2eSNathan Whitehorn 
155*302acc2eSNathan Whitehorn 	ofw_mem_regions(phys, physsz, avail, availsz);
156*302acc2eSNathan Whitehorn }
157*302acc2eSNathan Whitehorn 
158*302acc2eSNathan Whitehorn static u_long
159*302acc2eSNathan Whitehorn mpc85xx_timebase_freq(platform_t plat, struct cpuref *cpuref)
160*302acc2eSNathan Whitehorn {
161*302acc2eSNathan Whitehorn 	u_long ticks;
162*302acc2eSNathan Whitehorn 	phandle_t cpus, child;
163*302acc2eSNathan Whitehorn 	pcell_t freq;
164*302acc2eSNathan Whitehorn 
165*302acc2eSNathan Whitehorn 	if (bootinfo != NULL) {
166*302acc2eSNathan Whitehorn 		if (bootinfo[0] == 1) {
167*302acc2eSNathan Whitehorn 			/* Backward compatibility. See 8-STABLE. */
168*302acc2eSNathan Whitehorn 			ticks = bootinfo[3] >> 3;
169*302acc2eSNathan Whitehorn 		} else {
170*302acc2eSNathan Whitehorn 			/* Compatibility with Juniper's loader. */
171*302acc2eSNathan Whitehorn 			ticks = bootinfo[5] >> 3;
172*302acc2eSNathan Whitehorn 		}
173*302acc2eSNathan Whitehorn 	} else
174*302acc2eSNathan Whitehorn 		ticks = 0;
175*302acc2eSNathan Whitehorn 
176*302acc2eSNathan Whitehorn 	if ((cpus = OF_finddevice("/cpus")) == -1)
177*302acc2eSNathan Whitehorn 		goto out;
178*302acc2eSNathan Whitehorn 
179*302acc2eSNathan Whitehorn 	if ((child = OF_child(cpus)) == 0)
180*302acc2eSNathan Whitehorn 		goto out;
181*302acc2eSNathan Whitehorn 
182*302acc2eSNathan Whitehorn 	switch (OF_getproplen(child, "timebase-frequency")) {
183*302acc2eSNathan Whitehorn 	case 4:
184*302acc2eSNathan Whitehorn 	{
185*302acc2eSNathan Whitehorn 		uint32_t tbase;
186*302acc2eSNathan Whitehorn 		OF_getprop(child, "timebase-frequency", &tbase, sizeof(tbase));
187*302acc2eSNathan Whitehorn 		ticks = tbase;
188*302acc2eSNathan Whitehorn 		return (ticks);
189*302acc2eSNathan Whitehorn 	}
190*302acc2eSNathan Whitehorn 	case 8:
191*302acc2eSNathan Whitehorn 	{
192*302acc2eSNathan Whitehorn 		uint64_t tbase;
193*302acc2eSNathan Whitehorn 		OF_getprop(child, "timebase-frequency", &tbase, sizeof(tbase));
194*302acc2eSNathan Whitehorn 		ticks = tbase;
195*302acc2eSNathan Whitehorn 		return (ticks);
196*302acc2eSNathan Whitehorn 	}
197*302acc2eSNathan Whitehorn 	default:
198*302acc2eSNathan Whitehorn 		break;
199*302acc2eSNathan Whitehorn 	}
200*302acc2eSNathan Whitehorn 
201*302acc2eSNathan Whitehorn 	freq = 0;
202*302acc2eSNathan Whitehorn 	if (OF_getprop(child, "bus-frequency", (void *)&freq,
203*302acc2eSNathan Whitehorn 	    sizeof(freq)) <= 0)
204*302acc2eSNathan Whitehorn 		goto out;
205*302acc2eSNathan Whitehorn 
206*302acc2eSNathan Whitehorn 	/*
207*302acc2eSNathan Whitehorn 	 * Time Base and Decrementer are updated every 8 CCB bus clocks.
208*302acc2eSNathan Whitehorn 	 * HID0[SEL_TBCLK] = 0
209*302acc2eSNathan Whitehorn 	 */
210*302acc2eSNathan Whitehorn 	if (freq != 0)
211*302acc2eSNathan Whitehorn 		ticks = freq / 8;
212*302acc2eSNathan Whitehorn 
213*302acc2eSNathan Whitehorn out:
214*302acc2eSNathan Whitehorn 	if (ticks <= 0)
215*302acc2eSNathan Whitehorn 		panic("Unable to determine timebase frequency!");
216*302acc2eSNathan Whitehorn 
217*302acc2eSNathan Whitehorn 	return (ticks);
218*302acc2eSNathan Whitehorn }
219*302acc2eSNathan Whitehorn 
220*302acc2eSNathan Whitehorn static int
221*302acc2eSNathan Whitehorn mpc85xx_smp_first_cpu(platform_t plat, struct cpuref *cpuref)
222*302acc2eSNathan Whitehorn {
223*302acc2eSNathan Whitehorn 
224*302acc2eSNathan Whitehorn 	cpu = 0;
225*302acc2eSNathan Whitehorn 	cpuref->cr_cpuid = cpu;
226*302acc2eSNathan Whitehorn 	cpuref->cr_hwref = cpuref->cr_cpuid;
227*302acc2eSNathan Whitehorn 	if (bootverbose)
228*302acc2eSNathan Whitehorn 		printf("powerpc_smp_first_cpu: cpuid %d\n", cpuref->cr_cpuid);
229*302acc2eSNathan Whitehorn 	cpu++;
230*302acc2eSNathan Whitehorn 
231*302acc2eSNathan Whitehorn 	return (0);
232*302acc2eSNathan Whitehorn }
233*302acc2eSNathan Whitehorn 
234*302acc2eSNathan Whitehorn static int
235*302acc2eSNathan Whitehorn mpc85xx_smp_next_cpu(platform_t plat, struct cpuref *cpuref)
236*302acc2eSNathan Whitehorn {
237*302acc2eSNathan Whitehorn 
238*302acc2eSNathan Whitehorn 	if (cpu >= maxcpu)
239*302acc2eSNathan Whitehorn 		return (ENOENT);
240*302acc2eSNathan Whitehorn 
241*302acc2eSNathan Whitehorn 	cpuref->cr_cpuid = cpu++;
242*302acc2eSNathan Whitehorn 	cpuref->cr_hwref = cpuref->cr_cpuid;
243*302acc2eSNathan Whitehorn 	if (bootverbose)
244*302acc2eSNathan Whitehorn 		printf("powerpc_smp_next_cpu: cpuid %d\n", cpuref->cr_cpuid);
245*302acc2eSNathan Whitehorn 
246*302acc2eSNathan Whitehorn 	return (0);
247*302acc2eSNathan Whitehorn }
248*302acc2eSNathan Whitehorn 
249*302acc2eSNathan Whitehorn static int
250*302acc2eSNathan Whitehorn mpc85xx_smp_get_bsp(platform_t plat, struct cpuref *cpuref)
251*302acc2eSNathan Whitehorn {
252*302acc2eSNathan Whitehorn 
253*302acc2eSNathan Whitehorn 	cpuref->cr_cpuid = mfspr(SPR_PIR);
254*302acc2eSNathan Whitehorn 	cpuref->cr_hwref = cpuref->cr_cpuid;
255*302acc2eSNathan Whitehorn 
256*302acc2eSNathan Whitehorn 	return (0);
257*302acc2eSNathan Whitehorn }
258*302acc2eSNathan Whitehorn 
259*302acc2eSNathan Whitehorn static int
260*302acc2eSNathan Whitehorn mpc85xx_smp_start_cpu(platform_t plat, struct pcpu *pc)
261*302acc2eSNathan Whitehorn {
262*302acc2eSNathan Whitehorn #ifdef SMP
263*302acc2eSNathan Whitehorn 	uint32_t *tlb1;
264*302acc2eSNathan Whitehorn 	uint32_t bptr, eebpcr;
265*302acc2eSNathan Whitehorn 	int i, timeout;
266*302acc2eSNathan Whitehorn 
267*302acc2eSNathan Whitehorn 	eebpcr = ccsr_read4(OCP85XX_EEBPCR);
268*302acc2eSNathan Whitehorn 	if ((eebpcr & (1 << (pc->pc_cpuid + 24))) != 0) {
269*302acc2eSNathan Whitehorn 		printf("SMP: CPU %d already out of hold-off state!\n",
270*302acc2eSNathan Whitehorn 		    pc->pc_cpuid);
271*302acc2eSNathan Whitehorn 		return (ENXIO);
272*302acc2eSNathan Whitehorn 	}
273*302acc2eSNathan Whitehorn 
274*302acc2eSNathan Whitehorn 	ap_pcpu = pc;
275*302acc2eSNathan Whitehorn 
276*302acc2eSNathan Whitehorn 	i = 0;
277*302acc2eSNathan Whitehorn 	tlb1 = bp_tlb1;
278*302acc2eSNathan Whitehorn 	while (i < bp_ntlb1s && tlb1 < bp_tlb1_end) {
279*302acc2eSNathan Whitehorn 		mtspr(SPR_MAS0, MAS0_TLBSEL(1) | MAS0_ESEL(i));
280*302acc2eSNathan Whitehorn 		__asm __volatile("isync; tlbre");
281*302acc2eSNathan Whitehorn 		tlb1[0] = mfspr(SPR_MAS1);
282*302acc2eSNathan Whitehorn 		tlb1[1] = mfspr(SPR_MAS2);
283*302acc2eSNathan Whitehorn 		tlb1[2] = mfspr(SPR_MAS3);
284*302acc2eSNathan Whitehorn 		i++;
285*302acc2eSNathan Whitehorn 		tlb1 += 3;
286*302acc2eSNathan Whitehorn 	}
287*302acc2eSNathan Whitehorn 	if (i < bp_ntlb1s)
288*302acc2eSNathan Whitehorn 		bp_ntlb1s = i;
289*302acc2eSNathan Whitehorn 
290*302acc2eSNathan Whitehorn 	/*
291*302acc2eSNathan Whitehorn 	 * Set BPTR to the physical address of the boot page
292*302acc2eSNathan Whitehorn 	 */
293*302acc2eSNathan Whitehorn 	bptr = ((uint32_t)__boot_page - KERNBASE) + kernload;
294*302acc2eSNathan Whitehorn 	KASSERT((bptr & 0xfff) == 0,
295*302acc2eSNathan Whitehorn 	    ("%s: boot page is not aligned (%#x)", __func__, bptr));
296*302acc2eSNathan Whitehorn 	bptr = (bptr >> 12) | 0x80000000u;
297*302acc2eSNathan Whitehorn 	ccsr_write4(OCP85XX_BPTR, bptr);
298*302acc2eSNathan Whitehorn 	__asm __volatile("isync; msync");
299*302acc2eSNathan Whitehorn 
300*302acc2eSNathan Whitehorn 	/* Flush caches to have our changes hit DRAM. */
301*302acc2eSNathan Whitehorn 	cpu_flush_dcache(__boot_page, 4096);
302*302acc2eSNathan Whitehorn 
303*302acc2eSNathan Whitehorn 	/*
304*302acc2eSNathan Whitehorn 	 * Release AP from hold-off state
305*302acc2eSNathan Whitehorn 	 */
306*302acc2eSNathan Whitehorn 	eebpcr |= (1 << (pc->pc_cpuid + 24));
307*302acc2eSNathan Whitehorn 	ccsr_write4(OCP85XX_EEBPCR, eebpcr);
308*302acc2eSNathan Whitehorn 	__asm __volatile("isync; msync");
309*302acc2eSNathan Whitehorn 
310*302acc2eSNathan Whitehorn 	timeout = 500;
311*302acc2eSNathan Whitehorn 	while (!pc->pc_awake && timeout--)
312*302acc2eSNathan Whitehorn 		DELAY(1000);	/* wait 1ms */
313*302acc2eSNathan Whitehorn 
314*302acc2eSNathan Whitehorn 	/*
315*302acc2eSNathan Whitehorn 	 * Disable boot page translation so that the 4K page at the default
316*302acc2eSNathan Whitehorn 	 * address (= 0xfffff000) isn't permanently remapped and thus not
317*302acc2eSNathan Whitehorn 	 * usable otherwise.
318*302acc2eSNathan Whitehorn 	 */
319*302acc2eSNathan Whitehorn 	ccsr_write4(OCP85XX_BPTR, 0);
320*302acc2eSNathan Whitehorn 	__asm __volatile("isync; msync");
321*302acc2eSNathan Whitehorn 
322*302acc2eSNathan Whitehorn 	if (!pc->pc_awake)
323*302acc2eSNathan Whitehorn 		printf("SMP: CPU %d didn't wake up.\n", pc->pc_cpuid);
324*302acc2eSNathan Whitehorn 	return ((pc->pc_awake) ? 0 : EBUSY);
325*302acc2eSNathan Whitehorn #else
326*302acc2eSNathan Whitehorn 	/* No SMP support */
327*302acc2eSNathan Whitehorn 	return (ENXIO);
328*302acc2eSNathan Whitehorn #endif
329*302acc2eSNathan Whitehorn }
330*302acc2eSNathan Whitehorn 
331*302acc2eSNathan Whitehorn static void
332*302acc2eSNathan Whitehorn mpc85xx_reset(platform_t plat)
333*302acc2eSNathan Whitehorn {
334*302acc2eSNathan Whitehorn 
335*302acc2eSNathan Whitehorn 	/*
336*302acc2eSNathan Whitehorn 	 * Try the dedicated reset register first.
337*302acc2eSNathan Whitehorn 	 * If the SoC doesn't have one, we'll fall
338*302acc2eSNathan Whitehorn 	 * back to using the debug control register.
339*302acc2eSNathan Whitehorn 	 */
340*302acc2eSNathan Whitehorn 	ccsr_write4(OCP85XX_RSTCR, 2);
341*302acc2eSNathan Whitehorn 
342*302acc2eSNathan Whitehorn 	/* Clear DBCR0, disables debug interrupts and events. */
343*302acc2eSNathan Whitehorn 	mtspr(SPR_DBCR0, 0);
344*302acc2eSNathan Whitehorn 	__asm __volatile("isync");
345*302acc2eSNathan Whitehorn 
346*302acc2eSNathan Whitehorn 	/* Enable Debug Interrupts in MSR. */
347*302acc2eSNathan Whitehorn 	mtmsr(mfmsr() | PSL_DE);
348*302acc2eSNathan Whitehorn 
349*302acc2eSNathan Whitehorn 	/* Enable debug interrupts and issue reset. */
350*302acc2eSNathan Whitehorn 	mtspr(SPR_DBCR0, mfspr(SPR_DBCR0) | DBCR0_IDM | DBCR0_RST_SYSTEM);
351*302acc2eSNathan Whitehorn 
352*302acc2eSNathan Whitehorn 	printf("Reset failed...\n");
353*302acc2eSNathan Whitehorn 	while (1)
354*302acc2eSNathan Whitehorn 		;
355*302acc2eSNathan Whitehorn }
356*302acc2eSNathan Whitehorn 
357