static void atf_print_ver(void) { struct pt_regs regs; regs.regs[0] = ARM_STD_SVC_VERSION; smc_call(®s); printf("ARM Std FW version: %ld.%ld\n", regs.regs[0], regs.regs[1]); regs.regs[0] = THUNDERX_SVC_VERSION; smc_call(®s); printf("ThunderX OEM ver: %ld.%ld\n", regs.regs[0], regs.regs[1]); }
int __maybe_unused invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3, u32 *ret_payload) { /* * Added SIP service call Function Identifier * Make sure to stay in x0 register */ struct pt_regs regs; regs.regs[0] = pm_api_id; regs.regs[1] = ((u64)arg1 << 32) | arg0; regs.regs[2] = ((u64)arg3 << 32) | arg2; smc_call(®s); if (ret_payload != NULL) { ret_payload[0] = (u32)regs.regs[0]; ret_payload[1] = upper_32_bits(regs.regs[0]); ret_payload[2] = (u32)regs.regs[1]; ret_payload[3] = upper_32_bits(regs.regs[1]); ret_payload[4] = (u32)regs.regs[2]; } return regs.regs[0]; }
static void meson_init_shmem(void) { struct pt_regs regs; if (shmem_input && shmem_output) return; regs.regs[0] = FN_GET_SHARE_MEM_INPUT_BASE; smc_call(®s); shmem_input = (void *)regs.regs[0]; regs.regs[0] = FN_GET_SHARE_MEM_OUTPUT_BASE; smc_call(®s); shmem_output = (void *)regs.regs[0]; debug("Secure Monitor shmem: 0x%p 0x%p\n", shmem_input, shmem_output); }
ssize_t atf_get_pcount(void) { struct pt_regs regs; regs.regs[0] = THUNDERX_PART_COUNT; smc_call(®s); return regs.regs[0]; }
ssize_t atf_env_count(void) { struct pt_regs regs; regs.regs[0] = THUNDERX_ENV_COUNT; smc_call(®s); return regs.regs[0]; }
ssize_t atf_node_count(void) { struct pt_regs regs; regs.regs[0] = THUNDERX_NODE_COUNT; smc_call(®s); return regs.regs[0]; }
ssize_t atf_dram_size(unsigned int node) { struct pt_regs regs; regs.regs[0] = THUNDERX_DRAM_SIZE; regs.regs[1] = node; smc_call(®s); return regs.regs[0]; }
ssize_t atf_erase_nor(uintptr_t offset, size_t size) { struct pt_regs regs; regs.regs[0] = THUNDERX_NOR_ERASE; regs.regs[1] = offset; smc_call(®s); return regs.regs[0]; }
ssize_t atf_get_part(struct storage_partition *part, unsigned int index) { struct pt_regs regs; regs.regs[0] = THUNDERX_GET_PART; regs.regs[1] = (uintptr_t)part; regs.regs[2] = index; smc_call(®s); return regs.regs[0]; }
int __asm_flush_l3_cache(void) { struct pt_regs regs = {0}; isb(); regs.regs[0] = SMC_SIP_INVOKE_MCE | MCE_SMC_ROC_FLUSH_CACHE; smc_call(®s); return 0; }
ssize_t atf_read_nor(uintptr_t offset, void *buffer, size_t size) { struct pt_regs regs; regs.regs[0] = THUNDERX_NOR_READ; regs.regs[1] = offset; regs.regs[2] = size; regs.regs[3] = (uintptr_t)buffer; smc_call(®s); return regs.regs[0]; }
ssize_t atf_write_mmc(uintptr_t offset, const void *buffer, size_t size) { struct pt_regs regs; regs.regs[0] = THUNDERX_MMC_WRITE; regs.regs[1] = offset; regs.regs[2] = size; regs.regs[3] = (uintptr_t)buffer; smc_call(®s); return regs.regs[0]; }
static void __smc_wrapper(void) { unsigned int cpu = smp_processor_id(); TZ_DPRINTK("[TZ] cpu = %d before enter secure world cmd1 = %x, cmd2 = %x\n", cpu, smc->cmd1, smc->cmd2); if(cpu ==1) { smc_call(smc); } else { TZ_DPRINTK("[[Error SMC call CPU = %d!!\n", cpu); } TZ_DPRINTK("[TZ] cpu = %d before leave secure world \ncmd1 = %x, cmd2 = %x\n", cpu, smc->cmd1, smc->cmd2); }
ssize_t meson_sm_read_efuse(uintptr_t offset, void *buffer, size_t size) { struct pt_regs regs; meson_init_shmem(); regs.regs[0] = FN_EFUSE_READ; regs.regs[1] = offset; regs.regs[2] = size; smc_call(®s); if (regs.regs[0] == 0) return -1; memcpy(buffer, shmem_output, min(size, regs.regs[0])); return regs.regs[0]; }
int chip_id(unsigned char id) { struct pt_regs regs; int val = -EINVAL; if (current_el() != 3) { regs.regs[0] = ZYNQMP_SIP_SVC_CSU_DMA_CHIPID; regs.regs[1] = 0; regs.regs[2] = 0; regs.regs[3] = 0; smc_call(®s); /* * SMC returns: * regs[0][31:0] = status of the operation * regs[0][63:32] = CSU.IDCODE register * regs[1][31:0] = CSU.version register * regs[1][63:32] = CSU.IDCODE2 register */ switch (id) { case IDCODE: regs.regs[0] = upper_32_bits(regs.regs[0]); regs.regs[0] &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK | ZYNQMP_CSU_IDCODE_SVD_MASK; regs.regs[0] >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT; val = regs.regs[0]; break; case VERSION: regs.regs[1] = lower_32_bits(regs.regs[1]); regs.regs[1] &= ZYNQMP_CSU_SILICON_VER_MASK; val = regs.regs[1]; break; case IDCODE2: regs.regs[1] = lower_32_bits(regs.regs[1]); regs.regs[1] >>= ZYNQMP_CSU_VERSION_EMPTY_SHIFT; val = regs.regs[1]; break; default: printf("%s, Invalid Req:0x%x\n", __func__, id); } } else {
ssize_t atf_env_string(size_t index, char *str) { uint64_t *buf = (void *)str; struct pt_regs regs; regs.regs[0] = THUNDERX_ENV_STRING; regs.regs[1] = index; smc_call(®s); if (regs.regs > 0) { buf[0] = regs.regs[0]; buf[1] = regs.regs[1]; buf[2] = regs.regs[2]; buf[3] = regs.regs[3]; return 1; } else { return regs.regs[0]; } }