xref: /rk3399_rockchip-uboot/arch/powerpc/cpu/mpc85xx/mp.c (revision 8f3a7fa4a230f5e974e99b617138e2aaa45109e7)
1a47a12beSStefan Roese /*
2a47a12beSStefan Roese  * Copyright 2008-2010 Freescale Semiconductor, Inc.
3a47a12beSStefan Roese  *
4a47a12beSStefan Roese  * See file CREDITS for list of people who contributed to this
5a47a12beSStefan Roese  * project.
6a47a12beSStefan Roese  *
7a47a12beSStefan Roese  * This program is free software; you can redistribute it and/or
8a47a12beSStefan Roese  * modify it under the terms of the GNU General Public License as
9a47a12beSStefan Roese  * published by the Free Software Foundation; either version 2 of
10a47a12beSStefan Roese  * the License, or (at your option) any later version.
11a47a12beSStefan Roese  *
12a47a12beSStefan Roese  * This program is distributed in the hope that it will be useful,
13a47a12beSStefan Roese  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14a47a12beSStefan Roese  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15a47a12beSStefan Roese  * GNU General Public License for more details.
16a47a12beSStefan Roese  *
17a47a12beSStefan Roese  * You should have received a copy of the GNU General Public License
18a47a12beSStefan Roese  * along with this program; if not, write to the Free Software
19a47a12beSStefan Roese  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20a47a12beSStefan Roese  * MA 02111-1307 USA
21a47a12beSStefan Roese  */
22a47a12beSStefan Roese 
23a47a12beSStefan Roese #include <common.h>
24a47a12beSStefan Roese #include <asm/processor.h>
25a47a12beSStefan Roese #include <ioports.h>
26a47a12beSStefan Roese #include <lmb.h>
27a47a12beSStefan Roese #include <asm/io.h>
28a47a12beSStefan Roese #include <asm/mmu.h>
29a47a12beSStefan Roese #include <asm/fsl_law.h>
30a47a12beSStefan Roese #include "mp.h"
31a47a12beSStefan Roese 
32a47a12beSStefan Roese DECLARE_GLOBAL_DATA_PTR;
33a47a12beSStefan Roese 
34a47a12beSStefan Roese u32 get_my_id()
35a47a12beSStefan Roese {
36a47a12beSStefan Roese 	return mfspr(SPRN_PIR);
37a47a12beSStefan Roese }
38a47a12beSStefan Roese 
39a47a12beSStefan Roese int cpu_reset(int nr)
40a47a12beSStefan Roese {
41a47a12beSStefan Roese 	volatile ccsr_pic_t *pic = (void *)(CONFIG_SYS_MPC85xx_PIC_ADDR);
42a47a12beSStefan Roese 	out_be32(&pic->pir, 1 << nr);
43a47a12beSStefan Roese 	/* the dummy read works around an errata on early 85xx MP PICs */
44a47a12beSStefan Roese 	(void)in_be32(&pic->pir);
45a47a12beSStefan Roese 	out_be32(&pic->pir, 0x0);
46a47a12beSStefan Roese 
47a47a12beSStefan Roese 	return 0;
48a47a12beSStefan Roese }
49a47a12beSStefan Roese 
50a47a12beSStefan Roese int cpu_status(int nr)
51a47a12beSStefan Roese {
52a47a12beSStefan Roese 	u32 *table, id = get_my_id();
53a47a12beSStefan Roese 
54a47a12beSStefan Roese 	if (nr == id) {
55a47a12beSStefan Roese 		table = (u32 *)get_spin_virt_addr();
56a47a12beSStefan Roese 		printf("table base @ 0x%p\n", table);
57a47a12beSStefan Roese 	} else {
58a47a12beSStefan Roese 		table = (u32 *)get_spin_virt_addr() + nr * NUM_BOOT_ENTRY;
59a47a12beSStefan Roese 		printf("Running on cpu %d\n", id);
60a47a12beSStefan Roese 		printf("\n");
61a47a12beSStefan Roese 		printf("table @ 0x%p\n", table);
62a47a12beSStefan Roese 		printf("   addr - 0x%08x\n", table[BOOT_ENTRY_ADDR_LOWER]);
63a47a12beSStefan Roese 		printf("   pir  - 0x%08x\n", table[BOOT_ENTRY_PIR]);
64a47a12beSStefan Roese 		printf("   r3   - 0x%08x\n", table[BOOT_ENTRY_R3_LOWER]);
65a47a12beSStefan Roese 		printf("   r6   - 0x%08x\n", table[BOOT_ENTRY_R6_LOWER]);
66a47a12beSStefan Roese 	}
67a47a12beSStefan Roese 
68a47a12beSStefan Roese 	return 0;
69a47a12beSStefan Roese }
70a47a12beSStefan Roese 
71a47a12beSStefan Roese #ifdef CONFIG_FSL_CORENET
72a47a12beSStefan Roese int cpu_disable(int nr)
73a47a12beSStefan Roese {
74a47a12beSStefan Roese 	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
75a47a12beSStefan Roese 
76a47a12beSStefan Roese 	setbits_be32(&gur->coredisrl, 1 << nr);
77a47a12beSStefan Roese 
78a47a12beSStefan Roese 	return 0;
79a47a12beSStefan Roese }
80*8f3a7fa4SKumar Gala 
81*8f3a7fa4SKumar Gala int is_core_disabled(int nr) {
82*8f3a7fa4SKumar Gala 	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
83*8f3a7fa4SKumar Gala 	u32 coredisrl = in_be32(&gur->coredisrl);
84*8f3a7fa4SKumar Gala 
85*8f3a7fa4SKumar Gala 	return (coredisrl & (1 << nr));
86*8f3a7fa4SKumar Gala }
87a47a12beSStefan Roese #else
88a47a12beSStefan Roese int cpu_disable(int nr)
89a47a12beSStefan Roese {
90a47a12beSStefan Roese 	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
91a47a12beSStefan Roese 
92a47a12beSStefan Roese 	switch (nr) {
93a47a12beSStefan Roese 	case 0:
94a47a12beSStefan Roese 		setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_CPU0);
95a47a12beSStefan Roese 		break;
96a47a12beSStefan Roese 	case 1:
97a47a12beSStefan Roese 		setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_CPU1);
98a47a12beSStefan Roese 		break;
99a47a12beSStefan Roese 	default:
100a47a12beSStefan Roese 		printf("Invalid cpu number for disable %d\n", nr);
101a47a12beSStefan Roese 		return 1;
102a47a12beSStefan Roese 	}
103a47a12beSStefan Roese 
104a47a12beSStefan Roese 	return 0;
105a47a12beSStefan Roese }
106*8f3a7fa4SKumar Gala 
107*8f3a7fa4SKumar Gala int is_core_disabled(int nr) {
108*8f3a7fa4SKumar Gala 	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
109*8f3a7fa4SKumar Gala 	u32 devdisr = in_be32(&gur->devdisr);
110*8f3a7fa4SKumar Gala 
111*8f3a7fa4SKumar Gala 	switch (nr) {
112*8f3a7fa4SKumar Gala 	case 0:
113*8f3a7fa4SKumar Gala 		return (devdisr & MPC85xx_DEVDISR_CPU0);
114*8f3a7fa4SKumar Gala 	case 1:
115*8f3a7fa4SKumar Gala 		return (devdisr & MPC85xx_DEVDISR_CPU1);
116*8f3a7fa4SKumar Gala 	default:
117*8f3a7fa4SKumar Gala 		printf("Invalid cpu number for disable %d\n", nr);
118*8f3a7fa4SKumar Gala 	}
119*8f3a7fa4SKumar Gala 
120*8f3a7fa4SKumar Gala 	return 0;
121*8f3a7fa4SKumar Gala }
122a47a12beSStefan Roese #endif
123a47a12beSStefan Roese 
124a47a12beSStefan Roese static u8 boot_entry_map[4] = {
125a47a12beSStefan Roese 	0,
126a47a12beSStefan Roese 	BOOT_ENTRY_PIR,
127a47a12beSStefan Roese 	BOOT_ENTRY_R3_LOWER,
128a47a12beSStefan Roese 	BOOT_ENTRY_R6_LOWER,
129a47a12beSStefan Roese };
130a47a12beSStefan Roese 
13154841ab5SWolfgang Denk int cpu_release(int nr, int argc, char * const argv[])
132a47a12beSStefan Roese {
133a47a12beSStefan Roese 	u32 i, val, *table = (u32 *)get_spin_virt_addr() + nr * NUM_BOOT_ENTRY;
134a47a12beSStefan Roese 	u64 boot_addr;
135a47a12beSStefan Roese 
136a47a12beSStefan Roese 	if (nr == get_my_id()) {
137a47a12beSStefan Roese 		printf("Invalid to release the boot core.\n\n");
138a47a12beSStefan Roese 		return 1;
139a47a12beSStefan Roese 	}
140a47a12beSStefan Roese 
141a47a12beSStefan Roese 	if (argc != 4) {
142a47a12beSStefan Roese 		printf("Invalid number of arguments to release.\n\n");
143a47a12beSStefan Roese 		return 1;
144a47a12beSStefan Roese 	}
145a47a12beSStefan Roese 
146a47a12beSStefan Roese 	boot_addr = simple_strtoull(argv[0], NULL, 16);
147a47a12beSStefan Roese 
148a47a12beSStefan Roese 	/* handle pir, r3, r6 */
149a47a12beSStefan Roese 	for (i = 1; i < 4; i++) {
150a47a12beSStefan Roese 		if (argv[i][0] != '-') {
151a47a12beSStefan Roese 			u8 entry = boot_entry_map[i];
152a47a12beSStefan Roese 			val = simple_strtoul(argv[i], NULL, 16);
153a47a12beSStefan Roese 			table[entry] = val;
154a47a12beSStefan Roese 		}
155a47a12beSStefan Roese 	}
156a47a12beSStefan Roese 
157a47a12beSStefan Roese 	table[BOOT_ENTRY_ADDR_UPPER] = (u32)(boot_addr >> 32);
158a47a12beSStefan Roese 
159a47a12beSStefan Roese 	/* ensure all table updates complete before final address write */
160a47a12beSStefan Roese 	eieio();
161a47a12beSStefan Roese 
162a47a12beSStefan Roese 	table[BOOT_ENTRY_ADDR_LOWER] = (u32)(boot_addr & 0xffffffff);
163a47a12beSStefan Roese 
164a47a12beSStefan Roese 	return 0;
165a47a12beSStefan Roese }
166a47a12beSStefan Roese 
167a47a12beSStefan Roese u32 determine_mp_bootpg(void)
168a47a12beSStefan Roese {
169a47a12beSStefan Roese 	/* if we have 4G or more of memory, put the boot page at 4Gb-4k */
170a47a12beSStefan Roese 	if ((u64)gd->ram_size > 0xfffff000)
171a47a12beSStefan Roese 		return (0xfffff000);
172a47a12beSStefan Roese 
173a47a12beSStefan Roese 	return (gd->ram_size - 4096);
174a47a12beSStefan Roese }
175a47a12beSStefan Roese 
176a47a12beSStefan Roese ulong get_spin_phys_addr(void)
177a47a12beSStefan Roese {
178a47a12beSStefan Roese 	extern ulong __secondary_start_page;
179a47a12beSStefan Roese 	extern ulong __spin_table;
180a47a12beSStefan Roese 
181a47a12beSStefan Roese 	return (determine_mp_bootpg() +
182a47a12beSStefan Roese 		(ulong)&__spin_table - (ulong)&__secondary_start_page);
183a47a12beSStefan Roese }
184a47a12beSStefan Roese 
185a47a12beSStefan Roese ulong get_spin_virt_addr(void)
186a47a12beSStefan Roese {
187a47a12beSStefan Roese 	extern ulong __secondary_start_page;
188a47a12beSStefan Roese 	extern ulong __spin_table;
189a47a12beSStefan Roese 
190a47a12beSStefan Roese 	return (CONFIG_BPTR_VIRT_ADDR +
191a47a12beSStefan Roese 		(ulong)&__spin_table - (ulong)&__secondary_start_page);
192a47a12beSStefan Roese }
193a47a12beSStefan Roese 
194a47a12beSStefan Roese #ifdef CONFIG_FSL_CORENET
195a47a12beSStefan Roese static void plat_mp_up(unsigned long bootpg)
196a47a12beSStefan Roese {
197a47a12beSStefan Roese 	u32 up, cpu_up_mask, whoami;
198a47a12beSStefan Roese 	u32 *table = (u32 *)get_spin_virt_addr();
199a47a12beSStefan Roese 	volatile ccsr_gur_t *gur;
200a47a12beSStefan Roese 	volatile ccsr_local_t *ccm;
201a47a12beSStefan Roese 	volatile ccsr_rcpm_t *rcpm;
202a47a12beSStefan Roese 	volatile ccsr_pic_t *pic;
203a47a12beSStefan Roese 	int timeout = 10;
204a47a12beSStefan Roese 	u32 nr_cpus;
205a47a12beSStefan Roese 	struct law_entry e;
206a47a12beSStefan Roese 
207a47a12beSStefan Roese 	gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
208a47a12beSStefan Roese 	ccm = (void *)(CONFIG_SYS_FSL_CORENET_CCM_ADDR);
209a47a12beSStefan Roese 	rcpm = (void *)(CONFIG_SYS_FSL_CORENET_RCPM_ADDR);
210a47a12beSStefan Roese 	pic = (void *)(CONFIG_SYS_MPC85xx_PIC_ADDR);
211a47a12beSStefan Roese 
212a47a12beSStefan Roese 	nr_cpus = ((in_be32(&pic->frr) >> 8) & 0xff) + 1;
213a47a12beSStefan Roese 
214a47a12beSStefan Roese 	whoami = in_be32(&pic->whoami);
215a47a12beSStefan Roese 	cpu_up_mask = 1 << whoami;
216a47a12beSStefan Roese 	out_be32(&ccm->bstrl, bootpg);
217a47a12beSStefan Roese 
218a47a12beSStefan Roese 	e = find_law(bootpg);
219a47a12beSStefan Roese 	out_be32(&ccm->bstrar, LAW_EN | e.trgt_id << 20 | LAW_SIZE_4K);
220a47a12beSStefan Roese 
221a47a12beSStefan Roese 	/* readback to sync write */
222a47a12beSStefan Roese 	in_be32(&ccm->bstrar);
223a47a12beSStefan Roese 
224a47a12beSStefan Roese 	/* disable time base at the platform */
225a47a12beSStefan Roese 	out_be32(&rcpm->ctbenrl, cpu_up_mask);
226a47a12beSStefan Roese 
227a47a12beSStefan Roese 	/* release the hounds */
228a47a12beSStefan Roese 	up = ((1 << nr_cpus) - 1);
229a47a12beSStefan Roese 	out_be32(&gur->brrl, up);
230a47a12beSStefan Roese 
231a47a12beSStefan Roese 	/* wait for everyone */
232a47a12beSStefan Roese 	while (timeout) {
233a47a12beSStefan Roese 		int i;
234a47a12beSStefan Roese 		for (i = 0; i < nr_cpus; i++) {
235a47a12beSStefan Roese 			if (table[i * NUM_BOOT_ENTRY + BOOT_ENTRY_ADDR_LOWER])
236a47a12beSStefan Roese 				cpu_up_mask |= (1 << i);
237a47a12beSStefan Roese 		};
238a47a12beSStefan Roese 
239a47a12beSStefan Roese 		if ((cpu_up_mask & up) == up)
240a47a12beSStefan Roese 			break;
241a47a12beSStefan Roese 
242a47a12beSStefan Roese 		udelay(100);
243a47a12beSStefan Roese 		timeout--;
244a47a12beSStefan Roese 	}
245a47a12beSStefan Roese 
246a47a12beSStefan Roese 	if (timeout == 0)
247a47a12beSStefan Roese 		printf("CPU up timeout. CPU up mask is %x should be %x\n",
248a47a12beSStefan Roese 			cpu_up_mask, up);
249a47a12beSStefan Roese 
250a47a12beSStefan Roese 	/* enable time base at the platform */
251a47a12beSStefan Roese 	out_be32(&rcpm->ctbenrl, 0);
252a47a12beSStefan Roese 	mtspr(SPRN_TBWU, 0);
253a47a12beSStefan Roese 	mtspr(SPRN_TBWL, 0);
254a47a12beSStefan Roese 	out_be32(&rcpm->ctbenrl, (1 << nr_cpus) - 1);
255a47a12beSStefan Roese 
256a47a12beSStefan Roese #ifdef CONFIG_MPC8xxx_DISABLE_BPTR
257a47a12beSStefan Roese 	/*
258a47a12beSStefan Roese 	 * Disabling Boot Page Translation allows the memory region 0xfffff000
259a47a12beSStefan Roese 	 * to 0xffffffff to be used normally.  Leaving Boot Page Translation
260a47a12beSStefan Roese 	 * enabled remaps 0xfffff000 to SDRAM which makes that memory region
261a47a12beSStefan Roese 	 * unusable for normal operation but it does allow OSes to easily
262a47a12beSStefan Roese 	 * reset a processor core to put it back into U-Boot's spinloop.
263a47a12beSStefan Roese 	 */
264a47a12beSStefan Roese 	clrbits_be32(&ecm->bptr, 0x80000000);
265a47a12beSStefan Roese #endif
266a47a12beSStefan Roese }
267a47a12beSStefan Roese #else
268a47a12beSStefan Roese static void plat_mp_up(unsigned long bootpg)
269a47a12beSStefan Roese {
270a47a12beSStefan Roese 	u32 up, cpu_up_mask, whoami;
271a47a12beSStefan Roese 	u32 *table = (u32 *)get_spin_virt_addr();
272a47a12beSStefan Roese 	volatile u32 bpcr;
273a47a12beSStefan Roese 	volatile ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR);
274a47a12beSStefan Roese 	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
275a47a12beSStefan Roese 	volatile ccsr_pic_t *pic = (void *)(CONFIG_SYS_MPC85xx_PIC_ADDR);
276a47a12beSStefan Roese 	u32 devdisr;
277a47a12beSStefan Roese 	int timeout = 10;
278a47a12beSStefan Roese 
279a47a12beSStefan Roese 	whoami = in_be32(&pic->whoami);
280a47a12beSStefan Roese 	out_be32(&ecm->bptr, 0x80000000 | (bootpg >> 12));
281a47a12beSStefan Roese 
282a47a12beSStefan Roese 	/* disable time base at the platform */
283a47a12beSStefan Roese 	devdisr = in_be32(&gur->devdisr);
284a47a12beSStefan Roese 	if (whoami)
285a47a12beSStefan Roese 		devdisr |= MPC85xx_DEVDISR_TB0;
286a47a12beSStefan Roese 	else
287a47a12beSStefan Roese 		devdisr |= MPC85xx_DEVDISR_TB1;
288a47a12beSStefan Roese 	out_be32(&gur->devdisr, devdisr);
289a47a12beSStefan Roese 
290a47a12beSStefan Roese 	/* release the hounds */
291a47a12beSStefan Roese 	up = ((1 << cpu_numcores()) - 1);
292a47a12beSStefan Roese 	bpcr = in_be32(&ecm->eebpcr);
293a47a12beSStefan Roese 	bpcr |= (up << 24);
294a47a12beSStefan Roese 	out_be32(&ecm->eebpcr, bpcr);
295a47a12beSStefan Roese 	asm("sync; isync; msync");
296a47a12beSStefan Roese 
297a47a12beSStefan Roese 	cpu_up_mask = 1 << whoami;
298a47a12beSStefan Roese 	/* wait for everyone */
299a47a12beSStefan Roese 	while (timeout) {
300a47a12beSStefan Roese 		int i;
301a47a12beSStefan Roese 		for (i = 0; i < cpu_numcores(); i++) {
302a47a12beSStefan Roese 			if (table[i * NUM_BOOT_ENTRY + BOOT_ENTRY_ADDR_LOWER])
303a47a12beSStefan Roese 				cpu_up_mask |= (1 << i);
304a47a12beSStefan Roese 		};
305a47a12beSStefan Roese 
306a47a12beSStefan Roese 		if ((cpu_up_mask & up) == up)
307a47a12beSStefan Roese 			break;
308a47a12beSStefan Roese 
309a47a12beSStefan Roese 		udelay(100);
310a47a12beSStefan Roese 		timeout--;
311a47a12beSStefan Roese 	}
312a47a12beSStefan Roese 
313a47a12beSStefan Roese 	if (timeout == 0)
314a47a12beSStefan Roese 		printf("CPU up timeout. CPU up mask is %x should be %x\n",
315a47a12beSStefan Roese 			cpu_up_mask, up);
316a47a12beSStefan Roese 
317a47a12beSStefan Roese 	/* enable time base at the platform */
318a47a12beSStefan Roese 	if (whoami)
319a47a12beSStefan Roese 		devdisr |= MPC85xx_DEVDISR_TB1;
320a47a12beSStefan Roese 	else
321a47a12beSStefan Roese 		devdisr |= MPC85xx_DEVDISR_TB0;
322a47a12beSStefan Roese 	out_be32(&gur->devdisr, devdisr);
323a47a12beSStefan Roese 	mtspr(SPRN_TBWU, 0);
324a47a12beSStefan Roese 	mtspr(SPRN_TBWL, 0);
325a47a12beSStefan Roese 
326a47a12beSStefan Roese 	devdisr &= ~(MPC85xx_DEVDISR_TB0 | MPC85xx_DEVDISR_TB1);
327a47a12beSStefan Roese 	out_be32(&gur->devdisr, devdisr);
328a47a12beSStefan Roese 
329a47a12beSStefan Roese #ifdef CONFIG_MPC8xxx_DISABLE_BPTR
330a47a12beSStefan Roese 	/*
331a47a12beSStefan Roese 	 * Disabling Boot Page Translation allows the memory region 0xfffff000
332a47a12beSStefan Roese 	 * to 0xffffffff to be used normally.  Leaving Boot Page Translation
333a47a12beSStefan Roese 	 * enabled remaps 0xfffff000 to SDRAM which makes that memory region
334a47a12beSStefan Roese 	 * unusable for normal operation but it does allow OSes to easily
335a47a12beSStefan Roese 	 * reset a processor core to put it back into U-Boot's spinloop.
336a47a12beSStefan Roese 	 */
337a47a12beSStefan Roese 	clrbits_be32(&ecm->bptr, 0x80000000);
338a47a12beSStefan Roese #endif
339a47a12beSStefan Roese }
340a47a12beSStefan Roese #endif
341a47a12beSStefan Roese 
342a47a12beSStefan Roese void cpu_mp_lmb_reserve(struct lmb *lmb)
343a47a12beSStefan Roese {
344a47a12beSStefan Roese 	u32 bootpg = determine_mp_bootpg();
345a47a12beSStefan Roese 
346a47a12beSStefan Roese 	lmb_reserve(lmb, bootpg, 4096);
347a47a12beSStefan Roese }
348a47a12beSStefan Roese 
349a47a12beSStefan Roese void setup_mp(void)
350a47a12beSStefan Roese {
351a47a12beSStefan Roese 	extern ulong __secondary_start_page;
352a47a12beSStefan Roese 	extern ulong __bootpg_addr;
353a47a12beSStefan Roese 	ulong fixup = (ulong)&__secondary_start_page;
354a47a12beSStefan Roese 	u32 bootpg = determine_mp_bootpg();
355a47a12beSStefan Roese 
356a47a12beSStefan Roese 	/* Store the bootpg's SDRAM address for use by secondary CPU cores */
357a47a12beSStefan Roese 	__bootpg_addr = bootpg;
358a47a12beSStefan Roese 
359a47a12beSStefan Roese 	/* look for the tlb covering the reset page, there better be one */
360a47a12beSStefan Roese 	int i = find_tlb_idx((void *)CONFIG_BPTR_VIRT_ADDR, 1);
361a47a12beSStefan Roese 
362a47a12beSStefan Roese 	/* we found a match */
363a47a12beSStefan Roese 	if (i != -1) {
364a47a12beSStefan Roese 		/* map reset page to bootpg so we can copy code there */
365a47a12beSStefan Roese 		disable_tlb(i);
366a47a12beSStefan Roese 
367a47a12beSStefan Roese 		set_tlb(1, CONFIG_BPTR_VIRT_ADDR, bootpg, /* tlb, epn, rpn */
368a47a12beSStefan Roese 			MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, /* perms, wimge */
369a47a12beSStefan Roese 			0, i, BOOKE_PAGESZ_4K, 1); /* ts, esel, tsize, iprot */
370a47a12beSStefan Roese 
371a47a12beSStefan Roese 		memcpy((void *)CONFIG_BPTR_VIRT_ADDR, (void *)fixup, 4096);
372a47a12beSStefan Roese 
373a47a12beSStefan Roese 		plat_mp_up(bootpg);
374a47a12beSStefan Roese 	} else {
375a47a12beSStefan Roese 		puts("WARNING: No reset page TLB. "
376a47a12beSStefan Roese 			"Skipping secondary core setup\n");
377a47a12beSStefan Roese 	}
378a47a12beSStefan Roese }
379