1 /* 2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of ARM nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific 16 * prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <debug.h> 32 #include <runtime_svc.h> 33 34 #include "generic-arm64-smcall.h" 35 36 int trusty_disable_serial_debug; 37 38 struct dputc_state { 39 char linebuf[128]; 40 unsigned l; 41 }; 42 43 static struct dputc_state dputc_state[2]; 44 45 static void trusty_dputc(char ch, int secure) 46 { 47 unsigned i; 48 struct dputc_state *s = &dputc_state[!secure]; 49 50 if (trusty_disable_serial_debug) 51 return; 52 53 s->linebuf[s->l++] = ch; 54 if (s->l == sizeof(s->linebuf) || ch == '\n') { 55 if (secure) 56 printf("secure os: "); 57 else 58 printf("non-secure os: "); 59 for (i = 0; i < s->l; i++) { 60 putchar(s->linebuf[i]); 61 } 62 if (ch != '\n') { 63 printf(" <...>\n"); 64 } 65 s->l = 0; 66 } 67 } 68 69 static uint64_t trusty_get_reg_base(uint32_t reg) 70 { 71 switch (reg) { 72 case 0: 73 return PLAT_ARM_GICD_BASE; 74 75 case 1: 76 return PLAT_ARM_GICC_BASE; 77 78 default: 79 NOTICE("%s(0x%x) unknown reg\n", __func__, reg); 80 return SMC_UNK; 81 } 82 } 83 84 static uint64_t trusty_generic_platform_smc(uint32_t smc_fid, 85 uint64_t x1, 86 uint64_t x2, 87 uint64_t x3, 88 uint64_t x4, 89 void *cookie, 90 void *handle, 91 uint64_t flags) 92 { 93 switch(smc_fid) { 94 case SMC_FC_DEBUG_PUTC: 95 trusty_dputc(x1, is_caller_secure(flags)); 96 SMC_RET1(handle, 0); 97 98 case SMC_FC_GET_REG_BASE: 99 case SMC_FC64_GET_REG_BASE: 100 SMC_RET1(handle, trusty_get_reg_base(x1)); 101 102 default: 103 NOTICE("%s(0x%x, 0x%lx) unknown smc\n", __func__, smc_fid, x1); 104 SMC_RET1(handle, SMC_UNK); 105 } 106 } 107 108 /* Define a SPD runtime service descriptor for fast SMC calls */ 109 DECLARE_RT_SVC( 110 trusty_fast, 111 112 SMC_ENTITY_PLATFORM_MONITOR, 113 SMC_ENTITY_PLATFORM_MONITOR, 114 SMC_TYPE_FAST, 115 NULL, 116 trusty_generic_platform_smc 117 ); 118 119