blob: 43455f1a621f7f91e5048a6db9320b9ddaa21f3c [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
67noreturn void hftest_service_main(const void *fdt_ptr)
68{
69 struct memiter args;
70 hftest_test_fn service;
71 struct hftest_context *ctx;
72 struct ffa_value ret;
73 struct fdt fdt;
J-Alves4dff3e92022-05-23 11:33:52 +010074 ffa_vm_id_t own_id = hf_vm_get_id();
75 struct mailbox_buffers mb = set_up_mailbox();
76 ffa_notifications_bitmap_t bitmap;
77 struct ffa_partition_msg *message = (struct ffa_partition_msg *)mb.recv;
Raghu Krishnamurthy50af6602021-12-12 15:23:09 -080078
79 /* Receive the name of the service to run. */
J-Alves4dff3e92022-05-23 11:33:52 +010080 ffa_msg_wait();
81
82 /*
83 * Expect to wake up with indirect message related to the next service
84 * to be executed.
85 */
86 ret = ffa_notification_get(own_id, 0,
87 FFA_NOTIFICATION_FLAG_BITMAP_SPM |
88 FFA_NOTIFICATION_FLAG_BITMAP_HYP);
89 ASSERT_EQ(ret.func, FFA_SUCCESS_32);
90 bitmap = ffa_notification_get_from_framework(ret);
91 ASSERT_TRUE(is_ffa_spm_buffer_full_notification(bitmap) ||
92 is_ffa_hyp_buffer_full_notification(bitmap));
93 ASSERT_EQ(own_id, ffa_rxtx_header_receiver(&message->header));
94 memiter_init(&args, message->payload, message->header.size);
95
96 /* Find service handler. */
Raghu Krishnamurthy50af6602021-12-12 15:23:09 -080097 service = find_service(&args);
98 EXPECT_EQ(ffa_rx_release().func, FFA_SUCCESS_32);
99
100 /* Check the service was found. */
101 if (service == NULL) {
102 HFTEST_LOG_FAILURE();
103 HFTEST_LOG(HFTEST_LOG_INDENT
104 "Unable to find requested service");
105 abort();
106 }
107
108 if (!fdt_struct_from_ptr(fdt_ptr, &fdt)) {
109 HFTEST_LOG(HFTEST_LOG_INDENT "Unable to access the FDT");
110 abort();
111 }
112
113 /* Clean the context. */
114 ctx = hftest_get_context();
115 memset_s(ctx, sizeof(*ctx), 0, sizeof(*ctx));
116 ctx->abort = abort;
J-Alves4dff3e92022-05-23 11:33:52 +0100117 ctx->send = mb.send;
118 ctx->recv = mb.recv;
119
120 /*
121 * The memory size argument is to be used only by VMs. It is part of
122 * the dt provided by the Hypervisor. SPs expect to receive their
123 * FF-A manifest which doesn't have a memory size field.
124 */
125 if (!IS_SP_ID(own_id) &&
126 !fdt_get_memory_size(&fdt, &ctx->memory_size)) {
Raghu Krishnamurthy50af6602021-12-12 15:23:09 -0800127 HFTEST_LOG_FAILURE();
128 HFTEST_LOG(HFTEST_LOG_INDENT
129 "No entry in the FDT on memory size details");
130 abort();
131 }
132
133 /* Pause so the next time cycles are given the service will be run. */
134 ffa_yield();
135
136 /* Let the service run. */
137 service();
138
139 /* Cleanly handle it if the service returns. */
140 if (ctx->failures) {
141 abort();
142 }
143
144 for (;;) {
145 /* Hang if the service returns. */
146 }
147}