blob: 480a235acbef5f05cb5b24b977301ad79b6da782 [file] [log] [blame]
Channagoud Kadabi723f6792015-01-29 13:26:06 -08001/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28#include <debug.h>
29#include <rpmb.h>
30#include <rpmb_listener.h>
31#include <qseecom_lk_api.h>
32
33#define RPMB_LSTNR_VERSION_2 0x2
34
35typedef enum
36{
37 TZ_CM_CMD_RPMB_INIT = 0x101, //257
38 TZ_CM_CMD_RPMB_READ, //258
39 TZ_CM_CMD_RPMB_WRITE, //259
40 TZ_CM_CMD_RPMB_PARTITION, //260
41} tz_rpmb_cmd_type;
42
43struct tz_device_init_req
44{
45 uint32_t cmd_id;
46 uint32_t version;
47}__PACKED;
48
49/* RPMB Init response message */
50struct tz_device_init_resp
51{
52 uint32_t cmd_id; /* Command ID */
53 uint32_t version; /* Messaging version from RPMB listener */
54 uint32_t status; /* RPMB init status */
55 uint32_t num_sectors; /* Size of RPMB (in sectors) */
56 uint32_t rel_wr_count; /* Reliable write count for the RPMB */
57 uint32_t dev_type; /* Storage device type (like eMMC or UFS) */
58 uint32_t reserved1; /* Reserved 1 */
59 uint32_t reserved2; /* Reserved 2 */
60 uint32_t reserved3; /* Reserved 3 */
61 uint32_t reserved4; /* Reserved 4 */
62}__PACKED;
63
64struct tz_rpmb_rw_req
65{
66 uint32_t cmd_id;
67 uint32_t num_sectors;
68 uint32_t req_buff_len;
69 uint32_t req_buff_offset;
Sridhar Parasuramc97e0542015-06-26 16:14:58 -070070 uint32_t version;
71 uint32_t rel_wr_count;
Channagoud Kadabi723f6792015-01-29 13:26:06 -080072}__PACKED;
73
74struct tz_rpmb_rw_resp
75{
76 uint32_t cmd_id;
77 int32_t status;
78 uint32_t res_buff_len;
79 uint32_t res_buff_offset;
Sridhar Parasuramc97e0542015-06-26 16:14:58 -070080 uint32_t version;
Channagoud Kadabi723f6792015-01-29 13:26:06 -080081}__PACKED;
82
83typedef int (*ListenerCallback)(void*, uint32_t);
84
85static void handle_init_request(void *buf, uint32_t sz)
86{
87 struct tz_device_init_req *init_req_p = NULL;
88 struct tz_device_init_resp *init_resp = (struct tz_device_init_resp*) buf;
89 struct rpmb_init_info *rpmb_info = NULL;
90
91 init_req_p = (struct tz_device_init_req *) buf;
92
93 rpmb_info = rpmb_get_init_info();
94
95 if (rpmb_info)
96 init_resp->status = 0;
97
98 init_resp->cmd_id = init_req_p->cmd_id;
99 init_resp->version = RPMB_LSTNR_VERSION_2;
Sridhar Parasuram552f6492015-09-08 11:58:52 -0700100 init_resp->num_sectors = rpmb_info->size;
Channagoud Kadabi723f6792015-01-29 13:26:06 -0800101 init_resp->rel_wr_count = rpmb_info->rel_wr_count;
102 init_resp->dev_type = rpmb_info->dev_type;
103}
104
105static void handle_rw_request(void *buf, uint32_t sz)
106{
107 struct tz_rpmb_rw_req *req_p = (struct tz_rpmb_rw_req *)buf;
108 struct tz_rpmb_rw_resp *resp_p = NULL;
109 uint32_t *req_buf = buf + req_p->req_buff_offset;
110 uint32_t *resp_buf = buf + sizeof(struct tz_rpmb_rw_resp);
111
112 resp_p = (struct tz_rpmb_rw_resp *) buf;
113
114 switch (req_p->cmd_id)
115 {
116 case TZ_CM_CMD_RPMB_READ:
117#if DEBUG_RPMB
118 dprintf(INFO, "Read Request received\n");
Sridhar Parasuramc97e0542015-06-26 16:14:58 -0700119 dprintf(INFO, "READ: RPMB_REL_RW_COUNT 0x%x\n", req_p->rel_wr_count);
Channagoud Kadabi723f6792015-01-29 13:26:06 -0800120#endif
121 resp_p->status = rpmb_read(req_buf, req_p->num_sectors, resp_buf, &resp_p->res_buff_len);
122 break;
123 case TZ_CM_CMD_RPMB_WRITE:
124#if DEBUG_RPMB
125 dprintf(INFO, "Write Request received\n");
Sridhar Parasuramc97e0542015-06-26 16:14:58 -0700126 dprintf(INFO, "WRITE: RPMB_REL_RW_COUNT 0x%x\n", req_p->rel_wr_count);
Channagoud Kadabi723f6792015-01-29 13:26:06 -0800127#endif
Sridhar Parasuramc97e0542015-06-26 16:14:58 -0700128 resp_p->status = rpmb_write(req_buf, req_p->num_sectors, req_p->rel_wr_count, resp_buf, &resp_p->res_buff_len);
Channagoud Kadabi723f6792015-01-29 13:26:06 -0800129 break;
130 default:
131 dprintf(CRITICAL, "Unsupported request command request: %u\n", req_p->cmd_id);
132 ASSERT(0);
133 };
134
135 resp_p->res_buff_offset = sizeof(struct tz_rpmb_rw_resp);
136 resp_p->cmd_id = req_p->cmd_id;
137}
138
139int rpmb_cmd_handler(void *buf, uint32_t sz)
140{
141 int ret = 0;
142 uint32_t cmd_id;
143
144 ASSERT(buf);
145
146 cmd_id = (uint32_t) *((uint32_t *)buf);
147
148 switch(cmd_id)
149 {
150 case TZ_CM_CMD_RPMB_READ:
151 case TZ_CM_CMD_RPMB_WRITE:
152 handle_rw_request(buf, sz);
153 break;
154 case TZ_CM_CMD_RPMB_INIT:
155#if DEBUG_RPMB
156 dprintf(INFO, "RPMB init received\n");
157#endif
158 handle_init_request(buf, sz);
159 break;
160 case TZ_CM_CMD_RPMB_PARTITION:
161#if DEBUG_RPMB
162 dprintf(INFO, "Partition init received\n");
163#endif
164 ret = -1;
165 break;
166 default:
167 /* Does qseecom need a response here? */
168 dprintf(CRITICAL, "Unsupported Request from qseecom: %d\n", cmd_id);
169 ASSERT(0);
170 };
171
172 return ret;
173}
174
175int rpmb_listener_start()
176{
177 int ret;
178 struct qseecom_listener_services rpmb_listener;
179
180 rpmb_listener.service_name = "RPMB system services";
181 rpmb_listener.id = RPMB_LSTNR_ID;
Sridhar Parasuramc97e0542015-06-26 16:14:58 -0700182 rpmb_listener.sb_size = 25 * 1024;
Channagoud Kadabi723f6792015-01-29 13:26:06 -0800183 rpmb_listener.service_cmd_handler = rpmb_cmd_handler;
184
185 ret = qseecom_register_listener(&rpmb_listener);
186
187 if (ret < 0)
188 dprintf(CRITICAL, "Failed to register rpmb listener\n");
189
190 return ret;
191}
192
193int rpmb_listener_stop(int id)
194{
195 int ret;
196
197 ret = qseecom_deregister_listener(id);
198
199 if (ret < 0)
200 dprintf(CRITICAL, "Failed to unregister rpmb listener\n");
201
202 return ret;
203}
204