1*2132c707SSona Mathew /* 2*2132c707SSona Mathew * Copyright (c) 2025, Arm Limited. All rights reserved. 3*2132c707SSona Mathew * 4*2132c707SSona Mathew * SPDX-License-Identifier: BSD-3-Clause 5*2132c707SSona Mathew */ 6*2132c707SSona Mathew #include <errno.h> 7*2132c707SSona Mathew #include <stdint.h> 8*2132c707SSona Mathew #include <string.h> 9*2132c707SSona Mathew #include "rmmd_private.h" 10*2132c707SSona Mathew #include <common/debug.h> 11*2132c707SSona Mathew #include <lib/spinlock.h> 12*2132c707SSona Mathew #include <plat/common/platform.h> 13*2132c707SSona Mathew #include <services/rmmd_svc.h> 14*2132c707SSona Mathew #include <smccc_helpers.h> 15*2132c707SSona Mathew 16*2132c707SSona Mathew #define DIR_BIT_SHIFT 0xB 17*2132c707SSona Mathew #define KEYSET_BIT_SHIFT 0xC 18*2132c707SSona Mathew #define STREAM_ID_MASK 0xFF 19*2132c707SSona Mathew #define SUBSTREAM_MASK 0x7 20*2132c707SSona Mathew #define SUBSTREAM_SHIFT 0x8 21*2132c707SSona Mathew #define MAX_STREAM_ID 32U 22*2132c707SSona Mathew #define MAX_SUBSTREAM 3U 23*2132c707SSona Mathew 24*2132c707SSona Mathew bool extract_ide_stream_info(uint64_t ide_stream_info) 25*2132c707SSona Mathew { 26*2132c707SSona Mathew uint8_t keyset, dir; 27*2132c707SSona Mathew uint8_t stream_id, substream; 28*2132c707SSona Mathew 29*2132c707SSona Mathew /* Extract keyset, dir, substream and stream ID */ 30*2132c707SSona Mathew keyset = (ide_stream_info >> KEYSET_BIT_SHIFT) & 0x1; 31*2132c707SSona Mathew dir = (ide_stream_info >> DIR_BIT_SHIFT) & 0x1; 32*2132c707SSona Mathew stream_id = ide_stream_info & STREAM_ID_MASK; 33*2132c707SSona Mathew substream = (ide_stream_info >> SUBSTREAM_SHIFT) & SUBSTREAM_MASK; 34*2132c707SSona Mathew 35*2132c707SSona Mathew if ((stream_id >= MAX_STREAM_ID) || (substream >= MAX_SUBSTREAM)) { 36*2132c707SSona Mathew ERROR("invalid input: stream_id = %x, substream = %x\n", stream_id, substream); 37*2132c707SSona Mathew return false; 38*2132c707SSona Mathew } 39*2132c707SSona Mathew 40*2132c707SSona Mathew VERBOSE("keyset = %d, dir = %d, stream_id = %d and substream = %d\n", keyset, dir, 41*2132c707SSona Mathew stream_id, substream); 42*2132c707SSona Mathew 43*2132c707SSona Mathew return true; 44*2132c707SSona Mathew } 45*2132c707SSona Mathew 46*2132c707SSona Mathew int rmmd_el3_ide_key_program(uint64_t ecam_address, uint64_t rp_id, 47*2132c707SSona Mathew uint64_t ide_stream_info, rp_ide_key_info_t *ide_key_info_ptr, 48*2132c707SSona Mathew uint64_t request_id, uint64_t cookie) 49*2132c707SSona Mathew { 50*2132c707SSona Mathew int err; 51*2132c707SSona Mathew 52*2132c707SSona Mathew /* TODO: Do validation of params */ 53*2132c707SSona Mathew 54*2132c707SSona Mathew VERBOSE("IDE_KEY_PROG: ecam address = 0x%lx and rp_id = 0x%lx\n", ecam_address, rp_id); 55*2132c707SSona Mathew 56*2132c707SSona Mathew if (!extract_ide_stream_info(ide_stream_info)) { 57*2132c707SSona Mathew err = E_RMM_INVAL; 58*2132c707SSona Mathew goto exit_fn; 59*2132c707SSona Mathew } 60*2132c707SSona Mathew 61*2132c707SSona Mathew err = plat_rmmd_el3_ide_key_program(ecam_address, rp_id, ide_stream_info, 62*2132c707SSona Mathew ide_key_info_ptr, request_id, cookie); 63*2132c707SSona Mathew 64*2132c707SSona Mathew assert(err == E_RMM_OK || err == E_RMM_AGAIN || err == E_RMM_INVAL || 65*2132c707SSona Mathew err == E_RMM_IN_PROGRESS || err == E_RMM_UNK || err == E_RMM_FAULT); 66*2132c707SSona Mathew 67*2132c707SSona Mathew exit_fn: 68*2132c707SSona Mathew return err; 69*2132c707SSona Mathew } 70*2132c707SSona Mathew 71*2132c707SSona Mathew int rmmd_el3_ide_key_set_go(uint64_t ecam_address, uint64_t rp_id, 72*2132c707SSona Mathew uint64_t ide_stream_info, uint64_t request_id, 73*2132c707SSona Mathew uint64_t cookie) 74*2132c707SSona Mathew { 75*2132c707SSona Mathew int err; 76*2132c707SSona Mathew 77*2132c707SSona Mathew /* TODO: Do validation of params */ 78*2132c707SSona Mathew 79*2132c707SSona Mathew VERBOSE("IDE_KEY_SET_GO: ecam address = 0x%lx and rp_id = 0x%lx\n", ecam_address, rp_id); 80*2132c707SSona Mathew 81*2132c707SSona Mathew if (!extract_ide_stream_info(ide_stream_info)) { 82*2132c707SSona Mathew err = E_RMM_INVAL; 83*2132c707SSona Mathew goto exit_fn; 84*2132c707SSona Mathew } 85*2132c707SSona Mathew 86*2132c707SSona Mathew err = plat_rmmd_el3_ide_key_set_go(ecam_address, rp_id, ide_stream_info, 87*2132c707SSona Mathew request_id, cookie); 88*2132c707SSona Mathew 89*2132c707SSona Mathew assert(err == E_RMM_OK || err == E_RMM_AGAIN || err == E_RMM_INVAL || 90*2132c707SSona Mathew err == E_RMM_IN_PROGRESS || err == E_RMM_UNK || err == E_RMM_FAULT); 91*2132c707SSona Mathew 92*2132c707SSona Mathew exit_fn: 93*2132c707SSona Mathew return err; 94*2132c707SSona Mathew } 95*2132c707SSona Mathew 96*2132c707SSona Mathew int rmmd_el3_ide_key_set_stop(uint64_t ecam_address, uint64_t rp_id, 97*2132c707SSona Mathew uint64_t ide_stream_info, uint64_t request_id, 98*2132c707SSona Mathew uint64_t cookie) 99*2132c707SSona Mathew { 100*2132c707SSona Mathew int err; 101*2132c707SSona Mathew 102*2132c707SSona Mathew /* TODO: Do validation of params */ 103*2132c707SSona Mathew 104*2132c707SSona Mathew VERBOSE("IDE_KEY_SET_STOP: ecam address = 0x%lx and rp_id = 0x%lx\n", ecam_address, rp_id); 105*2132c707SSona Mathew 106*2132c707SSona Mathew if (!extract_ide_stream_info(ide_stream_info)) { 107*2132c707SSona Mathew err = E_RMM_INVAL; 108*2132c707SSona Mathew goto exit_fn; 109*2132c707SSona Mathew } 110*2132c707SSona Mathew 111*2132c707SSona Mathew err = plat_rmmd_el3_ide_key_set_stop(ecam_address, rp_id, ide_stream_info, 112*2132c707SSona Mathew request_id, cookie); 113*2132c707SSona Mathew 114*2132c707SSona Mathew assert(err == E_RMM_OK || err == E_RMM_AGAIN || err == E_RMM_INVAL || 115*2132c707SSona Mathew err == E_RMM_IN_PROGRESS || err == E_RMM_UNK || err == E_RMM_FAULT); 116*2132c707SSona Mathew 117*2132c707SSona Mathew exit_fn: 118*2132c707SSona Mathew return err; 119*2132c707SSona Mathew } 120*2132c707SSona Mathew 121*2132c707SSona Mathew int rmmd_el3_ide_km_pull_response(uint64_t ecam_address, uint64_t rp_id, 122*2132c707SSona Mathew uint64_t *req_resp, uint64_t *request_id, 123*2132c707SSona Mathew uint64_t *cookie) 124*2132c707SSona Mathew { 125*2132c707SSona Mathew int err; 126*2132c707SSona Mathew 127*2132c707SSona Mathew /* TODO: Do validation of params */ 128*2132c707SSona Mathew 129*2132c707SSona Mathew VERBOSE("IDE_KM_PULL: ecam address = 0x%lx, rp_id = 0x%lx\n", ecam_address, rp_id); 130*2132c707SSona Mathew 131*2132c707SSona Mathew err = plat_rmmd_el3_ide_km_pull_response(ecam_address, rp_id, req_resp, request_id, cookie); 132*2132c707SSona Mathew 133*2132c707SSona Mathew assert(err == E_RMM_OK || err == E_RMM_AGAIN || err == E_RMM_INVAL || 134*2132c707SSona Mathew err == E_RMM_IN_PROGRESS || err == E_RMM_UNK || err == E_RMM_FAULT); 135*2132c707SSona Mathew 136*2132c707SSona Mathew return err; 137*2132c707SSona Mathew } 138