diff options
| author | York Sun <yorksun@freescale.com> | 2012-10-08 07:44:30 +0000 | 
|---|---|---|
| committer | Andy Fleming <afleming@freescale.com> | 2012-10-22 14:31:32 -0500 | 
| commit | ffd06e0231ac3fd0c5810f39f6e23527948df1c7 (patch) | |
| tree | 7d648c2c312b9cc7a75c0350101aacc67afca399 /arch/powerpc/cpu/mpc85xx/mp.c | |
| parent | 3f0997b3255c1498ac92453aa3a7a1cc95914dfd (diff) | |
| download | olio-uboot-2014.01-ffd06e0231ac3fd0c5810f39f6e23527948df1c7.tar.xz olio-uboot-2014.01-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.c | 61 | 
1 files changed, 30 insertions, 31 deletions
| diff --git a/arch/powerpc/cpu/mpc85xx/mp.c b/arch/powerpc/cpu/mpc85xx/mp.c index 881b68175..e1197ac9e 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) { |