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