LS1021A. How to start secondary core in a baremetal program loaded via U-Boot?

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

LS1021A. How to start secondary core in a baremetal program loaded via U-Boot?

2,236 Views
ivanpetrov
Contributor II

Hello Everyone.

I am having problems booting up core1 of my ls1021a. I compile with QorIQ SDK and plan to run bare metal applications in SMP mode and load them via U-Boot. It seems to me that U-Boot somehow sends all secondary cores to sleep or wait-for-interrupt state during its initialization, so only core0 executes my startup.S code. I've been looking though the Linux kernel source files for this CPU and found the following functions related to second core boot-up procedure:

void ls1021a_set_secondary_entry(void)

{

    unsigned long paddr;

    if (dcfg_base) {

        paddr = virt_to_phys(secondary_startup);

        writel_relaxed(cpu_to_be32(paddr),

                dcfg_base + DCFG_CCSR_SCRATCHRW1);

    }

}

static int ls1021a_reset_secondary(unsigned int cpu)

{

    u32 tmp;

    if (!scfg_base || !dcfg_base || !dcsr_rcpm2_base)

        return -ENOMEM;

    writel_relaxed(secondary_pre_boot_entry,

            dcfg_base + DCFG_CCSR_SCRATCHRW1);

    /* Apply LS1021A specific to write to the BE SCFG space */

    tmp = ioread32be(scfg_base + SCFG_REVCR);

    iowrite32be(0xffffffff, scfg_base + SCFG_REVCR);

    /* Soft reset secondary core */

    iowrite32be(0x80000000, scfg_base + SCFG_CORESRENCR);

    iowrite32be(0x80000000, scfg_base +

                SCFG_CORE0_SFT_RST + STRIDE_4B * cpu);

    mdelay(15);

    /* Release secondary core */

    iowrite32be(1 << cpu, dcfg_base + DCFG_CCSR_BRR);

    ls1021a_set_secondary_entry();

    /* Disable core soft reset register */

    iowrite32be(0x0, scfg_base + SCFG_CORESRENCR);

    /* Revert back to the default */

    iowrite32be(tmp, scfg_base + SCFG_REVCR);

    return 0;

}

static int ls1021a_boot_secondary(unsigned int cpu, struct task_struct *idle)

{

    int ret = 0;

    if (system_state == SYSTEM_RUNNING)

        ret = ls1021a_reset_secondary(cpu);

    udelay(1);

    arch_send_wakeup_ipi_mask(cpumask_of(cpu));

    return ret;

}

static void __init ls1021a_smp_prepare_cpus(unsigned int max_cpus)

{

    ls1021a_secondary_iomap();

    secondary_pre_boot_entry = readl_relaxed(dcfg_base +

                        DCFG_CCSR_SCRATCHRW1);

    ls1021a_set_secondary_entry();

}

As far as I understand, in order to successful wake up core1 the following has to be executed by core0:

1) Set DCFG_CCSR_SCRATCHRW1 so that it points to the entry code for core1.

2) Enable soft reset .

3) Reset core1.

4) Release core1 from hold-off by setting DCFG_CCSR_BRR to 0x2 or 0x3.

5) Send software interrupt from core0 to core1.

It doesn't work for me when I load  my app via U-Boot. Core1 just doesn't start. I've checked all the big-little endian conversions and still nothing.

Is it a correct procedure? What could be the problem?

Labels (1)
0 Kudos
2 Replies

1,135 Views
yasetoliva
Contributor I

Hi, I'd like to know if you found any doc explaining the procedure for launching programs on the second core. Thanks

0 Kudos

1,135 Views
Pavel
NXP Employee
NXP Employee

We do not have ready solution.

See the following page:

http://www.denx.de/wiki/view/DULG/UBootStandalone#Section_5.12.4.

Find the following on this page:

Running on core other than core 0

See also attached file. Look at the "LS1021A_TWR_README.txt" file for the second core using.

See also core initialization is .tcl file.

These files are available if CodeWarrior is used.


Have a great day,
Pavel Chubakov

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos