Skip to content

Commit a8b4d5d

Browse files
author
Subrahmanya Lingappa
committed
test: add SYSTEM_SUSPEND service group coverage
Add a dedicated SYSTEM_SUSPEND test scenario and register it in the test object list. The scenario covers notification unsupported behavior, attributes for supported and unsupported suspend types, valid suspend callback flow, and invalid suspend type handling using a single-hart HSM fixture. Signed-off-by: Subrahmanya Lingappa <subrahmanya.lingappa@qti.qualcomm.com>
1 parent d0627a9 commit a8b4d5d

2 files changed

Lines changed: 304 additions & 0 deletions

File tree

test/objects.mk

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,8 @@ test-elfs-y += test_srvgrp_sysmsi
2323

2424
test_srvgrp_sysmsi-objs-y += test/test_log.o
2525
test_srvgrp_sysmsi-objs-y += test/test_common.o
26+
27+
test-elfs-y += test_srvgrp_syssusp
28+
29+
test_srvgrp_syssusp-objs-y += test/test_log.o
30+
test_srvgrp_syssusp-objs-y += test/test_common.o

test/test_srvgrp_syssusp.c

Lines changed: 299 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,299 @@
1+
// SPDX-License-Identifier: BSD-2-Clause
2+
/*
3+
* Copyright (c) 2024 Ventana Micro Systems Inc.
4+
*/
5+
6+
#include <librpmi.h>
7+
#include <stdio.h>
8+
#include "test_common.h"
9+
#include "test_log.h"
10+
11+
#define TEST_HART_ID 0
12+
#define TEST_EVENT_ID 0x0
13+
#define TEST_REQUEST_STATE_ENABLE 0x1
14+
#define TEST_RESUME_ADDR_LOW 0x80000000
15+
#define TEST_RESUME_ADDR_HIGH 0x0
16+
17+
static rpmi_uint32_t test_hartid_array[] = {
18+
TEST_HART_ID,
19+
};
20+
21+
static struct rpmi_system_suspend_type test_syssusp_types[] = {
22+
{
23+
.type = RPMI_SYSSUSP_TYPE_SUSPEND_TO_RAM,
24+
.attr = RPMI_SYSSUSP_ATTRS_FLAGS_RESUMEADDR,
25+
},
26+
};
27+
28+
static rpmi_uint32_t enable_notif_reqdata[] = {
29+
TEST_EVENT_ID,
30+
TEST_REQUEST_STATE_ENABLE,
31+
};
32+
33+
static rpmi_uint32_t enable_notif_expdata[] = {
34+
RPMI_ERR_NOTSUPP,
35+
};
36+
37+
static rpmi_uint32_t get_attrs_supp_reqdata[] = {
38+
RPMI_SYSSUSP_TYPE_SUSPEND_TO_RAM,
39+
};
40+
41+
static rpmi_uint32_t get_attrs_supp_expdata[] = {
42+
RPMI_SUCCESS,
43+
RPMI_SYSSUSP_ATTRS_FLAGS_SUSPENDTYPE | RPMI_SYSSUSP_ATTRS_FLAGS_RESUMEADDR,
44+
};
45+
46+
static rpmi_uint32_t get_attrs_notsupp_reqdata[] = {
47+
RPMI_SYSSUSP_TYPE_MAX,
48+
};
49+
50+
static rpmi_uint32_t get_attrs_notsupp_expdata[] = {
51+
RPMI_SUCCESS,
52+
0,
53+
};
54+
55+
static rpmi_uint32_t suspend_reqdata[] = {
56+
TEST_HART_ID,
57+
RPMI_SYSSUSP_TYPE_SUSPEND_TO_RAM,
58+
TEST_RESUME_ADDR_LOW,
59+
TEST_RESUME_ADDR_HIGH,
60+
};
61+
62+
static rpmi_uint32_t suspend_invalid_type_reqdata[] = {
63+
TEST_HART_ID,
64+
RPMI_SYSSUSP_TYPE_MAX,
65+
TEST_RESUME_ADDR_LOW,
66+
TEST_RESUME_ADDR_HIGH,
67+
};
68+
69+
static rpmi_uint32_t success_expdata[] = {
70+
RPMI_SUCCESS,
71+
};
72+
73+
static rpmi_uint32_t invalid_param_expdata[] = {
74+
RPMI_ERR_INVALID_PARAM,
75+
};
76+
77+
static rpmi_uint32_t prepare_count;
78+
static rpmi_uint32_t finalize_count;
79+
static rpmi_uint32_t resume_count;
80+
static rpmi_uint32_t last_hart_index;
81+
static rpmi_uint32_t last_suspend_type;
82+
static rpmi_uint64_t last_resume_addr;
83+
84+
static enum rpmi_hart_hw_state test_hart_get_hw_state(void *priv,
85+
rpmi_uint32_t hart_index)
86+
{
87+
return RPMI_HART_HW_STATE_STARTED;
88+
}
89+
90+
static struct rpmi_hsm_platform_ops test_hsm_ops = {
91+
.hart_get_hw_state = test_hart_get_hw_state,
92+
};
93+
94+
static enum rpmi_error
95+
test_system_suspend_prepare(void *priv, rpmi_uint32_t hart_index,
96+
const struct rpmi_system_suspend_type *syssusp_type,
97+
rpmi_uint64_t resume_addr)
98+
{
99+
prepare_count++;
100+
last_hart_index = hart_index;
101+
last_suspend_type = syssusp_type->type;
102+
last_resume_addr = resume_addr;
103+
return RPMI_SUCCESS;
104+
}
105+
106+
static rpmi_bool_t test_system_suspend_ready(void *priv, rpmi_uint32_t hart_index)
107+
{
108+
return true;
109+
}
110+
111+
static void test_system_suspend_finalize(void *priv, rpmi_uint32_t hart_index,
112+
const struct rpmi_system_suspend_type *syssusp_type,
113+
rpmi_uint64_t resume_addr)
114+
{
115+
finalize_count++;
116+
last_hart_index = hart_index;
117+
last_suspend_type = syssusp_type->type;
118+
last_resume_addr = resume_addr;
119+
}
120+
121+
static rpmi_bool_t test_system_suspend_can_resume(void *priv, rpmi_uint32_t hart_index)
122+
{
123+
return true;
124+
}
125+
126+
static enum rpmi_error
127+
test_system_suspend_resume(void *priv, rpmi_uint32_t hart_index,
128+
const struct rpmi_system_suspend_type *syssusp_type,
129+
rpmi_uint64_t resume_addr)
130+
{
131+
resume_count++;
132+
return RPMI_SUCCESS;
133+
}
134+
135+
static struct rpmi_syssusp_platform_ops test_syssusp_ops = {
136+
.system_suspend_prepare = test_system_suspend_prepare,
137+
.system_suspend_ready = test_system_suspend_ready,
138+
.system_suspend_finalize = test_system_suspend_finalize,
139+
.system_suspend_can_resume = test_system_suspend_can_resume,
140+
.system_suspend_resume = test_system_suspend_resume,
141+
};
142+
143+
static int test_suspend_callback_init(struct rpmi_test_scenario *scene,
144+
struct rpmi_test *test)
145+
{
146+
prepare_count = 0;
147+
finalize_count = 0;
148+
resume_count = 0;
149+
last_hart_index = -1U;
150+
last_suspend_type = RPMI_SYSSUSP_TYPE_MAX;
151+
last_resume_addr = 0;
152+
return 0;
153+
}
154+
155+
static int test_suspend_callback_verify(struct rpmi_test_scenario *scene,
156+
struct rpmi_test *test,
157+
struct rpmi_message *msg)
158+
{
159+
rpmi_uint64_t expected_resume_addr = TEST_RESUME_ADDR_LOW;
160+
161+
if (prepare_count != 1 || finalize_count != 1) {
162+
printf("%s: expected prepare/finalize once, got %d/%d\n",
163+
test->name, prepare_count, finalize_count);
164+
return 1;
165+
}
166+
167+
if (last_hart_index != 0 || last_suspend_type != RPMI_SYSSUSP_TYPE_SUSPEND_TO_RAM ||
168+
last_resume_addr != expected_resume_addr) {
169+
printf("%s: unexpected callback args hart=%d type=%d resume=0x%lx\n",
170+
test->name, last_hart_index, last_suspend_type,
171+
(unsigned long)last_resume_addr);
172+
return 1;
173+
}
174+
175+
return 0;
176+
}
177+
178+
static int test_syssusp_scenario_init(struct rpmi_test_scenario *scene)
179+
{
180+
struct rpmi_service_group *grp;
181+
struct rpmi_hsm *hsm;
182+
int ret;
183+
184+
ret = test_scenario_default_init(scene);
185+
if (ret)
186+
return RPMI_ERR_FAILED;
187+
188+
hsm = rpmi_hsm_create(ARRAY_SIZE(test_hartid_array),
189+
test_hartid_array, 0, NULL, &test_hsm_ops, NULL);
190+
if (!hsm) {
191+
printf("failed to create rpmi hsm");
192+
return RPMI_ERR_FAILED;
193+
}
194+
195+
grp = rpmi_service_group_syssusp_create(hsm,
196+
ARRAY_SIZE(test_syssusp_types),
197+
test_syssusp_types,
198+
&test_syssusp_ops, NULL);
199+
if (!grp) {
200+
printf("failed to create rpmi syssusp service group");
201+
return RPMI_ERR_FAILED;
202+
}
203+
204+
rpmi_context_add_group(scene->cntx, grp);
205+
return 0;
206+
}
207+
208+
static struct rpmi_test_scenario scenario_syssusp_default = {
209+
.name = "System Suspend Service Group",
210+
.shm_size = RPMI_SHM_SZ,
211+
.slot_size = RPMI_SLOT_SIZE,
212+
.max_num_groups = RPMI_SRVGRP_ID_MAX_COUNT,
213+
.priv = NULL,
214+
215+
.init = test_syssusp_scenario_init,
216+
.cleanup = test_scenario_default_cleanup,
217+
218+
.num_tests = 5,
219+
.tests = {
220+
{
221+
.name = "ENABLE NOTIFICATION TEST (notifications not supported)",
222+
.attrs = {
223+
.servicegroup_id = RPMI_SRVGRP_SYSTEM_SUSPEND,
224+
.service_id = RPMI_SYSSUSP_SRV_ENABLE_NOTIFICATION,
225+
.flags = RPMI_MSG_NORMAL_REQUEST,
226+
.request_data = enable_notif_reqdata,
227+
.request_data_len = sizeof(enable_notif_reqdata),
228+
.expected_data = enable_notif_expdata,
229+
.expected_data_len = sizeof(enable_notif_expdata),
230+
},
231+
.init_request_data = test_init_request_data_from_attrs,
232+
.init_expected_data = test_init_expected_data_from_attrs,
233+
},
234+
{
235+
.name = "GET ATTRIBUTES TEST (for supported suspend type)",
236+
.attrs = {
237+
.servicegroup_id = RPMI_SRVGRP_SYSTEM_SUSPEND,
238+
.service_id = RPMI_SYSSUSP_SRV_GET_ATTRIBUTES,
239+
.flags = RPMI_MSG_NORMAL_REQUEST,
240+
.request_data = get_attrs_supp_reqdata,
241+
.request_data_len = sizeof(get_attrs_supp_reqdata),
242+
.expected_data = get_attrs_supp_expdata,
243+
.expected_data_len = sizeof(get_attrs_supp_expdata),
244+
},
245+
.init_request_data = test_init_request_data_from_attrs,
246+
.init_expected_data = test_init_expected_data_from_attrs,
247+
},
248+
{
249+
.name = "GET ATTRIBUTES TEST (for unsupported suspend type)",
250+
.attrs = {
251+
.servicegroup_id = RPMI_SRVGRP_SYSTEM_SUSPEND,
252+
.service_id = RPMI_SYSSUSP_SRV_GET_ATTRIBUTES,
253+
.flags = RPMI_MSG_NORMAL_REQUEST,
254+
.request_data = get_attrs_notsupp_reqdata,
255+
.request_data_len = sizeof(get_attrs_notsupp_reqdata),
256+
.expected_data = get_attrs_notsupp_expdata,
257+
.expected_data_len = sizeof(get_attrs_notsupp_expdata),
258+
},
259+
.init_request_data = test_init_request_data_from_attrs,
260+
.init_expected_data = test_init_expected_data_from_attrs,
261+
},
262+
{
263+
.name = "SYSTEM SUSPEND (valid suspend type)",
264+
.attrs = {
265+
.servicegroup_id = RPMI_SRVGRP_SYSTEM_SUSPEND,
266+
.service_id = RPMI_SYSSUSP_SRV_SYSTEM_SUSPEND,
267+
.flags = RPMI_MSG_NORMAL_REQUEST,
268+
.request_data = suspend_reqdata,
269+
.request_data_len = sizeof(suspend_reqdata),
270+
.expected_data = success_expdata,
271+
.expected_data_len = sizeof(success_expdata),
272+
},
273+
.init_request_data = test_init_request_data_from_attrs,
274+
.init_expected_data = test_init_expected_data_from_attrs,
275+
.init = test_suspend_callback_init,
276+
.verify = test_suspend_callback_verify,
277+
},
278+
{
279+
.name = "SYSTEM SUSPEND (invalid suspend type)",
280+
.attrs = {
281+
.servicegroup_id = RPMI_SRVGRP_SYSTEM_SUSPEND,
282+
.service_id = RPMI_SYSSUSP_SRV_SYSTEM_SUSPEND,
283+
.flags = RPMI_MSG_NORMAL_REQUEST,
284+
.request_data = suspend_invalid_type_reqdata,
285+
.request_data_len = sizeof(suspend_invalid_type_reqdata),
286+
.expected_data = invalid_param_expdata,
287+
.expected_data_len = sizeof(invalid_param_expdata),
288+
},
289+
.init_request_data = test_init_request_data_from_attrs,
290+
.init_expected_data = test_init_expected_data_from_attrs,
291+
},
292+
},
293+
};
294+
295+
int main(int argc, char *argv[])
296+
{
297+
printf("Test System Suspend Service Group\n");
298+
return test_scenario_execute(&scenario_syssusp_default);
299+
}

0 commit comments

Comments
 (0)