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