bmips: add new target
[openwrt/openwrt.git] / target / linux / bmips / image / lzma-loader / src / head.S
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * LZMA compressed kernel loader for Atheros AR7XXX/AR9XXX based boards
4 *
5 * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
6 *
7 * Some parts of this code was based on the OpenWrt specific lzma-loader
8 * for the BCM47xx and ADM5120 based boards:
9 * Copyright (C) 2004 Manuel Novoa III (mjn3@codepoet.org)
10 * Copyright (C) 2005 by Oleg I. Vdovikin <oleg@cs.msu.su>
11 */
12
13 #include <asm/asm.h>
14 #include <asm/regdef.h>
15 #include "cp0regdef.h"
16 #include "cacheops.h"
17 #include "config.h"
18
19 #define KSEG0 0x80000000
20
21 .macro ehb
22 sll zero, 3
23 .endm
24
25 .text
26
27 LEAF(startup)
28 .set noreorder
29 .set mips32
30
31 mtc0 zero, CP0_WATCHLO # clear watch registers
32 mtc0 zero, CP0_WATCHHI
33 mtc0 zero, CP0_CAUSE # clear before writing status register
34
35 mfc0 t0, CP0_STATUS
36 li t1, 0x1000001f
37 or t0, t1
38 xori t0, 0x1f
39 mtc0 t0, CP0_STATUS
40 ehb
41
42 mtc0 zero, CP0_COUNT
43 mtc0 zero, CP0_COMPARE
44 ehb
45
46 la t0, __reloc_label # get linked address of label
47 bal __reloc_label # branch and link to label to
48 nop # get actual address
49 __reloc_label:
50 subu t0, ra, t0 # get reloc_delta
51
52 beqz t0, __reloc_done # if delta is 0 we are in the right place
53 nop
54
55 /* Copy our code to the right place */
56 la t1, _code_start # get linked address of _code_start
57 la t2, _code_end # get linked address of _code_end
58 addu t0, t0, t1 # calculate actual address of _code_start
59
60 __reloc_copy:
61 lw t3, 0(t0)
62 sw t3, 0(t1)
63 add t1, 4
64 blt t1, t2, __reloc_copy
65 add t0, 4
66
67 /* flush cache */
68 la t0, _code_start
69 la t1, _code_end
70
71 li t2, ~(CONFIG_CACHELINE_SIZE - 1)
72 and t0, t2
73 and t1, t2
74 li t2, CONFIG_CACHELINE_SIZE
75
76 b __flush_check
77 nop
78
79 __flush_line:
80 cache Hit_Writeback_Inv_D, 0(t0)
81 cache Hit_Invalidate_I, 0(t0)
82 add t0, t2
83
84 __flush_check:
85 bne t0, t1, __flush_line
86 nop
87
88 sync
89
90 __reloc_done:
91
92 /* clear bss */
93 la t0, _bss_start
94 la t1, _bss_end
95 b __bss_check
96 nop
97
98 __bss_fill:
99 sw zero, 0(t0)
100 addi t0, 4
101
102 __bss_check:
103 bne t0, t1, __bss_fill
104 nop
105
106 /* Setup new "C" stack */
107 la sp, _stack
108
109 /* reserve stack space for a0-a3 registers */
110 subu sp, 16
111
112 /* jump to the decompressor routine */
113 la t0, loader_main
114 jr t0
115 nop
116
117 .set reorder
118 END(startup)