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	;; setup port PA and PB default initial directions and data
54	;; (so we can flash LEDs, and so that DTR and others are set)
55
56	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
57	move.b	$r0, [R_PORT_PA_DIR]
58	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
59	move.b	$r0, [R_PORT_PA_DATA]
60
61	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
62	move.b	$r0, [R_PORT_PB_DIR]
63	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
64	move.b	$r0, [R_PORT_PB_DATA]
65
66	;; We need to setup the bus registers before we start using the DRAM
67#include "../../lib/dram_init.S"
68
69	;; Setup the stack to a suitably high address.
70	;; We assume 8 MB is the minimum DRAM in an eLinux
71	;; product and put the sp at the top for now.
72
73	move.d	0x40800000, $sp
74
75	;; setup the serial port at 115200 baud
76
77	moveq	0, $r0
78	move.d	$r0, [SERXOFF]
79
80	move.b	0x99, $r0
81	move.b	$r0, [SERBAUD]		; 115.2kbaud for both transmit
82					; and receive
83
84	move.b	0x40, $r0		; rec enable
85	move.b	$r0, [SERRECC]
86
87
88	moveq	0, $r1			; "timer" to clock out a LED red flash
89	move.d	CODE_START, $r3		; destination counter
90	move.d	CODE_LENGTH, $r4	; length
91	move.d	TIMEOUT_VALUE, $r5	; "timeout" until jump
92
93wait_ser:
94	addq	1, $r1
95	subq	1, $r5			; decrease timeout
96	beq	jump_start		; timed out
97	nop
98#ifndef CONFIG_ETRAX_NO_LEDS
99#ifdef CONFIG_ETRAX_PA_LEDS
100	move.b	CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r2
101#endif
102#ifdef CONFIG_ETRAX_PB_LEDS
103	move.b	CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r2
104#endif
105	move.d	(1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), $r0
106	btstq	16, $r1
107	bpl	1f
108	nop
109	or.d	$r0, $r2		; set bit
110	ba	2f
111	nop
1121:	not	$r0			; clear bit
113	and.d	$r0, $r2
1142:
115#ifdef CONFIG_ETRAX_PA_LEDS
116	move.b	$r2, [R_PORT_PA_DATA]
117#endif
118#ifdef CONFIG_ETRAX_PB_LEDS
119	move.b	$r2, [R_PORT_PB_DATA]
120#endif
121#endif
122
123	;; check if we got something on the serial port
124
125	move.b	[SERSTAT], $r0
126	btstq	0, $r0			; data_avail
127	bpl	wait_ser
128	nop
129
130	;; got something - copy the byte and loop
131
132	move.b	[SERRDAT], $r0
133	move.b	$r0, [$r3+]
134	move.d	TIMEOUT_VALUE, $r5	; reset "timeout"
135	subq	1, $r4			; decrease length
136	bne	wait_ser
137	nop
138jump_start:
139	;; jump into downloaded code
140
141	jump	CODE_START
142