ar71xx/mikrotik: re-enable 4KiB flash sector erase
[openwrt/openwrt.git] / target / linux / ramips / image / relocate / head.S
1 /*
2 * Kernel relocation stub for MIPS devices
3 *
4 * Copyright (C) 2015 Felix Fietkau <nbd@openwrt.org>
5 *
6 * Based on:
7 *
8 * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards
9 *
10 * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
11 *
12 * Some parts of this code was based on the OpenWrt specific lzma-loader
13 * for the BCM47xx and ADM5120 based boards:
14 * Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org)
15 * Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su>
16 *
17 * This program is free software; you can redistribute it and/or modify it
18 * under the terms of the GNU General Public License version 2 as published
19 * by the Free Software Foundation.
20 */
21
22 #include <asm/asm.h>
23 #include <asm/regdef.h>
24 #include "cp0regdef.h"
25 #include "cacheops.h"
26
27 #define KSEG0 0x80000000
28
29 .macro ehb
30 sll zero, 3
31 .endm
32
33 .macro reset
34 li t0, 0xbe000034
35 lw t1, 0(t0)
36 ori t1, 1
37 sw t1, 0(t0)
38 .endm
39
40 .text
41
42 LEAF(startup)
43 .set noreorder
44 .set mips32
45
46 .fill 0x10000
47
48 mtc0 zero, CP0_WATCHLO # clear watch registers
49 mtc0 zero, CP0_WATCHHI
50 mtc0 zero, CP0_CAUSE # clear before writing status register
51
52 mfc0 t0, CP0_STATUS
53 li t1, 0x1000001f
54 or t0, t1
55 xori t0, 0x1f
56 mtc0 t0, CP0_STATUS
57 ehb
58
59 mtc0 zero, CP0_COUNT
60 mtc0 zero, CP0_COMPARE
61 ehb
62
63 la t0, __reloc_label # get linked address of label
64 bal __reloc_label # branch and link to label to
65 nop # get actual address
66 __reloc_label:
67 subu t0, ra, t0 # get reloc_delta
68
69 /* Copy our code to the right place */
70 la t1, _code_start # get linked address of _code_start
71 la t2, _code_end # get linked address of _code_end
72
73 addu t4, t2, t0 # calculate actual address of _code_end
74 lw t5, 0(t4) # get extra data size
75
76 add t2, t5
77 add t2, 4
78
79 add t0, t1 # calculate actual address of _code_start
80
81 __reloc_copy:
82 lw t3, 0(t0)
83 sw t3, 0(t1)
84 add t1, 4
85 blt t1, t2, __reloc_copy
86 add t0, 4
87
88 /* flush cache */
89 la t0, _code_start
90 la t1, _code_end
91
92 li t2, ~(CONFIG_CACHELINE_SIZE - 1)
93 and t0, t2
94 and t1, t2
95 li t2, CONFIG_CACHELINE_SIZE
96
97 b __flush_check
98 nop
99
100 __flush_line:
101 cache Hit_Writeback_Inv_D, 0(t0)
102 cache Hit_Invalidate_I, 0(t0)
103 add t0, t2
104
105 __flush_check:
106 bne t0, t1, __flush_line
107 nop
108
109 sync
110
111 la t0, __reloc_back
112 j t0
113 nop
114
115 __reloc_back:
116 la t0, _code_end
117 add t0, 4
118
119 addu t1, t0, t5
120
121 li t2, KERNEL_ADDR
122
123 __kernel_copy:
124 lw t3, 0(t0)
125 sw t3, 0(t2)
126 add t0, 4
127 blt t0, t1, __kernel_copy
128 add t2, 4
129
130 /* flush cache */
131 li t0, KERNEL_ADDR
132 addu t1, t0, t5
133
134 add t1, CONFIG_CACHELINE_SIZE - 1
135 li t2, ~(CONFIG_CACHELINE_SIZE - 1)
136 and t0, t2
137 and t1, t2
138 li t2, CONFIG_CACHELINE_SIZE
139
140 b __kernel_flush_check
141 nop
142
143 __kernel_flush_line:
144 cache Hit_Writeback_Inv_D, 0(t0)
145 cache Hit_Invalidate_I, 0(t0)
146 add t0, t2
147
148 __kernel_flush_check:
149 bne t0, t1, __kernel_flush_line
150 nop
151
152 sync
153
154 li t0, KERNEL_ADDR
155 jr t0
156 nop
157
158 .set reorder
159 END(startup)