summaryrefslogtreecommitdiffstats
path: root/arch/powerpc/cpu/mpc85xx/mp.c
diff options
context:
space:
mode:
authorYork Sun <yorksun@freescale.com>2012-10-08 07:44:30 +0000
committerAndy Fleming <afleming@freescale.com>2012-10-22 14:31:32 -0500
commitffd06e0231ac3fd0c5810f39f6e23527948df1c7 (patch)
tree7d648c2c312b9cc7a75c0350101aacc67afca399 /arch/powerpc/cpu/mpc85xx/mp.c
parent3f0997b3255c1498ac92453aa3a7a1cc95914dfd (diff)
downloadblackbird-obmc-uboot-ffd06e0231ac3fd0c5810f39f6e23527948df1c7.tar.gz
blackbird-obmc-uboot-ffd06e0231ac3fd0c5810f39f6e23527948df1c7.zip
powerpc/mpc85xx: Rewrite spin table to comply with ePAPR v1.1
Move spin table to cached memory to comply with ePAPR v1.1. Load R3 with 64-bit value if CONFIG_SYS_PPC64 is defined. 'M' bit is set for DDR TLB to maintain cache coherence. See details in doc/README.mpc85xx-spin-table. Signed-off-by: York Sun <yorksun@freescale.com> Signed-off-by: Andy Fleming <afleming@freescale.com>
Diffstat (limited to 'arch/powerpc/cpu/mpc85xx/mp.c')
-rw-r--r--arch/powerpc/cpu/mpc85xx/mp.c61
1 files changed, 30 insertions, 31 deletions
diff --git a/arch/powerpc/cpu/mpc85xx/mp.c b/arch/powerpc/cpu/mpc85xx/mp.c
index 881b681755..e1197ac9e5 100644
--- a/arch/powerpc/cpu/mpc85xx/mp.c
+++ b/arch/powerpc/cpu/mpc85xx/mp.c
@@ -33,6 +33,8 @@
DECLARE_GLOBAL_DATA_PTR;
u32 fsl_ddr_get_intl3r(void);
+extern u32 __spin_table[];
+
u32 get_my_id()
{
return mfspr(SPRN_PIR);
@@ -78,10 +80,10 @@ int cpu_status(int nr)
return 0;
if (nr == id) {
- table = (u32 *)get_spin_virt_addr();
+ table = (u32 *)&__spin_table;
printf("table base @ 0x%p\n", table);
} else {
- table = (u32 *)get_spin_virt_addr() + nr * NUM_BOOT_ENTRY;
+ table = (u32 *)&__spin_table + nr * NUM_BOOT_ENTRY;
printf("Running on cpu %d\n", id);
printf("\n");
printf("table @ 0x%p\n", table);
@@ -154,7 +156,7 @@ static u8 boot_entry_map[4] = {
int cpu_release(int nr, int argc, char * const argv[])
{
- u32 i, val, *table = (u32 *)get_spin_virt_addr() + nr * NUM_BOOT_ENTRY;
+ u32 i, val, *table = (u32 *)&__spin_table + nr * NUM_BOOT_ENTRY;
u64 boot_addr;
if (hold_cores_in_reset(1))
@@ -200,11 +202,11 @@ u32 determine_mp_bootpg(unsigned int *pagesize)
struct law_entry e;
#endif
- /* if we have 4G or more of memory, put the boot page at 4Gb-4k */
- if ((u64)gd->ram_size > 0xfffff000)
- bootpg = 0xfffff000;
- else
- bootpg = gd->ram_size - 4096;
+
+ /* use last 4K of mapped memory */
+ bootpg = ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ?
+ CONFIG_MAX_MEM_MAPPED : gd->ram_size) +
+ CONFIG_SYS_SDRAM_BASE - 4096;
if (pagesize)
*pagesize = 4096;
@@ -255,29 +257,16 @@ u32 determine_mp_bootpg(unsigned int *pagesize)
return bootpg;
}
-ulong get_spin_phys_addr(void)
-{
- extern ulong __secondary_start_page;
- extern ulong __spin_table;
-
- return (determine_mp_bootpg() +
- (ulong)&__spin_table - (ulong)&__secondary_start_page);
-}
-
-ulong get_spin_virt_addr(void)
+phys_addr_t get_spin_phys_addr(void)
{
- extern ulong __secondary_start_page;
- extern ulong __spin_table;
-
- return (CONFIG_BPTR_VIRT_ADDR +
- (ulong)&__spin_table - (ulong)&__secondary_start_page);
+ return virt_to_phys(&__spin_table);
}
#ifdef CONFIG_FSL_CORENET
static void plat_mp_up(unsigned long bootpg, unsigned int pagesize)
{
u32 cpu_up_mask, whoami, brsize = LAW_SIZE_4K;
- u32 *table = (u32 *)get_spin_virt_addr();
+ u32 *table = (u32 *)&__spin_table;
volatile ccsr_gur_t *gur;
volatile ccsr_local_t *ccm;
volatile ccsr_rcpm_t *rcpm;
@@ -356,7 +345,7 @@ static void plat_mp_up(unsigned long bootpg, unsigned int pagesize)
static void plat_mp_up(unsigned long bootpg, unsigned int pagesize)
{
u32 up, cpu_up_mask, whoami;
- u32 *table = (u32 *)get_spin_virt_addr();
+ u32 *table = (u32 *)&__spin_table;
volatile u32 bpcr;
volatile ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR);
volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
@@ -440,10 +429,11 @@ void cpu_mp_lmb_reserve(struct lmb *lmb)
void setup_mp(void)
{
- extern ulong __secondary_start_page;
- extern ulong __bootpg_addr;
+ extern u32 __secondary_start_page;
+ extern u32 __bootpg_addr, __spin_table_addr, __second_half_boot_page;
- ulong fixup = (ulong)&__secondary_start_page;
+ int i;
+ ulong fixup = (u32)&__secondary_start_page;
u32 bootpg, bootpg_map, pagesize;
bootpg = determine_mp_bootpg(&pagesize);
@@ -464,11 +454,20 @@ void setup_mp(void)
if (hold_cores_in_reset(0))
return;
- /* Store the bootpg's SDRAM address for use by secondary CPU cores */
- __bootpg_addr = bootpg;
+ /*
+ * Store the bootpg's cache-able half address for use by secondary
+ * CPU cores to continue to boot
+ */
+ __bootpg_addr = (u32)virt_to_phys(&__second_half_boot_page);
+
+ /* Store spin table's physical address for use by secondary cores */
+ __spin_table_addr = (u32)get_spin_phys_addr();
+
+ /* flush bootpg it before copying invalidate any staled cacheline */
+ flush_cache(bootpg, 4096);
/* look for the tlb covering the reset page, there better be one */
- int i = find_tlb_idx((void *)CONFIG_BPTR_VIRT_ADDR, 1);
+ i = find_tlb_idx((void *)CONFIG_BPTR_VIRT_ADDR, 1);
/* we found a match */
if (i != -1) {
OpenPOWER on IntegriCloud