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
36 #include "hw_decompress.c"
37 #define GZIP_SIZE_OFFSET 0x4
38
39 #ifndef CONFIG_SYS_ICACHE_OFF
40 /* Invalidate entire I-cache and branch predictor array */
invalidate_icache_all(void)41 static void invalidate_icache_all(void)
42 {
43 /*
44 * Invalidate all instruction caches to PoU.
45 * Also flushes branch target cache.
46 */
47 asm volatile("mcr p15, 0, %0, c7, c5, 0" : : "r"(0));
48
49 /* Invalidate entire branch predictor array */
50 asm volatile("mcr p15, 0, %0, c7, c5, 6" : : "r"(0));
51
52 /* Full system DSB - make sure that the invalidation is complete */
53 dsb();
54
55 /* ISB - make sure the instruction stream sees it */
56 isb();
57 }
58 #else
invalidate_icache_all(void)59 static void invalidate_icache_all(void)
60 {
61 }
62 #endif
63
64 /******************************************************************************/
start_armboot(void)65 void start_armboot(void)
66 {
67 unsigned char *pdst_l32 = NULL;
68 unsigned int image_data_len;
69 int pdst_len;
70 int ret;
71 int i;
72 char *p = NULL;
73 char *q = NULL;
74
75 uart_early_init();
76 uart_early_puts("\r\nUncompress ");
77
78 /* use direct address mode */
79 hw_dec_type = 0;
80 /* init hw decompress IP */
81 hw_dec_init();
82
83 /* start decompress */
84 pdst_l32 = (unsigned char *)(uintptr_t)image_entry;
85 image_data_len = input_data_end - input_data;
86
87 /* get dets length from compress image */
88 p = (char *)&pdst_len;
89 q = (char *)(input_data_end - GZIP_SIZE_OFFSET);
90 for (i = 0; i < sizeof(int); i++)
91 p[i] = q[i];
92
93 ret = hw_dec_decompress(pdst_l32, &pdst_len, input_data, image_data_len, NULL);
94 if (!ret) {
95 uart_early_puts("Ok!");
96 } else {
97 uart_early_puts("Fail!");
98 while (1) ;
99 }
100 /* uinit hw decompress IP */
101 hw_dec_uinit();
102 void (*uboot)(void);
103 uboot = (void (*))CONFIG_SYS_TEXT_BASE;
104 invalidate_icache_all();
105 uboot();
106 }
107
hang(void)108 void hang(void)
109 {
110 uart_early_puts("### ERROR ### Please RESET the board ###\n");
111 for (;;) ;
112 }
113
114
do_bad_sync(void)115 void do_bad_sync(void)
116 {
117 uart_early_puts("bad sync abort\r\n");
118 uart_early_puts("Resetting CPU ...\r\n");
119 reset_cpu(0);
120 }
121
do_sync(void)122 void do_sync(void)
123 {
124 uart_early_puts("sync abort\r\n");
125 uart_early_puts("Resetting CPU ...\r\n");
126 reset_cpu(0);
127 }
128
do_bad_error(void)129 void do_bad_error(void)
130 {
131 uart_early_puts("bad error\r\n");
132 uart_early_puts("Resetting CPU ...\r\n");
133 reset_cpu(0);
134 }
135
do_error(void)136 void do_error(void)
137 {
138 uart_early_puts("error\r\n");
139 uart_early_puts("Resetting CPU ...\r\n");
140 reset_cpu(0);
141 }
142
do_bad_fiq(void)143 void do_bad_fiq(void)
144 {
145 uart_early_puts("bad fast interrupt request\r\n");
146 uart_early_puts("Resetting CPU ...\r\n");
147 reset_cpu(0);
148 }
149
do_bad_irq(void)150 void do_bad_irq(void)
151 {
152 uart_early_puts("bad interrupt request\r\n");
153 uart_early_puts("Resetting CPU ...\r\n");
154 reset_cpu(0);
155 }
156
do_fiq(void)157 void do_fiq(void)
158 {
159 uart_early_puts("fast interrupt request\r\n");
160 uart_early_puts("Resetting CPU ...\r\n");
161 reset_cpu(0);
162 }
163
do_irq(void)164 void do_irq(void)
165 {
166 uart_early_puts("interrupt request\r\n");
167 uart_early_puts("Resetting CPU ...\r\n");
168 reset_cpu(0);
169 }
170