1 /* 2 * Copyright (c) 2022 Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <dm.h> 9 #include <malloc.h> 10 #include <asm/sections.h> 11 #include <asm/io.h> 12 #include <asm/u-boot.h> 13 #include <lzma/LzmaTools.h> 14 #include <asm/arch/rk_atags.h> 15 16 #define UART_FIFO_EMPTY (BIT(6) | BIT(5)) 17 #define UART_LSR 0x14 18 19 static ulong g_uart_base = CONFIG_DEBUG_UART_BASE; 20 21 void board_init_f(ulong dummy) 22 { 23 } 24 25 ulong spl_relocate_stack_gd(void) 26 { 27 return 0; 28 } 29 30 int board_fit_config_name_match(const char *name) 31 { 32 return 0; 33 } 34 35 static void put_char(char ch) 36 { 37 ulong base = g_uart_base; 38 39 if (!g_uart_base) 40 return; 41 42 writel(ch, base); 43 if (ch == '\n') 44 writel('\r', base); 45 46 while (!(__arch_getl(base + UART_LSR) & UART_FIFO_EMPTY)) 47 ; 48 } 49 50 static void put_string(const char *str) 51 { 52 while (*str) { 53 put_char(*str); 54 str++; 55 } 56 } 57 58 static void put_dec_0_19(int dec) 59 { 60 if (dec >= 10) { 61 put_char('1'); 62 dec -= 10; 63 } 64 65 put_char(dec + '0'); 66 } 67 68 static void jump_entry(void *entry) 69 { 70 void (*entry_fn)(void) = (void *)entry; 71 72 flush_dcache_all(); 73 74 /* 75 * Turn off I-cache and invalidate it 76 */ 77 icache_disable(); 78 invalidate_icache_all(); 79 80 /* 81 * Turn off D-cache 82 * dcache_disable() in turn flushes the d-cache and disables MMU 83 */ 84 dcache_disable(); 85 invalidate_dcache_all(); 86 87 dsb(); 88 isb(); 89 90 entry_fn(); 91 } 92 93 int uart_init(void) 94 { 95 #if defined(CONFIG_ROCKCHIP_PRELOADER_SERIAL) && \ 96 defined(CONFIG_ROCKCHIP_PRELOADER_ATAGS) 97 struct tag *t; 98 99 t = atags_get_tag(ATAG_SERIAL); 100 if (t) { 101 if (t->u.serial.enable) 102 g_uart_base = t->u.serial.addr; 103 else 104 g_uart_base = 0; 105 106 put_char('#'); 107 } 108 #endif 109 return 0; 110 } 111 112 static void print_ret(int err, int err_algo) 113 { 114 static const char *err_msg[] = { 115 "OK", "BD", "TLB", "MAGIC", "HCRC", "DCRC", "ALGO", 116 }; 117 118 if (err) 119 put_string("ERR "); 120 put_string(err_msg[err]); 121 122 if (err_algo) { 123 put_char(' '); 124 put_dec_0_19(err_algo); 125 } 126 put_char('\n'); 127 } 128 129 void board_init_r(gd_t *dummy1, ulong dummy2) 130 { 131 const image_header_t *hdr; 132 const void *data; 133 ulong load_addr; 134 SizeT lzma_len; 135 SizeT src_lenp; 136 int err_algo = 0; 137 int err = 0; 138 139 uart_init(); 140 141 put_string("# DECOMP: "); 142 143 /* init malloc */ 144 gd->malloc_limit = CONFIG_VAL(SYS_MALLOC_F_LEN); 145 gd->malloc_ptr = 0; 146 147 /* set up bank */ 148 #ifndef CONFIG_ARM64 149 if (!gd->bd) { 150 gd->bd = calloc(1, sizeof(bd_t)); 151 if (!gd->bd) { 152 err = 1; 153 goto out; 154 } 155 gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; 156 gd->bd->bi_dram[0].size = SZ_16M; /* default */ 157 } 158 #endif 159 /* TLB memory should be SZ_16K base align and 4KB end align */ 160 gd->arch.tlb_size = PGTABLE_SIZE; 161 gd->arch.tlb_addr = (ulong)memalign(SZ_16K, ALIGN(PGTABLE_SIZE, SZ_4K)); 162 if (!gd->arch.tlb_addr) { 163 err = 2; 164 goto out; 165 } 166 167 /* Enable dcache */ 168 dcache_enable(); 169 170 /* Check */ 171 hdr = (void *)(&__bss_end); 172 if (!image_check_magic(hdr)) { 173 err = 3; 174 goto out; 175 } 176 177 if (!image_check_hcrc(hdr)) { 178 err = 4; 179 goto out; 180 } 181 182 if (!image_check_dcrc(hdr)) { 183 err = 5; 184 goto out; 185 } 186 187 /* Decompress... */ 188 load_addr = uimage_to_cpu(hdr->ih_load); 189 src_lenp = uimage_to_cpu(hdr->ih_ep); 190 data = (void *)hdr + sizeof(*hdr); 191 lzma_len = SZ_2M; /* default max size */ 192 err = lzmaBuffToBuffDecompress((uchar *)(load_addr), &lzma_len, 193 (uchar *)(data), src_lenp); 194 if (err) { 195 err_algo = err; 196 err = 6; 197 } 198 out: 199 print_ret(err, err_algo); 200 if (!err) 201 jump_entry((void *)load_addr); 202 203 /* hang */ 204 while (1) 205 ; 206 } 207