1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd 4 */ 5 6 #include <common.h> 7 #include <asm/io.h> 8 #include <asm/arch/rk_atags.h> 9 #include <asm/arch/param.h> 10 11 DECLARE_GLOBAL_DATA_PTR; 12 13 #define SDRAM_OFFSET(offset) (CONFIG_SYS_SDRAM_BASE + (offset)) 14 #define PARAM_DRAM_INFO_OFFSET (SZ_32M) 15 #define PARAM_OPTEE_INFO_OFFSET (SZ_32M + SZ_2M) 16 17 struct tos_param_t { 18 u32 version; 19 u32 checksum; 20 struct { 21 char name[8]; 22 s64 phy_addr; 23 u32 size; 24 u32 flags; 25 } tee_mem; 26 struct { 27 char name[8]; 28 s64 phy_addr; 29 u32 size; 30 u32 flags; 31 } drm_mem; 32 s64 reserve[8]; 33 }; 34 35 static uint16_t trust_checksum(const uint8_t *buf, uint16_t len) 36 { 37 uint16_t i, checksum = 0; 38 39 for (i = 0; i < len; i++) { 40 if (i % 2) 41 checksum += buf[i] << 8; 42 else 43 checksum += buf[i]; 44 } 45 checksum = ~checksum; 46 47 return checksum; 48 } 49 50 struct sysmem_property param_parse_atf_mem(void) 51 { 52 struct sysmem_property prop; 53 54 prop.name = "ATF"; 55 prop.base = 0; 56 prop.size = 0; 57 58 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 59 struct tag *t = NULL; 60 61 /* 62 * Get memory region of ATF 63 * 64 * 1. New way: atags info; 65 * 2. Leagcy way: 2MB size and start from ddr 0x0 offset; 66 */ 67 t = atags_get_tag(ATAG_ATF_MEM); 68 if (t && t->u.atf_mem.size) { 69 prop.base = t->u.atf_mem.phy_addr; 70 prop.size = t->u.atf_mem.size; 71 /* Sanity */ 72 if (prop.base + prop.size > SDRAM_OFFSET(SZ_1M)) { 73 printf("%s: ATF reserved region is not within 0-1MB " 74 "offset(0x%08llx-0x%08llx)!\n", 75 __func__, (u64)prop.base, (u64)prop.base + prop.size); 76 return prop; 77 } 78 } 79 #endif 80 81 /* Legacy */ 82 if (!prop.size) { 83 if (IS_ENABLED(CONFIG_ARM64) || 84 IS_ENABLED(CONFIG_ARM64_BOOT_AARCH32)) { 85 prop.base = SDRAM_OFFSET(0); 86 prop.size = SZ_1M; 87 } 88 } 89 90 debug("ATF: 0x%llx - 0x%llx\n", (u64)prop.base, (u64)prop.base + prop.size); 91 92 return prop; 93 } 94 95 struct sysmem_property param_parse_optee_mem(void) 96 { 97 struct tos_param_t *tos_parameter; 98 struct sysmem_property prop; 99 u32 checksum; 100 101 prop.name = "OP-TEE"; 102 prop.base = 0; 103 prop.size = 0; 104 105 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 106 struct tag *t = NULL; 107 108 /* 109 * Get memory region of OP-TEE 110 * 111 * 1. New way: atags info; 112 * 2. Leagcy way: info in ddr 34M offset; 113 */ 114 t = atags_get_tag(ATAG_TOS_MEM); 115 if (t && (t->u.tos_mem.tee_mem.flags == 1)) { 116 prop.base = t->u.tos_mem.tee_mem.phy_addr; 117 prop.size = t->u.tos_mem.tee_mem.size; 118 } 119 #endif 120 121 /* Legacy */ 122 if (!prop.size) { 123 tos_parameter = 124 (struct tos_param_t *)(SDRAM_OFFSET(PARAM_OPTEE_INFO_OFFSET)); 125 checksum = 126 trust_checksum((uint8_t *)(unsigned long)tos_parameter + 8, 127 sizeof(struct tos_param_t) - 8); 128 if ((checksum == tos_parameter->checksum) && 129 (tos_parameter->tee_mem.flags == 1)) { 130 prop.base = tos_parameter->tee_mem.phy_addr; 131 prop.size = tos_parameter->tee_mem.size; 132 } 133 } 134 135 if (prop.size) 136 gd->flags |= GD_FLG_BL32_ENABLED; 137 138 debug("TOS: 0x%llx - 0x%llx\n", (u64)prop.base, (u64)prop.base + prop.size); 139 140 return prop; 141 } 142 143 struct sysmem_property param_parse_common_resv_mem(void) 144 { 145 struct sysmem_property prop; 146 147 prop.name = "PSTORE/ATAGS/SHM"; 148 prop.base = SDRAM_OFFSET(SZ_1M); 149 prop.size = SZ_1M; 150 151 return prop; 152 } 153 154 int param_parse_bootdev(char **devtype, char **devnum) 155 { 156 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 157 struct tag *t; 158 159 t = atags_get_tag(ATAG_BOOTDEV); 160 if (t) { 161 switch (t->u.bootdev.devtype) { 162 case BOOT_TYPE_EMMC: 163 *devtype = "mmc"; 164 *devnum = "0"; 165 break; 166 case BOOT_TYPE_SD0: 167 case BOOT_TYPE_SD1: 168 *devtype = "mmc"; 169 *devnum = "1"; 170 break; 171 case BOOT_TYPE_NAND: 172 *devtype = "rknand"; 173 *devnum = "0"; 174 break; 175 case BOOT_TYPE_SPI_NAND: 176 *devtype = "spinand"; 177 *devnum = "0"; 178 break; 179 case BOOT_TYPE_SPI_NOR: 180 *devtype = "spinor"; 181 *devnum = "1"; 182 break; 183 case BOOT_TYPE_RAM: 184 *devtype = "ramdisk"; 185 *devnum = "0"; 186 break; 187 default: 188 printf("Unknown bootdev type: 0x%x\n", 189 t->u.bootdev.devtype); 190 return -EINVAL; 191 } 192 193 return 0; 194 } 195 #endif 196 197 return -ENOSYS; 198 } 199