Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of OmniWheels by
register_gateway.h
00001 /* 00002 * Copyright (c) 2015-2015, 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_REGISTER_GATEWAY_H__ 00018 #define __UVISOR_API_REGISTER_GATEWAY_H__ 00019 00020 #include "api/inc/register_gateway_exports.h" 00021 #include "api/inc/uvisor_exports.h" 00022 #include "api/inc/svc_exports.h" 00023 #include <stdint.h> 00024 00025 /** Get the offset of a struct member. 00026 * @internal 00027 */ 00028 #define __UVISOR_OFFSETOF(type, member) ((uint32_t) (&(((type *)(0))->member))) 00029 00030 /** Generate the SVCall opcode from the SVC ID. */ 00031 #define UVISOR_SVC_OPCODE(id) ((uint16_t) (0xDF00 | ((id) & 0xFF))) 00032 00033 /** Generate the opcode of the 16-bit Thumb-2 16-bit T2 encoding of the branch 00034 * instruction. 00035 * @internal 00036 * @note The branch instruction is encoded according to the Thumb-2 immediate 00037 * encoding rules: 00038 * <instr_addr>: B.N <label> 00039 * imm = (<label>_addr - PC) / 2 00040 * Where: 00041 * PC = <instr>_addr + 4 00042 * The +4 is to account for the pipelined PC at the time of the branch 00043 * instruction. See ARM DDI 0403E.b page A4-102 for more details. 00044 * @param instr[in] Address of the branch instruction 00045 * @param label[in] Address of the label 00046 * @returns the 16-bit encoding of the B.N <label> instruction. 00047 */ 00048 #define BRANCH_OPCODE(instr, label) \ 00049 (uint16_t) (0xE000 | (uint8_t) ((((uint32_t) (label) - ((uint32_t) (instr) + 4)) / 2) & 0xFF)) 00050 00051 /** `BX LR` encoding 00052 * @internal 00053 */ 00054 #define BXLR ((uint16_t) 0x4770) 00055 00056 /** Register Gateway - Read operation 00057 * 00058 * This macro provides an API to perform 32-bit read operations on restricted 00059 * registers. Such accesses are assembled into a read-only flash structure that 00060 * is read and validated by uVisor before performing the operation. 00061 * 00062 * @warning This API currently only supports link-time known value for the 00063 * address, operation and mask. 00064 * 00065 * @param box_name[in] The name of the source box as decalred in 00066 * `UVISOR_BOX_CONFIG`. 00067 * @param shared[in] Whether the gateway can be shared with other boxes or 00068 * not. Two values are available: UVISOR_RGW_SHARED, 00069 * UVISOR_RGW_EXCLUSIVE. 00070 * @param addr[in] The address for the data access. 00071 * @param operation[in] The operation to perform at the address for the read. It 00072 * is chosen among the `UVISOR_RGW_OP_*` macros. 00073 * @param mask[in] The mask to apply for the read operation. 00074 * @returns The value read from address using the operation and mask provided 00075 * (or their respective defaults if they have not been provided). 00076 */ 00077 #define uvisor_read(box_name, shared, addr, op, msk) \ 00078 ({ \ 00079 /* Instanstiate the gateway. This gets resolved at link-time. */ \ 00080 UVISOR_ALIGN(4) static TRegisterGateway const register_gateway = { \ 00081 .svc_opcode = UVISOR_SVC_OPCODE(UVISOR_SVC_ID_REGISTER_GATEWAY), \ 00082 .branch = BRANCH_OPCODE(__UVISOR_OFFSETOF(TRegisterGateway, branch), \ 00083 __UVISOR_OFFSETOF(TRegisterGateway, bxlr)), \ 00084 .magic = UVISOR_REGISTER_GATEWAY_MAGIC, \ 00085 .box_ptr = (uint32_t) & box_name ## _cfg_ptr, \ 00086 .address = (uint32_t) addr, \ 00087 .mask = msk, \ 00088 .operation = UVISOR_RGW_OP(op, sizeof(*addr), shared), \ 00089 .bxlr = BXLR \ 00090 }; \ 00091 \ 00092 /* Pointer to the register gateway we just created. The pointer is 00093 * located in a discoverable linker section. */ \ 00094 __attribute__((section(".keep.uvisor.register_gateway_ptr"))) \ 00095 static uint32_t const register_gateway_ptr = (uint32_t) ®ister_gateway; \ 00096 (void) register_gateway_ptr; \ 00097 \ 00098 /* Call the actual gateway. */ \ 00099 uint32_t result = ((uint32_t (*)(void)) ((uint32_t) ®ister_gateway | 1))(); \ 00100 (typeof(*addr)) result; \ 00101 }) 00102 00103 /** Register Gateway - Write operation 00104 * 00105 * This macro provides an API to perform 32-bit write operations on restricted 00106 * registers. Such accesses are assembled into a read-only flash structure that 00107 * is read and validated by uVisor before performing the operation. 00108 * 00109 * @warning This API currently only supports link-time known value for the 00110 * address, operation and mask. 00111 * 00112 * @param box_name[in] The name of the source box as decalred in 00113 * `UVISOR_BOX_CONFIG`. 00114 * @param shared[in] Whether the gateway can be shared with other boxes or 00115 * not. Two values are available: UVISOR_RGW_SHARED, 00116 * UVISOR_RGW_EXCLUSIVE. 00117 * @param addr[in] The address for the data access. 00118 * @param val[in] The value to write at address. 00119 * @param operation[in] The operation to perform at the address for the read. It 00120 * is chosen among the `UVISOR_RGW_OP_*` macros. 00121 * @param mask[in] The mask to apply for the write operation. 00122 */ 00123 #define uvisor_write(box_name, shared, addr, val, op, msk) \ 00124 { \ 00125 /* Instanstiate the gateway. This gets resolved at link-time. */ \ 00126 UVISOR_ALIGN(4) static TRegisterGateway const register_gateway = { \ 00127 .svc_opcode = UVISOR_SVC_OPCODE(UVISOR_SVC_ID_REGISTER_GATEWAY), \ 00128 .branch = BRANCH_OPCODE(__UVISOR_OFFSETOF(TRegisterGateway, branch), \ 00129 __UVISOR_OFFSETOF(TRegisterGateway, bxlr)), \ 00130 .magic = UVISOR_REGISTER_GATEWAY_MAGIC, \ 00131 .box_ptr = (uint32_t) & box_name ## _cfg_ptr, \ 00132 .address = (uint32_t) addr, \ 00133 .mask = msk, \ 00134 .operation = UVISOR_RGW_OP(op, sizeof(*addr), shared), \ 00135 .bxlr = BXLR \ 00136 }; \ 00137 \ 00138 /* Pointer to the register gateway we just created. The pointer is 00139 * located in a discoverable linker section. */ \ 00140 __attribute__((section(".keep.uvisor.register_gateway_ptr"))) \ 00141 static uint32_t const register_gateway_ptr = (uint32_t) ®ister_gateway; \ 00142 (void) register_gateway_ptr; \ 00143 \ 00144 /* Call the actual gateway. 00145 * The value is passed as the first argument. */ \ 00146 ((void (*)(uint32_t)) ((uint32_t) ((uint32_t) ®ister_gateway | 1)))((uint32_t) (val)); \ 00147 } 00148 00149 /** Get the selected bits at the target address. 00150 * @param box_name[in] Box name as defined by the uVisor box configuration 00151 * macro `UVISOR_BOX_CONFIG` 00152 * @param shared[in] Whether the gateway can be shared with other boxes or 00153 * not. Two values are available: UVISOR_RGW_SHARED, 00154 * UVISOR_RGW_EXCLUSIVE. 00155 * @param address[in] Target address 00156 * @param mask[in] Bits to select out of the target address 00157 * @returns The value `*address & mask`. 00158 */ 00159 #define UVISOR_BITS_GET(box_name, shared, address, mask) \ 00160 /* Register gateway implementation: 00161 * *address & mask */ \ 00162 uvisor_read(box_name, shared, address, UVISOR_RGW_OP_READ_AND, mask) 00163 00164 /** Check the selected bits at the target address. 00165 * @param box_name[in] Box name as defined by the uVisor box configuration 00166 * macro `UVISOR_BOX_CONFIG` 00167 * @param shared[in] Whether the gateway can be shared with other boxes or 00168 * not. Two values are available: UVISOR_RGW_SHARED, 00169 * UVISOR_RGW_EXCLUSIVE. 00170 * @param address[in] Address at which to check the bits 00171 * @param mask[in] Bits to select out of the target address 00172 * @returns The value `((*address & mask) == mask)`. 00173 */ 00174 #define UVISOR_BITS_CHECK(box_name, shared, address, mask) \ 00175 ((UVISOR_BITS_GET(box_name, shared, address, mask)) == (mask)) 00176 00177 /** Set the selected bits to 1 at the target address. 00178 * 00179 * Equivalent to: `*address |= mask`. 00180 * @param box_name[in] Box name as defined by the uVisor box configuration 00181 * macro `UVISOR_BOX_CONFIG` 00182 * @param shared[in] Whether the gateway can be shared with other boxes or 00183 * not. Two values are available: UVISOR_RGW_SHARED, 00184 * UVISOR_RGW_EXCLUSIVE. 00185 * @param address[in] Target address 00186 * @param mask[in] Bits to select out of the target address 00187 */ 00188 #define UVISOR_BITS_SET(box_name, shared, address, mask) \ 00189 /* Register gateway implementation: 00190 * *address |= (mask & mask) */ \ 00191 uvisor_write(box_name, shared, address, mask, UVISOR_RGW_OP_WRITE_OR, mask) 00192 00193 /** Clear the selected bits at the target address. 00194 * 00195 * Equivalent to: `*address &= ~mask`. 00196 * @param box_name[in] Box name as defined by the uVisor box configuration 00197 * macro `UVISOR_BOX_CONFIG` 00198 * @param shared[in] Whether the gateway can be shared with other boxes or 00199 * not. Two values are available: UVISOR_RGW_SHARED, 00200 * UVISOR_RGW_EXCLUSIVE. 00201 * @param address[in] Target address 00202 * @param mask[in] Bits to select out of the target address 00203 */ 00204 #define UVISOR_BITS_CLEAR(box_name, shared, address, mask) \ 00205 /* Register gateway implementation: 00206 * *address &= (0x00000000 | ~mask) */ \ 00207 uvisor_write(box_name, shared, address, 0x00000000, UVISOR_RGW_OP_WRITE_AND, mask) 00208 00209 /** Set the selected bits at the target address to the given value. 00210 * 00211 * Equivalent to: `*address = (*address & ~mask) | (value & mask)`. 00212 * @param box_name[in] Box name as defined by the uVisor box configuration 00213 * macro `UVISOR_BOX_CONFIG` 00214 * @param shared[in] Whether the gateway can be shared with other boxes or 00215 * not. Two values are available: UVISOR_RGW_SHARED, 00216 * UVISOR_RGW_EXCLUSIVE. 00217 * @param address[in] Target address 00218 * @param mask[in] Bits to select out of the target address 00219 * @param value[in] Value to write at the address location. Note: The value 00220 * must be already shifted to the correct bit position 00221 */ 00222 #define UVISOR_BITS_SET_VALUE(box_name, shared, address, mask, value) \ 00223 /* Register gateway implementation: 00224 * *address = (*address & ~mask) | (value & mask) */ \ 00225 uvisor_write(box_name, shared, address, value, UVISOR_RGW_OP_WRITE_REPLACE, mask) 00226 00227 /** Toggle the selected bits at the target address. 00228 * 00229 * Equivalent to: `*address ^= mask`. 00230 * @param box_name[in] Box name as defined by the uVisor box configuration 00231 * macro `UVISOR_BOX_CONFIG` 00232 * @param shared[in] Whether the gateway can be shared with other boxes or 00233 * not. Two values are available: UVISOR_RGW_SHARED, 00234 * UVISOR_RGW_EXCLUSIVE. 00235 * @param address[in] Target address 00236 * @param mask[in] Bits to select out of the target address 00237 */ 00238 #define UVISOR_BITS_TOGGLE(box_name, shared, address, mask) \ 00239 /* Register gateway implementation: 00240 * *address ^= (0xFFFFFFFF & mask) */ \ 00241 uvisor_write(box_name, shared, address, 0xFFFFFFFF, UVISOR_RGW_OP_WRITE_XOR, mask) 00242 00243 #endif /* __UVISOR_API_REGISTER_GATEWAY_H__ */
Generated on Fri Jul 22 2022 04:53:59 by
1.7.2
