blob: 6f7b3e61260bea02079919f2ea2bf32131ab176a [file] [log] [blame]
Jesper Nilssonef8028a2008-01-17 11:30:21 +01001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 * 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
Linus Torvalds1da177e2005-04-16 15:20:36 -07008#define ASSEMBLER_MACROS_ONLY
Jesper Nilsson556dcee2008-10-21 17:45:58 +02009#include <arch/sv_addr_ag.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070010
11#define CODE_START 0x40004000
12#define CODE_LENGTH 784
13#define TIMEOUT_VALUE 1000
Jesper Nilssonef8028a2008-01-17 11:30:21 +010014
15
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#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
Jesper Nilssonef8028a2008-01-17 11:30:21 +010036#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070037#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
Jesper Nilssonef8028a2008-01-17 11:30:21 +010050
51 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -070052 di
Jesper Nilssonef8028a2008-01-17 11:30:21 +010053#ifndef CONFIG_SVINTO_SIM
Linus Torvalds1da177e2005-04-16 15:20:36 -070054 ;; setup port PA and PB default initial directions and data
55 ;; (so we can flash LEDs, and so that DTR and others are set)
Jesper Nilssonef8028a2008-01-17 11:30:21 +010056
Linus Torvalds1da177e2005-04-16 15:20:36 -070057 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]
Jesper Nilssonef8028a2008-01-17 11:30:21 +010061
Linus Torvalds1da177e2005-04-16 15:20:36 -070062 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]
Jesper Nilssonef8028a2008-01-17 11:30:21 +010066
Linus Torvalds1da177e2005-04-16 15:20:36 -070067 ;; We need to setup the bus registers before we start using the DRAM
68#include "../../lib/dram_init.S"
Jesper Nilssonef8028a2008-01-17 11:30:21 +010069
Linus Torvalds1da177e2005-04-16 15:20:36 -070070#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
Jesper Nilssonef8028a2008-01-17 11:30:21 +010076
Linus Torvalds1da177e2005-04-16 15:20:36 -070077 ;; setup the serial port at 115200 baud
Jesper Nilssonef8028a2008-01-17 11:30:21 +010078
Linus Torvalds1da177e2005-04-16 15:20:36 -070079 moveq 0, $r0
Jesper Nilssonef8028a2008-01-17 11:30:21 +010080 move.d $r0, [SERXOFF]
Linus Torvalds1da177e2005-04-16 15:20:36 -070081
82 move.b 0x99, $r0
Jesper Nilssonef8028a2008-01-17 11:30:21 +010083 move.b $r0, [SERBAUD] ; 115.2kbaud for both transmit
84 ; and receive
Linus Torvalds1da177e2005-04-16 15:20:36 -070085
86 move.b 0x40, $r0 ; rec enable
Jesper Nilssonef8028a2008-01-17 11:30:21 +010087 move.b $r0, [SERRECC]
Linus Torvalds1da177e2005-04-16 15:20:36 -070088
89
Jesper Nilssonef8028a2008-01-17 11:30:21 +010090 moveq 0, $r1 ; "timer" to clock out a LED red flash
91 move.d CODE_START, $r3 ; destination counter
Linus Torvalds1da177e2005-04-16 15:20:36 -070092 move.d CODE_LENGTH, $r4 ; length
93 move.d TIMEOUT_VALUE, $r5 ; "timeout" until jump
94
95wait_ser:
96 addq 1, $r1
Jesper Nilssonef8028a2008-01-17 11:30:21 +010097 subq 1, $r5 ; decrease timeout
98 beq jump_start ; timed out
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 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
Jesper Nilssonef8028a2008-01-17 11:30:21 +01001141: not $r0 ; clear bit
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115 and.d $r0, $r2
Jesper Nilssonef8028a2008-01-17 11:30:21 +01001162:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117#ifdef CONFIG_ETRAX_PA_LEDS
118 move.b $r2, [R_PORT_PA_DATA]
Jesper Nilssonef8028a2008-01-17 11:30:21 +0100119#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120#ifdef CONFIG_ETRAX_PB_LEDS
121 move.b $r2, [R_PORT_PB_DATA]
122#endif
123#endif
Jesper Nilssonef8028a2008-01-17 11:30:21 +0100124
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 ;; check if we got something on the serial port
Jesper Nilssonef8028a2008-01-17 11:30:21 +0100126
Linus Torvalds1da177e2005-04-16 15:20:36 -0700127 move.b [SERSTAT], $r0
Jesper Nilssonef8028a2008-01-17 11:30:21 +0100128 btstq 0, $r0 ; data_avail
Linus Torvalds1da177e2005-04-16 15:20:36 -0700129 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"
Jesper Nilssonef8028a2008-01-17 11:30:21 +0100137 subq 1, $r4 ; decrease length
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138 bne wait_ser
139 nop
140jump_start:
141 ;; jump into downloaded code
142
143 jump CODE_START