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