blob: fc3f0383ae5b8ae9db4a5e102faa933908b4d4a2 [file] [log] [blame]
Miklos Balint386b8b52017-11-29 13:12:32 +00001/*
Jamie Foxd4c3c742020-02-17 16:08:40 +00002 * Copyright (c) 2017-2020, Arm Limited. All rights reserved.
Miklos Balint386b8b52017-11-29 13:12:32 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
Miklos Balint6a139ae2018-04-04 19:44:37 +02008#include <arm_cmse.h>
9
Ken Liu1f345b02020-05-30 21:11:05 +080010#include "tfm/tfm_core_svc.h"
Miklos Balint386b8b52017-11-29 13:12:32 +000011#include "tfm_secure_api.h"
Miklos Balint6a139ae2018-04-04 19:44:37 +020012#include "tfm_internal.h"
Mingyang Sun67a1c0e2020-06-04 17:18:16 +080013#include "tfm/tfm_spm_services_api.h"
Ken Liu1f345b02020-05-30 21:11:05 +080014#include "tfm/spm_api.h"
Jamie Foxcc31d402019-01-28 17:13:52 +000015#include "psa/service.h"
Miklos Balint386b8b52017-11-29 13:12:32 +000016
Summer Qine304f962020-02-20 11:03:55 +080017#ifndef TFM_PSA_API
Miklos Balint6a139ae2018-04-04 19:44:37 +020018nsfptr_t ns_entry;
19
20void jump_to_ns_code(void)
21{
Miklos Balint6a139ae2018-04-04 19:44:37 +020022 /* Calls the non-secure Reset_Handler to jump to the non-secure binary */
23 ns_entry();
24}
Miklos Balint386b8b52017-11-29 13:12:32 +000025
Miklos Balint386b8b52017-11-29 13:12:32 +000026__attribute__((naked))
Mate Toth-Pal21a74c92018-04-13 14:05:41 +020027int32_t tfm_core_get_caller_client_id(int32_t *caller_client_id)
28{
Antonio de Angelisf2dea5b2019-04-16 14:50:50 +010029 __ASM volatile(
Mate Toth-Pal21a74c92018-04-13 14:05:41 +020030 "SVC %0\n"
31 "BX LR\n"
32 : : "I" (TFM_SVC_GET_CALLER_CLIENT_ID));
33}
34
35__attribute__((naked))
Mate Toth-Pal179a1562019-11-08 11:40:27 +010036int32_t tfm_core_validate_secure_caller(void)
Miklos Balint4d487622018-10-03 14:04:54 +020037{
Antonio de Angelisf2dea5b2019-04-16 14:50:50 +010038 __ASM volatile(
Mate Toth-Pal179a1562019-11-08 11:40:27 +010039 "SVC %0\n"
40 "BX lr\n"
41 : : "I" (TFM_SVC_VALIDATE_SECURE_CALLER));
Miklos Balint4d487622018-10-03 14:04:54 +020042}
43
Mate Toth-Pal179a1562019-11-08 11:40:27 +010044#endif
45
Miklos Balint4d487622018-10-03 14:04:54 +020046__attribute__((naked))
47int32_t tfm_spm_request(void)
48{
Antonio de Angelisf2dea5b2019-04-16 14:50:50 +010049 __ASM volatile(
Miklos Balint4d487622018-10-03 14:04:54 +020050 "SVC %0\n"
51 "BX lr\n"
52 : : "I" (TFM_SVC_SPM_REQUEST));
53}
54
55__attribute__((naked))
Mate Toth-Pal179a1562019-11-08 11:40:27 +010056int32_t tfm_spm_request_reset_vote(void)
Miklos Balint386b8b52017-11-29 13:12:32 +000057{
Antonio de Angelisf2dea5b2019-04-16 14:50:50 +010058 __ASM volatile(
Mate Toth-Pal179a1562019-11-08 11:40:27 +010059 "MOVS R0, %0\n"
60 "B tfm_spm_request\n"
61 : : "I" (TFM_SPM_REQUEST_RESET_VOTE));
Miklos Balint386b8b52017-11-29 13:12:32 +000062}
63
Tamas Ban9ff535b2018-09-18 08:15:18 +010064__attribute__((naked))
Tamas Bana24ce042019-02-20 11:50:22 +000065int32_t tfm_core_get_boot_data(uint8_t major_type,
66 struct tfm_boot_data *boot_status,
67 uint32_t len)
Tamas Ban9ff535b2018-09-18 08:15:18 +010068{
Antonio de Angelisf2dea5b2019-04-16 14:50:50 +010069 __ASM volatile(
Tamas Ban9ff535b2018-09-18 08:15:18 +010070 "SVC %0\n"
71 "BX lr\n"
72 : : "I" (TFM_SVC_GET_BOOT_DATA));
73}
Mate Toth-Pal4341de02018-10-02 12:55:47 +020074
75__attribute__((naked))
76void tfm_enable_irq(psa_signal_t irq_signal)
77{
78 __ASM("SVC %0\n"
79 "BX LR\n"
80 : : "I" (TFM_SVC_ENABLE_IRQ));
81}
82
83__attribute__((naked))
84void tfm_disable_irq(psa_signal_t irq_signal)
85{
86 __ASM("SVC %0\n"
87 "BX LR\n"
88 : : "I" (TFM_SVC_DISABLE_IRQ));
89}
90
91#ifndef TFM_PSA_API
92
93__attribute__((naked))
94static psa_signal_t psa_wait_internal(psa_signal_t signal_mask,
95 uint32_t timeout)
96{
97 __ASM("SVC %0\n"
98 "BX LR\n"
99 : : "I" (TFM_SVC_PSA_WAIT));
100}
101
102psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout)
103{
104 /* FIXME: By using the 'WFI' instruction this function blocks until an
105 * interrupt happens. It is necessary to do this here as tfm_core_psa_wait
106 * runs with the priority of the SVC, so it cannot be interrupted, so
107 * waiting in it for the required interrupt to happen is not an option.
108 */
109 psa_signal_t actual_signal_mask;
110
111 while (1) {
112 actual_signal_mask = psa_wait_internal(signal_mask, timeout);
113 if ((actual_signal_mask & signal_mask) != 0) {
114 return actual_signal_mask;
115 }
116 __WFI();
117 }
118}
119
120__attribute__((naked))
121void psa_eoi(psa_signal_t irq_signal)
122{
123 __ASM("SVC %0\n"
124 "BX LR\n"
125 : : "I" (TFM_SVC_PSA_EOI));
126}
127
128#endif