Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers secure_access.h Source File

secure_access.h

00001 /*
00002  * Copyright (c) 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_SECURE_ACCESS_H__
00018 #define __UVISOR_API_SECURE_ACCESS_H__
00019 
00020 #include "api/inc/uvisor_exports.h"
00021 #include "api/inc/vmpu_exports.h"
00022 #include <stddef.h>
00023 #include <stdint.h>
00024 
00025 static UVISOR_FORCEINLINE void uvisor_write32(uint32_t volatile * volatile addr, uint32_t val)
00026 {
00027     UVISOR_ASM_MEMORY_ACCESS(str, uint32_t, addr, val);
00028 }
00029 
00030 static UVISOR_FORCEINLINE void uvisor_write16(uint16_t volatile * volatile addr, uint16_t val)
00031 {
00032     UVISOR_ASM_MEMORY_ACCESS(strh, uint16_t, addr, val);
00033 }
00034 
00035 static UVISOR_FORCEINLINE void uvisor_write8(uint8_t volatile * volatile addr, uint8_t val)
00036 {
00037     UVISOR_ASM_MEMORY_ACCESS(strb, uint8_t, addr, val);
00038 }
00039 
00040 static UVISOR_FORCEINLINE uint32_t uvisor_read32(uint32_t volatile * volatile addr)
00041 {
00042     return UVISOR_ASM_MEMORY_ACCESS(ldr, uint32_t, addr);
00043 }
00044 
00045 static UVISOR_FORCEINLINE uint16_t uvisor_read16(uint16_t volatile * volatile addr)
00046 {
00047     return UVISOR_ASM_MEMORY_ACCESS(ldrh, uint16_t, addr);
00048 }
00049 
00050 static UVISOR_FORCEINLINE uint8_t uvisor_read8(uint8_t volatile * volatile addr)
00051 {
00052     return UVISOR_ASM_MEMORY_ACCESS(ldrb, uint8_t, addr);
00053 }
00054 
00055 /* The switch statement will be optimised away since the compiler already knows
00056  * the sizeof_type. */
00057 static UVISOR_FORCEINLINE void __address_write(size_t sizeof_type, volatile uint32_t *addr, uint32_t val)
00058 {
00059     switch(sizeof_type) {
00060         case 4:
00061             uvisor_write32((volatile uint32_t * volatile) addr, (uint32_t) val);
00062             break;
00063         case 2:
00064             uvisor_write16((volatile uint16_t * volatile) addr, (uint16_t) val);
00065             break;
00066         case 1:
00067             uvisor_write8((volatile uint8_t * volatile) addr, (uint8_t) val);
00068             break;
00069         default:
00070             uvisor_error(USER_NOT_ALLOWED);
00071             break;
00072     }
00073 }
00074 
00075 #define ADDRESS_WRITE(type, addr, val) __address_write(sizeof(type), (volatile uint32_t *) addr, (uint32_t) val)
00076 
00077 /* the conditional statement will be optimised away since the compiler already
00078  * knows the sizeof(type) */
00079 #define ADDRESS_READ(type, addr) \
00080     (sizeof(type) == 4 ? uvisor_read32((uint32_t volatile * volatile) (addr)) : \
00081      sizeof(type) == 2 ? uvisor_read16((uint16_t volatile * volatile) (addr)) : \
00082      sizeof(type) == 1 ? uvisor_read8((uint8_t volatile * volatile) (addr)) : 0)
00083 
00084 #define UNION_READ(type, addr, fieldU, fieldB) \
00085     ({ \
00086         type res; \
00087         res.fieldU = ADDRESS_READ(type, addr); \
00088         res.fieldB; \
00089     })
00090 
00091 #endif /* __UVISOR_API_SECURE_ACCESS_H__ */