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
|
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2008-2010 Freescale Semiconductor, Inc.
*/
#include <common.h>
#include <cpu_func.h>
#include <asm/global_data.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(u32 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(u32 nr)
{
/* dummy function so common/cmd_mp.c will build */
return 0;
}
int cpu_disable(u32 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(u32 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));
}
|