Lee Kai Xuan / mbed-os

Fork of mbed-os by erkin yucel

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers svc_exports.h Source File

svc_exports.h

00001 /*
00002  * Copyright (c) 2013-2016, ARM Limited, All Rights Reserved
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License"); you may
00006  * not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  * http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00013  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 #ifndef __UVISOR_API_SVC_EXPORTS_H__
00018 #define __UVISOR_API_SVC_EXPORTS_H__
00019 
00020 #include "api/inc/uvisor_exports.h"
00021 #include <stdint.h>
00022 
00023 /* An SVCall takes a 8bit immediate, which is used as follows:
00024  *
00025  * For fast APIs:
00026  *
00027  *   7   6   5   4   3   2   1   0
00028  * .---.---.---.---.---.---.---.---.
00029  * | 1 | N | N | N | h | h | h | h |
00030  * '---'---'---'---'---'---'---'---'
00031  *   |   |_______|   |___________|
00032  *   |       |         |
00033  *   |       |         |
00034  *   |       |         |
00035  *   |       |        (h) Handler index in the hardcoded table (max 16)
00036  *   |       |
00037  *   |      (N) Number of arguments to pass to the handler (max 4)
00038  *   |
00039  *   SVCall mode: Fast
00040  *
00041  * For slow APIs:
00042  *
00043  *   7   6   5   4   3   2   1   0
00044  * .---.---.---.---.---.---.---.---.
00045  * | 0 | c | c | c | c | c | c | c |
00046  * '---'---'---'---'---'---'---'---'
00047  *   |   |_______________________|
00048  *   |               |
00049  *   |               |
00050  *   |              (c) Handler index in the custom table (max 128)
00051  *   |
00052  *   SVCall mode: Slow
00053  */
00054 
00055 /* 1 bit of the SVCall imm8 field is used to determine the mode, fast/slow. */
00056 #define UVISOR_SVC_MODE_FAST  1
00057 #define UVISOR_SVC_MODE_SLOW  0
00058 #define UVISOR_SVC_MODE_BIT   7
00059 #define UVISOR_SVC_MODE_MASK  ((uint8_t) (1 << UVISOR_SVC_MODE_BIT))
00060 #define UVISOR_SVC_MODE(mode) ((uint8_t) (((mode) << UVISOR_SVC_MODE_BIT) & UVISOR_SVC_MODE_MASK))
00061 
00062 /* 7 or 4 bits of the SVCall imm8 field are used to determine the table index,
00063  * depending on the mode, fast/slow. */
00064 #define UVISOR_SVC_FAST_INDEX_MAX  (1 << 4)
00065 #define UVISOR_SVC_SLOW_INDEX_MAX  (1 << 7)
00066 #define UVISOR_SVC_FAST_INDEX_BIT  0
00067 #define UVISOR_SVC_FAST_INDEX_MASK ((uint8_t) (0xF << UVISOR_SVC_FAST_INDEX_BIT))
00068 #define UVISOR_SVC_SLOW_INDEX_BIT  0
00069 #define UVISOR_SVC_SLOW_INDEX_MASK ((uint8_t) (0x7F << UVISOR_SVC_SLOW_INDEX_BIT))
00070 #define UVISOR_SVC_FAST_INDEX(index) ((uint8_t) (((index) << UVISOR_SVC_FAST_INDEX_BIT) & UVISOR_SVC_FAST_INDEX_MASK))
00071 #define UVISOR_SVC_SLOW_INDEX(index) ((uint8_t) (((index) << UVISOR_SVC_SLOW_INDEX_BIT) & UVISOR_SVC_SLOW_INDEX_MASK))
00072 
00073 /* When the SVC mode is "fast", the imm8 field also contains a specification of
00074  * the call interface (number of arguments).
00075  * This is needed for context switches, since the stack manipulation routines
00076  * need to know how many arguments to copy from source to destination. */
00077 #define UVISOR_SVC_FAST_NARGS_BIT         4
00078 #define UVISOR_SVC_FAST_NARGS_MASK        ((uint8_t) (0x7 << UVISOR_SVC_FAST_NARGS_BIT))
00079 #define UVISOR_SVC_FAST_NARGS_SET(nargs)  ((uint8_t) (((nargs) << UVISOR_SVC_FAST_NARGS_BIT) & UVISOR_SVC_FAST_NARGS_MASK))
00080 #define UVISOR_SVC_FAST_NARGS_GET(svc_id) (((uint8_t) (svc_id) & UVISOR_SVC_FAST_NARGS_MASK) >> UVISOR_SVC_FAST_NARGS_BIT)
00081 
00082 /* Macros to build the SVCall imm8 field.
00083  * For slow APIs only the SVC handler index is needed.
00084  * For fast APIs the SVC handler index and the number of arguments are needed. */
00085 #define UVISOR_SVC_CUSTOM_TABLE(index) ((uint8_t) (UVISOR_SVC_MODE(UVISOR_SVC_MODE_SLOW) | \
00086                                                    UVISOR_SVC_SLOW_INDEX(index)))
00087 #define UVISOR_SVC_FIXED_TABLE(index, nargs) ((uint8_t) (UVISOR_SVC_MODE(UVISOR_SVC_MODE_FAST) | \
00088                                                          UVISOR_SVC_FAST_INDEX(index) | \
00089                                                          UVISOR_SVC_FAST_NARGS_SET(nargs)))
00090 
00091 /* SVC immediate values for custom table */
00092 #define UVISOR_SVC_ID_ISR_SET               UVISOR_SVC_CUSTOM_TABLE(1)
00093 #define UVISOR_SVC_ID_ISR_GET               UVISOR_SVC_CUSTOM_TABLE(2)
00094 #define UVISOR_SVC_ID_IRQ_ENABLE            UVISOR_SVC_CUSTOM_TABLE(3)
00095 #define UVISOR_SVC_ID_IRQ_DISABLE           UVISOR_SVC_CUSTOM_TABLE(4)
00096 #define UVISOR_SVC_ID_IRQ_PEND_CLR          UVISOR_SVC_CUSTOM_TABLE(5)
00097 #define UVISOR_SVC_ID_IRQ_PEND_SET          UVISOR_SVC_CUSTOM_TABLE(6)
00098 #define UVISOR_SVC_ID_IRQ_PEND_GET          UVISOR_SVC_CUSTOM_TABLE(7)
00099 #define UVISOR_SVC_ID_IRQ_PRIO_SET          UVISOR_SVC_CUSTOM_TABLE(8)
00100 #define UVISOR_SVC_ID_IRQ_PRIO_GET          UVISOR_SVC_CUSTOM_TABLE(9)
00101 #define UVISOR_SVC_ID_BENCHMARK_CFG         UVISOR_SVC_CUSTOM_TABLE(10)
00102 #define UVISOR_SVC_ID_BENCHMARK_RST         UVISOR_SVC_CUSTOM_TABLE(11)
00103 #define UVISOR_SVC_ID_BENCHMARK_STOP        UVISOR_SVC_CUSTOM_TABLE(12)
00104 #define UVISOR_SVC_ID_HALT_USER_ERR         UVISOR_SVC_CUSTOM_TABLE(13)
00105 #define UVISOR_SVC_ID_IRQ_LEVEL_GET         UVISOR_SVC_CUSTOM_TABLE(14)
00106 #define UVISOR_SVC_ID_BOX_ID_SELF           UVISOR_SVC_CUSTOM_TABLE(15)
00107 #define UVISOR_SVC_ID_BOX_ID_CALLER         UVISOR_SVC_CUSTOM_TABLE(16)
00108 #define UVISOR_SVC_ID_BOX_NAMESPACE_FROM_ID UVISOR_SVC_CUSTOM_TABLE(17)
00109 #define UVISOR_SVC_ID_DEBUG_REBOOT          UVISOR_SVC_CUSTOM_TABLE(18)
00110 #define UVISOR_SVC_ID_DEBUG_REGISTER_BOX    UVISOR_SVC_CUSTOM_TABLE(19)
00111 #define UVISOR_SVC_ID_IRQ_DISABLE_ALL       UVISOR_SVC_CUSTOM_TABLE(20)
00112 #define UVISOR_SVC_ID_IRQ_ENABLE_ALL        UVISOR_SVC_CUSTOM_TABLE(21)
00113 #define UVISOR_SVC_ID_PAGE_MALLOC           UVISOR_SVC_CUSTOM_TABLE(22)
00114 #define UVISOR_SVC_ID_PAGE_FREE             UVISOR_SVC_CUSTOM_TABLE(23)
00115 
00116 /* SVC immediate values for hardcoded table (call from unprivileged) */
00117 #define UVISOR_SVC_ID_UNVIC_OUT           UVISOR_SVC_FIXED_TABLE(0, 0)
00118 /* Deprecated: UVISOR_SVC_ID_CX_IN(nargs) UVISOR_SVC_FIXED_TABLE(1, nargs) */
00119 /* Deprecated: UVISOR_SVC_ID_CX_OUT       UVISOR_SVC_FIXED_TABLE(2, 0) */
00120 #define UVISOR_SVC_ID_REGISTER_GATEWAY    UVISOR_SVC_FIXED_TABLE(3, 0)
00121 #define UVISOR_SVC_ID_BOX_INIT_FIRST      UVISOR_SVC_FIXED_TABLE(4, 0)
00122 #define UVISOR_SVC_ID_BOX_INIT_NEXT       UVISOR_SVC_FIXED_TABLE(5, 0)
00123 
00124 /* SVC immediate values for hardcoded table (call from privileged) */
00125 #define UVISOR_SVC_ID_UNVIC_IN         UVISOR_SVC_FIXED_TABLE(0, 0)
00126 
00127 /** Generate the SVCall opcode from the SVC ID. */
00128 #define UVISOR_SVC_OPCODE(id) ((uint16_t) 0xDF00 | (uint8_t) ((id) & 0xFF))
00129 
00130 /* macro to execute an SVCall; additional metadata can be provided, which will
00131  * be appended right after the svc instruction */
00132 /* note: the macro is implicitly overloaded to allow 0 to 4 32bits arguments */
00133 #if defined(__CC_ARM)
00134 
00135 #elif defined(__GNUC__)
00136 
00137 #define UVISOR_SVC(id, metadata, ...) \
00138     ({ \
00139         UVISOR_MACRO_REGS_ARGS(uint32_t, ##__VA_ARGS__); \
00140         UVISOR_MACRO_REGS_RETVAL(uint32_t, res); \
00141         asm volatile( \
00142             "svc %[svc_id]\n" \
00143             metadata \
00144             : UVISOR_MACRO_GCC_ASM_OUTPUT(res) \
00145             : UVISOR_MACRO_GCC_ASM_INPUT(__VA_ARGS__), \
00146               [svc_id] "I" ((id) & 0xFF) \
00147         ); \
00148         res; \
00149     })
00150 
00151 #define UVISOR_FUNCTION_CALL(dst_fn, ...) \
00152     ({ \
00153         UVISOR_MACRO_REGS_ARGS(uint32_t, ##__VA_ARGS__); \
00154         UVISOR_MACRO_REGS_RETVAL(uint32_t, res); \
00155         asm volatile( \
00156             "bl " UVISOR_TO_STRING(dst_fn) "\n" \
00157             : UVISOR_MACRO_GCC_ASM_OUTPUT(res) \
00158             : UVISOR_MACRO_GCC_ASM_INPUT(__VA_ARGS__) \
00159         ); \
00160         res; \
00161     })
00162 
00163 #endif /* defined(__CC_ARM) || defined(__GNUC__) */
00164 
00165 #endif /* __UVISOR_API_SVC_EXPORTS_H__ */