2 Copyright © 1995-2010, The AROS Development Team. All rights reserved.
11 #include <asm/arm/mmu.h>
12 #include <utility/tagitem.h>
13 #include <aros/macros.h>
18 #include "serialdebug.h"
22 asm(" .section .aros.startup \n"
23 " .globl bootstrap \n"
24 " .type bootstrap,%function \n"
26 " movw r0,#:lower16:tmp_stack_ptr\n"
27 " movt r0,#:upper16:tmp_stack_ptr\n"
32 static __used
unsigned char __stack
[BOOT_STACK_SIZE
];
33 static __used
void * tmp_stack_ptr
= &__stack
[BOOT_STACK_SIZE
-16];
35 static struct TagItem tags
[128];
36 static struct TagItem
*tag
= &tags
[0];
37 static unsigned long *mem_upper
= NULL
;
38 static unsigned long *mem_lower
= NULL
;
39 static void *pkg_image
;
40 static uint32_t pkg_size
;
42 static void parse_atags(struct tag
*tags
)
46 kprintf("[BOOT] Parsing ATAGS\n");
50 kprintf("[BOOT] %08x (%04x): ", t
->hdr
.tag
, t
->hdr
.size
);
54 kprintf("Memory (%08x-%08x)\n", t
->u
.mem
.start
, t
->u
.mem
.size
+ t
->u
.mem
.start
- 1);
55 tag
->ti_Tag
= KRN_MEMLower
;
56 tag
->ti_Data
= t
->u
.mem
.start
;
57 mem_lower
= &tag
->ti_Data
;
60 tag
->ti_Tag
= KRN_MEMUpper
;
61 tag
->ti_Data
= t
->u
.mem
.start
+ t
->u
.mem
.size
;
62 mem_upper
= &tag
->ti_Data
;
68 char *cmdline
= malloc(strlen(t
->u
.cmdline
.cmdline
) + 1);
69 strcpy(cmdline
, t
->u
.cmdline
.cmdline
);
70 kprintf("CMDLine: \"%s\"\n", cmdline
);
72 tag
->ti_Tag
= KRN_CmdLine
;
73 tag
->ti_Data
= (intptr_t)cmdline
;
78 kprintf("RAMDISK: (%08x-%08x)\n", t
->u
.initrd
.start
, t
->u
.initrd
.size
+ t
->u
.initrd
.start
- 1);
79 pkg_image
= (void *)t
->u
.initrd
.start
;
80 pkg_size
= t
->u
.initrd
.size
;
89 void setup_mmu(uintptr_t kernel_phys
, uintptr_t kernel_virt
, uintptr_t length
)
92 uintptr_t first_1M_page
= kernel_virt
& 0xfff00000;
93 uintptr_t last_1M_page
= ((kernel_virt
+ length
+ 0x000fffff) & 0xfff00000) - 1;
95 kprintf("[BOOT] Preparing initial MMU map\n");
97 /* Use memory right below kernel for page dir */
98 pde_t
*page_dir
= (pde_t
*)(((uintptr_t)kernel_phys
- 16384) & ~ 16383);
100 kprintf("[BOOT] First level MMU page at %08x\n", page_dir
);
103 for (i
=0; i
< 4096; i
++)
106 /* 1:1 memory mapping */
107 for (i
=(*mem_lower
>> 20); i
< (*mem_upper
>> 20); i
++)
109 //page_dir[i].raw = 0;
110 page_dir
[i
].section
.type
= PDE_TYPE_SECTION
;
111 page_dir
[i
].section
.b
= 0;
112 page_dir
[i
].section
.c
= 1; /* Cacheable */
113 page_dir
[i
].section
.ap
= 3; /* All can read&write */
114 page_dir
[i
].section
.base_address
= i
;
117 /* 0x70000000 - 0x7fffffff */
118 for (i
= (0x70000000 >> 20); i
< (0x80000000 >> 20); i
++)
120 //page_dir[i].raw = 0;
121 page_dir
[i
].section
.type
= PDE_TYPE_SECTION
;
122 page_dir
[i
].section
.b
= 1; /* Shared device */
123 page_dir
[i
].section
.c
= 0; /* Non-Cacheable */
124 page_dir
[i
].section
.ap
= 3; /* All can read&write */
125 page_dir
[i
].section
.base_address
= i
;
128 kprintf("[BOOT] Preparing mapping for kernel (%d bytes, pages %08x to %08x)\n",
129 length
, first_1M_page
, last_1M_page
);
131 int fp
= first_1M_page
>> 20;
132 int lp
= last_1M_page
>> 20;
134 pte_t
*current_pte
= (pte_t
*)page_dir
;
138 for (i
= fp
; i
< lp
; i
++)
140 current_pte
= (pte_t
*)((uintptr_t)current_pte
- 1024);
142 page_dir
[i
].coarse
.type
= PDE_TYPE_COARSE
;
143 page_dir
[i
].coarse
.domain
= 0;
144 page_dir
[i
].coarse
.sbz
= 0;
145 page_dir
[i
].coarse
.imp
= 0;
146 page_dir
[i
].coarse
.base_address
= (intptr_t)current_pte
>> 10;
149 for (j
= 0; j
< 256; j
++)
151 uintptr_t synth_addr
= (i
<< 20) + (j
<< 12);
153 if (synth_addr
< kernel_virt
)
154 current_pte
[j
].raw
= 0;
155 else if (synth_addr
< kernel_virt
+ length
)
157 current_pte
[j
].raw
= 0;
158 current_pte
[j
].page
.base_address
= (synth_addr
- kernel_virt
+ kernel_phys
) >> 12;
159 current_pte
[j
].page
.b
= 0;
160 current_pte
[j
].page
.c
= 1;
161 current_pte
[j
].page
.ap
= 3;
162 current_pte
[j
].page
.type
= PTE_TYPE_PAGE
;
165 current_pte
[j
].raw
= 0;
169 /* Write page_dir address to ttbr0 */
170 asm volatile ("mcr p15, 0, %0, c2, c0, 0"::"r"(page_dir
));
171 /* Write ttbr control N = 0 (use only ttbr0) */
172 asm volatile ("mcr p15, 0, %0, c2, c0, 2"::"r"(0));
174 *mem_upper
= (intptr_t)current_pte
;
177 void boot(uintptr_t dummy
, uintptr_t arch
, struct tag
* atags
)
180 void (*entry
)(struct TagItem
*tags
) = NULL
;
182 /* Enable NEON and VFP */
183 asm volatile ("mrc p15, 0, %0, c1, c0, 2":"=r"(tmp
));
186 asm volatile ("mcr p15, 0, %0, c1, c0, 2"::"r"(tmp
));
188 fmxr(cr8
, fmrx(cr8
) | 1 << 30);
190 kprintf("[BOOT] AROS for EfikaMX bootstrap\n");
192 asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r"(tmp
));
193 kprintf("[BOOT] control register %08x\n", tmp
);
194 tmp
&= ~2; /* Disable MMU and caches */
195 tmp
|= 1 << 13; /* Exception vectors at 0xffff0000 */
196 asm volatile ("mcr p15, 0, %0, c1, c0, 0"::"r"(tmp
));
198 asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r"(tmp
));
199 kprintf("[BOOT] control register %08x\n", tmp
);
201 tag
->ti_Tag
= KRN_BootLoader
;
202 tag
->ti_Data
= (IPTR
)"Bootstrap/EfikaMX ARM";
207 kprintf("[BOOT] Bootstrap @ %08x-%08x\n", &__bootstrap_start
, &__bootstrap_end
);
208 kprintf("[BOOT] Topmost address for kernel: %p\n", *mem_upper
);
212 *mem_upper
= *mem_upper
& ~4095;
214 unsigned long kernel_phys
= *mem_upper
;
215 unsigned long kernel_virt
= kernel_phys
;
217 unsigned long total_size_ro
, total_size_rw
;
218 uint32_t size_ro
, size_rw
;
220 /* Calculate total size of kernel and modules */
222 getElfSize(&_binary_kernel_bin_start
, &size_rw
, &size_ro
);
224 total_size_ro
= size_ro
= (size_ro
+ 4095) & ~4095;
225 total_size_rw
= size_rw
= (size_rw
+ 4095) & ~4095;
227 if (pkg_image
&& pkg_size
)
229 uint8_t *base
= pkg_image
;
231 if (base
[0] == 0x7f && base
[1] == 'E' && base
[2] == 'L' && base
[3] == 'F')
233 kprintf("[BOOT] Kernel image is ELF file\n");
235 getElfSize(base
, &size_rw
, &size_ro
);
237 total_size_ro
+= (size_ro
+ 4095) & ~4095;
238 total_size_rw
+= (size_rw
+ 4095) & ~4095;
240 else if (base
[0] == 'P' && base
[1] == 'K' && base
[2] == 'G' && base
[3] == 0x01)
242 kprintf("[BOOT] Kernel image is a package:\n");
244 uint8_t *file
= base
+4;
245 uint32_t total_length
= AROS_BE2LONG(*(uint32_t*)file
); /* Total length of the module */
246 const uint8_t *file_end
= base
+total_length
;
249 kprintf("[BOOT] Package size: %dKB\n", total_length
>> 10);
253 while(file
< file_end
)
255 const char *filename
= remove_path(file
+4);
257 /* get text length */
258 len
= AROS_BE2LONG(*(uint32_t*)file
);
259 /* display the file name */
260 kprintf("[BOOT] %s \n", filename
);
264 len
= AROS_BE2LONG(*(uint32_t *)file
);
268 getElfSize(file
, &size_rw
, &size_ro
);
270 total_size_ro
+= (size_ro
+ 4095) & ~4095;
271 total_size_rw
+= (size_rw
+ 4095) & ~4095;
273 /* go to the next file */
279 kernel_phys
= *mem_upper
- total_size_ro
- total_size_rw
;
280 kernel_virt
= 0xffff0000 - total_size_ro
- total_size_rw
;
282 /* Adjust "top of memory" pointer */
283 *mem_upper
= kernel_phys
;
285 kprintf("[BOOT] Physical address of kernel: %p\n", kernel_phys
);
286 kprintf("[BOOT] Virtual address of kernel: %p\n", kernel_virt
);
288 entry
= (void (*)(struct TagItem
*))kernel_virt
;
290 initAllocator(kernel_phys
, kernel_phys
+ total_size_ro
, kernel_virt
- kernel_phys
);
292 tag
->ti_Tag
= KRN_KernelLowest
;
293 tag
->ti_Data
= kernel_phys
;
296 tag
->ti_Tag
= KRN_KernelHighest
;
297 tag
->ti_Data
= kernel_phys
+ ((total_size_ro
+ 4095) & ~4095) + ((total_size_rw
+ 4095) & ~4095);
300 loadElf(&_binary_kernel_bin_start
);
302 if (pkg_image
&& pkg_size
)
304 uint8_t *base
= pkg_image
;
306 if (base
[0] == 0x7f && base
[1] == 'E' && base
[2] == 'L' && base
[3] == 'F')
308 kprintf("[BOOT] Kernel image is ELF file\n");
313 else if (base
[0] == 'P' && base
[1] == 'K' && base
[2] == 'G' && base
[3] == 0x01)
315 kprintf("[BOOT] Kernel image is a package:\n");
317 uint8_t *file
= base
+4;
318 uint32_t total_length
= AROS_BE2LONG(*(uint32_t*)file
); /* Total length of the module */
319 const uint8_t *file_end
= base
+total_length
;
322 kprintf("[BOOT] Package size: %dKB\n", total_length
>> 10);
326 while(file
< file_end
)
328 const char *filename
= remove_path(file
+4);
330 /* get text length */
331 len
= AROS_BE2LONG(*(uint32_t*)file
);
332 /* display the file name */
333 kprintf("[BOOT] %s ", filename
);
337 len
= AROS_BE2LONG(*(uint32_t *)file
);
343 /* go to the next file */
349 arm_flush_cache(kernel_phys
, total_size_ro
+ total_size_rw
);
351 tag
->ti_Tag
= KRN_KernelBss
;
352 tag
->ti_Data
= (IPTR
)tracker
;
355 setup_mmu(kernel_phys
, kernel_virt
, total_size_ro
+ total_size_rw
);
358 tag
->ti_Tag
= TAG_DONE
;
361 kprintf("[BOOT] Kernel taglist contains %d entries\n", ((intptr_t)tag
- (intptr_t)tags
)/sizeof(struct TagItem
));
362 kprintf("[BOOT] Bootstrap wasted %d bytes of memory for kernels use\n", mem_used() );
366 /* Set domains - Dom0 is usable, rest is disabled */
367 asm volatile ("mrc p15, 0, %0, c3, c0, 0":"=r"(tmp
));
368 kprintf("[BOOT] Domain access control register: %08x\n", tmp
);
369 asm volatile ("mcr p15, 0, %0, c3, c0, 0"::"r"(0x00000001));
371 asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r"(tmp
));
372 kprintf("[BOOT] control register %08x\n", tmp
);
373 tmp
|= 1; /* Enable MMU */
374 asm volatile ("mcr p15, 0, %0, c1, c0, 0"::"r"(tmp
));
376 asm volatile ("mrc p15, 0, %0, c1, c0, 0":"=r"(tmp
));
377 kprintf("[BOOT] control register %08x\n", tmp
);
379 kprintf("[BOOT] Heading over to AROS kernel @ %08x\n", entry
);
383 kprintf("[BOOT] Back? Something wrong happened...\n");
387 kprintf("[BOOT] kernel entry pointer not set?\n");