Merge branch 'akpm'
[linux-2.6/next.git] / arch / cris / boot / rescue / kimagerescue.S
blob6f7b3e61260bea02079919f2ea2bf32131ab176a
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  */
8 #define ASSEMBLER_MACROS_ONLY
9 #include <arch/sv_addr_ag.h>
11 #define CODE_START 0x40004000
12 #define CODE_LENGTH 784
13 #define TIMEOUT_VALUE 1000
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
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
51         nop
52         di
53 #ifndef CONFIG_SVINTO_SIM
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)
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]
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]
67         ;; We need to setup the bus registers before we start using the DRAM
68 #include "../../lib/dram_init.S"
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.
75         move.d  0x40800000, $sp
77         ;; setup the serial port at 115200 baud
79         moveq   0, $r0
80         move.d  $r0, [SERXOFF]
82         move.b  0x99, $r0
83         move.b  $r0, [SERBAUD]          ; 115.2kbaud for both transmit
84                                         ; and receive
86         move.b  0x40, $r0               ; rec enable
87         move.b  $r0, [SERRECC]
90         moveq   0, $r1                  ; "timer" to clock out a LED red flash
91         move.d  CODE_START, $r3         ; destination counter
92         move.d  CODE_LENGTH, $r4        ; length
93         move.d  TIMEOUT_VALUE, $r5      ; "timeout" until jump
95 wait_ser:
96         addq    1, $r1
97         subq    1, $r5                  ; decrease timeout
98         beq     jump_start              ; timed out
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
114 1:      not     $r0                     ; clear bit
115         and.d   $r0, $r2
117 #ifdef CONFIG_ETRAX_PA_LEDS
118         move.b  $r2, [R_PORT_PA_DATA]
119 #endif
120 #ifdef CONFIG_ETRAX_PB_LEDS
121         move.b  $r2, [R_PORT_PB_DATA]
122 #endif
123 #endif
125         ;; check if we got something on the serial port
127         move.b  [SERSTAT], $r0
128         btstq   0, $r0                  ; data_avail
129         bpl     wait_ser
130         nop
132         ;; got something - copy the byte and loop
134         move.b  [SERRDAT], $r0
135         move.b  $r0, [$r3+]
136         move.d  TIMEOUT_VALUE, $r5      ; reset "timeout"
137         subq    1, $r4                  ; decrease length
138         bne     wait_ser
139         nop
140 jump_start:
141         ;; jump into downloaded code
143         jump    CODE_START