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 gd->flags |= GD_FLG_BL32_ENABLED; 133 } 134 } 135 136 debug("TOS: 0x%llx - 0x%llx\n", (u64)prop.base, (u64)prop.base + prop.size); 137 138 return prop; 139 } 140 141 struct sysmem_property param_parse_common_resv_mem(void) 142 { 143 struct sysmem_property prop; 144 145 prop.name = "PSTORE/ATAGS/SHM"; 146 prop.base = SDRAM_OFFSET(SZ_1M); 147 prop.size = SZ_1M; 148 149 return prop; 150 } 151 152 int param_parse_bootdev(char **devtype, char **devnum) 153 { 154 #ifdef CONFIG_ROCKCHIP_PRELOADER_ATAGS 155 struct tag *t; 156 157 t = atags_get_tag(ATAG_BOOTDEV); 158 if (t) { 159 switch (t->u.bootdev.devtype) { 160 case BOOT_TYPE_EMMC: 161 *devtype = "mmc"; 162 *devnum = "0"; 163 break; 164 case BOOT_TYPE_SD0: 165 case BOOT_TYPE_SD1: 166 *devtype = "mmc"; 167 *devnum = "1"; 168 break; 169 case BOOT_TYPE_NAND: 170 *devtype = "rknand"; 171 *devnum = "0"; 172 break; 173 case BOOT_TYPE_SPI_NAND: 174 *devtype = "spinand"; 175 *devnum = "0"; 176 break; 177 case BOOT_TYPE_SPI_NOR: 178 *devtype = "spinor"; 179 *devnum = "1"; 180 break; 181 case BOOT_TYPE_RAM: 182 *devtype = "ramdisk"; 183 *devnum = "0"; 184 break; 185 default: 186 printf("Unknown bootdev type: 0x%x\n", 187 t->u.bootdev.devtype); 188 return -EINVAL; 189 } 190 191 return 0; 192 } 193 #endif 194 195 return -ENOSYS; 196 } 197