Exemplo n.º 1
0
int __cpuinit zynq_cpun_start(u32 address, int cpu)
{
	u32 trampoline_code_size = &zynq_secondary_trampoline_end -
						&zynq_secondary_trampoline;

	if (cpu > ncores) {
		pr_warn("CPU No. is not available in the system\n");
		return -1;
	}

	/* MS: Expectation that SLCR are directly map and accessible */
	/* Not possible to jump to non aligned address */
	if (!(address & 3) && (!address || (address >= trampoline_code_size))) {
		/* Store pointer to ioremap area which points to address 0x0 */
		static u8 __iomem *zero;
		u32 trampoline_size = &zynq_secondary_trampoline_jump -
						&zynq_secondary_trampoline;

		zynq_slcr_cpu_stop(cpu);

		if (__pa(PAGE_OFFSET)) {
			zero = ioremap(0, trampoline_code_size);
			if (!zero) {
				pr_warn("BOOTUP jump vectors not accessible\n");
				return -1;
			}
		} else {
			zero = (__force u8 __iomem *)PAGE_OFFSET;
		}

		/*
		 * This is elegant way how to jump to any address
		 * 0x0: Load address at 0x8 to r0
		 * 0x4: Jump by mov instruction
		 * 0x8: Jumping address
		 */
		memcpy((__force void *)zero, &zynq_secondary_trampoline,
						trampoline_size);
		writel(address, zero + trampoline_size);

		flush_cache_all();
		outer_flush_range(0, trampoline_code_size);
		smp_wmb();

		if (__pa(PAGE_OFFSET))
			iounmap(zero);

		zynq_slcr_cpu_start(cpu);

		return 0;
	}

	pr_warn("Can't start CPU%d: Wrong starting address %x\n", cpu, address);

	return -1;
}
Exemplo n.º 2
0
static int zynq_cpu_kill(unsigned cpu)
{
	unsigned long timeout = jiffies + msecs_to_jiffies(50);

	while (zynq_slcr_cpu_state_read(cpu))
		if (time_after(jiffies, timeout))
			return 0;

	zynq_slcr_cpu_stop(cpu);
	return 1;
}
Exemplo n.º 3
0
static int zynq_cpu_kill(unsigned cpu)
{
	zynq_slcr_cpu_stop(cpu);
	return 1;
}