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

Subversion Repositories c0or1k

[/] [c0or1k/] [trunk/] [src/] [glue/] [arm/] [smp.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 drasko
/*
2
 * Copyright (C) 2010 B Labs Ltd.
3
 *
4
 * Authors: Prem Mallappa, Bahadir Balban
5
 *
6
 * SMP Initialization of cores.
7
 */
8
 
9
#include <l4/generic/platform.h>
10
#include INC_GLUE(smp.h)
11
#include INC_GLUE(init.h)
12
#include INC_GLUE(mapping.h)
13
#include INC_SUBARCH(cpu.h)
14
#include INC_SUBARCH(proc.h)
15
#include INC_SUBARCH(mmu_ops.h)
16
#include INC_ARCH(linker.h)
17
#include INC_ARCH(io.h)
18
#include <l4/drivers/irq/gic/gic.h>
19
 
20
unsigned long secondary_run_signal;
21
unsigned long secondary_ready_signal;
22
 
23
void __smp_start(void);
24
 
25
void smp_start_cores(void)
26
{
27
        void (*smp_start_func)(int) =
28
                (void (*)(int))virt_to_phys(__smp_start);
29
 
30
        /* FIXME: Check why this high-level version doesn't work */
31
        // v7_up_dcache_op_setway(CACHE_SETWAY_CLEAN);
32
        v7_clean_invalidate_setway();
33
 
34
        /* We dont probably need this, it is not listed as a requirement */
35
        arm_smp_inval_icache_entirely();
36
 
37
        /* Start other cpus */
38
        for (int cpu = 1; cpu < CONFIG_NCPU; cpu++) {
39
                printk("%s: Bringing up CPU%d\n", __KERNELNAME__, cpu);
40
                if ((platform_smp_start(cpu, smp_start_func)) < 0) {
41
                        printk("FATAL: Could not start secondary cpu. "
42
                               "cpu=%d\n", cpu);
43
                        BUG();
44
                }
45
 
46
                /* Wait for this particular secondary to become ready */
47
                while(!(secondary_ready_signal & CPUID_TO_MASK(cpu)))
48
                        dmb();
49
        }
50
 
51
        scu_print_state();
52
}
53
 
54
void init_smp(void)
55
{
56
        /* Start_secondary_cpus */
57
        if (CONFIG_NCPU > 1) {
58
                /* This sets IPI function pointer at bare minimum */
59
                platform_smp_init(CONFIG_NCPU);
60
        }
61
}
62
 
63
void secondary_setup_idle_task(void)
64
{
65
        /* This also has its spid allocated by primary */
66
        current->space = &init_space;
67
        TASK_PGD(current) = &init_pgd;
68
 
69
        /* We need a thread id */
70
        current->tid = id_new(&kernel_resources.ktcb_ids);
71
}
72
 
73
/*
74
 * Idle wait before any tasks become available for running.
75
 *
76
 * FIXME: This should be changed such that tasks running on other
77
 * cpus can be killed and secondaries wait on an idle task.
78
 *
79
 * Currently the tasks are held in wfi() even if asked to be killed
80
 * until a new runnable task becomes runnable. This may be problematic
81
 * for a pager who issued a kill request and is waiting for it to finish.
82
 */
83
void sched_secondary_start(void)
84
{
85
        while (!secondary_run_signal)
86
                dmb();
87
 
88
        secondary_setup_idle_task();
89
 
90
        setup_idle_caps();
91
 
92
        idle_task();
93
 
94
        BUG();
95
}
96
 
97
 
98
/*
99
 * this is where it jumps from secondary_start(), which is called from
100
 * board_smp_start() to align each core to start here
101
 */
102
 
103
void smp_secondary_init(void)
104
{
105
        /* Print early core start message */
106
        // print_early("Secondary core started.\n");
107
 
108
        /* Start virtual memory */
109
        start_virtual_memory();
110
 
111
        arm_smp_inval_tlb_entirely();
112
        arm_smp_inval_bpa_entirely();
113
        dsb();
114
        isb();
115
 
116
        printk("%s: CPU%d: Virtual memory enabled.\n",
117
               __KERNELNAME__, smp_get_cpuid());
118
 
119
        /* Mostly initialize GIC CPU interface */
120
        secondary_init_platform();
121
 
122
        printk("%s: CPU%d: Initialized.\n",
123
               __KERNELNAME__, smp_get_cpuid());
124
 
125
        sched_init();
126
 
127
        /* Signal primary that we are ready */
128
        dmb();
129
        secondary_ready_signal |= cpu_mask_self();
130
 
131
        /*
132
         * Wait for the first runnable task to become available
133
         */
134
        sched_secondary_start();
135
}
136
 

powered by: WebSVN 2.1.0

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