summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/cpu/mpc86xx/mp.c
blob: de705f0ae80ac22103c999d377f6dbac91d06bfa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
 * Copyright 2008-2010 Freescale Semiconductor, Inc.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <asm/processor.h>
#include <asm/mmu.h>
#include <ioports.h>
#include <lmb.h>
#include <asm/io.h>
#include <asm/mp.h>

DECLARE_GLOBAL_DATA_PTR;

int cpu_reset(int nr)
{
	/* dummy function so common/cmd_mp.c will build
	 * should be implemented in the future, when cpu_release()
	 * is supported.  Be aware there may be a similiar bug
	 * as exists on MPC85xx w/its PIC having a timing window
	 * associated to resetting the core */
	return 1;
}

int cpu_status(int nr)
{
	/* dummy function so common/cmd_mp.c will build */
	return 0;
}

int cpu_disable(int nr)
{
	volatile immap_t *immap = (immap_t *) CONFIG_SYS_CCSRBAR;
	volatile ccsr_gur_t *gur = &immap->im_gur;

	switch (nr) {
	case 0:
		setbits_be32(&gur->devdisr, MPC86xx_DEVDISR_CPU0);
		break;
	case 1:
		setbits_be32(&gur->devdisr, MPC86xx_DEVDISR_CPU1);
		break;
	default:
		printf("Invalid cpu number for disable %d\n", nr);
		return 1;
	}

	return 0;
}

int is_core_disabled(int nr) {
	immap_t *immap = (immap_t *) CONFIG_SYS_CCSRBAR;
	ccsr_gur_t *gur = &immap->im_gur;
	u32 devdisr = in_be32(&gur->devdisr);

	switch (nr) {
	case 0:
		return (devdisr & MPC86xx_DEVDISR_CPU0);
	case 1:
		return (devdisr & MPC86xx_DEVDISR_CPU1);
	default:
		printf("Invalid cpu number for disable %d\n", nr);
	}

	return 0;
}

int cpu_release(int nr, int argc, char * const argv[])
{
	/* dummy function so common/cmd_mp.c will build
	 * should be implemented in the future */
	return 1;
}

u32 determine_mp_bootpg(unsigned int *pagesize)
{
	if (pagesize)
		*pagesize = 4096;

	/* if we have 4G or more of memory, put the boot page at 4Gb-1M */
	if ((u64)gd->ram_size > 0xfffff000)
		return (0xfff00000);

	return (gd->ram_size - (1024 * 1024));
}

void cpu_mp_lmb_reserve(struct lmb *lmb)
{
	u32 bootpg = determine_mp_bootpg(NULL);

	/* tell u-boot we stole a page */
	lmb_reserve(lmb, bootpg, 4096);
}

/*
 * Copy the code for other cpus to execute into an
 * aligned location accessible via BPTR
 */
void setup_mp(void)
{
	extern ulong __secondary_start_page;
	ulong fixup = (ulong)&__secondary_start_page;
	u32 bootpg = determine_mp_bootpg(NULL);
	u32 bootpg_va;

	if (bootpg >= CONFIG_SYS_MAX_DDR_BAT_SIZE) {
		/* We're not covered by the DDR mapping, set up BAT  */
		write_bat(DBAT7, CONFIG_SYS_SCRATCH_VA | BATU_BL_128K |
			  BATU_VS | BATU_VP,
			  bootpg | BATL_PP_RW | BATL_MEMCOHERENCE);
		bootpg_va = CONFIG_SYS_SCRATCH_VA;
	} else {
		bootpg_va = bootpg;
	}

	memcpy((void *)bootpg_va, (void *)fixup, 4096);
	flush_cache(bootpg_va, 4096);

	/* remove the temporary BAT mapping */
	if (bootpg >= CONFIG_SYS_MAX_DDR_BAT_SIZE)
		write_bat(DBAT7, 0, 0);

	/* If the physical location of bootpg is not at fff00000, set BPTR */
	if (bootpg != 0xfff00000)
		out_be32((uint *)(CONFIG_SYS_CCSRBAR + 0x20), 0x80000000 |
			 (bootpg >> 12));
}
OpenPOWER on IntegriCloud