GNU Linux-libre 4.14.266-gnu1
[releases.git] / arch / cris / boot / rescue / kimagerescue.S
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Rescue code to be prepended on a kimage and copied to the
4  * rescue serial port.
5  * This is called from the rescue code, it will copy received data to
6  * 4004000 and after a timeout jump to it.
7  */
8
9 #define ASSEMBLER_MACROS_ONLY
10 #include <arch/sv_addr_ag.h>
11
12 #define CODE_START 0x40004000
13 #define CODE_LENGTH 784
14 #define TIMEOUT_VALUE 1000
15
16
17 #ifdef CONFIG_ETRAX_RESCUE_SER0
18 #define SERXOFF R_SERIAL0_XOFF
19 #define SERBAUD R_SERIAL0_BAUD
20 #define SERRECC R_SERIAL0_REC_CTRL
21 #define SERRDAT R_SERIAL0_REC_DATA
22 #define SERSTAT R_SERIAL0_STATUS
23 #endif
24 #ifdef CONFIG_ETRAX_RESCUE_SER1
25 #define SERXOFF R_SERIAL1_XOFF
26 #define SERBAUD R_SERIAL1_BAUD
27 #define SERRECC R_SERIAL1_REC_CTRL
28 #define SERRDAT R_SERIAL1_REC_DATA
29 #define SERSTAT R_SERIAL1_STATUS
30 #endif
31 #ifdef CONFIG_ETRAX_RESCUE_SER2
32 #define SERXOFF R_SERIAL2_XOFF
33 #define SERBAUD R_SERIAL2_BAUD
34 #define SERRECC R_SERIAL2_REC_CTRL
35 #define SERRDAT R_SERIAL2_REC_DATA
36 #define SERSTAT R_SERIAL2_STATUS
37 #endif
38 #ifdef CONFIG_ETRAX_RESCUE_SER3
39 #define SERXOFF R_SERIAL3_XOFF
40 #define SERBAUD R_SERIAL3_BAUD
41 #define SERRECC R_SERIAL3_REC_CTRL
42 #define SERRDAT R_SERIAL3_REC_DATA
43 #define SERSTAT R_SERIAL3_STATUS
44 #endif
45
46         .text
47         ;; This is the entry point of the rescue code
48         ;; 0x80000000 if loaded in flash (as it should be)
49         ;; since etrax actually starts at address 2 when booting from flash, we
50         ;; put a nop (2 bytes) here first so we dont accidentally skip the di
51
52         nop
53         di
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         ;; Setup the stack to a suitably high address.
71         ;; We assume 8 MB is the minimum DRAM in an eLinux
72         ;; product and put the sp at the top for now.
73
74         move.d  0x40800000, $sp
75
76         ;; setup the serial port at 115200 baud
77
78         moveq   0, $r0
79         move.d  $r0, [SERXOFF]
80
81         move.b  0x99, $r0
82         move.b  $r0, [SERBAUD]          ; 115.2kbaud for both transmit
83                                         ; and receive
84
85         move.b  0x40, $r0               ; rec enable
86         move.b  $r0, [SERRECC]
87
88
89         moveq   0, $r1                  ; "timer" to clock out a LED red flash
90         move.d  CODE_START, $r3         ; destination counter
91         move.d  CODE_LENGTH, $r4        ; length
92         move.d  TIMEOUT_VALUE, $r5      ; "timeout" until jump
93
94 wait_ser:
95         addq    1, $r1
96         subq    1, $r5                  ; decrease timeout
97         beq     jump_start              ; timed out
98         nop
99 #ifndef CONFIG_ETRAX_NO_LEDS
100 #ifdef CONFIG_ETRAX_PA_LEDS
101         move.b  CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r2
102 #endif
103 #ifdef CONFIG_ETRAX_PB_LEDS
104         move.b  CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r2
105 #endif
106         move.d  (1 << CONFIG_ETRAX_LED1R) | (1 << CONFIG_ETRAX_LED2R), $r0
107         btstq   16, $r1
108         bpl     1f
109         nop
110         or.d    $r0, $r2                ; set bit
111         ba      2f
112         nop
113 1:      not     $r0                     ; clear bit
114         and.d   $r0, $r2
115 2:
116 #ifdef CONFIG_ETRAX_PA_LEDS
117         move.b  $r2, [R_PORT_PA_DATA]
118 #endif
119 #ifdef CONFIG_ETRAX_PB_LEDS
120         move.b  $r2, [R_PORT_PB_DATA]
121 #endif
122 #endif
123
124         ;; check if we got something on the serial port
125
126         move.b  [SERSTAT], $r0
127         btstq   0, $r0                  ; data_avail
128         bpl     wait_ser
129         nop
130
131         ;; got something - copy the byte and loop
132
133         move.b  [SERRDAT], $r0
134         move.b  $r0, [$r3+]
135         move.d  TIMEOUT_VALUE, $r5      ; reset "timeout"
136         subq    1, $r4                  ; decrease length
137         bne     wait_ser
138         nop
139 jump_start:
140         ;; jump into downloaded code
141
142         jump    CODE_START