how to enable p4040's 4cores?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

how to enable p4040's 4cores?

1,985 Views
mgkiller
Contributor III

hi all,

I have a question about P4040.

When executing the command cat /proc/cpuinfo, I can only see the processor:0, is that mean processor:1 ~ 3 didn't work?

And how to set registers (in u-boot?) to let the four cores work together?

Finally, how to test the performance of multi-core CPU?


Any help is appreciated!

Labels (1)
Tags (2)
0 Kudos
11 Replies

1,160 Views
ivankrivonos
Contributor I

Please check that you don`t have "mp_holdoff" variable set in the u-boot environment page.

This variable set to any value prevents u-boot from unlocking the cores 1..core_max. As a result,

u-boot will not put them into ePAPR boot table/FDT nodes, and linux will not find them. If you have

this variable set, just issue "setenv mp_holdoff" "saveenv" in the u-boot console, then

boot the linux kernel as usual

0 Kudos

1,160 Views
lunminliang
NXP Employee
NXP Employee

You can use the standard "Dhrystone" for cpu performance test, see http://en.wikipedia.org/wiki/Dhrystone

0 Kudos

1,160 Views
marius_grigoras
NXP Employee
NXP Employee

Hi,

As far I know you must enable the cores using BRR register (Boot Release Register):

mem [CCSRBAR_addr 0xE00E4] = 0x0000000f

And is a good practice also to enables the clocks to any core timebases on the device:

mem [CCSRBAR_addr 0xE2084] = 0x0000000f

Hope this helps,

Marius

0 Kudos

1,160 Views
mgkiller
Contributor III

I have read these two registers you mentioned. They are all 0x0000000f in u-boot & fs. The problem remain.why?

0 Kudos

1,160 Views
marius_grigoras
NXP Employee
NXP Employee

Hi,

From my experience, I observed if the cores are in debug before starting the u-boot, the u-boot will initialize the rest of the cores (brr register) but cannot start them.

Try to make a hw reset before starting the u-boot or a ccs::reset_to_user from ccs console. If you are using CW please select all the cores for reset operation.

Regards,

Marius

0 Kudos

1,160 Views
mgkiller
Contributor III

additional remarks:


printk when booting kernel:

e500 family performance monitor hardware support registered

smp_85xx_kick_cpu: timeout waiting for core 1 to ack

smp: failed starting cpu 1 (rc -2)

smp_85xx_kick_cpu: timeout waiting for core 2 to ack

smp: failed starting cpu 2 (rc -2)

smp_85xx_kick_cpu: timeout waiting for core 3 to ack

smp: failed starting cpu 3 (rc -2)

Brought up 1 CPUs

printk when booting u-boot:

CPU up timeout. CPU up mask is 1 should be f

below is the relative code:

static void plat_mp_up(unsigned long bootpg)

{

    u32 cpu_up_mask, whoami;

    u32 *table = (u32 *)get_spin_virt_addr();

    volatile ccsr_gur_t *gur;

    volatile ccsr_local_t *ccm;

    volatile ccsr_rcpm_t *rcpm;

    volatile ccsr_pic_t *pic;

    int timeout = 10;

    u32 mask = cpu_mask();

    struct law_entry e;

    gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);

    ccm = (void *)(CONFIG_SYS_FSL_CORENET_CCM_ADDR);

    rcpm = (void *)(CONFIG_SYS_FSL_CORENET_RCPM_ADDR);

    pic = (void *)(CONFIG_SYS_MPC8xxx_PIC_ADDR);

    whoami = in_be32(&pic->whoami);

    cpu_up_mask = 1 << whoami;

    out_be32(&ccm->bstrl, bootpg);

    e = find_law(bootpg);

    out_be32(&ccm->bstrar, LAW_EN | e.trgt_id << 20 | LAW_SIZE_4K);

    /* readback to sync write */

    in_be32(&ccm->bstrar);

    /* disable time base at the platform */

    out_be32(&rcpm->ctbenrl, cpu_up_mask);

    out_be32(&gur->brrl, mask);

    /* wait for everyone */

    while (timeout) {

        unsigned int i, cpu, nr_cpus = cpu_numcores();

        for_each_cpu(i, cpu, nr_cpus, mask) {

            if (table[cpu * NUM_BOOT_ENTRY + BOOT_ENTRY_ADDR_LOWER])

                cpu_up_mask |= (1 << cpu);

        }

        if ((cpu_up_mask & mask) == mask)

            break;

        udelay(100);

        timeout--;

    }

    if (timeout == 0)

        printf("CPU up timeout. CPU up mask is %x should be %x\n",

            cpu_up_mask, mask);

    /* enable time base at the platform */

    out_be32(&rcpm->ctbenrl, 0);

    /* readback to sync write */

    in_be32(&rcpm->ctbenrl);

    mtspr(SPRN_TBWU, 0);

    mtspr(SPRN_TBWL, 0);

    out_be32(&rcpm->ctbenrl, mask);

#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(&ccm->bstrar, LAW_EN);

#endif

}


0 Kudos

1,160 Views
marius_grigoras
NXP Employee
NXP Employee

You must to find in the u-boot code something like

out_be32(&gur->brrl, mask);

in static void plat_mp_up(unsigned long bootpg) function from arch/powerpc/cpu/mpc85xx/mp.c

But I observed that you already have this piece of code. Indeed, the problem is that cpu_mask is 1 instead of f. Can you please make a try to hardcode this to f? Maybe is a problem with cpu_mask()

Taking a look into cpu_mask() function it seems that for some cases it ca returns 1.

/*

* Return a 32-bit mask indicating which cores are present on this SOC.

*/

u32 cpu_mask()

{

  ccsr_pic_t __iomem *pic = (void *)CONFIG_SYS_MPC8xxx_PIC_ADDR;

  struct cpu_type *cpu = gd->cpu;

  /* better to query feature reporting register than just assume 1 */

  if (cpu == &cpu_type_unknown)

  return ((in_be32(&pic->frr) & MPC8xxx_PICFRR_NCPU_MASK) >>

  MPC8xxx_PICFRR_NCPU_SHIFT) + 1;

  return cpu->mask;

}

Please let me know the results,

Marius

0 Kudos

1,160 Views
mgkiller
Contributor III

hi Marius,

     i think you make a small mistake.

     "CPU up mask is 1 should be f" means cpu_up_mask=1 and mask=f;  'mask' gets value from cpu_mask(),which return f. so cpu_up_mask = 1 make the error. but i don't know why?

      i wanna to know what is the meaning for this piece of code?

            if (table[cpu * NUM_BOOT_ENTRY + BOOT_ENTRY_ADDR_LOWER])

                cpu_up_mask |= (1 << cpu);

  

0 Kudos

1,160 Views
marius_grigoras
NXP Employee
NXP Employee

cpu_up_mask = 1 << whoami; whoami is 0 (because the u-boot runs on first core) ..so that's why cpu_up_mask = 1.

cpu_up_mask it's used to enable CoreTimebaseEnable only for core0.

This piece of code about you're asking is a simple heuristic used for be sure that all cores are proper initialized after BRR's writing.

0 Kudos

1,160 Views
mgkiller
Contributor III

Hi Marius,

     Think you for your help, but my problem remaind.

      And do you know what would cause some cores are not proper initialized after BRR's writing? i really have no idea?

0 Kudos

1,160 Views
mgkiller
Contributor III

hi, marius viorel grigoras

thank you for your reply:smileyhappy:,my problem is still there.

my question is:

which registers should i care about?and where thy are? in u-boot? or linux kernel?

can you show me the detail step?:smileyconfused:

0 Kudos