OpenCores
URL https://opencores.org/ocsvn/c0or1k/c0or1k/trunk

Subversion Repositories c0or1k

[/] [c0or1k/] [trunk/] [src/] [platform/] [realview/] [smp.c] - Rev 2

Compare with Previous | Blame | View Log

/*
 * Copyright 2010 B Labs.Ltd.
 *
 * Author: Prem Mallappa  <prem.mallappa@b-labs.co.uk>
 *
 * Description: SMP related platform definitions
 */
#include <l4/generic/platform.h>
#include INC_ARCH(io.h)
#include INC_SUBARCH(proc.h)
#include INC_PLAT(platform.h)
#include INC_PLAT(offsets.h)
#include INC_PLAT(sysctrl.h)
#include INC_GLUE(smp.h)
#include INC_GLUE(ipi.h)
#include INC_GLUE(mapping.h)
#include INC_SUBARCH(cpu.h)
#include <l4/drivers/irq/gic/gic.h>
#include <l4/lib/string.h>
#include <l4/generic/space.h>
 
extern struct irq_desc irq_desc_array[IRQS_MAX];
 
/* Print some SCU information */
void scu_print_state(void)
{
	volatile u32 scu_cfg = read(SCU_VBASE + SCU_CFG_REG);
	int ncpu = (scu_cfg & SCU_CFG_NCPU_MASK) + 1;
	printk("%s: SMP: %d CPU cluster, CPU", __KERNELNAME__, ncpu);
	for (int i = 0; i < ncpu; i++) {
		if ((1 << i) & (scu_cfg >> SCU_CFG_SMP_NCPU_SHIFT))
			printk("%d/", i);
	}
	printk(" are participating in SMP\n");
 
}
 
void scu_init(void)
{
	volatile u32 scu_ctrl =	read(SCU_VBASE + SCU_CTRL_REG);
 
	/* Enable the SCU */
	if (!(scu_ctrl & SCU_CTRL_EN))
		scu_ctrl |= SCU_CTRL_EN;
 
	write(scu_ctrl, SCU_VBASE + SCU_CTRL_REG);
}
 
void platform_smp_init(int ncpus)
{
	/* Add GIC SoftIRQ (aka IPI) */
	for (int i = 0; i < 16; i++) {
		strncpy(irq_desc_array[i].name, "SoftInt", 8);
		irq_desc_array[i].chip  = &irq_chip_array[0];
		irq_desc_array[i].handler = &ipi_handler;
	}
 
	add_boot_mapping(PLATFORM_SYSTEM_REGISTERS, PLATFORM_SYSREGS_VBASE,
			 PAGE_SIZE, MAP_IO_DEFAULT);
 
}
 
int platform_smp_start(int cpu, void (*smp_start_func)(int))
{
 	/*
	 * Wake up just one core by writing the starting address to FLAGS
	 * register in SYSCTRL
	 */
	write(0xffffffff, SYS_FLAGS_CLR + PLATFORM_SYSREGS_VBASE);
	write((unsigned int)smp_start_func, SYS_FLAGS_SET + PLATFORM_SYSREGS_VBASE);
	dsb();	/* Make sure the write occurs */
 
	/* Wake up other core who is waiting on a WFI. */
	gic_send_ipi(CPUID_TO_MASK(cpu), 0);
 
	return 0;
}
 
void secondary_init_platform(void)
{
	gic_cpu_init(0, GIC0_CPU_VBASE);
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.