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

Subversion Repositories c0or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 drasko
/*
2
 * Main initialisation code for the ARM kernel
3
 *
4
 * Copyright (C) 2007 - 2010 B Labs Ltd.
5
 */
6
#include <l4/lib/mutex.h>
7
#include <l4/lib/printk.h>
8
#include <l4/lib/string.h>
9
#include <l4/lib/idpool.h>
10
#include <l4/generic/platform.h>
11
#include <l4/generic/scheduler.h>
12
#include <l4/generic/space.h>
13
#include <l4/generic/tcb.h>
14
#include <l4/generic/bootmem.h>
15
#include <l4/generic/resource.h>
16
#include <l4/generic/container.h>
17
#include INC_ARCH(linker.h)
18
#include INC_ARCH(asm.h)
19
#include INC_SUBARCH(mm.h)
20
#include INC_SUBARCH(cpu.h)
21
#include INC_SUBARCH(mmu_ops.h)
22
#include INC_SUBARCH(perfmon.h)
23
#include INC_GLUE(memlayout.h)
24
#include INC_GLUE(memory.h)
25
#include INC_GLUE(mapping.h)
26
#include INC_GLUE(message.h)
27
#include INC_GLUE(syscall.h)
28
#include INC_GLUE(init.h)
29
#include INC_GLUE(smp.h)
30
#include INC_PLAT(platform.h)
31
#include INC_API(syscall.h)
32
#include INC_API(kip.h)
33
#include INC_API(mutex.h)
34
 
35
unsigned int kernel_mapping_end;
36
 
37
void print_sections(void)
38
{
39
        dprintk("_start_kernel: ",(unsigned int)_start_kernel);
40
        dprintk("_start_text: ",(unsigned int)_start_text);
41
        dprintk("_end_text: ",  (unsigned int)_end_text);
42
        dprintk("_start_data: ", (unsigned int)_start_data);
43
        dprintk("_end_data: ",  (unsigned int)_end_data);
44
        dprintk("_start_vectors: ",(unsigned int)_start_vectors);
45
        dprintk("arm_high_vector: ",(unsigned int)arm_high_vector);
46
        dprintk("_end_vectors: ",(unsigned int)_end_vectors);
47
        dprintk("_start_kip: ", (unsigned int) _start_kip);
48
        dprintk("_end_kip: ", (unsigned int) _end_kip);
49
        dprintk("_start_syscalls: ", (unsigned int) _start_syscalls);
50
        dprintk("_end_syscalls: ", (unsigned int) _end_syscalls);
51
        dprintk("_start_bootstack: ", (unsigned int)_start_bootstack);
52
        dprintk("_end_bootstack: ", (unsigned int)_end_bootstack);
53
        dprintk("_start_bootstack: ", (unsigned int)_start_bootstack);
54
        dprintk("_end_bootstack: ", (unsigned int)_end_bootstack);
55
        dprintk("_start_init_pgd: ", (unsigned int)_start_init_pgd);
56
        dprintk("_end_init_pgd: ", (unsigned int)_end_init_pgd);
57
        dprintk("_end_kernel: ", (unsigned int)_end_kernel);
58
        dprintk("_start_init: ", (unsigned int)_start_init);
59
        dprintk("_end_init: ", (unsigned int)_end_init);
60
        dprintk("_end: ", (unsigned int)_end);
61
}
62
 
63
/* This calculates what address the kip field would have in userspace. */
64
#define KIP_USR_OFFSETOF(kip, field) ((void *)(((unsigned long)&kip.field - \
65
                                        (unsigned long)&kip) + USER_KIP_PAGE))
66
 
67
/* The kip is non-standard, using 0xBB to indicate mine for now ;-) */
68
void kip_init()
69
{
70
        struct utcb **utcb_ref;
71
 
72
        /*
73
         * TODO: Adding utcb size might be useful
74
         */
75
        memset(&kip, 0, PAGE_SIZE);
76
        memcpy(&kip, "L4\230K", 4); /* Name field = l4uK */
77
        kip.api_version         = 0xBB;
78
        kip.api_subversion      = 1;
79
        kip.api_flags           = 0;             /* LE, 32-bit architecture */
80
        kip.kdesc.magic         = 0xBBB;
81
        kip.kdesc.version       = CODEZERO_VERSION;
82
        kip.kdesc.subversion    = CODEZERO_SUBVERSION;
83
        strncpy(kip.kdesc.date, __DATE__, KDESC_DATE_SIZE);
84
        strncpy(kip.kdesc.time, __TIME__, KDESC_TIME_SIZE);
85
 
86
        kip_init_syscalls();
87
 
88
        /* KIP + 0xFF0 is pointer to UTCB segment start address */
89
        utcb_ref = (struct utcb **)((unsigned long)&kip + UTCB_KIP_OFFSET);
90
 
91
        add_boot_mapping(virt_to_phys(&kip), USER_KIP_PAGE, PAGE_SIZE,
92
                         MAP_USR_RO);
93
        printk("%s: Kernel built on %s, %s\n", __KERNELNAME__,
94
               kip.kdesc.date, kip.kdesc.time);
95
}
96
 
