mirror of https://github.com/ARMmbed/mbed-os.git
Update uVisor page allocator and box initialization
parent
2a7f02033d
commit
7e006c769e
|
@ -1,7 +1,7 @@
|
|||
513 Milosch Meriac
|
||||
424 Alessandro Angelino
|
||||
18 Jaeden Amero
|
||||
18 Niklas Hauser
|
||||
511 Milosch Meriac
|
||||
433 Alessandro Angelino
|
||||
28 Niklas Hauser
|
||||
22 Jaeden Amero
|
||||
3 Hugo Vincent
|
||||
3 JaredCJR
|
||||
3 Jim Huang
|
||||
|
|
|
@ -1 +1 @@
|
|||
v0.9.17-alpha
|
||||
v0.9.20-alpha
|
||||
|
|
|
@ -46,7 +46,6 @@ UVISOR_EXTERN const uint32_t __uvisor_mode;
|
|||
0, \
|
||||
0, \
|
||||
0, \
|
||||
0, \
|
||||
NULL, \
|
||||
acl_list, \
|
||||
acl_list_count \
|
||||
|
@ -78,8 +77,7 @@ UVISOR_EXTERN const uint32_t __uvisor_mode;
|
|||
sizeof(RtxBoxIndex), \
|
||||
context_size, \
|
||||
__uvisor_box_heapsize, \
|
||||
__uvisor_box_main_function, \
|
||||
__uvisor_box_main_priority, \
|
||||
__uvisor_box_lib_config, \
|
||||
__uvisor_box_namespace, \
|
||||
acl_list, \
|
||||
acl_list_count \
|
||||
|
@ -123,9 +121,9 @@ UVISOR_EXTERN const uint32_t __uvisor_mode;
|
|||
/* Use this macro before UVISOR_BOX_CONFIG to define the function the main
|
||||
* thread of your box will use for its body. If you don't want a main thread,
|
||||
* too bad: you have to have one. */
|
||||
#define UVISOR_BOX_MAIN(function, priority) \
|
||||
static void (*const __uvisor_box_main_function)(void const *) = (function); \
|
||||
static const int32_t __uvisor_box_main_priority = (priority);
|
||||
#define UVISOR_BOX_MAIN(function, priority, stack_size) \
|
||||
static osThreadDef(function, priority, stack_size); \
|
||||
static const void * const __uvisor_box_lib_config = osThread(function);
|
||||
|
||||
#define UVISOR_BOX_HEAPSIZE(heap_size) \
|
||||
static const uint32_t __uvisor_box_heapsize = heap_size;
|
||||
|
|
|
@ -114,9 +114,12 @@
|
|||
#define UVISOR_SVC_ID_PAGE_FREE UVISOR_SVC_CUSTOM_TABLE(23)
|
||||
|
||||
/* SVC immediate values for hardcoded table (call from unprivileged) */
|
||||
#define UVISOR_SVC_ID_UNVIC_OUT UVISOR_SVC_FIXED_TABLE(0, 0)
|
||||
#define UVISOR_SVC_ID_REGISTER_GATEWAY UVISOR_SVC_FIXED_TABLE(3, 0)
|
||||
#define UVISOR_SVC_ID_BOX_MAIN_NEXT UVISOR_SVC_FIXED_TABLE(5, 0)
|
||||
#define UVISOR_SVC_ID_UNVIC_OUT UVISOR_SVC_FIXED_TABLE(0, 0)
|
||||
/* Deprecated: UVISOR_SVC_ID_CX_IN(nargs) UVISOR_SVC_FIXED_TABLE(1, nargs) */
|
||||
/* Deprecated: UVISOR_SVC_ID_CX_OUT UVISOR_SVC_FIXED_TABLE(2, 0) */
|
||||
#define UVISOR_SVC_ID_REGISTER_GATEWAY UVISOR_SVC_FIXED_TABLE(3, 0)
|
||||
#define UVISOR_SVC_ID_BOX_INIT_FIRST UVISOR_SVC_FIXED_TABLE(4, 0)
|
||||
#define UVISOR_SVC_ID_BOX_INIT_NEXT UVISOR_SVC_FIXED_TABLE(5, 0)
|
||||
|
||||
/* SVC immediate values for hardcoded table (call from privileged) */
|
||||
#define UVISOR_SVC_ID_UNVIC_IN UVISOR_SVC_FIXED_TABLE(0, 0)
|
||||
|
|
|
@ -104,13 +104,24 @@
|
|||
|
||||
#if defined(UVISOR_PRESENT) && UVISOR_PRESENT == 1
|
||||
|
||||
/** Round an address down to the closest 32-byte boundary.
|
||||
* @param address[in] The address to round.
|
||||
*/
|
||||
#define UVISOR_ROUND32_DOWN(address) ((address) & ~0x1FUL)
|
||||
|
||||
/** Round an address up to the closest 32-byte boundary.
|
||||
* @param address[in] The address to round.
|
||||
*/
|
||||
#define UVISOR_ROUND32_UP(address) UVISOR_ROUND32_DOWN((address) + 31UL)
|
||||
|
||||
|
||||
#if defined(ARCH_MPU_ARMv7M)
|
||||
#define UVISOR_REGION_ROUND_DOWN(x) ((x) & ~((1UL << UVISOR_REGION_BITS(x)) - 1))
|
||||
#define UVISOR_REGION_ROUND_UP(x) (1UL << UVISOR_REGION_BITS(x))
|
||||
#define UVISOR_STACK_SIZE_ROUND(x) UVISOR_REGION_ROUND_UP(x)
|
||||
#elif defined(ARCH_MPU_KINETIS)
|
||||
#define UVISOR_REGION_ROUND_DOWN(x) ((x) & ~0x1FUL)
|
||||
#define UVISOR_REGION_ROUND_UP(x) UVISOR_REGION_ROUND_DOWN((x) + 31UL)
|
||||
#define UVISOR_REGION_ROUND_DOWN(x) UVISOR_ROUND32_DOWN(x)
|
||||
#define UVISOR_REGION_ROUND_UP(x) UVISOR_ROUND32_UP(x)
|
||||
#define UVISOR_STACK_SIZE_ROUND(x) UVISOR_REGION_ROUND_UP((x) + (UVISOR_STACK_BAND_SIZE * 2))
|
||||
#else
|
||||
#error "Unknown MPU architecture. uvisor: Check your Makefile. uvisor-lib: Check if uVisor is supported"
|
||||
|
@ -158,8 +169,9 @@ typedef struct {
|
|||
/* Contains user provided size of box heap without guards of buffers. */
|
||||
uint32_t heap_size;
|
||||
|
||||
void (*main_function)(void const *argument);
|
||||
int32_t main_priority;
|
||||
/* Opaque-to-uVisor data that potentially contains uvisor-lib-specific or
|
||||
* OS-specific per-box configuration */
|
||||
const void * const lib_config;
|
||||
|
||||
const char * box_namespace;
|
||||
const UvisorBoxAclItem * const acl_list;
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <uvisor.h>
|
||||
#include "page_allocator.h"
|
||||
#include "page_allocator_faults.h"
|
||||
#include "mpu/vmpu_unpriv_access.h"
|
||||
#include "mpu/vmpu.h"
|
||||
#include "halt.h"
|
||||
|
@ -38,40 +39,31 @@
|
|||
|
||||
#endif /* defined(UVISOR_PRESENT) && (UVISOR_PRESENT == 1) */
|
||||
|
||||
/* We can only protect a small number of pages efficiently, so there should be
|
||||
* a relatively low limit to the number of pages.
|
||||
* By default a maximum of 16 pages are allowed. This can only be overridden
|
||||
* by the porting engineer for the current platform. */
|
||||
#ifndef UVISOR_PAGE_TABLE_MAX_COUNT
|
||||
#define UVISOR_PAGE_TABLE_MAX_COUNT ((uint32_t) 16)
|
||||
#endif
|
||||
/* The number of pages is decided by the page size. A small page size leads to
|
||||
* a lot of pages, however, number of pages is capped for efficiency.
|
||||
* Furthermore, when allocating large continous memory, a too small page size
|
||||
* will lead to allocation failures. This can only be overridden
|
||||
* by the porting engineer for the current platform. */
|
||||
#ifndef UVISOR_PAGE_SIZE_MINIMUM
|
||||
#define UVISOR_PAGE_SIZE_MINIMUM ((uint32_t) 1024)
|
||||
#endif
|
||||
#include "page_allocator_config.h"
|
||||
|
||||
/* The page box_id is the box id which is 8-bit large. */
|
||||
typedef uint8_t page_owner_t;
|
||||
/* Maps the page to the owning box handle. */
|
||||
static page_owner_t g_page_owner_table[UVISOR_PAGE_TABLE_MAX_COUNT];
|
||||
/* Define a unused value for the page table. */
|
||||
#define UVISOR_PAGE_UNUSED ((page_owner_t) (-1))
|
||||
|
||||
page_owner_t g_page_owner_table[UVISOR_PAGE_TABLE_MAX_COUNT];
|
||||
/* Contains the configured page size. */
|
||||
static uint32_t g_page_size;
|
||||
uint32_t g_page_size;
|
||||
/* Points to the beginning of the page heap. */
|
||||
static const void * g_page_heap_start;
|
||||
const void * g_page_heap_start;
|
||||
/* Points to the end of the page heap. */
|
||||
static const void * g_page_heap_end;
|
||||
const void * g_page_heap_end;
|
||||
/* Contains the number of free pages. */
|
||||
static uint8_t g_page_count_free;
|
||||
uint8_t g_page_count_free;
|
||||
/* Contains the total number of available pages. */
|
||||
static uint8_t g_page_count_total;
|
||||
uint8_t g_page_count_total;
|
||||
|
||||
/* Helper function maps pointer to page id, or UVISOR_PAGE_UNUSED. */
|
||||
uint8_t page_allocator_get_page_from_address(uint32_t address)
|
||||
{
|
||||
/* Range check the returned pointer. */
|
||||
if (address < (uint32_t) g_page_heap_start || address >= (uint32_t) g_page_heap_end) {
|
||||
return UVISOR_PAGE_UNUSED;
|
||||
}
|
||||
/* Compute the index for the pointer. */
|
||||
return (address - (uint32_t) g_page_heap_start) / g_page_size;
|
||||
}
|
||||
|
||||
void page_allocator_init(void * const heap_start, void * const heap_end, const uint32_t * const page_size)
|
||||
{
|
||||
|
@ -142,8 +134,9 @@ void page_allocator_init(void * const heap_start, void * const heap_end, const u
|
|||
(unsigned int) (g_page_size / 1024));
|
||||
|
||||
uint32_t page = 0;
|
||||
for (; page < g_page_count_total; page++) {
|
||||
for (; page < UVISOR_PAGE_TABLE_MAX_COUNT; page++) {
|
||||
g_page_owner_table[page] = UVISOR_PAGE_UNUSED;
|
||||
page_allocator_reset_faults(page);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,6 +180,8 @@ int page_allocator_malloc(UvisorPageTable * const table)
|
|||
if (g_page_owner_table[page] == UVISOR_PAGE_UNUSED) {
|
||||
/* Marry this page to the box id. */
|
||||
g_page_owner_table[page] = box_id;
|
||||
/* Reset the fault count for this page. */
|
||||
page_allocator_reset_faults(page);
|
||||
/* Get the pointer to the page. */
|
||||
void * ptr = (void *) g_page_heap_start + page * g_page_size;
|
||||
/* Zero the entire page before handing it out. */
|
||||
|
@ -239,14 +234,14 @@ int page_allocator_free(const UvisorPageTable * const table)
|
|||
int table_size = page_count;
|
||||
for (; table_size > 0; page_table++, table_size--) {
|
||||
void * page = (void *) page_table_read((uint32_t) page_table);
|
||||
/* Compute the index for the pointer. */
|
||||
uint8_t page_index = page_allocator_get_page_from_address((uint32_t) page);
|
||||
/* Range check the returned pointer. */
|
||||
if (page < g_page_heap_start || page >= g_page_heap_end) {
|
||||
if (page_index == UVISOR_PAGE_UNUSED) {
|
||||
DPRINTF("uvisor_page_free: FAIL: Pointer 0x%08x does not belong to any page!\n\n", (unsigned int) page);
|
||||
UVISOR_PAGE_ALLOCATOR_MUTEX_RELEASE;
|
||||
return UVISOR_ERROR_PAGE_INVALID_PAGE_ORIGIN;
|
||||
}
|
||||
/* Compute the index for the pointer. */
|
||||
uint32_t page_index = (page - g_page_heap_start) / g_page_size;
|
||||
/* Check if the page belongs to the caller. */
|
||||
if (g_page_owner_table[page_index] == box_id) {
|
||||
g_page_owner_table[page_index] = UVISOR_PAGE_UNUSED;
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __PAGE_ALLOCATOR_CONFIG_H__
|
||||
#define __PAGE_ALLOCATOR_CONFIG_H__
|
||||
/* This file can be compiled externally to provide the page allocator algorithm
|
||||
* for devices NOT supported by uVisor. For this purpose this file is copied as
|
||||
* is into the target build folder and compiled by the target build system. */
|
||||
|
||||
/* We can only protect a small number of pages efficiently, so there should be
|
||||
* a relatively low limit to the number of pages.
|
||||
* By default a maximum of 16 pages are allowed. This can only be overwritten
|
||||
* by the porting engineer for the current platform. */
|
||||
#ifndef UVISOR_PAGE_TABLE_MAX_COUNT
|
||||
#define UVISOR_PAGE_TABLE_MAX_COUNT ((uint32_t) 16)
|
||||
#endif
|
||||
/* The number of pages is decided by the page size. A small page size leads to
|
||||
* a lot of pages, however, number of pages is capped for efficiency.
|
||||
* Furthermore, when allocating large continous memory, a too small page size
|
||||
* will lead to allocation failures. This can only be overwritten
|
||||
* by the porting engineer for the current platform. */
|
||||
#ifndef UVISOR_PAGE_SIZE_MINIMUM
|
||||
#define UVISOR_PAGE_SIZE_MINIMUM ((uint32_t) 1024)
|
||||
#endif
|
||||
|
||||
/* The page box_id is the box id which is 8-bit large. */
|
||||
typedef uint8_t page_owner_t;
|
||||
/* Define a unused value for the page table. */
|
||||
#define UVISOR_PAGE_UNUSED ((page_owner_t) (-1))
|
||||
|
||||
#endif /* __PAGE_ALLOCATOR_CONFIG_H__ */
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "uvisor-lib/uvisor-lib.h"
|
||||
#include "mbed_interface.h"
|
||||
#include "cmsis_os.h"
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/* This function is called by uVisor in unprivileged mode. On this OS, we
|
||||
* create box main threads for the box. */
|
||||
void __uvisor_lib_box_init(void * lib_config)
|
||||
{
|
||||
osThreadId thread_id;
|
||||
osThreadDef_t * flash_thread_def = lib_config;
|
||||
osThreadDef_t thread_def;
|
||||
|
||||
/* Copy thread definition from flash to RAM. The thread definition is most
|
||||
* likely in flash, so we need to copy it to box-local RAM before we can
|
||||
* modify it. */
|
||||
memcpy(&thread_def, flash_thread_def, sizeof(thread_def));
|
||||
|
||||
/* Note that the box main thread stack is separate from the box stack. This
|
||||
* is because the thread must be created to use a different stack than the
|
||||
* stack osCreateThread() is called from, as context information is saved
|
||||
* to the thread stack by the call to osCreateThread(). */
|
||||
/* Allocate memory for the main thread from the process heap (which is
|
||||
* private to the process). This memory is never freed, even if the box's
|
||||
* main thread exits. */
|
||||
thread_def.stack_pointer = malloc_p(thread_def.stacksize);
|
||||
|
||||
if (thread_def.stack_pointer == NULL) {
|
||||
/* No process heap memory available */
|
||||
mbed_die();
|
||||
}
|
||||
|
||||
thread_id = osThreadCreate(&thread_def, NULL);
|
||||
|
||||
if (thread_id == NULL) {
|
||||
/* Failed to create thread */
|
||||
mbed_die();
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, ARM Limited, All Rights Reserved
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "uvisor-lib/uvisor-lib.h"
|
||||
#include "mbed_interface.h"
|
||||
#include "cmsis_os.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/* This function is called by uVisor in unprivileged mode to create box main
|
||||
* threads. */
|
||||
void __uvisor_lib_box_main_handler(
|
||||
void (*function)(void const *),
|
||||
int32_t priority,
|
||||
uint32_t stack_pointer,
|
||||
uint32_t stack_size)
|
||||
{
|
||||
osThreadId thread_id;
|
||||
osThreadDef_t thread_def;
|
||||
thread_def.pthread = function;
|
||||
thread_def.tpriority = priority;
|
||||
thread_def.stacksize = stack_size;
|
||||
thread_def.stack_pointer = malloc(stack_size); /* XXX */
|
||||
|
||||
thread_id = osThreadCreate(&thread_def, NULL);
|
||||
|
||||
if (thread_id == NULL) {
|
||||
mbed_die();
|
||||
}
|
||||
}
|
|
@ -111,7 +111,8 @@ static void * memory(void * ptr, size_t size, int heap, int operation)
|
|||
return NULL;
|
||||
}
|
||||
/* Check if we need to aquire the mutex. */
|
||||
int mutexed = (is_kernel_initialized() && (heap == HEAP_PROCESS));
|
||||
int mutexed = is_kernel_initialized() &&
|
||||
((heap == HEAP_PROCESS) || __uvisor_ps->index.box_heap == __uvisor_ps->index.active_heap);
|
||||
void * allocator = (heap == HEAP_PROCESS) ?
|
||||
(__uvisor_ps->index.box_heap) :
|
||||
(__uvisor_ps->index.active_heap);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#define HALT_ERROR(id, ...) {}
|
||||
#define UVISOR_PAGE_ALLOCATOR_MUTEX_AQUIRE page_allocator_mutex_aquire()
|
||||
#define UVISOR_PAGE_ALLOCATOR_MUTEX_RELEASE osMutexRelease(g_page_allocator_mutex_id)
|
||||
#define page_allocator_reset_faults(...) {}
|
||||
|
||||
/* Forward declaration of the page allocator API. */
|
||||
int page_allocator_malloc(UvisorPageTable * const table);
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue