Skip to content
Snippets Groups Projects
Commit 536eeefa authored by Armin Luntzer's avatar Armin Luntzer
Browse files

SPARC:

 - add leon_force_irq()
 - set multiprocessor interrupt for cross-cpu signalling
 - implement SMP functions
 - call smp_init() in setup_arch()
parent aa219008
No related branches found
No related tags found
No related merge requests found
......@@ -24,6 +24,10 @@
/* use IRQMP for inter-processor interrupt */
#define LEON3_IPIRQ 12
#define ASI_LEON3_SYSCTRL 0x02
#define ASI_LEON3_SYSCTRL_CCR 0x00
......
......@@ -187,7 +187,7 @@ __asm__ __volatile__( \
" nop\n\t" \
"here:\n\t" \
: \
: "r" (&(current_set[leon3_cpuid()])), \
: "r" (&(current_set[smp_cpu_id()])), \
"r" (&(next->thread_info)), \
"i" (TI_KSP), \
"i" (TI_KPC), \
......
......@@ -27,6 +27,7 @@ obj-y += stack.o
obj-y += traps/data_access_exception_trap.o
obj-y += traps/data_access_exception.o
obj-y += irq.o
obj-y += smp.o
obj-y += time.o
obj-y += clockevent.o
......
......@@ -461,7 +461,7 @@ static void leon_mask_irq(unsigned int irq, int cpu)
* @param cpu the cpu for which the interrupt is to be enabled
*/
static void leon_enable_irq(unsigned int irq, int cpu)
void leon_enable_irq(unsigned int irq, int cpu)
{
leon_clear_irq(irq);
......@@ -476,7 +476,7 @@ static void leon_enable_irq(unsigned int irq, int cpu)
* @param cpu the cpu for which the interrupt is to be disabled
*/
static void leon_disable_irq(unsigned int irq, int cpu)
void leon_disable_irq(unsigned int irq, int cpu)
{
leon_clear_irq(irq);
......@@ -484,6 +484,28 @@ static void leon_disable_irq(unsigned int irq, int cpu)
}
/**
* @brief force an interrupt
*
* @param irq the interrupt to force
* @param cpu the cpu on which to force the interrupt (set < 0 for all)
*
* @note interrupts must be enabled for this to work
*/
void leon_force_irq(unsigned int irq, int cpu)
{
#ifdef CONFIG_LEON3
if (cpu >= 0) {
iowrite32be((1 << irq), &leon_irqctrl_regs->irq_mpforce[cpu]);
return;
}
#endif
iowrite32be((1 << irq), &leon_irqctrl_regs->irq_force);
}
/**
* @brief queue a handler for delayed exectuion
*
......
......@@ -21,6 +21,10 @@
#include <stack.h>
#include <kernel/kmem.h>
#include <kernel/sched.h>
#include <kernel/smp.h>
void *_kernel_stack_top;
void *_kernel_stack_bottom;
......@@ -56,8 +60,6 @@ static void reserve_kernel_stack(void)
/* the (aligned) top of the stack */
_kernel_stack_top = (void *) (char *) _kernel_stack_bottom + k_stack_sz;
_kernel_stack_top = ALIGN_PTR(_kernel_stack_top, STACK_ALIGN);
printk("xxxxx reserved %p to %p\n", _kernel_stack_top, _kernel_stack_bottom);
}
......@@ -116,26 +118,30 @@ extern struct task_struct *kernel[];
void smp_cpu_entry(void)
{
reserve_kernel_stack();
BUG_ON(stack_migrate(NULL, _kernel_stack_top));
reserve_kernel_stack();
BUG_ON(stack_migrate(NULL, _kernel_stack_top));
printk("hi i'm cpu %d\n", leon3_cpuid());
printk("hi i'm cpu %d\n", leon3_cpuid());
BUG_ON(!leon3_cpuid());
BUG_ON(!leon3_cpuid());
/* signal ready */
iowrite32be(0x1, &cpu1_ready);
/* signal ready */
iowrite32be(0x1, &cpu1_ready);
while (ioread32be(&cpu1_ready) != 0x2);
BUG_ON(clockevents_offer_device());
kthread_init_main();
iowrite32be(0x3, &cpu1_ready);
iowrite32be(0x3, &cpu1_ready);
while (ioread32be(&cpu1_ready) != 0x4);
while(1) {
// printk(".\n");
cpu_relax();
}
// printk("1\n");
sched_enable();
while(1)
cpu_relax();
}
......@@ -164,5 +170,9 @@ void setup_arch(void)
sparc_clockevent_init();
smp_init();
boot_cpus();
sched_enable();
}
/**
* @file arch/sparc/kernel/smp.c
*
* @ingroup sparc
* @brief implements architecture-specific @ref kernel_smp interface
*/
#include <kernel/smp.h>
#include <irq.h>
#include <asm/io.h>
#include <asm/irq.h>
#ifdef CONFIG_LEON3
#include <asm/leon.h>
#endif
int smp_cpu_id(void)
{
#ifdef CONFIG_LEON3
return leon3_cpuid();
#else /* !CONFIG_LEON3 */
return 0;
#endif /* CONFIG_LEON3 */
}
void smp_send_reschedule(int cpu)
{
#ifdef CONFIG_LEON3
/* trigger reschedule via forced IRQMP extended interrupt */
/* TODO sanity check for cpu id */
leon_force_irq(LEON3_IPIRQ, cpu);
#endif /* CONFIG_LEON3 */
}
void smp_init(void)
{
#ifdef CONFIG_LEON3
/* XXX need number of CPUs here */
leon_enable_irq(LEON3_IPIRQ, 0);
leon_enable_irq(LEON3_IPIRQ, 1);
#endif /* CONFIG_LEON3 */
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment