• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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