1/*
2 *  Code that sets up the DRAM registers, calls the
3 *  decompressor to unpack the piggybacked kernel, and jumps.
4 *
5 *  Copyright (C) 1999 - 2006, Axis Communications AB
6 */
7
8#define ASSEMBLER_MACROS_ONLY
9#include <hwregs/asm/reg_map_asm.h>
10#include <mach/startup.inc>
11
12#define RAM_INIT_MAGIC 0x56902387
13#define COMMAND_LINE_MAGIC 0x87109563
14
15	;; Exported symbols
16
17	.globl	input_data
18
19	.text
20start:
21	di
22
23	;; Start clocks for used blocks.
24	START_CLOCKS
25
26	;; Initialize the DRAM registers.
27	cmp.d	RAM_INIT_MAGIC, $r8	; Already initialized?
28	beq	dram_init_finished
29	nop
30
31#if defined CONFIG_ETRAXFS
32#include "../../arch-v32/mach-fs/dram_init.S"
33#elif defined CONFIG_CRIS_MACH_ARTPEC3
34#include "../../arch-v32/mach-a3/dram_init.S"
35#else
36#error Only ETRAXFS and ARTPEC-3 supported!
37#endif
38
39dram_init_finished:
40
41	GIO_INIT
42	;; Setup the stack to a suitably high address.
43	;; We assume 8 MB is the minimum DRAM and put
44	;; the SP at the top for now.
45
46	move.d	0x40800000, $sp
47
48	;; Figure out where the compressed piggyback image is.
49	;; It is either in [NOR] flash (we don't want to copy it
50	;; to DRAM before unpacking), or copied to DRAM
51	;; by the [NAND] flash boot loader.
52	;; The piggyback image is at _edata, but relative to where the
53	;; image is actually located in memory, not where it is linked
54	;; (the decompressor is linked at 0x40700000+ and runs there).
55	;; Use (_edata - herami) as offset to the current PC.
56
57hereami:
58	lapcq	., $r5		; get PC
59	and.d	0x7fffffff, $r5	; strip any non-cache bit
60	move.d	$r5, $r0	; source address of 'herami'
61	add.d	_edata, $r5
62	sub.d	hereami, $r5	; r5 = flash address of '_edata'
63	move.d	hereami, $r1	; destination
64
65	;; Copy text+data to DRAM
66
67	move.d	_edata, $r2	; end destination
681:	move.w	[$r0+], $r3	; from herami+ source
69	move.w	$r3, [$r1+]	; to hereami+ destination (linked address)
70	cmp.d	$r2, $r1	; finish when destination == _edata
71	bcs	1b
72	nop
73	move.d	input_data, $r0 ; for the decompressor
74	move.d	$r5, [$r0]	; for the decompressor
75
76	;; Clear the decompressors BSS (between _edata and _end)
77
78	moveq	0, $r0
79	move.d	_edata, $r1
80	move.d	_end, $r2
811:	move.w	$r0, [$r1+]
82	cmp.d	$r2, $r1
83	bcs	1b
84	nop
85
86	;;  Save command line magic and address.
87	move.d	_cmd_line_magic, $r0
88	move.d  $r10, [$r0]
89	move.d	_cmd_line_addr, $r0
90	move.d  $r11, [$r0]
91
92	;;  Save boot source indicator
93	move.d	_boot_source, $r0
94	move.d	$r12, [$r0]
95
96	;; Do the decompression and save compressed size in _inptr
97
98	jsr	decompress_kernel
99	nop
100
101	;; Restore boot source indicator
102	move.d	_boot_source, $r12
103	move.d	[$r12], $r12
104
105	;; Restore command line magic and address.
106	move.d  _cmd_line_magic, $r10
107	move.d  [$r10], $r10
108	move.d  _cmd_line_addr, $r11
109	move.d  [$r11], $r11
110
111	;; Put start address of root partition in r9 so the kernel can use it
112	;; when mounting from flash
113	move.d  input_data, $r0
114	move.d	[$r0], $r9		; flash address of compressed kernel
115	move.d  inptr, $r0
116	add.d	[$r0], $r9		; size of compressed kernel
117	cmp.d   0x40000000, $r9		; image in DRAM ?
118	blo	enter_kernel		; no, must be [NOR] flash, jump
119	nop				; delay slot
120	and.d   0x001fffff, $r9		; assume compressed kernel was < 2M
121
122enter_kernel:
123	;; Enter the decompressed kernel
124	move.d	RAM_INIT_MAGIC, $r8	; Tell kernel that DRAM is initialized
125	jump	0x40004000	; kernel is linked to this address
126	nop
127
128	.data
129
130input_data:
131	.dword	0		; used by the decompressor
132_cmd_line_magic:
133	.dword 0
134_cmd_line_addr:
135	.dword 0
136_boot_source:
137	.dword 0
138
139#if defined CONFIG_ETRAXFS
140#include "../../arch-v32/mach-fs/hw_settings.S"
141#elif defined CONFIG_CRIS_MACH_ARTPEC3
142#include "../../arch-v32/mach-a3/hw_settings.S"
143#else
144#error Only ETRAXFS and ARTPEC-3 supported!
145#endif
146