blob: 5ceead6717625edc25a8638c6e1456f6e1d86f47 [file] [log] [blame]
J-Alves35e61922021-05-06 10:01:05 +01001/*
2 * Copyright 2021 The Hafnium Authors.
3 *
4 * Use of this source code is governed by a BSD-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/BSD-3-Clause.
7 */
8
9#include <stdalign.h>
10#include <stdint.h>
11
Raghu Krishnamurthy50af6602021-12-12 15:23:09 -080012#include "hf/fdt_handler.h"
13#include "hf/ffa.h"
14#include "hf/memiter.h"
J-Alves35e61922021-05-06 10:01:05 +010015#include "hf/mm.h"
16#include "hf/std.h"
17
Raghu Krishnamurthy50af6602021-12-12 15:23:09 -080018#include "vmapi/hf/call.h"
19
J-Alves35e61922021-05-06 10:01:05 +010020#include "test/hftest.h"
21#include "test/hftest_impl.h"
J-Alves4dff3e92022-05-23 11:33:52 +010022#include "test/vmapi/ffa.h"
J-Alves35e61922021-05-06 10:01:05 +010023
24HFTEST_ENABLE();
25
Raghu Krishnamurthy50af6602021-12-12 15:23:09 -080026extern struct hftest_test hftest_begin[];
27extern struct hftest_test hftest_end[];
28
J-Alves35e61922021-05-06 10:01:05 +010029static struct hftest_context global_context;
30
31struct hftest_context *hftest_get_context(void)
32{
33 return &global_context;
34}
35
36noreturn void abort(void)
37{
38 HFTEST_LOG("Service contained failures.");
39 /* Cause a fault, as a secondary/SP can't power down the machine. */
40 *((volatile uint8_t *)1) = 1;
41
42 /* This should never be reached, but to make the compiler happy... */
43 for (;;) {
44 }
45}
Raghu Krishnamurthy50af6602021-12-12 15:23:09 -080046
47/** Find the service with the name passed in the arguments. */
48static hftest_test_fn find_service(struct memiter *args)
49{
50 struct memiter service_name;
51 struct hftest_test *test;
52
53 if (!memiter_parse_str(args, &service_name)) {
54 return NULL;
55 }
56
57 for (test = hftest_begin; test < hftest_end; ++test) {
58 if (test->kind == HFTEST_KIND_SERVICE &&
59 memiter_iseq(&service_name, test->name)) {
60 return test->fn;
61 }
62 }
63
64 return NULL;
65}
66
J-Alvese2354862022-12-08 17:35:51 +000067void hftest_context_init(struct hftest_context *ctx, void *send, void *recv)
68{
69 memset_s(ctx, sizeof(*ctx), 0, sizeof(*ctx));
70 ctx->abort = abort;
71 ctx->send = send;
72 ctx->recv = recv;
73}
74
Raghu Krishnamurthy50af6602021-12-12 15:23:09 -080075noreturn void hftest_service_main(const void *fdt_ptr)
76{
77 struct memiter args;
78 hftest_test_fn service;
79 struct hftest_context *ctx;
80 struct ffa_value ret;
81 struct fdt fdt;
J-Alves4dff3e92022-05-23 11:33:52 +010082 ffa_vm_id_t own_id = hf_vm_get_id();
83 struct mailbox_buffers mb = set_up_mailbox();
84 ffa_notifications_bitmap_t bitmap;
85 struct ffa_partition_msg *message = (struct ffa_partition_msg *)mb.recv;
Raghu Krishnamurthy50af6602021-12-12 15:23:09 -080086
87 /* Receive the name of the service to run. */
J-Alves8dacd982023-02-08 17:42:25 +000088 ret = ffa_msg_wait();
89 EXPECT_EQ(ret.func, FFA_RUN_32);
J-Alves4dff3e92022-05-23 11:33:52 +010090
91 /*
92 * Expect to wake up with indirect message related to the next service
93 * to be executed.
94 */
95 ret = ffa_notification_get(own_id, 0,
96 FFA_NOTIFICATION_FLAG_BITMAP_SPM |
97 FFA_NOTIFICATION_FLAG_BITMAP_HYP);
98 ASSERT_EQ(ret.func, FFA_SUCCESS_32);
99 bitmap = ffa_notification_get_from_framework(ret);
100 ASSERT_TRUE(is_ffa_spm_buffer_full_notification(bitmap) ||
101 is_ffa_hyp_buffer_full_notification(bitmap));
102 ASSERT_EQ(own_id, ffa_rxtx_header_receiver(&message->header));
103 memiter_init(&args, message->payload, message->header.size);
104
105 /* Find service handler. */
Raghu Krishnamurthy50af6602021-12-12 15:23:09 -0800106 service = find_service(&args);
107 EXPECT_EQ(ffa_rx_release().func, FFA_SUCCESS_32);
108
109 /* Check the service was found. */
110 if (service == NULL) {
111 HFTEST_LOG_FAILURE();
112 HFTEST_LOG(HFTEST_LOG_INDENT
113 "Unable to find requested service");
114 abort();
115 }
116
117 if (!fdt_struct_from_ptr(fdt_ptr, &fdt)) {
118 HFTEST_LOG(HFTEST_LOG_INDENT "Unable to access the FDT");
119 abort();
120 }
121
122 /* Clean the context. */
123 ctx = hftest_get_context();
J-Alvese2354862022-12-08 17:35:51 +0000124 hftest_context_init(ctx, mb.send, mb.recv);
J-Alves4dff3e92022-05-23 11:33:52 +0100125
126 /*
127 * The memory size argument is to be used only by VMs. It is part of
128 * the dt provided by the Hypervisor. SPs expect to receive their
129 * FF-A manifest which doesn't have a memory size field.
130 */
131 if (!IS_SP_ID(own_id) &&
132 !fdt_get_memory_size(&fdt, &ctx->memory_size)) {
Raghu Krishnamurthy50af6602021-12-12 15:23:09 -0800133 HFTEST_LOG_FAILURE();
134 HFTEST_LOG(HFTEST_LOG_INDENT
135 "No entry in the FDT on memory size details");
136 abort();
137 }
138
139 /* Pause so the next time cycles are given the service will be run. */
140 ffa_yield();
141
142 /* Let the service run. */
143 service();
144
145 /* Cleanly handle it if the service returns. */
146 if (ctx->failures) {
147 abort();
148 }
149
150 for (;;) {
151 /* Hang if the service returns. */
152 }
153}
Madhukar Pappireddy29235ec2022-12-22 10:18:41 -0600154
Kathleen Capellacf313482023-02-02 17:29:44 -0500155ffa_vm_id_t hftest_get_dir_req_source_id(void)
Madhukar Pappireddy29235ec2022-12-22 10:18:41 -0600156{
157 struct hftest_context *ctx = hftest_get_context();
158 return ctx->dir_req_source_id;
159}
160
161void hftest_set_dir_req_source_id(ffa_vm_id_t id)
162{
163 struct hftest_context *ctx = hftest_get_context();
164 ctx->dir_req_source_id = id;
165}