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