aboutsummaryrefslogtreecommitdiffstats
path: root/arch/cris/boot
diff options
context:
space:
mode:
authorJesper Nilsson <jesper.nilsson@axis.com>2009-04-21 05:44:57 -0400
committerJesper Nilsson <jesper.nilsson@axis.com>2009-04-21 05:44:57 -0400
commit66ab3a74c5ce737effc2c64391e036b0938b1c36 (patch)
treeabe71b0c811dd13c9b9ad2587ba8779a8f852220 /arch/cris/boot
parenta939b96cccdb65df80a52447ec8e4a6d79c56dbb (diff)
CRIS: Merge machine dependent boot/compressed and boot/rescue
Merge the machine dependent boot directories for v10 and v32. This avoids some code duplication and eases the way for further merging later on. Signed-off-by: Jesper Nilsson <jesper.nilsson@axis.com>
Diffstat (limited to 'arch/cris/boot')
-rw-r--r--arch/cris/boot/.gitignore2
-rw-r--r--arch/cris/boot/Makefile24
-rw-r--r--arch/cris/boot/compressed/Makefile38
-rw-r--r--arch/cris/boot/compressed/README24
-rw-r--r--arch/cris/boot/compressed/decompress_v10.lds30
-rw-r--r--arch/cris/boot/compressed/decompress_v32.lds30
-rw-r--r--arch/cris/boot/compressed/head_v10.S126
-rw-r--r--arch/cris/boot/compressed/head_v32.S145
-rw-r--r--arch/cris/boot/compressed/misc.c391
-rw-r--r--arch/cris/boot/rescue/Makefile47
-rw-r--r--arch/cris/boot/rescue/head_v10.S360
-rw-r--r--arch/cris/boot/rescue/head_v32.S26
-rw-r--r--arch/cris/boot/rescue/kimagerescue.S143
-rw-r--r--arch/cris/boot/rescue/rescue_v10.lds20
-rw-r--r--arch/cris/boot/rescue/rescue_v32.lds43
-rw-r--r--arch/cris/boot/rescue/testrescue.S24
-rw-r--r--arch/cris/boot/tools/build.c287
17 files changed, 1760 insertions, 0 deletions
diff --git a/arch/cris/boot/.gitignore b/arch/cris/boot/.gitignore
new file mode 100644
index 000000000000..171a0853caf8
--- /dev/null
+++ b/arch/cris/boot/.gitignore
@@ -0,0 +1,2 @@
1Image
2zImage
diff --git a/arch/cris/boot/Makefile b/arch/cris/boot/Makefile
new file mode 100644
index 000000000000..144f3afa0119
--- /dev/null
+++ b/arch/cris/boot/Makefile
@@ -0,0 +1,24 @@
1#
2# arch/cris/boot/Makefile
3#
4
5objcopyflags-$(CONFIG_ETRAX_ARCH_V10) += -R .note -R .comment
6objcopyflags-$(CONFIG_ETRAX_ARCH_V32) += --remove-section=.bss
7
8OBJCOPYFLAGS = -O binary $(objcopyflags-y)
9
10
11subdir- := compressed rescue
12targets := Image
13
14$(obj)/Image: vmlinux FORCE
15 $(call if_changed,objcopy)
16 @echo ' Kernel: $@ is ready'
17
18$(obj)/compressed/vmlinux: $(obj)/Image FORCE
19 $(Q)$(MAKE) $(build)=$(obj)/compressed $@
20 $(Q)$(MAKE) $(build)=$(obj)/rescue $(obj)/rescue/rescue.bin
21
22$(obj)/zImage: $(obj)/compressed/vmlinux
23 @cp $< $@
24 @echo ' Kernel: $@ is ready'
diff --git a/arch/cris/boot/compressed/Makefile b/arch/cris/boot/compressed/Makefile
new file mode 100644
index 000000000000..8fe9338c1775
--- /dev/null
+++ b/arch/cris/boot/compressed/Makefile
@@ -0,0 +1,38 @@
1#
2# arch/cris/boot/compressed/Makefile
3#
4
5asflags-y += $(LINUXINCLUDE)
6ccflags-y += -O2 $(LINUXINCLUDE)
7
8# asflags-$(CONFIG_ETRAX_ARCH_V32) += -I$(srctree)/include/asm/mach \
9# -I$(srctree)/include/asm/arch
10# ccflags-$(CONFIG_ETRAX_ARCH_V32) += -O2 -I$(srctree)/include/asm/mach
11# -I$(srctree)/include/asm/arch
12
13arch-$(CONFIG_ETRAX_ARCH_V10) = v10
14arch-$(CONFIG_ETRAX_ARCH_V32) = v32
15
16ldflags-y += -T $(srctree)/$(src)/decompress_$(arch-y).lds
17
18OBJECTS-$(CONFIG_ETRAX_ARCH_V32) = $(obj)/head_v32.o
19OBJECTS-$(CONFIG_ETRAX_ARCH_V10) = $(obj)/head_v10.o
20OBJECTS= $(OBJECTS-y) $(obj)/misc.o
21OBJCOPYFLAGS = -O binary --remove-section=.bss
22
23quiet_cmd_image = BUILD $@
24cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@
25
26targets := vmlinux piggy.gz decompress.o decompress.bin
27
28$(obj)/decompress.o: $(OBJECTS) FORCE
29 $(call if_changed,ld)
30
31$(obj)/decompress.bin: $(obj)/decompress.o FORCE
32 $(call if_changed,objcopy)
33
34$(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE
35 $(call if_changed,image)
36
37$(obj)/piggy.gz: $(obj)/../Image FORCE
38 $(call if_changed,gzip)
diff --git a/arch/cris/boot/compressed/README b/arch/cris/boot/compressed/README
new file mode 100644
index 000000000000..182c5d75784b
--- /dev/null
+++ b/arch/cris/boot/compressed/README
@@ -0,0 +1,24 @@
1Creation of the self-extracting compressed kernel image (vmlinuz)
2-----------------------------------------------------------------
3
4This can be slightly confusing because it's a process with many steps.
5
6The kernel object built by the arch/etrax100/Makefile, vmlinux, is split
7by that makefile into text and data binary files, vmlinux.text and
8vmlinux.data.
9
10Those files together with a ROM filesystem can be catted together and
11burned into a flash or executed directly at the DRAM origin.
12
13They can also be catted together and compressed with gzip, which is what
14happens in this makefile. Together they make up piggy.img.
15
16The decompressor is built into the file decompress.o. It is turned into
17the binary file decompress.bin, which is catted together with piggy.img
18into the file vmlinuz. It can be executed in an arbitrary place in flash.
19
20Be careful - it assumes some things about free locations in DRAM. It
21assumes the DRAM starts at 0x40000000 and that it is at least 8 MB,
22so it puts its code at 0x40700000, and initial stack at 0x40800000.
23
24-Bjorn
diff --git a/arch/cris/boot/compressed/decompress_v10.lds b/arch/cris/boot/compressed/decompress_v10.lds
new file mode 100644
index 000000000000..e80f4594d543
--- /dev/null
+++ b/arch/cris/boot/compressed/decompress_v10.lds
@@ -0,0 +1,30 @@
1/* OUTPUT_FORMAT(elf32-us-cris) */
2OUTPUT_FORMAT(elf32-cris)
3
4MEMORY
5 {
6 dram : ORIGIN = 0x40700000,
7 LENGTH = 0x00100000
8 }
9
10SECTIONS
11{
12 .text :
13 {
14 _stext = . ;
15 *(.text)
16 *(.rodata)
17 *(.rodata.*)
18 _etext = . ;
19 } > dram
20 .data :
21 {
22 *(.data)
23 _edata = . ;
24 } > dram
25 .bss :
26 {
27 *(.bss)
28 _end = ALIGN( 0x10 ) ;
29 } > dram
30}
diff --git a/arch/cris/boot/compressed/decompress_v32.lds b/arch/cris/boot/compressed/decompress_v32.lds
new file mode 100644
index 000000000000..3c837feca3ac
--- /dev/null
+++ b/arch/cris/boot/compressed/decompress_v32.lds
@@ -0,0 +1,30 @@
1/*#OUTPUT_FORMAT(elf32-us-cris) */
2OUTPUT_ARCH (crisv32)
3
4MEMORY
5 {
6 dram : ORIGIN = 0x40700000,
7 LENGTH = 0x00100000
8 }
9
10SECTIONS
11{
12 .text :
13 {
14 _stext = . ;
15 *(.text)
16 *(.rodata)
17 *(.rodata.*)
18 _etext = . ;
19 } > dram
20 .data :
21 {
22 *(.data)
23 _edata = . ;
24 } > dram
25 .bss :
26 {
27 *(.bss)
28 _end = ALIGN( 0x10 ) ;
29 } > dram
30}
diff --git a/arch/cris/boot/compressed/head_v10.S b/arch/cris/boot/compressed/head_v10.S
new file mode 100644
index 000000000000..9edb8ade7e1f
--- /dev/null
+++ b/arch/cris/boot/compressed/head_v10.S
@@ -0,0 +1,126 @@
1/*
2 * arch/cris/boot/compressed/head.S
3 *
4 * Copyright (C) 1999, 2001 Axis Communications AB
5 *
6 * Code that sets up the DRAM registers, calls the
7 * decompressor to unpack the piggybacked kernel, and jumps.
8 *
9 */
10
11#define ASSEMBLER_MACROS_ONLY
12#include <arch/sv_addr_ag.h>
13
14#define RAM_INIT_MAGIC 0x56902387
15#define COMMAND_LINE_MAGIC 0x87109563
16
17 ;; Exported symbols
18
19 .globl input_data
20
21
22 .text
23
24 nop
25 di
26
27;; We need to initialze DRAM registers before we start using the DRAM
28
29 cmp.d RAM_INIT_MAGIC, $r8 ; Already initialized?
30 beq dram_init_finished
31 nop
32
33#include "../../arch-v10/lib/dram_init.S"
34
35dram_init_finished:
36
37 ;; Initiate the PA and PB ports
38
39 move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
40 move.b $r0, [R_PORT_PA_DATA]
41
42 move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
43 move.b $r0, [R_PORT_PA_DIR]
44
45 move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
46 move.b $r0, [R_PORT_PB_DATA]
47
48 move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
49 move.b $r0, [R_PORT_PB_DIR]
50
51 ;; Setup the stack to a suitably high address.
52 ;; We assume 8 MB is the minimum DRAM in an eLinux
53 ;; product and put the sp at the top for now.
54
55 move.d 0x40800000, $sp
56
57 ;; Figure out where the compressed piggyback image is
58 ;; in the flash (since we wont try to copy it to DRAM
59 ;; before unpacking). It is at _edata, but in flash.
60 ;; Use (_edata - basse) as offset to the current PC.
61
62basse: move.d $pc, $r5
63 and.d 0x7fffffff, $r5 ; strip any non-cache bit
64 subq 2, $r5 ; compensate for the move.d $pc instr
65 move.d $r5, $r0 ; save for later - flash address of 'basse'
66 add.d _edata, $r5
67 sub.d basse, $r5 ; $r5 = flash address of '_edata'
68
69 ;; Copy text+data to DRAM
70
71 move.d basse, $r1 ; destination
72 move.d _edata, $r2 ; end destination
731: move.w [$r0+], $r3
74 move.w $r3, [$r1+]
75 cmp.d $r2, $r1
76 bcs 1b
77 nop
78
79 move.d $r5, [input_data] ; for the decompressor
80
81
82 ;; Clear the decompressors BSS (between _edata and _end)
83
84 moveq 0, $r0
85 move.d _edata, $r1
86 move.d _end, $r2
871: move.w $r0, [$r1+]
88 cmp.d $r2, $r1
89 bcs 1b
90 nop
91
92 ;; Save command line magic and address.
93 move.d _cmd_line_magic, $r12
94 move.d $r10, [$r12]
95 move.d _cmd_line_addr, $r12
96 move.d $r11, [$r12]
97
98 ;; Do the decompression and save compressed size in inptr
99
100 jsr decompress_kernel
101
102 ;; Put start address of root partition in $r9 so the kernel can use it
103 ;; when mounting from flash
104
105 move.d [input_data], $r9 ; flash address of compressed kernel
106 add.d [inptr], $r9 ; size of compressed kernel
107
108 ;; Restore command line magic and address.
109 move.d _cmd_line_magic, $r10
110 move.d [$r10], $r10
111 move.d _cmd_line_addr, $r11
112 move.d [$r11], $r11
113
114 ;; Enter the decompressed kernel
115 move.d RAM_INIT_MAGIC, $r8 ; Tell kernel that DRAM is initialized
116 jump 0x40004000 ; kernel is linked to this address
117
118 .data
119
120input_data:
121 .dword 0 ; used by the decompressor
122_cmd_line_magic:
123 .dword 0
124_cmd_line_addr:
125 .dword 0
126#include "../../arch-v10/lib/hw_settings.S"
diff --git a/arch/cris/boot/compressed/head_v32.S b/arch/cris/boot/compressed/head_v32.S
new file mode 100644
index 000000000000..f483005f3d48
--- /dev/null
+++ b/arch/cris/boot/compressed/head_v32.S
@@ -0,0 +1,145 @@
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
diff --git a/arch/cris/boot/compressed/misc.c b/arch/cris/boot/compressed/misc.c
new file mode 100644
index 000000000000..47bc190ba6d4
--- /dev/null
+++ b/arch/cris/boot/compressed/misc.c
@@ -0,0 +1,391 @@
1/*
2 * misc.c
3 *
4 * This is a collection of several routines from gzip-1.0.3
5 * adapted for Linux.
6 *
7 * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
8 * puts by Nick Holloway 1993, better puts by Martin Mares 1995
9 * adaptation for Linux/CRIS Axis Communications AB, 1999
10 *
11 */
12
13/* where the piggybacked kernel image expects itself to live.
14 * it is the same address we use when we network load an uncompressed
15 * image into DRAM, and it is the address the kernel is linked to live
16 * at by vmlinux.lds.S
17 */
18
19#define KERNEL_LOAD_ADR 0x40004000
20
21#include <linux/types.h>
22
23#ifdef CONFIG_ETRAX_ARCH_V32
24#include <hwregs/reg_rdwr.h>
25#include <hwregs/reg_map.h>
26#include <hwregs/ser_defs.h>
27#include <hwregs/pinmux_defs.h>
28#ifdef CONFIG_CRIS_MACH_ARTPEC3
29#include <hwregs/clkgen_defs.h>
30#endif
31#else
32#include <arch/svinto.h>
33#endif
34
35/*
36 * gzip declarations
37 */
38
39#define OF(args) args
40#define STATIC static
41
42void *memset(void *s, int c, size_t n);
43void *memcpy(void *__dest, __const void *__src, size_t __n);
44
45#define memzero(s, n) memset((s), 0, (n))
46
47typedef unsigned char uch;
48typedef unsigned short ush;
49typedef unsigned long ulg;
50
51#define WSIZE 0x8000 /* Window size must be at least 32k, */
52 /* and a power of two */
53
54static uch *inbuf; /* input buffer */
55static uch window[WSIZE]; /* Sliding window buffer */
56
57unsigned inptr = 0; /* index of next byte to be processed in inbuf
58 * After decompression it will contain the
59 * compressed size, and head.S will read it.
60 */
61
62static unsigned outcnt = 0; /* bytes in output buffer */
63
64/* gzip flag byte */
65#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
66#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
67#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
68#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
69#define COMMENT 0x10 /* bit 4 set: file comment present */
70#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
71#define RESERVED 0xC0 /* bit 6,7: reserved */
72
73#define get_byte() (inbuf[inptr++])
74
75/* Diagnostic functions */
76#ifdef DEBUG
77# define Assert(cond, msg) do { \
78 if (!(cond)) \
79 error(msg); \
80 } while (0)
81# define Trace(x) fprintf x
82# define Tracev(x) do { \
83 if (verbose) \
84 fprintf x; \
85 } while (0)
86# define Tracevv(x) do { \
87 if (verbose > 1) \
88 fprintf x; \
89 } while (0)
90# define Tracec(c, x) do { \
91 if (verbose && (c)) \
92 fprintf x; \
93 } while (0)
94# define Tracecv(c, x) do { \
95 if (verbose > 1 && (c)) \
96 fprintf x; \
97 } while (0)
98#else
99# define Assert(cond, msg)
100# define Trace(x)
101# define Tracev(x)
102# define Tracevv(x)
103# define Tracec(c, x)
104# define Tracecv(c, x)
105#endif
106
107static void flush_window(void);
108static void error(char *m);
109static void puts(const char *);
110
111extern char *input_data; /* lives in head.S */
112
113static long bytes_out;
114static uch *output_data;
115static unsigned long output_ptr;
116
117/* the "heap" is put directly after the BSS ends, at end */
118
119extern int _end;
120static long free_mem_ptr = (long)&_end;
121static long free_mem_end_ptr;
122
123#include "../../../../../lib/inflate.c"
124
125/* decompressor info and error messages to serial console */
126
127#ifdef CONFIG_ETRAX_ARCH_V32
128static inline void serout(const char *s, reg_scope_instances regi_ser)
129{
130 reg_ser_rs_stat_din rs;
131 reg_ser_rw_dout dout = {.data = *s};
132
133 do {
134 rs = REG_RD(ser, regi_ser, rs_stat_din);
135 }
136 while (!rs.tr_rdy);/* Wait for transceiver. */
137
138 REG_WR(ser, regi_ser, rw_dout, dout);
139}
140#endif
141
142static void puts(const char *s)
143{
144#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
145 while (*s) {
146#ifdef CONFIG_ETRAX_DEBUG_PORT0
147#ifdef CONFIG_ETRAX_ARCH_V32
148 serout(s, regi_ser0);
149#else
150 while (!(*R_SERIAL0_STATUS & (1 << 5)))
151 ;
152 *R_SERIAL0_TR_DATA = *s++;
153#endif
154#endif
155#ifdef CONFIG_ETRAX_DEBUG_PORT1
156#ifdef CONFIG_ETRAX_ARCH_V32
157 serout(s, regi_ser1);
158#else
159 while (!(*R_SERIAL1_STATUS & (1 << 5)))
160 ;
161 *R_SERIAL1_TR_DATA = *s++;
162#endif
163#endif
164#ifdef CONFIG_ETRAX_DEBUG_PORT2
165#ifdef CONFIG_ETRAX_ARCH_V32
166 serout(s, regi_ser2);
167#else
168 while (!(*R_SERIAL2_STATUS & (1 << 5)))
169 ;
170 *R_SERIAL2_TR_DATA = *s++;
171#endif
172#endif
173#ifdef CONFIG_ETRAX_DEBUG_PORT3
174#ifdef CONFIG_ETRAX_ARCH_V32
175 serout(s, regi_ser3);
176#else
177 while (!(*R_SERIAL3_STATUS & (1 << 5)))
178 ;
179 *R_SERIAL3_TR_DATA = *s++;
180#endif
181#endif
182 *s++;
183 }
184/* CONFIG_ETRAX_DEBUG_PORT_NULL */
185#endif
186}
187
188void *memset(void *s, int c, size_t n)
189{
190 int i;
191 char *ss = (char*)s;
192
193 for (i=0;i<n;i++) ss[i] = c;
194
195 return s;
196}
197
198void *memcpy(void *__dest, __const void *__src, size_t __n)
199{
200 int i;
201 char *d = (char *)__dest, *s = (char *)__src;
202
203 for (i = 0; i < __n; i++)
204 d[i] = s[i];
205
206 return __dest;
207}
208
209/* ===========================================================================
210 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
211 * (Used for the decompressed data only.)
212 */
213
214static void flush_window(void)
215{
216 ulg c = crc; /* temporary variable */
217 unsigned n;
218 uch *in, *out, ch;
219
220 in = window;
221 out = &output_data[output_ptr];
222 for (n = 0; n < outcnt; n++) {
223 ch = *out = *in;
224 out++;
225 in++;
226 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
227 }
228 crc = c;
229 bytes_out += (ulg)outcnt;
230 output_ptr += (ulg)outcnt;
231 outcnt = 0;
232}
233
234static void error(char *x)
235{
236 puts("\n\n");
237 puts(x);
238 puts("\n\n -- System halted\n");
239
240 while(1); /* Halt */
241}
242
243void setup_normal_output_buffer(void)
244{
245 output_data = (char *)KERNEL_LOAD_ADR;
246}
247
248#ifdef CONFIG_ETRAX_ARCH_V32
249static inline void serial_setup(reg_scope_instances regi_ser)
250{
251 reg_ser_rw_xoff xoff;
252 reg_ser_rw_tr_ctrl tr_ctrl;
253 reg_ser_rw_rec_ctrl rec_ctrl;
254 reg_ser_rw_tr_baud_div tr_baud;
255 reg_ser_rw_rec_baud_div rec_baud;
256
257 /* Turn off XOFF. */
258 xoff = REG_RD(ser, regi_ser, rw_xoff);
259
260 xoff.chr = 0;
261 xoff.automatic = regk_ser_no;
262
263 REG_WR(ser, regi_ser, rw_xoff, xoff);
264
265 /* Set baudrate and stopbits. */
266 tr_ctrl = REG_RD(ser, regi_ser, rw_tr_ctrl);
267 rec_ctrl = REG_RD(ser, regi_ser, rw_rec_ctrl);
268 tr_baud = REG_RD(ser, regi_ser, rw_tr_baud_div);
269 rec_baud = REG_RD(ser, regi_ser, rw_rec_baud_div);
270
271 tr_ctrl.stop_bits = 1; /* 2 stop bits. */
272 tr_ctrl.en = 1; /* enable transmitter */
273 rec_ctrl.en = 1; /* enabler receiver */
274
275 /*
276 * The baudrate setup used to be a bit fishy, but now transmitter and
277 * receiver are both set to the intended baud rate, 115200.
278 * The magic value is 29.493 MHz.
279 */
280 tr_ctrl.base_freq = regk_ser_f29_493;
281 rec_ctrl.base_freq = regk_ser_f29_493;
282 tr_baud.div = (29493000 / 8) / 115200;
283 rec_baud.div = (29493000 / 8) / 115200;
284
285 REG_WR(ser, regi_ser, rw_tr_ctrl, tr_ctrl);
286 REG_WR(ser, regi_ser, rw_tr_baud_div, tr_baud);
287 REG_WR(ser, regi_ser, rw_rec_ctrl, rec_ctrl);
288 REG_WR(ser, regi_ser, rw_rec_baud_div, rec_baud);
289}
290#endif
291
292void decompress_kernel(void)
293{
294 char revision;
295 char compile_rev;
296
297#ifdef CONFIG_ETRAX_ARCH_V32
298 /* Need at least a CRISv32 to run. */
299 compile_rev = 32;
300#if defined(CONFIG_ETRAX_DEBUG_PORT1) || \
301 defined(CONFIG_ETRAX_DEBUG_PORT2) || \
302 defined(CONFIG_ETRAX_DEBUG_PORT3)
303 reg_pinmux_rw_hwprot hwprot;
304
305#ifdef CONFIG_CRIS_MACH_ARTPEC3
306 reg_clkgen_rw_clk_ctrl clk_ctrl;
307
308 /* Enable corresponding clock region when serial 1..3 selected */
309
310 clk_ctrl = REG_RD(clkgen, regi_clkgen, rw_clk_ctrl);
311 clk_ctrl.sser_ser_dma6_7 = regk_clkgen_yes;
312 REG_WR(clkgen, regi_clkgen, rw_clk_ctrl, clk_ctrl);
313#endif
314
315 /* pinmux setup for ports 1..3 */
316 hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
317#endif
318
319
320#ifdef CONFIG_ETRAX_DEBUG_PORT0
321 serial_setup(regi_ser0);
322#endif
323#ifdef CONFIG_ETRAX_DEBUG_PORT1
324 hwprot.ser1 = regk_pinmux_yes;
325 serial_setup(regi_ser1);
326#endif
327#ifdef CONFIG_ETRAX_DEBUG_PORT2
328 hwprot.ser2 = regk_pinmux_yes;
329 serial_setup(regi_ser2);
330#endif
331#ifdef CONFIG_ETRAX_DEBUG_PORT3
332 hwprot.ser3 = regk_pinmux_yes;
333 serial_setup(regi_ser3);
334#endif
335#if defined(CONFIG_ETRAX_DEBUG_PORT1) || \
336 defined(CONFIG_ETRAX_DEBUG_PORT2) || \
337 defined(CONFIG_ETRAX_DEBUG_PORT3)
338 REG_WR(pinmux, regi_pinmux, rw_hwprot, hwprot);
339#endif
340
341 /* input_data is set in head.S */
342 inbuf = input_data;
343#else /* CRISv10 */
344 /* Need at least a crisv10 to run. */
345 compile_rev = 10;
346
347 /* input_data is set in head.S */
348 inbuf = input_data;
349
350#ifdef CONFIG_ETRAX_DEBUG_PORT0
351 *R_SERIAL0_XOFF = 0;
352 *R_SERIAL0_BAUD = 0x99;
353 *R_SERIAL0_TR_CTRL = 0x40;
354#endif
355#ifdef CONFIG_ETRAX_DEBUG_PORT1
356 *R_SERIAL1_XOFF = 0;
357 *R_SERIAL1_BAUD = 0x99;
358 *R_SERIAL1_TR_CTRL = 0x40;
359#endif
360#ifdef CONFIG_ETRAX_DEBUG_PORT2
361 *R_GEN_CONFIG = 0x08;
362 *R_SERIAL2_XOFF = 0;
363 *R_SERIAL2_BAUD = 0x99;
364 *R_SERIAL2_TR_CTRL = 0x40;
365#endif
366#ifdef CONFIG_ETRAX_DEBUG_PORT3
367 *R_GEN_CONFIG = 0x100;
368 *R_SERIAL3_XOFF = 0;
369 *R_SERIAL3_BAUD = 0x99;
370 *R_SERIAL3_TR_CTRL = 0x40;
371#endif
372#endif
373
374 setup_normal_output_buffer();
375
376 makecrc();
377
378 __asm__ volatile ("move $vr,%0" : "=rm" (revision));
379 if (revision < compile_rev) {
380#ifdef CONFIG_ETRAX_ARCH_V32
381 puts("You need an ETRAX FS to run Linux 2.6/crisv32\n");
382#else
383 puts("You need an ETRAX 100LX to run linux 2.6\n");
384#endif
385 while(1);
386 }
387
388 puts("Uncompressing Linux...\n");
389 gunzip();
390 puts("Done. Now booting the kernel\n");
391}
diff --git a/arch/cris/boot/rescue/Makefile b/arch/cris/boot/rescue/Makefile
new file mode 100644
index 000000000000..52bd0bd1dd22
--- /dev/null
+++ b/arch/cris/boot/rescue/Makefile
@@ -0,0 +1,47 @@
1#
2# Makefile for rescue (bootstrap) code
3#
4
5# CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE)
6# ccflags-$(CONFIG_ETRAX_ARCH_V32) += -I$(srctree)/include/asm/arch/mach/ \
7# -I$(srctree)/include/asm/arch
8# asflags-y += -I $(srctree)/include/asm/arch/mach/ -I $(srctree)/include/asm/arch
9# LD = gcc-cris -mlinux -march=v32 -nostdlib
10
11asflags-y += $(LINUXINCLUDE)
12ccflags-y += -O2 $(LINUXINCLUDE)
13arch-$(CONFIG_ETRAX_ARCH_V10) = v10
14arch-$(CONFIG_ETRAX_ARCH_V32) = v32
15
16ldflags-y += -T $(srctree)/$(src)/rescue_$(arch-y).lds
17OBJCOPYFLAGS = -O binary --remove-section=.bss
18obj-$(CONFIG_ETRAX_ARCH_V32) = $(obj)/head_v32.o
19obj-$(CONFIG_ETRAX_ARCH_V10) = $(obj)/head_v10.o
20OBJECTS := $(obj-y)
21
22targets := rescue.o rescue.bin
23
24$(obj)/rescue.o: $(OBJECTS) FORCE
25 $(call if_changed,ld)
26
27$(obj)/rescue.bin: $(obj)/rescue.o FORCE
28 $(call if_changed,objcopy)
29 cp -p $(obj)/rescue.bin $(objtree)
30
31$(obj)/testrescue.bin: $(obj)/testrescue.o
32 $(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/testrescue.o tr.bin
33# Pad it to 784 bytes
34 dd if=/dev/zero of=tmp2423 bs=1 count=784
35 cat tr.bin tmp2423 >testrescue_tmp.bin
36 dd if=testrescue_tmp.bin of=$(obj)/testrescue.bin bs=1 count=784
37 rm tr.bin tmp2423 testrescue_tmp.bin
38
39
40$(obj)/kimagerescue.bin: $(obj)/kimagerescue.o
41 $(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/kimagerescue.o ktr.bin
42# Pad it to 784 bytes, that's what the rescue loader expects
43 dd if=/dev/zero of=tmp2423 bs=1 count=784
44 cat ktr.bin tmp2423 >kimagerescue_tmp.bin
45 dd if=kimagerescue_tmp.bin of=$(obj)/kimagerescue.bin bs=1 count=784
46 rm ktr.bin tmp2423 kimagerescue_tmp.bin
47
diff --git a/arch/cris/boot/rescue/head_v10.S b/arch/cris/boot/rescue/head_v10.S
new file mode 100644
index 000000000000..2fafe247a25b
--- /dev/null
+++ b/arch/cris/boot/rescue/head_v10.S
@@ -0,0 +1,360 @@
1/*
2 * Rescue code, made to reside at the beginning of the
3 * flash-memory. when it starts, it checks a partition
4 * table at the first sector after the rescue sector.
5 * the partition table was generated by the product builder
6 * script and contains offsets, lengths, types and checksums
7 * for each partition that this code should check.
8 *
9 * If any of the checksums fail, we assume the flash is so
10 * corrupt that we cant use it to boot into the ftp flash
11 * loader, and instead we initialize the serial port to
12 * receive a flash-loader and new flash image. we dont include
13 * any flash code here, but just accept a certain amount of
14 * bytes from the serial port and jump into it. the downloaded
15 * code is put in the cache.
16 *
17 * The partitiontable is designed so that it is transparent to
18 * code execution - it has a relative branch opcode in the
19 * beginning that jumps over it. each entry contains extra
20 * data so we can add stuff later.
21 *
22 * Partition table format:
23 *
24 * Code transparency:
25 *
26 * 2 bytes [opcode 'nop']
27 * 2 bytes [opcode 'di']
28 * 4 bytes [opcode 'ba <offset>', 8-bit or 16-bit version]
29 * 2 bytes [opcode 'nop', delay slot]
30 *
31 * Table validation (at +10):
32 *
33 * 2 bytes [magic/version word for partitiontable - 0xef, 0xbe]
34 * 2 bytes [length of all entries plus the end marker]
35 * 4 bytes [checksum for the partitiontable itself]
36 *
37 * Entries, each with the following format, last has offset -1:
38 *
39 * 4 bytes [offset in bytes, from start of flash]
40 * 4 bytes [length in bytes of partition]
41 * 4 bytes [checksum, simple longword sum]
42 * 2 bytes [partition type]
43 * 2 bytes [flags, only bit 0 used, ro/rw = 1/0]
44 * 16 bytes [reserved for future use]
45 *
46 * End marker
47 *
48 * 4 bytes [-1]
49 *
50 * 10 bytes [0, padding]
51 *
52 * Bit 0 in flags signifies RW or RO. The rescue code only bothers
53 * to check the checksum for RO partitions, since the others will
54 * change their data without updating the checksums. A 1 in bit 0
55 * means RO, 0 means RW. That way, it is possible to set a partition
56 * in RO mode initially, and later mark it as RW, since you can always
57 * write 0's to the flash.
58 *
59 * During the wait for serial input, the status LED will flash so the
60 * user knows something went wrong.
61 *
62 * Copyright (C) 1999-2007 Axis Communications AB
63 */
64
65#ifdef CONFIG_ETRAX_AXISFLASHMAP
66
67#define ASSEMBLER_MACROS_ONLY
68#include <arch/sv_addr_ag.h>
69
70 ;; The partitiontable is looked for at the first sector after the boot
71 ;; sector. Sector size is 65536 bytes in all flashes we use.
72
73#define PTABLE_START CONFIG_ETRAX_PTABLE_SECTOR
74#define PTABLE_MAGIC 0xbeef
75
76 ;; The normal Etrax100 on-chip boot ROM does serial boot at 0x380000f0.
77 ;; That is not where we put our downloaded serial boot-code.
78 ;; The length is enough for downloading code that loads the rest
79 ;; of itself (after having setup the DRAM etc).
80 ;; It is the same length as the on-chip ROM loads, so the same
81 ;; host loader can be used to load a rescued product as well as
82 ;; one booted through the Etrax serial boot code.
83
84#define CODE_START 0x40000000
85#define CODE_LENGTH 784
86
87#ifdef CONFIG_ETRAX_RESCUE_SER0
88#define SERXOFF R_SERIAL0_XOFF
89#define SERBAUD R_SERIAL0_BAUD
90#define SERRECC R_SERIAL0_REC_CTRL
91#define SERRDAT R_SERIAL0_REC_DATA
92#define SERSTAT R_SERIAL0_STATUS
93#endif
94#ifdef CONFIG_ETRAX_RESCUE_SER1
95#define SERXOFF R_SERIAL1_XOFF
96#define SERBAUD R_SERIAL1_BAUD
97#define SERRECC R_SERIAL1_REC_CTRL
98#define SERRDAT R_SERIAL1_REC_DATA
99#define SERSTAT R_SERIAL1_STATUS
100#endif
101#ifdef CONFIG_ETRAX_RESCUE_SER2
102#define SERXOFF R_SERIAL2_XOFF
103#define SERBAUD R_SERIAL2_BAUD
104#define SERRECC R_SERIAL2_REC_CTRL
105#define SERRDAT R_SERIAL2_REC_DATA
106#define SERSTAT R_SERIAL2_STATUS
107#endif
108#ifdef CONFIG_ETRAX_RESCUE_SER3
109#define SERXOFF R_SERIAL3_XOFF
110#define SERBAUD R_SERIAL3_BAUD
111#define SERRECC R_SERIAL3_REC_CTRL
112#define SERRDAT R_SERIAL3_REC_DATA
113#define SERSTAT R_SERIAL3_STATUS
114#endif
115
116#define NOP_DI 0xf025050f
117#define RAM_INIT_MAGIC 0x56902387
118
119 .text
120
121 ;; This is the entry point of the rescue code
122 ;; 0x80000000 if loaded in flash (as it should be)
123 ;; Since etrax actually starts at address 2 when booting from flash, we
124 ;; put a nop (2 bytes) here first so we dont accidentally skip the di
125
126 nop
127 di
128
129 jump in_cache ; enter cached area instead
130in_cache:
131
132
133 ;; First put a jump test to give a possibility of upgrading the
134 ;; rescue code without erasing/reflashing the sector.
135 ;; We put a longword of -1 here and if it is not -1, we jump using
136 ;; the value as jump target. Since we can always change 1's to 0's
137 ;; without erasing the sector, it is possible to add new
138 ;; code after this and altering the jumptarget in an upgrade.
139
140jtcd: move.d [jumptarget], $r0
141 cmp.d 0xffffffff, $r0
142 beq no_newjump
143 nop
144
145 jump [$r0]
146
147jumptarget:
148 .dword 0xffffffff ; can be overwritten later to insert new code
149
150no_newjump:
151#ifdef CONFIG_ETRAX_ETHERNET
152 ;; Start MII clock to make sure it is running when tranceiver is reset
153 move.d 0x3, $r0 ; enable = on, phy = mii_clk
154 move.d $r0, [R_NETWORK_GEN_CONFIG]
155#endif
156
157 ;; We need to setup the bus registers before we start using the DRAM
158#include "../../../arch-v10/lib/dram_init.S"
159
160 ;; we now should go through the checksum-table and check the listed
161 ;; partitions for errors.
162
163 move.d PTABLE_START, $r3
164 move.d [$r3], $r0
165 cmp.d NOP_DI, $r0 ; make sure the nop/di is there...
166 bne do_rescue
167 nop
168
169 ;; skip the code transparency block (10 bytes).
170
171 addq 10, $r3
172
173 ;; check for correct magic
174
175 move.w [$r3+], $r0
176 cmp.w PTABLE_MAGIC, $r0
177 bne do_rescue ; didn't recognize - trig rescue
178 nop
179
180 ;; check for correct ptable checksum
181
182 movu.w [$r3+], $r2 ; ptable length
183 move.d $r2, $r8 ; save for later, length of total ptable
184 addq 28, $r8 ; account for the rest
185 move.d [$r3+], $r4 ; ptable checksum
186 move.d $r3, $r1
187 jsr checksum ; r1 source, r2 length, returns in r0
188
189 cmp.d $r0, $r4
190 bne do_rescue ; didn't match - trig rescue
191 nop
192
193 ;; ptable is ok. validate each entry.
194
195 moveq -1, $r7
196
197ploop: move.d [$r3+], $r1 ; partition offset (from ptable start)
198 bne notfirst ; check if it is the partition containing ptable
199 nop ; yes..
200 move.d $r8, $r1 ; for its checksum check, skip the ptable
201 move.d [$r3+], $r2 ; partition length
202 sub.d $r8, $r2 ; minus the ptable length
203 ba bosse
204 nop
205notfirst:
206 cmp.d -1, $r1 ; the end of the ptable ?
207 beq flash_ok ; if so, the flash is validated
208 move.d [$r3+], $r2 ; partition length
209bosse: move.d [$r3+], $r5 ; checksum
210 move.d [$r3+], $r4 ; type and flags
211 addq 16, $r3 ; skip the reserved bytes
212 btstq 16, $r4 ; check ro flag
213 bpl ploop ; rw partition, skip validation
214 nop
215 btstq 17, $r4 ; check bootable flag
216 bpl 1f
217 nop
218 move.d $r1, $r7 ; remember boot partition offset
2191:
220 add.d PTABLE_START, $r1
221
222 jsr checksum ; checksum the partition
223
224 cmp.d $r0, $r5
225 beq ploop ; checksums matched, go to next entry
226 nop
227
228 ;; otherwise fall through to the rescue code.
229
230do_rescue:
231 ;; setup port PA and PB default initial directions and data
232 ;; (so we can flash LEDs, and so that DTR and others are set)
233
234 move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
235 move.b $r0, [R_PORT_PA_DIR]
236 move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
237 move.b $r0, [R_PORT_PA_DATA]
238
239 move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
240 move.b $r0, [R_PORT_PB_DIR]
241 move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
242 move.b $r0, [R_PORT_PB_DATA]
243
244 ;; setup the serial port at 115200 baud
245
246 moveq 0, $r0
247 move.d $r0, [SERXOFF]
248
249 move.b 0x99, $r0
250 move.b $r0, [SERBAUD] ; 115.2kbaud for both transmit and receive
251
252 move.b 0x40, $r0 ; rec enable
253 move.b $r0, [SERRECC]
254
255 moveq 0, $r1 ; "timer" to clock out a LED red flash
256 move.d CODE_START, $r3 ; destination counter
257 movu.w CODE_LENGTH, $r4; length
258
259wait_ser:
260 addq 1, $r1
261#ifndef CONFIG_ETRAX_NO_LEDS
262#ifdef CONFIG_ETRAX_PA_LEDS
263 move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r2
264#endif
265#ifdef CONFIG_ETRAX_PB_LEDS
266 move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r2
267#endif
268 move.d (1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), $r0
269 btstq 16, $r1
270 bpl 1f
271 nop
272 or.d $r0, $r2 ; set bit
273 ba 2f
274 nop
2751: not $r0 ; clear bit
276 and.d $r0, $r2
2772:
278#ifdef CONFIG_ETRAX_PA_LEDS
279 move.b $r2, [R_PORT_PA_DATA]
280#endif
281#ifdef CONFIG_ETRAX_PB_LEDS
282 move.b $r2, [R_PORT_PB_DATA]
283#endif
284#ifdef CONFIG_ETRAX_90000000_LEDS
285 move.b $r2, [0x90000000]
286#endif
287#endif
288
289 ;; check if we got something on the serial port
290
291 move.b [SERSTAT], $r0
292 btstq 0, $r0 ; data_avail
293 bpl wait_ser
294 nop
295
296 ;; got something - copy the byte and loop
297
298 move.b [SERRDAT], $r0
299 move.b $r0, [$r3+]
300
301 subq 1, $r4 ; decrease length
302 bne wait_ser
303 nop
304
305 ;; jump into downloaded code
306
307 move.d RAM_INIT_MAGIC, $r8 ; Tell next product that DRAM is
308 ; initialized
309 jump CODE_START
310
311flash_ok:
312 ;; check r7, which contains either -1 or the partition to boot from
313
314 cmp.d -1, $r7
315 bne 1f
316 nop
317 move.d PTABLE_START, $r7; otherwise use the ptable start
3181:
319 move.d RAM_INIT_MAGIC, $r8 ; Tell next product that DRAM is
320 ; initialized
321 jump $r7 ; boot!
322
323
324 ;; Helper subroutines
325
326 ;; Will checksum by simple addition
327 ;; r1 - source
328 ;; r2 - length in bytes
329 ;; result will be in r0
330checksum:
331 moveq 0, $r0
332 moveq CONFIG_ETRAX_FLASH1_SIZE, $r6
333
334 ;; If the first physical flash memory is exceeded wrap to the
335 ;; second one
336 btstq 26, $r1 ; Are we addressing first flash?
337 bpl 1f
338 nop
339 clear.d $r6
340
3411: test.d $r6 ; 0 = no wrapping
342 beq 2f
343 nop
344 lslq 20, $r6 ; Convert MB to bytes
345 sub.d $r1, $r6
346
3472: addu.b [$r1+], $r0
348 subq 1, $r6 ; Flash memory left
349 beq 3f
350 subq 1, $r2 ; Length left
351 bne 2b
352 nop
353 ret
354 nop
355
3563: move.d MEM_CSE1_START, $r1 ; wrap to second flash
357 ba 2b
358 nop
359
360#endif
diff --git a/arch/cris/boot/rescue/head_v32.S b/arch/cris/boot/rescue/head_v32.S
new file mode 100644
index 000000000000..5f846b7700a3
--- /dev/null
+++ b/arch/cris/boot/rescue/head_v32.S
@@ -0,0 +1,26 @@
1/*
2 * Just get started by jumping to CONFIG_ETRAX_PTABLE_SECTOR to start
3 * kernel decompressor.
4 *
5 * In practice, this only works for NOR flash (or some convoluted RAM boot)
6 * and hence is not really useful for Artpec-3, so it's Etrax FS / NOR only.
7 *
8 */
9
10#include <mach/startup.inc>
11
12#ifdef CONFIG_ETRAX_AXISFLASHMAP
13
14;; Code
15
16 .text
17start:
18
19 ;; Start clocks for used blocks.
20 START_CLOCKS
21
22 move.d CONFIG_ETRAX_PTABLE_SECTOR, $r10
23 jump $r10 ; Jump to decompressor
24 nop
25
26#endif
diff --git a/arch/cris/boot/rescue/kimagerescue.S b/arch/cris/boot/rescue/kimagerescue.S
new file mode 100644
index 000000000000..6f7b3e61260b
--- /dev/null
+++ b/arch/cris/boot/rescue/kimagerescue.S
@@ -0,0 +1,143 @@
1/*
2 * Rescue code to be prepended on a kimage and copied to the
3 * rescue serial port.
4 * This is called from the rescue code, it will copy received data to
5 * 4004000 and after a timeout jump to it.
6 */
7
8#define ASSEMBLER_MACROS_ONLY
9#include <arch/sv_addr_ag.h>
10
11#define CODE_START 0x40004000
12#define CODE_LENGTH 784
13#define TIMEOUT_VALUE 1000
14
15
16#ifdef CONFIG_ETRAX_RESCUE_SER0
17#define SERXOFF R_SERIAL0_XOFF
18#define SERBAUD R_SERIAL0_BAUD
19#define SERRECC R_SERIAL0_REC_CTRL
20#define SERRDAT R_SERIAL0_REC_DATA
21#define SERSTAT R_SERIAL0_STATUS
22#endif
23#ifdef CONFIG_ETRAX_RESCUE_SER1
24#define SERXOFF R_SERIAL1_XOFF
25#define SERBAUD R_SERIAL1_BAUD
26#define SERRECC R_SERIAL1_REC_CTRL
27#define SERRDAT R_SERIAL1_REC_DATA
28#define SERSTAT R_SERIAL1_STATUS
29#endif
30#ifdef CONFIG_ETRAX_RESCUE_SER2
31#define SERXOFF R_SERIAL2_XOFF
32#define SERBAUD R_SERIAL2_BAUD
33#define SERRECC R_SERIAL2_REC_CTRL
34#define SERRDAT R_SERIAL2_REC_DATA
35#define SERSTAT R_SERIAL2_STATUS
36#endif
37#ifdef CONFIG_ETRAX_RESCUE_SER3
38#define SERXOFF R_SERIAL3_XOFF
39#define SERBAUD R_SERIAL3_BAUD
40#define SERRECC R_SERIAL3_REC_CTRL
41#define SERRDAT R_SERIAL3_REC_DATA
42#define SERSTAT R_SERIAL3_STATUS
43#endif
44
45 .text
46 ;; This is the entry point of the rescue code
47 ;; 0x80000000 if loaded in flash (as it should be)
48 ;; since etrax actually starts at address 2 when booting from flash, we
49 ;; put a nop (2 bytes) here first so we dont accidentally skip the di
50
51 nop
52 di
53#ifndef CONFIG_SVINTO_SIM
54 ;; setup port PA and PB default initial directions and data
55 ;; (so we can flash LEDs, and so that DTR and others are set)
56
57 move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
58 move.b $r0, [R_PORT_PA_DIR]
59 move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
60 move.b $r0, [R_PORT_PA_DATA]
61
62 move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
63 move.b $r0, [R_PORT_PB_DIR]
64 move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
65 move.b $r0, [R_PORT_PB_DATA]
66
67 ;; We need to setup the bus registers before we start using the DRAM
68#include "../../lib/dram_init.S"
69
70#endif
71 ;; Setup the stack to a suitably high address.
72 ;; We assume 8 MB is the minimum DRAM in an eLinux
73 ;; product and put the sp at the top for now.
74
75 move.d 0x40800000, $sp
76
77 ;; setup the serial port at 115200 baud
78
79 moveq 0, $r0
80 move.d $r0, [SERXOFF]
81
82 move.b 0x99, $r0
83 move.b $r0, [SERBAUD] ; 115.2kbaud for both transmit
84 ; and receive
85
86 move.b 0x40, $r0 ; rec enable
87 move.b $r0, [SERRECC]
88
89
90 moveq 0, $r1 ; "timer" to clock out a LED red flash
91 move.d CODE_START, $r3 ; destination counter
92 move.d CODE_LENGTH, $r4 ; length
93 move.d TIMEOUT_VALUE, $r5 ; "timeout" until jump
94
95wait_ser:
96 addq 1, $r1
97 subq 1, $r5 ; decrease timeout
98 beq jump_start ; timed out
99 nop
100#ifndef CONFIG_ETRAX_NO_LEDS
101#ifdef CONFIG_ETRAX_PA_LEDS
102 move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r2
103#endif
104#ifdef CONFIG_ETRAX_PB_LEDS
105 move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r2
106#endif
107 move.d (1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), $r0
108 btstq 16, $r1
109 bpl 1f
110 nop
111 or.d $r0, $r2 ; set bit
112 ba 2f
113 nop
1141: not $r0 ; clear bit
115 and.d $r0, $r2
1162:
117#ifdef CONFIG_ETRAX_PA_LEDS
118 move.b $r2, [R_PORT_PA_DATA]
119#endif
120#ifdef CONFIG_ETRAX_PB_LEDS
121 move.b $r2, [R_PORT_PB_DATA]
122#endif
123#endif
124
125 ;; check if we got something on the serial port
126
127 move.b [SERSTAT], $r0
128 btstq 0, $r0 ; data_avail
129 bpl wait_ser
130 nop
131
132 ;; got something - copy the byte and loop
133
134 move.b [SERRDAT], $r0
135 move.b $r0, [$r3+]
136 move.d TIMEOUT_VALUE, $r5 ; reset "timeout"
137 subq 1, $r4 ; decrease length
138 bne wait_ser
139 nop
140jump_start:
141 ;; jump into downloaded code
142
143 jump CODE_START
diff --git a/arch/cris/boot/rescue/rescue_v10.lds b/arch/cris/boot/rescue/rescue_v10.lds
new file mode 100644
index 000000000000..0b52a9490db6
--- /dev/null
+++ b/arch/cris/boot/rescue/rescue_v10.lds
@@ -0,0 +1,20 @@
1MEMORY
2 {
3 flash : ORIGIN = 0x00000000,
4 LENGTH = 0x00100000
5 }
6
7SECTIONS
8{
9 .text :
10 {
11 stext = . ;
12 *(.text)
13 etext = . ;
14 } > flash
15 .data :
16 {
17 *(.data)
18 edata = . ;
19 } > flash
20}
diff --git a/arch/cris/boot/rescue/rescue_v32.lds b/arch/cris/boot/rescue/rescue_v32.lds
new file mode 100644
index 000000000000..8ac646bc1a2b
--- /dev/null
+++ b/arch/cris/boot/rescue/rescue_v32.lds
@@ -0,0 +1,43 @@
1/*#OUTPUT_FORMAT(elf32-us-cris) */
2OUTPUT_ARCH (crisv32)
3/* Now that NAND support has been stripped, this file could be simplified,
4 * but it doesn't do any harm on the other hand so why bother. */
5
6MEMORY
7 {
8 bootblk : ORIGIN = 0x38000000,
9 LENGTH = 0x00004000
10 intmem : ORIGIN = 0x38004000,
11 LENGTH = 0x00005000
12 }
13
14SECTIONS
15{
16 .text :
17 {
18 _stext = . ;
19 *(.text)
20 *(.init.text)
21 *(.rodata)
22 *(.rodata.*)
23 _etext = . ;
24 } > bootblk
25 .data :
26 {
27 *(.data)
28 _edata = . ;
29 } > bootblk
30 .bss :
31 {
32 _bss = . ;
33 *(.bss)
34 _end = ALIGN( 0x10 ) ;
35 } > intmem
36
37 /* Get rid of stuff from EXPORT_SYMBOL(foo). */
38 /DISCARD/ :
39 {
40 *(__ksymtab_strings)
41 *(__ksymtab)
42 }
43}
diff --git a/arch/cris/boot/rescue/testrescue.S b/arch/cris/boot/rescue/testrescue.S
new file mode 100644
index 000000000000..fc7ec674eca5
--- /dev/null
+++ b/arch/cris/boot/rescue/testrescue.S
@@ -0,0 +1,24 @@
1/*
2 * Simple testcode to download by the rescue block.
3 * Just lights some LEDs to show it was downloaded correctly.
4 *
5 * Copyright (C) 1999 Axis Communications AB
6 */
7
8#define ASSEMBLER_MACROS_ONLY
9#include <arch/sv_addr_ag.h>
10
11 .text
12
13 nop
14 nop
15 moveq -1, $r2
16 move.b $r2, [R_PORT_PA_DIR]
17 moveq 0, $r2
18 move.b $r2, [R_PORT_PA_DATA]
19
20endless:
21 nop
22 ba endless
23 nop
24
diff --git a/arch/cris/boot/tools/build.c b/arch/cris/boot/tools/build.c
new file mode 100644
index 000000000000..c8adef364160
--- /dev/null
+++ b/arch/cris/boot/tools/build.c
@@ -0,0 +1,287 @@
1/*
2 * linux/tools/build.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
6
7/*
8 * This file builds a disk-image from three different files:
9 *
10 * - bootsect: exactly 512 bytes of 8086 machine code, loads the rest
11 * - setup: 8086 machine code, sets up system parm
12 * - system: 80386 code for actual system
13 *
14 * It does some checking that all files are of the correct type, and
15 * just writes the result to stdout, removing headers and padding to
16 * the right amount. It also writes some system data to stderr.
17 */
18
19/*
20 * Changes by tytso to allow root device specification
21 * High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
22 * Cross compiling fixes by Gertjan van Wingerde, July 1996
23 */
24
25#include <stdio.h> /* fprintf */
26#include <string.h>
27#include <stdlib.h> /* contains exit */
28#include <sys/types.h> /* unistd.h needs this */
29#include <sys/stat.h>
30#include <sys/sysmacros.h>
31#include <unistd.h> /* contains read/write */
32#include <fcntl.h>
33#include <errno.h>
34
35#define MINIX_HEADER 32
36
37#define N_MAGIC_OFFSET 1024
38#ifndef __BFD__
39static int GCC_HEADER = sizeof(struct exec);
40#endif
41
42#ifdef __BIG_KERNEL__
43#define SYS_SIZE 0xffff
44#else
45#define SYS_SIZE DEF_SYSSIZE
46#endif
47
48#define DEFAULT_MAJOR_ROOT 0
49#define DEFAULT_MINOR_ROOT 0
50
51/* max nr of sectors of setup: don't change unless you also change
52 * bootsect etc */
53#define SETUP_SECTS 4
54
55#define STRINGIFY(x) #x
56
57typedef union {
58 int i;
59 long l;
60 short s[2];
61 char b[4];
62} conv;
63
64long intel_long(long l)
65{
66 conv t;
67
68 t.b[0] = l & 0xff; l >>= 8;
69 t.b[1] = l & 0xff; l >>= 8;
70 t.b[2] = l & 0xff; l >>= 8;
71 t.b[3] = l & 0xff; l >>= 8;
72 return t.l;
73}
74
75int intel_int(int i)
76{
77 conv t;
78
79 t.b[0] = i & 0xff; i >>= 8;
80 t.b[1] = i & 0xff; i >>= 8;
81 t.b[2] = i & 0xff; i >>= 8;
82 t.b[3] = i & 0xff; i >>= 8;
83 return t.i;
84}
85
86short intel_short(short l)
87{
88 conv t;
89
90 t.b[0] = l & 0xff; l >>= 8;
91 t.b[1] = l & 0xff; l >>= 8;
92 return t.s[0];
93}
94
95void die(const char * str)
96{
97 fprintf(stderr,"%s\n",str);
98 exit(1);
99}
100
101void usage(void)
102{
103 die("Usage: build bootsect setup system [rootdev] [> image]");
104}
105
106int main(int argc, char ** argv)
107{
108 int i,c,id,sz,tmp_int;
109 unsigned long sys_size, tmp_long;
110 char buf[1024];
111#ifndef __BFD__
112 struct exec *ex = (struct exec *)buf;
113#endif
114 char major_root, minor_root;
115 struct stat sb;
116 unsigned char setup_sectors;
117
118 if ((argc < 4) || (argc > 5))
119 usage();
120 if (argc > 4) {
121 if (!strcmp(argv[4], "CURRENT")) {
122 if (stat("/", &sb)) {
123 perror("/");
124 die("Couldn't stat /");
125 }
126 major_root = major(sb.st_dev);
127 minor_root = minor(sb.st_dev);
128 } else if (strcmp(argv[4], "FLOPPY")) {
129 if (stat(argv[4], &sb)) {
130 perror(argv[4]);
131 die("Couldn't stat root device.");
132 }
133 major_root = major(sb.st_rdev);
134 minor_root = minor(sb.st_rdev);
135 } else {
136 major_root = 0;
137 minor_root = 0;
138 }
139 } else {
140 major_root = DEFAULT_MAJOR_ROOT;
141 minor_root = DEFAULT_MINOR_ROOT;
142 }
143 fprintf(stderr, "Root device is (%d, %d)\n", major_root, minor_root);
144 for (i=0;i<sizeof buf; i++) buf[i]=0;
145 if ((id=open(argv[1],O_RDONLY,0))<0)
146 die("Unable to open 'boot'");
147 if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
148 die("Unable to read header of 'boot'");
149 if (((long *) buf)[0]!=intel_long(0x04100301))
150 die("Non-Minix header of 'boot'");
151 if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
152 die("Non-Minix header of 'boot'");
153 if (((long *) buf)[3] != 0)
154 die("Illegal data segment in 'boot'");
155 if (((long *) buf)[4] != 0)
156 die("Illegal bss in 'boot'");
157 if (((long *) buf)[5] != 0)
158 die("Non-Minix header of 'boot'");
159 if (((long *) buf)[7] != 0)
160 die("Illegal symbol table in 'boot'");
161 i=read(id,buf,sizeof buf);
162 fprintf(stderr,"Boot sector %d bytes.\n",i);
163 if (i != 512)
164 die("Boot block must be exactly 512 bytes");
165 if ((*(unsigned short *)(buf+510)) != (unsigned short)intel_short(0xAA55))
166 die("Boot block hasn't got boot flag (0xAA55)");
167 buf[508] = (char) minor_root;
168 buf[509] = (char) major_root;
169 i=write(1,buf,512);
170 if (i!=512)
171 die("Write call failed");
172 close (id);
173
174 if ((id=open(argv[2],O_RDONLY,0))<0)
175 die("Unable to open 'setup'");
176 if (read(id,buf,MINIX_HEADER) != MINIX_HEADER)
177 die("Unable to read header of 'setup'");
178 if (((long *) buf)[0]!=intel_long(0x04100301))
179 die("Non-Minix header of 'setup'");
180 if (((long *) buf)[1]!=intel_long(MINIX_HEADER))
181 die("Non-Minix header of 'setup'");
182 if (((long *) buf)[3] != 0)
183 die("Illegal data segment in 'setup'");
184 if (((long *) buf)[4] != 0)
185 die("Illegal bss in 'setup'");
186 if (((long *) buf)[5] != 0)
187 die("Non-Minix header of 'setup'");
188 if (((long *) buf)[7] != 0)
189 die("Illegal symbol table in 'setup'");
190 for (i=0 ; (c=read(id,buf,sizeof buf))>0 ; i+=c )
191#ifdef __BIG_KERNEL__
192 {
193 if (!i) {
194 /* Working with memcpy because of alignment constraints
195 on Sparc - Gertjan */
196 memcpy(&tmp_long, &buf[2], sizeof(long));
197 if (tmp_long != intel_long(0x53726448) )
198 die("Wrong magic in loader header of 'setup'");
199 memcpy(&tmp_int, &buf[6], sizeof(int));
200 if (tmp_int < intel_int(0x200))
201 die("Wrong version of loader header of 'setup'");
202 buf[0x11] = 1; /* LOADED_HIGH */
203 tmp_long = intel_long(0x100000);
204 memcpy(&buf[0x14], &tmp_long, sizeof(long)); /* code32_start */
205 }
206#endif
207 if (write(1,buf,c)!=c)
208 die("Write call failed");
209#ifdef __BIG_KERNEL__
210 }
211#endif
212 if (c != 0)
213 die("read-error on 'setup'");
214 close (id);
215 setup_sectors = (unsigned char)((i + 511) / 512);
216 /* for compatibility with LILO */
217 if (setup_sectors < SETUP_SECTS)
218 setup_sectors = SETUP_SECTS;
219 fprintf(stderr,"Setup is %d bytes.\n",i);
220 for (c=0 ; c<sizeof(buf) ; c++)
221 buf[c] = '\0';
222 while (i < setup_sectors * 512) {
223 c = setup_sectors * 512 - i;
224 if (c > sizeof(buf))
225 c = sizeof(buf);
226 if (write(1,buf,c) != c)
227 die("Write call failed");
228 i += c;
229 }
230
231 if ((id=open(argv[3],O_RDONLY,0))<0)
232 die("Unable to open 'system'");
233#ifndef __BFD__
234 if (read(id,buf,GCC_HEADER) != GCC_HEADER)
235 die("Unable to read header of 'system'");
236 if (N_MAGIC(*ex) == ZMAGIC) {
237 GCC_HEADER = N_MAGIC_OFFSET;
238 lseek(id, GCC_HEADER, SEEK_SET);
239 } else if (N_MAGIC(*ex) != QMAGIC)
240 die("Non-GCC header of 'system'");
241 fprintf(stderr,"System is %d kB (%d kB code, %d kB data and %d kB bss)\n",
242 (ex->a_text+ex->a_data+ex->a_bss)/1024,
243 ex->a_text /1024,
244 ex->a_data /1024,
245 ex->a_bss /1024);
246 sz = N_SYMOFF(*ex) - GCC_HEADER + 4;
247#else
248 if (fstat (id, &sb)) {
249 perror ("fstat");
250 die ("Unable to stat 'system'");
251 }
252 sz = sb.st_size;
253 fprintf (stderr, "System is %d kB\n", sz/1024);
254#endif
255 sys_size = (sz + 15) / 16;
256 if (sys_size > SYS_SIZE)
257 die("System is too big");
258 while (sz > 0) {
259 int l, n;
260
261 l = sz;
262 if (l > sizeof(buf))
263 l = sizeof(buf);
264 if ((n=read(id, buf, l)) != l) {
265 if (n == -1)
266 perror(argv[1]);
267 else
268 fprintf(stderr, "Unexpected EOF\n");
269 die("Can't read 'system'");
270 }
271 if (write(1, buf, l) != l)
272 die("Write failed");
273 sz -= l;
274 }
275 close(id);
276 if (lseek(1, 497, 0) == 497) {
277 if (write(1, &setup_sectors, 1) != 1)
278 die("Write of setup sectors failed");
279 }
280 if (lseek(1,500,0) == 500) {
281 buf[0] = (sys_size & 0xff);
282 buf[1] = ((sys_size >> 8) & 0xff);
283 if (write(1, buf, 2) != 2)
284 die("Write failed");
285 }
286 return(0);
287}