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 |
ef8028a7 | 53 | #ifndef CONFIG_SVINTO_SIM |
1da177e4 LT |
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) | |
ef8028a7 | 56 | |
1da177e4 LT |
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] | |
ef8028a7 | 61 | |
1da177e4 LT |
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] | |
ef8028a7 | 66 | |
1da177e4 LT |
67 | ;; We need to setup the bus registers before we start using the DRAM |
68 | #include "../../lib/dram_init.S" | |
ef8028a7 | 69 | |
1da177e4 LT |
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 | |
ef8028a7 | 76 | |
1da177e4 | 77 | ;; setup the serial port at 115200 baud |
ef8028a7 | 78 | |
1da177e4 | 79 | moveq 0, $r0 |
ef8028a7 | 80 | move.d $r0, [SERXOFF] |
1da177e4 LT |
81 | |
82 | move.b 0x99, $r0 | |
ef8028a7 JN |
83 | move.b $r0, [SERBAUD] ; 115.2kbaud for both transmit |
84 | ; and receive | |
1da177e4 LT |
85 | |
86 | move.b 0x40, $r0 ; rec enable | |
ef8028a7 | 87 | move.b $r0, [SERRECC] |
1da177e4 LT |
88 | |
89 | ||
ef8028a7 JN |
90 | moveq 0, $r1 ; "timer" to clock out a LED red flash |
91 | move.d CODE_START, $r3 ; destination counter | |
1da177e4 LT |
92 | move.d CODE_LENGTH, $r4 ; length |
93 | move.d TIMEOUT_VALUE, $r5 ; "timeout" until jump | |
94 | ||
95 | wait_ser: | |
96 | addq 1, $r1 | |
ef8028a7 JN |
97 | subq 1, $r5 ; decrease timeout |
98 | beq jump_start ; timed out | |
1da177e4 LT |
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 | |
ef8028a7 | 114 | 1: not $r0 ; clear bit |
1da177e4 | 115 | and.d $r0, $r2 |
ef8028a7 | 116 | 2: |
1da177e4 LT |
117 | #ifdef CONFIG_ETRAX_PA_LEDS |
118 | move.b $r2, [R_PORT_PA_DATA] | |
ef8028a7 | 119 | #endif |
1da177e4 LT |
120 | #ifdef CONFIG_ETRAX_PB_LEDS |
121 | move.b $r2, [R_PORT_PB_DATA] | |
122 | #endif | |
123 | #endif | |
ef8028a7 | 124 | |
1da177e4 | 125 | ;; check if we got something on the serial port |
ef8028a7 | 126 | |
1da177e4 | 127 | move.b [SERSTAT], $r0 |
ef8028a7 | 128 | btstq 0, $r0 ; data_avail |
1da177e4 LT |
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" | |
ef8028a7 | 137 | subq 1, $r4 ; decrease length |
1da177e4 LT |
138 | bne wait_ser |
139 | nop | |
140 | jump_start: | |
141 | ;; jump into downloaded code | |
142 | ||
143 | jump CODE_START |