1 /*
2 * startup.c
3 *
4 * This file is used to initialize the board hardware.
5 *
6 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 *
21 */
22
23 #include <config.h>
24 #include <linux/kconfig.h>
25 #include <asm/io.h>
26 #include <compiler.h>
27 #include <hicpu_common.h>
28
29 /******************************************************************************/
30 const uintptr_t image_entry = (CONFIG_SYS_TEXT_BASE);
31
32 /******************************************************************************/
33 #define error(_s) uart_early_puts(_s)
34 #define putstr(_s) uart_early_puts(_s)
35 #define EXCEPTION_LEVEL1 1
36 #define EXCEPTION_LEVEL2 2
37 #include "hw_decompress.c"
38 #define GZIP_SIZE_OFFSET 0x4
39
40 void invalidate_icache_all(void);
41 void __asm_invalidate_icache_all(void);
42
43 /******************************************************************************/
start_armboot(void)44 void start_armboot(void)
45 {
46 unsigned char *pdst_h32 = NULL;
47 unsigned char *pdst_l32 = NULL;
48 unsigned char *input_data_h32 = NULL;
49 unsigned int image_data_len;
50 int pdst_len;
51 int ret;
52 uart_early_init();
53 uart_early_puts("\r\nUncompress ");
54
55 /* use direct address mode */
56 hw_dec_type = 0;
57 /* init hw decompress IP */
58 hw_dec_init();
59
60 /* start decompress */
61 pdst_l32 = (unsigned char *)(uintptr_t)image_entry;
62 image_data_len = input_data_end - input_data;
63 for (int i = 0; i < sizeof(pdst_len); i++)
64 *((char *)(&pdst_len) + i) = *((char *)(input_data_end -
65 GZIP_SIZE_OFFSET) + i);
66
67 ret = hw_dec_decompress(pdst_h32, pdst_l32, &pdst_len, input_data_h32,
68 input_data, image_data_len, NULL);
69 if (!ret) {
70 uart_early_puts("Ok!");
71 } else {
72 uart_early_puts("Fail!");
73 while (1) ;
74 }
75
76 /* uinit hw decompress IP */
77 hw_dec_uinit();
78 void (*uboot)(void);
79 uboot = (void (*))CONFIG_SYS_TEXT_BASE;
80 invalidate_icache_all();
81 uboot();
82 }
83
84 /******************************************************************************/
hang(void)85 void hang(void)
86 {
87 uart_early_puts("### ERROR ### Please RESET the board ###\n");
88 for (; ;);
89 }
90
invalidate_icache_all(void)91 void invalidate_icache_all(void)
92 {
93 __asm_invalidate_icache_all();
94 }
95
current_el(void)96 static inline unsigned int current_el(void)
97 {
98 unsigned int el;
99 asm volatile("mrs %0, CurrentEL" : "=r"(el) : : "cc");
100 return el >> 2; /* Move Left 2bit */
101 }
102
set_sctlr(unsigned int val)103 static void set_sctlr(unsigned int val)
104 {
105 unsigned int el;
106
107 el = current_el();
108 if (el == EXCEPTION_LEVEL1)
109 asm volatile("msr sctlr_el1, %0" : : "r"(val) : "cc");
110 else if (el == EXCEPTION_LEVEL2)
111 asm volatile("msr sctlr_el2, %0" : : "r"(val) : "cc");
112 else
113 asm volatile("msr sctlr_el3, %0" : : "r"(val) : "cc");
114
115 asm volatile("isb");
116 }
117
get_sctlr(void)118 static unsigned int get_sctlr(void)
119 {
120 unsigned int el, val;
121
122 el = current_el();
123 if (el == EXCEPTION_LEVEL1)
124 asm volatile("mrs %0, sctlr_el1" : "=r"(val) : : "cc");
125 else if (el == EXCEPTION_LEVEL2)
126 asm volatile("mrs %0, sctlr_el2" : "=r"(val) : : "cc");
127 else
128 asm volatile("mrs %0, sctlr_el3" : "=r"(val) : : "cc");
129
130 return val;
131 }
132
icache_enable(void)133 void icache_enable(void)
134 {
135 invalidate_icache_all();
136 #define CR_I (1 << 12) /* Icache enable */
137 set_sctlr(get_sctlr() | CR_I);
138 }
139
do_bad_sync(void)140 void do_bad_sync(void)
141 {
142 uart_early_puts("bad sync abort\r\n");
143 uart_early_puts("Resetting CPU ...\r\n");
144 reset_cpu(0);
145 }
146
do_sync(void)147 void do_sync(void)
148 {
149 uart_early_puts("sync abort\r\n");
150 uart_early_puts("Resetting CPU ...\r\n");
151 reset_cpu(0);
152 }
153
do_bad_error(void)154 void do_bad_error(void)
155 {
156 uart_early_puts("bad error\r\n");
157 uart_early_puts("Resetting CPU ...\r\n");
158 reset_cpu(0);
159 }
160
do_error(void)161 void do_error(void)
162 {
163 uart_early_puts("error\r\n");
164 uart_early_puts("Resetting CPU ...\r\n");
165 reset_cpu(0);
166 }
167
do_bad_fiq(void)168 void do_bad_fiq(void)
169 {
170 uart_early_puts("bad fast interrupt request\r\n");
171 uart_early_puts("Resetting CPU ...\r\n");
172 reset_cpu(0);
173 }
174
do_bad_irq(void)175 void do_bad_irq(void)
176 {
177 uart_early_puts("bad interrupt request\r\n");
178 uart_early_puts("Resetting CPU ...\r\n");
179 reset_cpu(0);
180 }
181
do_fiq(void)182 void do_fiq(void)
183 {
184 uart_early_puts("fast interrupt request\r\n");
185 uart_early_puts("Resetting CPU ...\r\n");
186 reset_cpu(0);
187 }
188
do_irq(void)189 void do_irq(void)
190 {
191 uart_early_puts("interrupt request\r\n");
192 uart_early_puts("Resetting CPU ...\r\n");
193 reset_cpu(0);
194 }
195