1*54fd6939SJiyong Park /* 2*54fd6939SJiyong Park * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. 3*54fd6939SJiyong Park * 4*54fd6939SJiyong Park * SPDX-License-Identifier: BSD-3-Clause 5*54fd6939SJiyong Park */ 6*54fd6939SJiyong Park 7*54fd6939SJiyong Park #include <stdio.h> 8*54fd6939SJiyong Park 9*54fd6939SJiyong Park #include <common/debug.h> 10*54fd6939SJiyong Park #include <common/runtime_svc.h> 11*54fd6939SJiyong Park #include <platform_def.h> 12*54fd6939SJiyong Park 13*54fd6939SJiyong Park #include "generic-arm64-smcall.h" 14*54fd6939SJiyong Park 15*54fd6939SJiyong Park #ifndef PLAT_ARM_GICD_BASE 16*54fd6939SJiyong Park #ifdef GICD_BASE 17*54fd6939SJiyong Park #define PLAT_ARM_GICD_BASE GICD_BASE 18*54fd6939SJiyong Park #define PLAT_ARM_GICC_BASE GICC_BASE 19*54fd6939SJiyong Park #ifdef GICR_BASE 20*54fd6939SJiyong Park #define PLAT_ARM_GICR_BASE GICR_BASE 21*54fd6939SJiyong Park #endif 22*54fd6939SJiyong Park #else 23*54fd6939SJiyong Park #error PLAT_ARM_GICD_BASE or GICD_BASE must be defined 24*54fd6939SJiyong Park #endif 25*54fd6939SJiyong Park #endif 26*54fd6939SJiyong Park 27*54fd6939SJiyong Park #ifndef PLAT_ARM_GICR_BASE 28*54fd6939SJiyong Park #define PLAT_ARM_GICR_BASE SMC_UNK 29*54fd6939SJiyong Park #endif 30*54fd6939SJiyong Park 31*54fd6939SJiyong Park int trusty_disable_serial_debug; 32*54fd6939SJiyong Park 33*54fd6939SJiyong Park struct dputc_state { 34*54fd6939SJiyong Park char linebuf[128]; 35*54fd6939SJiyong Park unsigned l; 36*54fd6939SJiyong Park }; 37*54fd6939SJiyong Park 38*54fd6939SJiyong Park static struct dputc_state dputc_state[2]; 39*54fd6939SJiyong Park 40*54fd6939SJiyong Park static void trusty_dputc(char ch, int secure) 41*54fd6939SJiyong Park { 42*54fd6939SJiyong Park unsigned i; 43*54fd6939SJiyong Park struct dputc_state *s = &dputc_state[!secure]; 44*54fd6939SJiyong Park 45*54fd6939SJiyong Park if (trusty_disable_serial_debug) 46*54fd6939SJiyong Park return; 47*54fd6939SJiyong Park 48*54fd6939SJiyong Park s->linebuf[s->l++] = ch; 49*54fd6939SJiyong Park if (s->l == sizeof(s->linebuf) || ch == '\n') { 50*54fd6939SJiyong Park if (secure) 51*54fd6939SJiyong Park printf("secure os: "); 52*54fd6939SJiyong Park else 53*54fd6939SJiyong Park printf("non-secure os: "); 54*54fd6939SJiyong Park for (i = 0; i < s->l; i++) { 55*54fd6939SJiyong Park putchar(s->linebuf[i]); 56*54fd6939SJiyong Park } 57*54fd6939SJiyong Park if (ch != '\n') { 58*54fd6939SJiyong Park printf(" <...>\n"); 59*54fd6939SJiyong Park } 60*54fd6939SJiyong Park s->l = 0; 61*54fd6939SJiyong Park } 62*54fd6939SJiyong Park } 63*54fd6939SJiyong Park 64*54fd6939SJiyong Park static uint64_t trusty_get_reg_base(uint32_t reg) 65*54fd6939SJiyong Park { 66*54fd6939SJiyong Park switch (reg) { 67*54fd6939SJiyong Park case SMC_GET_GIC_BASE_GICD: 68*54fd6939SJiyong Park return PLAT_ARM_GICD_BASE; 69*54fd6939SJiyong Park 70*54fd6939SJiyong Park case SMC_GET_GIC_BASE_GICC: 71*54fd6939SJiyong Park return PLAT_ARM_GICC_BASE; 72*54fd6939SJiyong Park 73*54fd6939SJiyong Park case SMC_GET_GIC_BASE_GICR: 74*54fd6939SJiyong Park return PLAT_ARM_GICR_BASE; 75*54fd6939SJiyong Park 76*54fd6939SJiyong Park default: 77*54fd6939SJiyong Park NOTICE("%s(0x%x) unknown reg\n", __func__, reg); 78*54fd6939SJiyong Park return SMC_UNK; 79*54fd6939SJiyong Park } 80*54fd6939SJiyong Park } 81*54fd6939SJiyong Park 82*54fd6939SJiyong Park static uintptr_t trusty_generic_platform_smc(uint32_t smc_fid, 83*54fd6939SJiyong Park u_register_t x1, 84*54fd6939SJiyong Park u_register_t x2, 85*54fd6939SJiyong Park u_register_t x3, 86*54fd6939SJiyong Park u_register_t x4, 87*54fd6939SJiyong Park void *cookie, 88*54fd6939SJiyong Park void *handle, 89*54fd6939SJiyong Park u_register_t flags) 90*54fd6939SJiyong Park { 91*54fd6939SJiyong Park switch (smc_fid) { 92*54fd6939SJiyong Park case SMC_FC_DEBUG_PUTC: 93*54fd6939SJiyong Park trusty_dputc(x1, is_caller_secure(flags)); 94*54fd6939SJiyong Park SMC_RET1(handle, 0); 95*54fd6939SJiyong Park 96*54fd6939SJiyong Park case SMC_FC_GET_REG_BASE: 97*54fd6939SJiyong Park case SMC_FC64_GET_REG_BASE: 98*54fd6939SJiyong Park SMC_RET1(handle, trusty_get_reg_base(x1)); 99*54fd6939SJiyong Park 100*54fd6939SJiyong Park default: 101*54fd6939SJiyong Park NOTICE("%s(0x%x, 0x%lx) unknown smc\n", __func__, smc_fid, x1); 102*54fd6939SJiyong Park SMC_RET1(handle, SMC_UNK); 103*54fd6939SJiyong Park } 104*54fd6939SJiyong Park } 105*54fd6939SJiyong Park 106*54fd6939SJiyong Park /* Define a SPD runtime service descriptor for fast SMC calls */ 107*54fd6939SJiyong Park DECLARE_RT_SVC( 108*54fd6939SJiyong Park trusty_fast, 109*54fd6939SJiyong Park 110*54fd6939SJiyong Park SMC_ENTITY_PLATFORM_MONITOR, 111*54fd6939SJiyong Park SMC_ENTITY_PLATFORM_MONITOR, 112*54fd6939SJiyong Park SMC_TYPE_FAST, 113*54fd6939SJiyong Park NULL, 114*54fd6939SJiyong Park trusty_generic_platform_smc 115*54fd6939SJiyong Park ); 116*54fd6939SJiyong Park 117