97
void vectors_init()
98
{
99
        unsigned int size = ((u32)_end_vectors - (u32)arm_high_vector);
100
 
101
        /* Map the vectors in high vector page */
102
        add_boot_mapping(virt_to_phys(arm_high_vector),
103
                         ARM_HIGH_VECTOR, size, MAP_KERN_RWX);
104
 
105
        /* Kernel memory trapping is enabled at this point. */
106
}
107
 
108
 
109
#include <l4/generic/cap-types.h>
110
#include <l4/api/capability.h>
111
#include <l4/generic/capability.h>
112
 
113
/* This is what an idle task needs */
114
static DECLARE_PERCPU(struct capability, pmd_cap);
115
 
116
/*
117
 * FIXME: Add this when initializing kernel resources
118
 * This is a hack.
119
 */
120
void setup_idle_caps()
121
{
122
        struct capability *cap = &per_cpu(pmd_cap);
123
 
124
        cap_list_init(&current->cap_list);
125
        cap->type = CAP_RTYPE_MAPPOOL | CAP_TYPE_QUANTITY;
126
        cap->size = 50;
127
 
128
        link_init(&cap->list);
129
        cap_list_insert(cap, &current->cap_list);
130
}
131
 
132
/*
133
 * Set up current stack's beginning, and initial page tables
134
 * as a valid task environment for idle task for current cpu
135
 */
136
void setup_idle_task()
137
{
138
        memset(current, 0, sizeof(struct ktcb));
139
 
140
        current->space = &init_space;
141
        TASK_PGD(current) = &init_pgd;
142
 
143
        /* Initialize space caps list */
144
        cap_list_init(&current->space->cap_list);
145
 
146
        /*
147
         * FIXME: This must go to kernel resources init.
148
         */
149
 
150
        /* Init scheduler structs */
151
        sched_init_task(current, TASK_PRIO_NORMAL);
152
 
153
        /*
154
         * If using split page tables, kernel
155
         * resources must point at the global pgd
156
         * TODO: We may need this for V6, in the future
157
         */
158
#if defined(CONFIG_SUBARCH_V7)
159
        kernel_resources.pgd_global = &init_global_pgd;
160
#endif
161
}
162
 
163
void remove_initial_mapping(void)
164
{
165
        /* At this point, execution is on virtual addresses. */
166
        remove_section_mapping(virt_to_phys(_start_kernel));
167
}
168
 
169
void init_finalize(void)
170
{
171
        /* Set up idle task capabilities */
172
        setup_idle_caps();
173
 
174
        platform_timer_start();
175
 
176
#if defined (CONFIG_SMP)
177
        /* Tell other cores to continue */
178
        secondary_run_signal = 1;
179
        dmb();
180
#endif
181
 
182
        idle_task();
183
}
184
 
185
void start_kernel(void)
186
{
187
        print_early("\n"__KERNELNAME__": start kernel...\n");
188
 
189
        // print_sections();
190
 
191
        /* Early cpu initialization */
192
        cpu_startup();
193
 
194
        /*
195
         * Initialise section mappings
196
         * for the kernel area
197
         */
198
        init_kernel_mappings();
199
 
200
        print_early("\n"__KERNELNAME__": Init kernel mappings...\n");
201
 
202
        /*
203
         * Enable virtual memory
204
         * and jump to virtual addresses
205
         */
206
        start_virtual_memory();
207
 
208
        /*
209
         * Set up initial page tables and ktcb
210
         * as a valid environment for idle task
211
         */
212
        setup_idle_task();
213
 
214
        /*
215
         * Initialise platform-specific
216
         * page mappings, and peripherals
217
         */
218
        platform_init();
219
 
220
        /* Can only print when uart is mapped */
221
        printk("%s: Virtual memory enabled.\n",
222
               __KERNELNAME__);
223
 
224
        /* Identify CPUs and system */
225
        system_identify();
226
 
227
        sched_init();
228
 
229
        /*
230
         * Map and enable high vector page.
231
         * Faults can be handled after here.
232
         */
233
        vectors_init();
234
 
235
        /* Try to initialize secondary cores if there are any */
236
        smp_start_cores();
237
 
238
        /* Remove one-to-one kernel mapping */
239
        remove_initial_mapping();
240
 
241
        /* Remap 1MB kernel sections as 4Kb pages. */
242
        remap_as_pages((void *)page_align(_start_kernel),
243
                       (void *)page_align_up(_end_kernel));
244
 
245
        /*
246
         * Initialise kip and map
247
         * for userspace access
248
         */
249
        kip_init();
250
 
251
        /* Initialise system call page */
252
        syscall_init();
253
 
254
        /* Init performance monitor, if enabled */
255
        perfmon_init();
256
 
257
        /*
258
         * Evaluate system resources
259
         * and set up resource pools
260
         */
261
        init_system_resources(&kernel_resources);
262
 
263
        /*
264
         * Free boot memory, switch to first
265
         * task's stack and start scheduler
266
         */
267
        init_finalize();
268
 
269
        BUG();
270
}
271
 

powered by: WebSVN 2.1.0

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