• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3  *
4  * This program is free software; you can redistribute  it and/or modify it
5  * under  the terms of  the GNU General  Public License as published by the
6  * Free Software Foundation;  either version 2 of the  License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  */
18 
19 #include <config.h>
20 #include <linux/kconfig.h>
21 #include <asm/io.h>
22 #include <compiler.h>
23 
24 /******************************************************************************/
25 extern void uart_early_init(void);
26 extern void uart_early_puts(const char *ss);
27 extern void reset_cpu(unsigned long addr);
28 
29 extern void mmu_pagedir_init(unsigned long);
30 extern void mmu_pagedir_cached_range(unsigned long,
31 			                 unsigned long, unsigned long);
32 extern void mmu_startup(unsigned long);
33 
34 extern void dcache_flush_all(void);
35 extern void dcache_inv_all(void);
36 extern void mmu_turnoff(void);
37 
38 
39 /******************************************************************************/
40 const unsigned long IMAGE_ENTRY = (CONFIG_SYS_TEXT_BASE);
41 
42 extern unsigned char input_data[];
43 extern unsigned char input_data_end[];
44 extern unsigned long _start;
45 
46 /******************************************************************************/
47 #define error(_s)               uart_early_puts(_s)
48 #define putstr(_s)              uart_early_puts(_s)
49 
50 #define large_malloc(_n)        malloc(_n)
51 #define large_free(_n)          free(_n)
52 
53 /******************************************************************************/
54 /*
55  * this value will be (_start - CONFIG_SYS_MALLOC_LEN)
56  */
57 static long malloc_start_lzma;
58 
59 /******************************************************************************/
malloc(unsigned int size)60 static void *malloc(unsigned int size)
61 {
62 	void *ptr = (void *)malloc_start_lzma;
63 	malloc_start_lzma += size;
64 
65 	if (malloc_start_lzma >= (unsigned long)&_start)
66 		return NULL;
67 
68 	return ptr;
69 }
70 /******************************************************************************/
free(void * ptr)71 static void free(void *ptr)
72 {
73 }
74 /******************************************************************************/
75 
76 #include "unlzma.c"
77 
78 #ifndef CONFIG_SYS_ICACHE_OFF
79 /* Invalidate entire I-cache and branch predictor array */
invalidate_icache_all(void)80 static void invalidate_icache_all(void)
81 {
82     /*
83      * Invalidate all instruction caches to PoU.
84      * Also flushes branch target cache.
85      */
86     asm volatile ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
87 
88     /* Invalidate entire branch predictor array */
89     asm volatile ("mcr p15, 0, %0, c7, c5, 6" : : "r" (0));
90 
91     /* Full system DSB - make sure that the invalidation is complete */
92     dsb();
93 
94     /* ISB - make sure the instruction stream sees it */
95     isb();
96 }
97 #else
invalidate_icache_all(void)98 static void invalidate_icache_all(void)
99 {
100 }
101 #endif
102 
103 #ifdef CONFIG_EARLY_DCACHE_ENABLE
early_dcache_enable(void)104 static int early_dcache_enable(void)
105 {
106 	unsigned long pdt = CONFIG_SYS_SDRAM_BASE + SZ_64K;
107 	mmu_pagedir_init(pdt);
108 	mmu_pagedir_cached_range(pdt, CONFIG_SYS_SDRAM_BASE, SZ_256M);
109 	mmu_startup(pdt);
110 
111 	return 0;
112 }
113 
early_dcache_disable(void)114 static int early_dcache_disable(void)
115 {
116 	int i = 0;
117 
118 	dcache_flush_all();
119 
120 	/* mem barrier to sync up things */
121 	asm("mcr p15, 0, %0, c7, c10, 4" : : "r"(i));
122 
123 	dcache_inv_all();
124 
125 	mmu_turnoff();
126 
127 	return 0;
128 }
129 #endif
130 
131 /******************************************************************************/
start_armboot(void)132 void start_armboot(void)
133 {
134 	unsigned char *pdst = (unsigned char *)(uintptr_t)IMAGE_ENTRY;
135 	unsigned int image_data_len = input_data_end - input_data;
136 
137 	malloc_start_lzma = ((uintptr_t)&_start - CONFIG_SYS_MALLOC_LEN);
138 	uart_early_init();
139 
140 	if (input_data[0] == 0x5D) {
141 		uart_early_puts("\nUncompress");
142 		//early_dcache_enable();
143 		decompress(input_data, image_data_len, pdst);
144 		//early_dcache_disable();
145 		uart_early_puts("Ok\r\n");
146 	} else {
147 		int *s = (int *)input_data;
148 		int *d = (int *)pdst;
149 		unsigned int len = ((image_data_len + 3) >> 2);
150 		while (len--)
151 			*d++ = *s++;
152 	}
153 
154 	void (*uboot)(void);
155 	uboot = (void (*))CONFIG_SYS_TEXT_BASE;
156 	invalidate_icache_all();
157 	uboot();
158 }
159 
160 /******************************************************************************/
hang(void)161 void hang(void)
162 {
163     uart_early_puts("### ERROR ### Please RESET the board ###\n");
164     for (;;)
165         ;
166 }
167 
168 
do_bad_sync(void)169 void do_bad_sync(void)
170 {
171     uart_early_puts("bad sync abort\r\n");
172     uart_early_puts("Resetting CPU ...\r\n");
173     reset_cpu(0);
174 }
175 
do_sync(void)176 void do_sync(void)
177 {
178     uart_early_puts("sync abort\r\n");
179     uart_early_puts("Resetting CPU ...\r\n");
180     reset_cpu(0);
181 }
182 
do_bad_error(void)183 void do_bad_error(void)
184 {
185     uart_early_puts("bad error\r\n");
186     uart_early_puts("Resetting CPU ...\r\n");
187     reset_cpu(0);
188 }
189 
do_error(void)190 void do_error(void)
191 {
192     uart_early_puts("error\r\n");
193     uart_early_puts("Resetting CPU ...\r\n");
194     reset_cpu(0);
195 }
196 
do_bad_fiq(void)197 void do_bad_fiq(void)
198 {
199     uart_early_puts("bad fast interrupt request\r\n");
200     uart_early_puts("Resetting CPU ...\r\n");
201     reset_cpu(0);
202 }
203 
do_bad_irq(void)204 void do_bad_irq(void)
205 {
206     uart_early_puts("bad interrupt request\r\n");
207     uart_early_puts("Resetting CPU ...\r\n");
208     reset_cpu(0);
209 }
210 
do_fiq(void)211 void do_fiq(void)
212 {
213     uart_early_puts("fast interrupt request\r\n");
214     uart_early_puts("Resetting CPU ...\r\n");
215     reset_cpu(0);
216 }
217 
do_irq(void)218 void do_irq(void)
219 {
220     uart_early_puts("interrupt request\r\n");
221     uart_early_puts("Resetting CPU ...\r\n");
222     reset_cpu(0);
223 }
224