blob: c58a5b8a9df31562f2e8be8bef050954df62a033 [file] [log] [blame]
Fuad Tabbaa48d1222019-12-09 15:42:32 +00001/*
2 * Copyright 2019 The Hafnium Authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "hf/dlog.h"
18
19#include "vmapi/hf/call.h"
20
21#include "../msr.h"
22#include "test/hftest.h"
23
24/**
25 * Tracks the number of times the exception handler has been invoked.
26 */
Fuad Tabbab0ef2a42019-12-19 11:19:25 +000027static int exception_handler_exception_count = 0;
Fuad Tabbaa48d1222019-12-09 15:42:32 +000028
29/**
30 * Sends the number of exceptions handled to the Primary VM.
31 */
Fuad Tabbab0ef2a42019-12-19 11:19:25 +000032void exception_handler_send_exception_count(void)
Fuad Tabbaa48d1222019-12-09 15:42:32 +000033{
34 void *send_buf = SERVICE_SEND_BUFFER();
35
Fuad Tabbab0ef2a42019-12-19 11:19:25 +000036 dlog("Sending exception_count %d to primary VM\n",
37 exception_handler_exception_count);
Fuad Tabbaa48d1222019-12-09 15:42:32 +000038 memcpy_s(send_buf, SPCI_MSG_PAYLOAD_MAX,
Fuad Tabbab0ef2a42019-12-19 11:19:25 +000039 (const void *)&exception_handler_exception_count,
40 sizeof(exception_handler_exception_count));
Fuad Tabbaa48d1222019-12-09 15:42:32 +000041 EXPECT_EQ(spci_msg_send(hf_vm_get_id(), HF_PRIMARY_VM_ID,
Fuad Tabbab0ef2a42019-12-19 11:19:25 +000042 sizeof(exception_handler_exception_count), 0)
Fuad Tabbaa48d1222019-12-09 15:42:32 +000043 .func,
44 SPCI_SUCCESS_32);
45}
46
47/**
48 * Receives the number of exceptions handled.
49 */
Fuad Tabbab0ef2a42019-12-19 11:19:25 +000050int exception_handler_receive_exception_count(
Fuad Tabbaa48d1222019-12-09 15:42:32 +000051 const struct spci_value *send_res,
52 const struct spci_memory_region *recv_buf)
53{
Fuad Tabbab0ef2a42019-12-19 11:19:25 +000054 int exception_count = *((const int *)recv_buf);
Fuad Tabbaa48d1222019-12-09 15:42:32 +000055
56 EXPECT_EQ(send_res->func, SPCI_MSG_SEND_32);
Fuad Tabbab0ef2a42019-12-19 11:19:25 +000057 EXPECT_EQ(spci_msg_send_size(*send_res), sizeof(exception_count));
Fuad Tabbaa48d1222019-12-09 15:42:32 +000058 EXPECT_EQ(spci_rx_release().func, SPCI_SUCCESS_32);
Fuad Tabbab0ef2a42019-12-19 11:19:25 +000059 return exception_count;
Fuad Tabbaa48d1222019-12-09 15:42:32 +000060}
61
62/**
63 * EL1 exception handler to use in unit test VMs.
64 * Skips the instruction that triggered the exception.
65 */
66bool exception_handler_skip_instruction(void)
67{
68 dlog("%s function is triggered!\n", __func__);
Fuad Tabbab0ef2a42019-12-19 11:19:25 +000069 ++exception_handler_exception_count;
Fuad Tabbaa48d1222019-12-09 15:42:32 +000070
71 /* Skip instruction that triggered the exception. */
72 uint64_t next_pc = read_msr(elr_el1);
73 next_pc += 4UL;
74 write_msr(elr_el1, next_pc);
75
76 /* Indicate that elr_el1 should not be restored. */
77 return true;
78}
79
80/**
81 * EL1 exception handler to use in unit test VMs.
82 * Yields control back to the hypervisor and sends the number of exceptions.
83 */
84bool exception_handler_yield(void)
85{
86 dlog("%s function is triggered!\n", __func__);
Fuad Tabbab0ef2a42019-12-19 11:19:25 +000087 ++exception_handler_exception_count;
Fuad Tabbaa48d1222019-12-09 15:42:32 +000088
Fuad Tabbab0ef2a42019-12-19 11:19:25 +000089 exception_handler_send_exception_count();
Fuad Tabbaa48d1222019-12-09 15:42:32 +000090
91 /* Indicate that elr_el1 should not be restored. */
92 return true;
93}
94
95/**
96 * Returns the number of times the instruction handler was invoked.
97 */
98int exception_handler_get_num(void)
99{
Fuad Tabbab0ef2a42019-12-19 11:19:25 +0000100 return exception_handler_exception_count;
Fuad Tabbaa48d1222019-12-09 15:42:32 +0000101}
102
103/**
104 * Resets the number of exceptions counter;
105 */
106void exception_handler_reset(void)
107{
Fuad Tabbab0ef2a42019-12-19 11:19:25 +0000108 exception_handler_exception_count = 0;
Fuad Tabbaa48d1222019-12-09 15:42:32 +0000109}