summaryrefslogtreecommitdiffstats
path: root/cpu/mpc85xx/mp.c
diff options
context:
space:
mode:
authorPeter Tyser <ptyser@xes-inc.com>2009-10-23 15:55:47 -0500
committerKumar Gala <galak@kernel.crashing.org>2009-10-27 09:34:57 -0500
commit5ccd29c3679b3669b0bde5c501c1aa0f325a7acb (patch)
tree4c5acb10e0b505ae41ff4d4b3e3b03da56bfcf0f /cpu/mpc85xx/mp.c
parent70ed869ea5f6b1d13d7b140c83ec0dcd8a127ddc (diff)
downloadtalos-obmc-uboot-5ccd29c3679b3669b0bde5c501c1aa0f325a7acb.tar.gz
talos-obmc-uboot-5ccd29c3679b3669b0bde5c501c1aa0f325a7acb.zip
85xx: MP Boot Page Translation update
This change has 3 goals: - Have secondary cores be released into spin loops at their 'true' address in SDRAM. Previously, secondary cores were put into spin loops in the 0xfffffxxx address range which required that boot page translation was always enabled while cores were in their spin loops. - Allow the TLB window that the primary core uses to access the secondary cores boot page to be placed at any address. Previously, a TLB window at 0xfffff000 was always used to access the seconary cores' boot page. This TLB address requirement overlapped with other peripherals on some boards (eg XPedite5370). By default, the boot page TLB will still use the 0xfffffxxx address range, but this can be overridden on a board-by-board basis by defining a custom CONFIG_BPTR_VIRT_ADDR. Note that the TLB used to map the boot page remains in use while U-Boot executes. Previously it was only temporarily used, then restored to its initial value. - Allow Boot Page Translation to be disabled on bootup. Previously, Boot Page Translation was always left enabled after secondary cores were brought out of reset. This caused the 0xfffffxxx address range to somewhat "magically" be translated to an address in SDRAM. Some boards may not want this oddity in their memory map, so defining CONFIG_MPC8xxx_DISABLE_BPTR will turn off Boot Page Translation after the secondary cores are initialized. These changes are only applicable to 85xx boards with CONFIG_MP defined. Signed-off-by: Peter Tyser <ptyser@xes-inc.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'cpu/mpc85xx/mp.c')
-rw-r--r--cpu/mpc85xx/mp.c70
1 files changed, 46 insertions, 24 deletions
diff --git a/cpu/mpc85xx/mp.c b/cpu/mpc85xx/mp.c
index b5c6020c7f..00b6450692 100644
--- a/cpu/mpc85xx/mp.c
+++ b/cpu/mpc85xx/mp.c
@@ -52,10 +52,10 @@ int cpu_status(int nr)
u32 *table, id = get_my_id();
if (nr == id) {
- table = (u32 *)get_spin_addr();
+ table = (u32 *)get_spin_virt_addr();
printf("table base @ 0x%p\n", table);
} else {
- table = (u32 *)get_spin_addr() + nr * NUM_BOOT_ENTRY;
+ table = (u32 *)get_spin_virt_addr() + nr * NUM_BOOT_ENTRY;
printf("Running on cpu %d\n", id);
printf("\n");
printf("table @ 0x%p\n", table);
@@ -77,7 +77,7 @@ static u8 boot_entry_map[4] = {
int cpu_release(int nr, int argc, char *argv[])
{
- u32 i, val, *table = (u32 *)get_spin_addr() + nr * NUM_BOOT_ENTRY;
+ u32 i, val, *table = (u32 *)get_spin_virt_addr() + nr * NUM_BOOT_ENTRY;
u64 boot_addr;
if (nr == get_my_id()) {
@@ -124,23 +124,29 @@ u32 determine_mp_bootpg(void)
return (gd->ram_size - 4096);
}
-ulong get_spin_addr(void)
+ulong get_spin_phys_addr(void)
{
extern ulong __secondary_start_page;
extern ulong __spin_table;
- ulong addr =
- (ulong)&__spin_table - (ulong)&__secondary_start_page;
- addr += 0xfffff000;
+ return (determine_mp_bootpg() +
+ (ulong)&__spin_table - (ulong)&__secondary_start_page);
+}
+
+ulong get_spin_virt_addr(void)
+{
+ extern ulong __secondary_start_page;
+ extern ulong __spin_table;
- return addr;
+ return (CONFIG_BPTR_VIRT_ADDR +
+ (ulong)&__spin_table - (ulong)&__secondary_start_page);
}
#ifdef CONFIG_FSL_CORENET
static void plat_mp_up(unsigned long bootpg)
{
u32 up, cpu_up_mask, whoami;
- u32 *table = (u32 *)get_spin_addr();
+ u32 *table = (u32 *)get_spin_virt_addr();
volatile ccsr_gur_t *gur;
volatile ccsr_local_t *ccm;
volatile ccsr_rcpm_t *rcpm;
@@ -194,12 +200,23 @@ static void plat_mp_up(unsigned long bootpg)
mtspr(SPRN_TBWU, 0);
mtspr(SPRN_TBWL, 0);
out_be32(&rcpm->ctbenrl, (1 << nr_cpus) - 1);
+
+#ifdef CONFIG_MPC8xxx_DISABLE_BPTR
+ /*
+ * Disabling Boot Page Translation allows the memory region 0xfffff000
+ * to 0xffffffff to be used normally. Leaving Boot Page Translation
+ * enabled remaps 0xfffff000 to SDRAM which makes that memory region
+ * unusable for normal operation but it does allow OSes to easily
+ * reset a processor core to put it back into U-Boot's spinloop.
+ */
+ clrbits_be32(&ecm->bptr, 0x80000000);
+#endif
}
#else
static void plat_mp_up(unsigned long bootpg)
{
u32 up, cpu_up_mask, whoami;
- u32 *table = (u32 *)get_spin_addr();
+ u32 *table = (u32 *)get_spin_virt_addr();
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);
@@ -256,6 +273,17 @@ static void plat_mp_up(unsigned long bootpg)
devdisr &= ~(MPC85xx_DEVDISR_TB0 | MPC85xx_DEVDISR_TB1);
out_be32(&gur->devdisr, devdisr);
+
+#ifdef CONFIG_MPC8xxx_DISABLE_BPTR
+ /*
+ * Disabling Boot Page Translation allows the memory region 0xfffff000
+ * to 0xffffffff to be used normally. Leaving Boot Page Translation
+ * enabled remaps 0xfffff000 to SDRAM which makes that memory region
+ * unusable for normal operation but it does allow OSes to easily
+ * reset a processor core to put it back into U-Boot's spinloop.
+ */
+ clrbits_be32(&ecm->bptr, 0x80000000);
+#endif
}
#endif
@@ -269,33 +297,27 @@ void cpu_mp_lmb_reserve(struct lmb *lmb)
void setup_mp(void)
{
extern ulong __secondary_start_page;
+ extern ulong __bootpg_addr;
ulong fixup = (ulong)&__secondary_start_page;
u32 bootpg = determine_mp_bootpg();
+ /* Store the bootpg's SDRAM address for use by secondary CPU cores */
+ __bootpg_addr = bootpg;
+
/* look for the tlb covering the reset page, there better be one */
- int i = find_tlb_idx((void *)0xfffff000, 1);
+ int i = find_tlb_idx((void *)CONFIG_BPTR_VIRT_ADDR, 1);
/* we found a match */
if (i != -1) {
/* map reset page to bootpg so we can copy code there */
disable_tlb(i);
- set_tlb(1, 0xfffff000, bootpg, /* tlb, epn, rpn */
- MAS3_SX|MAS3_SW|MAS3_SR, MAS2_M, /* perms, wimge */
- 0, i, BOOKE_PAGESZ_4K, 1); /* ts, esel, tsize, iprot */
-
- memcpy((void *)0xfffff000, (void *)fixup, 4096);
- flush_cache(0xfffff000, 4096);
-
- disable_tlb(i);
-
- /* setup reset page back to 1:1, we'll use HW boot translation
- * to map this where we want
- */
- set_tlb(1, 0xfffff000, 0xfffff000, /* tlb, epn, rpn */
+ set_tlb(1, CONFIG_BPTR_VIRT_ADDR, bootpg, /* tlb, epn, rpn */
MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I, /* perms, wimge */
0, i, BOOKE_PAGESZ_4K, 1); /* ts, esel, tsize, iprot */
+ memcpy((void *)CONFIG_BPTR_VIRT_ADDR, (void *)fixup, 4096);
+
plat_mp_up(bootpg);
} else {
puts("WARNING: No reset page TLB. "
OpenPOWER on IntegriCloud