aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris/arch-v32/kernel/head.S
diff options
context:
space:
mode:
Diffstat (limited to 'arch/cris/arch-v32/kernel/head.S')
-rw-r--r--arch/cris/arch-v32/kernel/head.S204
1 files changed, 116 insertions, 88 deletions
diff --git a/arch/cris/arch-v32/kernel/head.S b/arch/cris/arch-v32/kernel/head.S
index 20bd80a84e48..2d66a7c320e1 100644
--- a/arch/cris/arch-v32/kernel/head.S
+++ b/arch/cris/arch-v32/kernel/head.S
@@ -4,22 +4,25 @@
4 * Copyright (C) 2003, Axis Communications AB 4 * Copyright (C) 2003, Axis Communications AB
5 */ 5 */
6 6
7
8#define ASSEMBLER_MACROS_ONLY 7#define ASSEMBLER_MACROS_ONLY
9 8
10/* 9/*
11 * The macros found in mmu_defs_asm.h uses the ## concatenation operator, so 10 * The macros found in mmu_defs_asm.h uses the ## concatenation operator, so
12 * -traditional must not be used when assembling this file. 11 * -traditional must not be used when assembling this file.
13 */ 12 */
14#include <asm/arch/hwregs/reg_rdwr.h> 13#include <hwregs/reg_rdwr.h>
15#include <asm/arch/hwregs/asm/mmu_defs_asm.h> 14#include <asm/arch/memmap.h>
16#include <asm/arch/hwregs/asm/reg_map_asm.h> 15#include <hwregs/intr_vect.h>
17#include <asm/arch/hwregs/asm/config_defs_asm.h> 16#include <hwregs/asm/mmu_defs_asm.h>
18#include <asm/arch/hwregs/asm/bif_core_defs_asm.h> 17#include <hwregs/asm/reg_map_asm.h>
18#include <asm/arch/mach/startup.inc>
19 19
20#define CRAMFS_MAGIC 0x28cd3d45 20#define CRAMFS_MAGIC 0x28cd3d45
21#define JHEAD_MAGIC 0x1FF528A6
22#define JHEAD_SIZE 8
21#define RAM_INIT_MAGIC 0x56902387 23#define RAM_INIT_MAGIC 0x56902387
22#define COMMAND_LINE_MAGIC 0x87109563 24#define COMMAND_LINE_MAGIC 0x87109563
25#define NAND_BOOT_MAGIC 0x9a9db001
23 26
24 ;; NOTE: R8 and R9 carry information from the decompressor (if the 27 ;; NOTE: R8 and R9 carry information from the decompressor (if the
25 ;; kernel was compressed). They must not be used in the code below 28 ;; kernel was compressed). They must not be used in the code below
@@ -30,12 +33,11 @@
30 .global romfs_start 33 .global romfs_start
31 .global romfs_length 34 .global romfs_length
32 .global romfs_in_flash 35 .global romfs_in_flash
36 .global nand_boot
33 .global swapper_pg_dir 37 .global swapper_pg_dir
34 .global crisv32_nand_boot
35 .global crisv32_nand_cramfs_offset
36 38
37 ;; Dummy section to make it bootable with current VCS simulator 39 ;; Dummy section to make it bootable with current VCS simulator
38#ifdef CONFIG_ETRAXFS_SIM 40#ifdef CONFIG_ETRAX_VCS_SIM
39 .section ".boot", "ax" 41 .section ".boot", "ax"
40 ba tstart 42 ba tstart
41 nop 43 nop
@@ -51,33 +53,15 @@ tstart:
51 ;; 53 ;;
52 di 54 di
53 55
54 ;; Start clocks for used blocks. 56 START_CLOCKS
55 move.d REG_ADDR(config, regi_config, rw_clk_ctrl), $r1 57
56 move.d [$r1], $r0 58 SETUP_WAIT_STATES
57 or.d REG_STATE(config, rw_clk_ctrl, cpu, yes) | \ 59
58 REG_STATE(config, rw_clk_ctrl, bif, yes) | \ 60 GIO_INIT
59 REG_STATE(config, rw_clk_ctrl, fix_io, yes), $r0 61
60 move.d $r0, [$r1] 62#ifdef CONFIG_SMP
61 63secondary_cpu_entry: /* Entry point for secondary CPUs */
62 ;; Set up waitstates etc 64 di
63 move.d REG_ADDR(bif_core, regi_bif_core, rw_grp1_cfg), $r0
64 move.d CONFIG_ETRAX_MEM_GRP1_CONFIG, $r1
65 move.d $r1, [$r0]
66 move.d REG_ADDR(bif_core, regi_bif_core, rw_grp2_cfg), $r0
67 move.d CONFIG_ETRAX_MEM_GRP2_CONFIG, $r1
68 move.d $r1, [$r0]
69 move.d REG_ADDR(bif_core, regi_bif_core, rw_grp3_cfg), $r0
70 move.d CONFIG_ETRAX_MEM_GRP3_CONFIG, $r1
71 move.d $r1, [$r0]
72 move.d REG_ADDR(bif_core, regi_bif_core, rw_grp4_cfg), $r0
73 move.d CONFIG_ETRAX_MEM_GRP4_CONFIG, $r1
74 move.d $r1, [$r0]
75
76#ifdef CONFIG_ETRAXFS_SIM
77 ;; Set up minimal flash waitstates
78 move.d 0, $r10
79 move.d REG_ADDR(bif_core, regi_bif_core, rw_grp1_cfg), $r11
80 move.d $r10, [$r11]
81#endif 65#endif
82 66
83 ;; Setup and enable the MMU. Use same configuration for both the data 67 ;; Setup and enable the MMU. Use same configuration for both the data
@@ -85,7 +69,7 @@ tstart:
85 ;; 69 ;;
86 ;; Note; 3 cycles is needed for a bank-select to take effect. Further; 70 ;; Note; 3 cycles is needed for a bank-select to take effect. Further;
87 ;; bank 1 is the instruction MMU, bank 2 is the data MMU. 71 ;; bank 1 is the instruction MMU, bank 2 is the data MMU.
88#ifndef CONFIG_ETRAXFS_SIM 72#ifndef CONFIG_ETRAX_VCS_SIM
89 move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \ 73 move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \
90 | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \ 74 | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \
91 | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb), $r0 75 | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb), $r0
@@ -93,7 +77,7 @@ tstart:
93 ;; Map the virtual DRAM to the RW eprom area at address 0. 77 ;; Map the virtual DRAM to the RW eprom area at address 0.
94 ;; Also map 0xa for the hook calls, 78 ;; Also map 0xa for the hook calls,
95 move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \ 79 move.d REG_FIELD(mmu, rw_mm_kbase_hi, base_e, 8) \
96 | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 0) \ 80 | REG_FIELD(mmu, rw_mm_kbase_hi, base_c, 4) \
97 | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb) \ 81 | REG_FIELD(mmu, rw_mm_kbase_hi, base_b, 0xb) \
98 | REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0xa), $r0 82 | REG_FIELD(mmu, rw_mm_kbase_hi, base_a, 0xa), $r0
99#endif 83#endif
@@ -104,7 +88,7 @@ tstart:
104 88
105 ;; Enable certain page protections and setup linear mapping 89 ;; Enable certain page protections and setup linear mapping
106 ;; for f,e,c,b,4,0. 90 ;; for f,e,c,b,4,0.
107#ifndef CONFIG_ETRAXFS_SIM 91#ifndef CONFIG_ETRAX_VCS_SIM
108 move.d REG_STATE(mmu, rw_mm_cfg, we, on) \ 92 move.d REG_STATE(mmu, rw_mm_cfg, we, on) \
109 | REG_STATE(mmu, rw_mm_cfg, acc, on) \ 93 | REG_STATE(mmu, rw_mm_cfg, acc, on) \
110 | REG_STATE(mmu, rw_mm_cfg, ex, on) \ 94 | REG_STATE(mmu, rw_mm_cfg, ex, on) \
@@ -183,17 +167,11 @@ tstart:
183 nop 167 nop
184 nop 168 nop
185 nop 169 nop
186 move $s10, $r0 170 move $s12, $r0
187 cmpq 0, $r0 171 cmpq 0, $r0
188 beq master_cpu 172 beq master_cpu
189 nop 173 nop
190slave_cpu: 174slave_cpu:
191 ; A slave waits for cpu_now_booting to be equal to CPU ID.
192 move.d cpu_now_booting, $r1
193slave_wait:
194 cmp.d [$r1], $r0
195 bne slave_wait
196 nop
197 ; Time to boot-up. Get stack location provided by master CPU. 175 ; Time to boot-up. Get stack location provided by master CPU.
198 move.d smp_init_current_idle_thread, $r1 176 move.d smp_init_current_idle_thread, $r1
199 move.d [$r1], $sp 177 move.d [$r1], $sp
@@ -203,9 +181,16 @@ slave_wait:
203 jsr smp_callin 181 jsr smp_callin
204 nop 182 nop
205master_cpu: 183master_cpu:
184 /* Set up entry point for secondary CPUs. The boot ROM has set up
185 * EBP at start of internal memory. The CPU will get there
186 * later when we issue an IPI to them... */
187 move.d MEM_INTMEM_START + IPI_INTR_VECT * 4, $r0
188 move.d secondary_cpu_entry, $r1
189 move.d $r1, [$r0]
206#endif 190#endif
207#ifndef CONFIG_ETRAXFS_SIM 191#ifndef CONFIG_ETRAX_VCS_SIM
208 ;; Check if starting from DRAM or flash. 192 ; Check if starting from DRAM (network->RAM boot or unpacked
193 ; compressed kernel), or directly from flash.
209 lapcq ., $r0 194 lapcq ., $r0
210 and.d 0x7fffffff, $r0 ; Mask off the non-cache bit. 195 and.d 0x7fffffff, $r0 ; Mask off the non-cache bit.
211 cmp.d 0x10000, $r0 ; Arbitrary, something above this code. 196 cmp.d 0x10000, $r0 ; Arbitrary, something above this code.
@@ -232,12 +217,13 @@ _inflash:
232 beq _dram_initialized 217 beq _dram_initialized
233 nop 218 nop
234 219
235#include "../lib/dram_init.S" 220#include "../mach/dram_init.S"
236 221
237_dram_initialized: 222_dram_initialized:
238 ;; Copy the text and data section to DRAM. This depends on that the 223 ;; Copy the text and data section to DRAM. This depends on that the
239 ;; variables used below are correctly set up by the linker script. 224 ;; variables used below are correctly set up by the linker script.
240 ;; The calculated value stored in R4 is used below. 225 ;; The calculated value stored in R4 is used below.
226 ;; Leave the cramfs file system (piggybacked after the kernel) in flash.
241 moveq 0, $r0 ; Source. 227 moveq 0, $r0 ; Source.
242 move.d text_start, $r1 ; Destination. 228 move.d text_start, $r1 ; Destination.
243 move.d __vmlinux_end, $r2 229 move.d __vmlinux_end, $r2
@@ -249,7 +235,7 @@ _dram_initialized:
249 blo 1b 235 blo 1b
250 nop 236 nop
251 237
252 ;; Keep CRAMFS in flash. 238 ;; Check for cramfs.
253 moveq 0, $r0 239 moveq 0, $r0
254 move.d romfs_length, $r1 240 move.d romfs_length, $r1
255 move.d $r0, [$r1] 241 move.d $r0, [$r1]
@@ -258,6 +244,7 @@ _dram_initialized:
258 bne 1f 244 bne 1f
259 nop 245 nop
260 246
247 ;; Set length and start of cramfs, set romfs_in_flash flag
261 addoq +4, $r4, $acr 248 addoq +4, $r4, $acr
262 move.d [$acr], $r0 249 move.d [$acr], $r0
263 move.d romfs_length, $r1 250 move.d romfs_length, $r1
@@ -273,35 +260,32 @@ _dram_initialized:
273 nop 260 nop
274 261
275_inram: 262_inram:
276 ;; Check if booting from NAND flash (in that case we just remember the offset 263 ;; Check if booting from NAND flash; if so, set appropriate flags
277 ;; into the flash where cramfs should be). 264 ;; and move on.
278 move.d REG_ADDR(config, regi_config, r_bootsel), $r0 265 cmp.d NAND_BOOT_MAGIC, $r12
279 move.d [$r0], $r0 266 bne move_cramfs ; not nand, jump
280 and.d REG_MASK(config, r_bootsel, boot_mode), $r0
281 cmp.d REG_STATE(config, r_bootsel, boot_mode, nand), $r0
282 bne move_cramfs
283 moveq 1,$r0
284 move.d crisv32_nand_boot, $r1
285 move.d $r0, [$r1]
286 move.d crisv32_nand_cramfs_offset, $r1
287 move.d $r9, [$r1]
288 moveq 1, $r0 267 moveq 1, $r0
289 move.d romfs_in_flash, $r1 268 move.d nand_boot, $r1 ; tell axisflashmap we're booting from NAND
269 move.d $r0, [$r1]
270 moveq 0, $r0 ; tell axisflashmap romfs is not in
271 move.d romfs_in_flash, $r1 ; (directly accessed) flash
290 move.d $r0, [$r1] 272 move.d $r0, [$r1]
291 jump _start_it 273 jump _start_it ; continue with boot
292 nop 274 nop
293 275
294move_cramfs: 276move_cramfs:
295 ;; Move the cramfs after BSS. 277 ;; kernel is in DRAM.
278 ;; Must figure out if there is a piggybacked rootfs image or not.
279 ;; Set romfs_length to 0 => no rootfs image available by default.
296 moveq 0, $r0 280 moveq 0, $r0
297 move.d romfs_length, $r1 281 move.d romfs_length, $r1
298 move.d $r0, [$r1] 282 move.d $r0, [$r1]
299 283
300#ifndef CONFIG_ETRAXFS_SIM 284#ifndef CONFIG_ETRAX_VCS_SIM
301 ;; The kernel could have been unpacked to DRAM by the loader, but 285 ;; The kernel could have been unpacked to DRAM by the loader, but
302 ;; the cramfs image could still be inte the flash immediately 286 ;; the cramfs image could still be in the flash immediately
303 ;; following the compressed kernel image. The loaded passes the address 287 ;; following the compressed kernel image. The loader passes the address
304 ;; of the bute succeeding the last compressed byte in the flash in 288 ;; of the byte succeeding the last compressed byte in the flash in
305 ;; register R9 when starting the kernel. 289 ;; register R9 when starting the kernel.
306 cmp.d 0x0ffffff8, $r9 290 cmp.d 0x0ffffff8, $r9
307 bhs _no_romfs_in_flash ; R9 points outside the flash area. 291 bhs _no_romfs_in_flash ; R9 points outside the flash area.
@@ -310,11 +294,13 @@ move_cramfs:
310 ba _no_romfs_in_flash 294 ba _no_romfs_in_flash
311 nop 295 nop
312#endif 296#endif
297 ;; cramfs rootfs might to be in flash. Check for it.
313 move.d [$r9], $r0 ; cramfs_super.magic 298 move.d [$r9], $r0 ; cramfs_super.magic
314 cmp.d CRAMFS_MAGIC, $r0 299 cmp.d CRAMFS_MAGIC, $r0
315 bne _no_romfs_in_flash 300 bne _no_romfs_in_flash
316 nop 301 nop
317 302
303 ;; found cramfs in flash. set address and size, and romfs_in_flash flag.
318 addoq +4, $r9, $acr 304 addoq +4, $r9, $acr
319 move.d [$acr], $r0 305 move.d [$acr], $r0
320 move.d romfs_length, $r1 306 move.d romfs_length, $r1
@@ -330,27 +316,43 @@ move_cramfs:
330 nop 316 nop
331 317
332_no_romfs_in_flash: 318_no_romfs_in_flash:
333 ;; Look for cramfs. 319 ;; No romfs in flash, so look for cramfs, or jffs2 with jhead,
320 ;; after kernel in RAM, as is the case with network->RAM boot.
321 ;; For cramfs, partition starts with magic and length.
322 ;; For jffs2, a jhead is prepended which contains with magic and length.
323 ;; The jhead is not part of the jffs2 partition however.
334#ifndef CONFIG_ETRAXFS_SIM 324#ifndef CONFIG_ETRAXFS_SIM
335 move.d __vmlinux_end, $r0 325 move.d __vmlinux_end, $r0
336#else 326#else
337 move.d __end, $r0 327 move.d __end, $r0
338#endif 328#endif
339 move.d [$r0], $r1 329 move.d [$r0], $r1
340 cmp.d CRAMFS_MAGIC, $r1 330 cmp.d CRAMFS_MAGIC, $r1 ; cramfs magic?
341 bne 2f 331 beq 2f ; yes, jump
332 nop
333 cmp.d JHEAD_MAGIC, $r1 ; jffs2 (jhead) magic?
334 bne 4f ; no, skip copy
342 nop 335 nop
336 addq 4, $r0 ; location of jffs2 size
337 move.d [$r0+], $r2 ; fetch jffs2 size -> r2
338 ; r0 now points to start of jffs2
339 ba 3f
340 nop
3412:
342 addoq +4, $r0, $acr ; location of cramfs size
343 move.d [$acr], $r2 ; fetch cramfs size -> r2
344 ; r0 still points to start of cramfs
3453:
346 ;; Now, move the root fs to after kernel's BSS
343 347
344 addoq +4, $r0, $acr 348 move.d _end, $r1 ; start of cramfs -> r1
345 move.d [$acr], $r2
346 move.d _end, $r1
347 move.d romfs_start, $r3 349 move.d romfs_start, $r3
348 move.d $r1, [$r3] 350 move.d $r1, [$r3] ; store at romfs_start (for axisflashmap)
349 move.d romfs_length, $r3 351 move.d romfs_length, $r3
350 move.d $r2, [$r3] 352 move.d $r2, [$r3] ; store size at romfs_length
351 353
352#ifndef CONFIG_ETRAXFS_SIM 354#ifndef CONFIG_ETRAX_VCS_SIM
353 add.d $r2, $r0 355 add.d $r2, $r0 ; copy from end and downwards
354 add.d $r2, $r1 356 add.d $r2, $r1
355 357
356 lsrq 1, $r2 ; Size is in bytes, we copy words. 358 lsrq 1, $r2 ; Size is in bytes, we copy words.
@@ -365,10 +367,17 @@ _no_romfs_in_flash:
365 nop 367 nop
366#endif 368#endif
367 369
3682: 3704:
371 ;; BSS move done.
372 ;; Clear romfs_in_flash flag, as we now know romfs is in DRAM
373 ;; Also clear nand_boot flag; if we got here, we know we've not
374 ;; booted from NAND flash.
369 moveq 0, $r0 375 moveq 0, $r0
370 move.d romfs_in_flash, $r1 376 move.d romfs_in_flash, $r1
371 move.d $r0, [$r1] 377 move.d $r0, [$r1]
378 moveq 0, $r0
379 move.d nand_boot, $r1
380 move.d $r0, [$r1]
372 381
373 jump _start_it ; Jump to cached code. 382 jump _start_it ; Jump to cached code.
374 nop 383 nop
@@ -384,8 +393,8 @@ _start_it:
384 move.d cris_command_line, $r10 393 move.d cris_command_line, $r10
385 or.d 0x80000000, $r11 ; Make it virtual 394 or.d 0x80000000, $r11 ; Make it virtual
3861: 3951:
387 move.b [$r11+], $r12 396 move.b [$r11+], $r1
388 move.b $r12, [$r10+] 397 move.b $r1, [$r10+]
389 subq 1, $r13 398 subq 1, $r13
390 bne 1b 399 bne 1b
391 nop 400 nop
@@ -401,7 +410,7 @@ no_command_line:
401 move.d etrax_irv, $r1 ; Set the exception base register and pointer. 410 move.d etrax_irv, $r1 ; Set the exception base register and pointer.
402 move.d $r0, [$r1] 411 move.d $r0, [$r1]
403 412
404#ifndef CONFIG_ETRAXFS_SIM 413#ifndef CONFIG_ETRAX_VCS_SIM
405 ;; Clear the BSS region from _bss_start to _end. 414 ;; Clear the BSS region from _bss_start to _end.
406 move.d __bss_start, $r0 415 move.d __bss_start, $r0
407 move.d _end, $r1 416 move.d _end, $r1
@@ -411,7 +420,7 @@ no_command_line:
411 nop 420 nop
412#endif 421#endif
413 422
414#ifdef CONFIG_ETRAXFS_SIM 423#ifdef CONFIG_ETRAX_VCS_SIM
415 /* Set the watchdog timeout to something big. Will be removed when */ 424 /* Set the watchdog timeout to something big. Will be removed when */
416 /* watchdog can be disabled with command line option */ 425 /* watchdog can be disabled with command line option */
417 move.d 0x7fffffff, $r10 426 move.d 0x7fffffff, $r10
@@ -423,25 +432,44 @@ no_command_line:
423 move.d __bss_start, $r0 432 move.d __bss_start, $r0
424 movem [$r0], $r13 433 movem [$r0], $r13
425 434
435#ifdef CONFIG_ETRAX_L2CACHE
436 jsr l2cache_init
437 nop
438#endif
439
426 jump start_kernel ; Jump to start_kernel() in init/main.c. 440 jump start_kernel ; Jump to start_kernel() in init/main.c.
427 nop 441 nop
428 442
429 .data 443 .data
430etrax_irv: 444etrax_irv:
431 .dword 0 445 .dword 0
446
447; Variables for communication with the Axis flash map driver (axisflashmap),
448; and for setting up memory in arch/cris/kernel/setup.c .
449
450; romfs_start is set to the start of the root file system, if it exists
451; in directly accessible memory (i.e. NOR Flash when booting from Flash,
452; or RAM when booting directly from a network-downloaded RAM image)
432romfs_start: 453romfs_start:
433 .dword 0 454 .dword 0
455
456; romfs_length is set to the size of the root file system image, if it exists
457; in directly accessible memory (see romfs_start). Otherwise it is set to 0.
434romfs_length: 458romfs_length:
435 .dword 0 459 .dword 0
460
461; romfs_in_flash is set to 1 if the root file system resides in directly
462; accessible flash memory (i.e. NOR flash). It is set to 0 for RAM boot
463; or NAND flash boot.
436romfs_in_flash: 464romfs_in_flash:
437 .dword 0 465 .dword 0
438crisv32_nand_boot: 466
439 .dword 0 467; nand_boot is set to 1 when the kernel has been booted from NAND flash
440crisv32_nand_cramfs_offset: 468nand_boot:
441 .dword 0 469 .dword 0
442 470
443swapper_pg_dir = 0xc0002000 471swapper_pg_dir = 0xc0002000
444 472
445 .section ".init.data", "aw" 473 .section ".init.data", "aw"
446 474
447#include "../lib/hw_settings.S" 475#include "../mach/hw_settings.S"