Commit | Line | Data |
---|---|---|
ef8028a7 | 1 | /* |
1da177e4 LT |
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 | ||
1da177e4 | 8 | #define ASSEMBLER_MACROS_ONLY |
556dcee7 | 9 | #include <arch/sv_addr_ag.h> |
1da177e4 LT |
10 | |
11 | #define CODE_START 0x40004000 | |
12 | #define CODE_LENGTH 784 | |
13 | #define TIMEOUT_VALUE 1000 | |
ef8028a7 JN |
14 | |
15 | ||
1da177e4 LT |
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 | |
ef8028a7 | 36 | #endif |
1da177e4 LT |
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 | |
ef8028a7 JN |
50 | |
51 | nop | |
1da177e4 | 52 | di |
1da177e4 LT |
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) | |
ef8028a7 | 55 | |
1da177e4 LT |
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] | |
ef8028a7 | 60 | |
1da177e4 LT |
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] | |
ef8028a7 | 65 | |
1da177e4 LT |
66 | ;; We need to setup the bus registers before we start using the DRAM |
67 | #include "../../lib/dram_init.S" | |
ef8028a7 | 68 | |
1da177e4 LT |
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 | |
ef8028a7 | 74 | |
1da177e4 | 75 | ;; setup the serial port at 115200 baud |
ef8028a7 | 76 | |
1da177e4 | 77 | moveq 0, $r0 |
ef8028a7 | 78 | move.d $r0, [SERXOFF] |
1da177e4 LT |
79 | |
80 | move.b 0x99, $r0 | |
ef8028a7 JN |
81 | move.b $r0, [SERBAUD] ; 115.2kbaud for both transmit |
82 | ; and receive | |
1da177e4 LT |
83 | |
84 | move.b 0x40, $r0 ; rec enable | |
ef8028a7 | 85 | move.b $r0, [SERRECC] |
1da177e4 LT |
86 | |
87 | ||
ef8028a7 JN |
88 | moveq 0, $r1 ; "timer" to clock out a LED red flash |
89 | move.d CODE_START, $r3 ; destination counter | |
1da177e4 LT |
90 | move.d CODE_LENGTH, $r4 ; length |
91 | move.d TIMEOUT_VALUE, $r5 ; "timeout" until jump | |
92 | ||
93 | wait_ser: | |
94 | addq 1, $r1 | |
ef8028a7 JN |
95 | subq 1, $r5 ; decrease timeout |
96 | beq jump_start ; timed out | |
1da177e4 LT |
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 | |
ef8028a7 | 112 | 1: not $r0 ; clear bit |
1da177e4 | 113 | and.d $r0, $r2 |
ef8028a7 | 114 | 2: |
1da177e4 LT |
115 | #ifdef CONFIG_ETRAX_PA_LEDS |
116 | move.b $r2, [R_PORT_PA_DATA] | |
ef8028a7 | 117 | #endif |
1da177e4 LT |
118 | #ifdef CONFIG_ETRAX_PB_LEDS |
119 | move.b $r2, [R_PORT_PB_DATA] | |
120 | #endif | |
121 | #endif | |
ef8028a7 | 122 | |
1da177e4 | 123 | ;; check if we got something on the serial port |
ef8028a7 | 124 | |
1da177e4 | 125 | move.b [SERSTAT], $r0 |
ef8028a7 | 126 | btstq 0, $r0 ; data_avail |
1da177e4 LT |
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" | |
ef8028a7 | 135 | subq 1, $r4 ; decrease length |
1da177e4 LT |
136 | bne wait_ser |
137 | nop | |
138 | jump_start: | |
139 | ;; jump into downloaded code | |
140 | ||
141 | jump CODE_START |