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
extract_ide_stream_info(uint64_t ide_stream_info)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
rmmd_el3_ide_key_program(uint64_t ecam_address,uint64_t rp_id,uint64_t ide_stream_info,rp_ide_key_info_t * ide_key_info_ptr,uint64_t request_id,uint64_t cookie)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
rmmd_el3_ide_key_set_go(uint64_t ecam_address,uint64_t rp_id,uint64_t ide_stream_info,uint64_t request_id,uint64_t cookie)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
rmmd_el3_ide_key_set_stop(uint64_t ecam_address,uint64_t rp_id,uint64_t ide_stream_info,uint64_t request_id,uint64_t cookie)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
rmmd_el3_ide_km_pull_response(uint64_t ecam_address,uint64_t rp_id,uint64_t * req_resp,uint64_t * request_id,uint64_t * cookie)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