Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers unsupported_page_allocator.c Source File

unsupported_page_allocator.c

00001 /*
00002  * Copyright (c) 2015-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 #include "uvisor-lib/uvisor-lib.h"
00018 
00019 #if !(defined(UVISOR_PRESENT) && (UVISOR_PRESENT == 1))
00020 
00021 #include "cmsis.h"
00022 
00023 /* This is the fallback implementation for using the page allocator from uVisor
00024  * inside an OS as a normal function.
00025  * Be aware that the page allocator is not re-entrant, so the OS must provide a
00026  * mutex implementation to enable thread-safety!
00027  */
00028 #define DPRINTF(...) {}
00029 #define g_active_box 0
00030 #define vmpu_is_box_id_valid(...) 0
00031 #define vmpu_public_flash_addr(...) 1
00032 #define vmpu_sram_addr(...) 1
00033 #define vmpu_public_sram_addr(...) 1
00034 #define HALT_ERROR(id, ...) {}
00035 #define UVISOR_PAGE_ALLOCATOR_MUTEX_AQUIRE  page_allocator_mutex_aquire()
00036 #define UVISOR_PAGE_ALLOCATOR_MUTEX_RELEASE osMutexRelease(g_page_allocator_mutex_id)
00037 #define page_allocator_reset_faults(...) {}
00038 
00039 /* Forward declaration of the page allocator API. */
00040 int page_allocator_malloc(UvisorPageTable * const table);
00041 int page_allocator_free(const UvisorPageTable * const table);
00042 
00043 int uvisor_page_malloc(UvisorPageTable *const table)
00044 {
00045     return page_allocator_malloc(table);
00046 }
00047 
00048 int uvisor_page_free(const UvisorPageTable *const table)
00049 {
00050     return page_allocator_free(table);
00051 }
00052 
00053 /* Implement mutex for page allocator. */
00054 static osMutexId_t g_page_allocator_mutex_id = NULL;
00055 static osRtxMutex_t g_page_allocator_mutex_data;
00056 static osMutexDef_t g_page_allocator_mutex_attr = {
00057   .name = "uvisor_malloc_mutex",
00058   .attr_bits = 0, /* Non-recursive */
00059   .cb_mem = &g_page_allocator_mutex_data,
00060   .cb_size = sizeof(g_page_allocator_mutex_data)
00061 };
00062 
00063 static void page_allocator_mutex_aquire()
00064 {
00065     if (g_page_allocator_mutex_id == NULL) {
00066         /* Create mutex if not already done. */
00067         g_page_allocator_mutex_id = osMutexNew(&g_page_allocator_mutex_attr);
00068         if (g_page_allocator_mutex_id == NULL) {
00069             /* Mutex failed to be created. */
00070             return;
00071         }
00072     }
00073 
00074     osMutexAcquire(g_page_allocator_mutex_id, osWaitForever);
00075 }
00076 
00077 /* Alignment of MPU regions is not required anymore, however we still require
00078  * a 32B alignment, to have some page size granularity. */
00079 static inline int vmpu_is_region_size_valid(uint32_t size)
00080 {
00081     return ((size & ~31) == size);
00082 }
00083 static inline uint32_t vmpu_round_up_region(uint32_t addr, uint32_t size)
00084 {
00085     if (!vmpu_is_region_size_valid(size)) {
00086         return 0;
00087     }
00088     const uint32_t mask = size - 1;
00089     /* Adding the mask can overflow. */
00090     const uint32_t rounded_addr = addr + mask;
00091     /* Check for overflow. */
00092     if (rounded_addr < addr) {
00093         /* This means the address was too large to align. */
00094         return 0;
00095     }
00096     /* Mask the rounded address to get the aligned address. */
00097     return (rounded_addr & ~mask);
00098 }
00099 static inline uint32_t page_table_read(uint32_t addr)
00100 {
00101     return *((uint32_t *) addr);
00102 }
00103 static inline void page_table_write(uint32_t addr, uint32_t data)
00104 {
00105     *((uint32_t *) addr) = data;
00106 }
00107 
00108 /* Include the original page allocator source directly. */
00109 #include "../page_allocator.c_inc"
00110 
00111 #endif