Remove uVisor from mbed-os

pull/7592/head
Oren Cohen 2018-06-19 15:32:19 +03:00
parent f5fb3c1911
commit 787317b7eb
171 changed files with 25 additions and 7888 deletions

View File

@ -41,86 +41,6 @@
/* ########################### Core Secure Access ########################### */
#ifdef FEATURE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
/* Secure uVisor implementation. */
/** Set the value at the target address.
*
* Equivalent to: `*address = value`.
* @param address[in] Target address
* @param value[in] Value to write at the address location.
*/
#define SECURE_WRITE(address, value) \
uvisor_write(public_box, UVISOR_RGW_SHARED, address, value, UVISOR_RGW_OP_WRITE, 0xFFFFFFFFUL)
/** Get the value at the target address.
*
* @param address[in] Target address
* @returns The value `*address`.
*/
#define SECURE_READ(address) \
uvisor_read(public_box, UVISOR_RGW_SHARED, address, UVISOR_RGW_OP_READ, 0xFFFFFFFFUL)
/** Get the selected bits at the target address.
*
* @param address[in] Target address
* @param mask[in] Bits to select out of the target address
* @returns The value `*address & mask`.
*/
#define SECURE_BITS_GET(address, mask) \
UVISOR_BITS_GET(public_box, UVISOR_RGW_SHARED, address, mask)
/** Check the selected bits at the target address.
*
* @param address[in] Address at which to check the bits
* @param mask[in] Bits to select out of the target address
* @returns The value `((*address & mask) == mask)`.
*/
#define SECURE_BITS_CHECK(address, mask) \
UVISOR_BITS_CHECK(public_box, UVISOR_RGW_SHARED, address, mask)
/** Set the selected bits to 1 at the target address.
*
* Equivalent to: `*address |= mask`.
* @param address[in] Target address
* @param mask[in] Bits to select out of the target address
*/
#define SECURE_BITS_SET(address, mask) \
UVISOR_BITS_SET(public_box, UVISOR_RGW_SHARED, address, mask)
/** Clear the selected bits at the target address.
*
* Equivalent to: `*address &= ~mask`.
* @param address[in] Target address
* @param mask[in] Bits to select out of the target address
*/
#define SECURE_BITS_CLEAR(address, mask) \
UVISOR_BITS_CLEAR(public_box, UVISOR_RGW_SHARED, address, mask)
/** Set the selected bits at the target address to the given value.
*
* Equivalent to: `*address = (*address & ~mask) | (value & mask)`.
* @param address[in] Target address
* @param mask[in] Bits to select out of the target address
* @param value[in] Value to write at the address location. Note: The value
* must be already shifted to the correct bit position
*/
#define SECURE_BITS_SET_VALUE(address, mask, value) \
UVISOR_BITS_SET_VALUE(public_box, UVISOR_RGW_SHARED, address, mask, value)
/** Toggle the selected bits at the target address.
*
* Equivalent to: `*address ^= mask`.
* @param address[in] Target address
* @param mask[in] Bits to select out of the target address
*/
#define SECURE_BITS_TOGGLE(address, mask) \
UVISOR_BITS_TOGGLE(public_box, UVISOR_RGW_SHARED, address, mask)
#else
/* Insecure fallback implementation. */
/** Set the value at the target address.
@ -196,6 +116,4 @@
#define SECURE_BITS_TOGGLE(address, mask) \
*(address) ^= (mask)
#endif
#endif /* __CORE_CM_SECURE_ACCESS_H */

View File

@ -846,7 +846,6 @@ EXCLUDE_PATTERNS = */tools/* \
*/features/storage/* \
*/features/unsupported/* \
*/features/lwipstack/* \
*/features/FEATURE_UVISOR/* \
*/features/nanostack/sal-stack-nanostack/* \
*/features/nanostack/coap-service/* \
*/mbed-trace/* \

View File

@ -10,5 +10,5 @@
"EXPAND_AS_DEFINED": "",
"SKIP_FUNCTION_MACROS": "NO",
"STRIP_CODE_COMMENTS": "NO",
"EXCLUDE_PATTERNS": "*/tools/* */targets/* */features/mbedtls/* */features/storage/* */features/unsupported/* */BUILD/* */rtos/TARGET_CORTEX/rtx*/* */cmsis/* */features/lwipstack/* */features/FEATURE_UVISOR/* */nanostack/sal-stack-nanostack/* */nanostack/coap-service/* */ble/generic/* */ble/pal/* */mbed-trace/* */mbed-coap/* */nanostack-libservice/* */mbed-client-randlib/* */nanostack/sal-stack-nanostack-eventloop/*"
"EXCLUDE_PATTERNS": "*/tools/* */targets/* */features/mbedtls/* */features/storage/* */features/unsupported/* */BUILD/* */rtos/TARGET_CORTEX/rtx*/* */cmsis/* */features/lwipstack/* */nanostack/sal-stack-nanostack/* */nanostack/coap-service/* */ble/generic/* */ble/pal/* */mbed-trace/* */mbed-coap/* */nanostack-libservice/* */mbed-client-randlib/* */nanostack/sal-stack-nanostack-eventloop/*"
}

View File

@ -1,26 +0,0 @@
600 Alessandro Angelino
592 Milosch Meriac
213 Jaeden Amero
89 Niklas Hauser
27 Fangyi Zhou
17 Michael Schwarcz
9 Irit Arkin
8 Alexander Zilberkant
7 Amir Cohen
6 Roman Kuznetsov
5 Amanda Butler
4 Oren Cohen
3 AnotherButler
3 Danny Shavit
3 Hugo Vincent
3 Jan Jongboom
3 JaredCJR
3 Jim Huang
2 Jethro Hsu
2 Nathan Chong
2 Vincenzo Frascino
2 ccli8
2 tonyyanxuan
1 Aksel Skauge Mellbye
1 Michael Bartling
1 Russ Butler

View File

@ -1,487 +0,0 @@
# Getting started guide for uVisor on mbed OS
This guide will help you start uVisor on mbed OS by showing you how to create a sample application for the NXP FRDM-K64F board.
The uVisor provides sandboxed environments and resources protection for applications built for ARM Cortex-M3 and Cortex-M4 devices. This guide will show you how to enable the uVisor and configure a secure box to access some exclusive resources (memory, peripherals, interrupts). For more information about the uVisor design philosophy, please see the uVisor [introductory document](../../README.md).
## Requirements
To run the `blinky` application on mbed OS with uVisor enabled, you need:
- A platform and a toolchain that uVisor on mbed OS supports. You can verify this on [the official list](../README.md#supported-platforms). If uVisor supports your platform internally but not on mbed OS, the porting process is incomplete. To port your platform to uVisor and enable it on mbed OS, please follow the [uVisor porting guide for mbed OS](../core/PORTING.md).
- Git.
- mbed CLI. Run `pip install mbed-cli` to install it.
The remainder of this guide assumes:
- You are developing on a \*nix machine in the `~/code` folder.
- You are building the app for the [NXP FRDM-K64F](http://developer.mbed.org/platforms/FRDM-K64F/) target with the [GNU ARM Embedded Toolchain](https://launchpad.net/gcc-arm-embedded).
You can use these instructions as guidelines in the case of other targets on other host OSs.
## Start with the `blinky` app
[Go to top](#overview)
Create a new mbed application called `uvisor-example` by running the following commands:
```bash
$ cd ~/code
$ mbed new uvisor-example
$ cd uvisor-example
```
The mbed CLI tools automatically fetch the mbed codebase. By default, Git tracks your code changes, so you can push your application to a Git server if you want to.
Once the import process finishes, create a `source` folder:
```bash
$ mkdir ~/code/uvisor-example/source
```
Place a new file `main.cpp` in it:
```C
/* ~/code/uvisor-example/source/main.cpp */
#include "mbed.h"
DigitalOut led(LED1);
int main(void)
{
while (true) {
led = !led;
wait(0.5);
}
}
```
This application blinks an LED from the main thread, which the OS creates by default.
---
**Checkpoint**
Compile the application:
```bash
$ mbed compile -m K64F -t GCC_ARM
```
The resulting binary is located at:
```bash
~/code/uvisor-example/BUILD/K64F/GCC_ARM/uvisor-example.bin
```
Drag and drop it onto the USB device mounted on your computer to flash the device. When the flashing process is complete, press the reset button on the device. The device's LED blinks.
## Enable uVisor
[Go to top](#overview)
To enable the uVisor on the app, add these lines to the beginning of the `main.cpp` file:
```C
/* ~/code/uvisor-example/source/main.cpp */
#include "mbed.h"
#include "uvisor-lib/uvisor-lib.h"
/* Public box Access Control Lists (ACLs). */
/* Note: These are specific to the NXP FRDM-K64F board. See the section below
* for more information. */
static const UvisorBoxAclItem g_public_box_acls[] = {
/* For the LED */
{SIM, sizeof(*SIM), UVISOR_TACLDEF_PERIPH},
{PORTB, sizeof(*PORTB), UVISOR_TACLDEF_PERIPH},
/* For messages printed on the serial port */
{OSC, sizeof(*OSC), UVISOR_TACLDEF_PERIPH},
{MCG, sizeof(*MCG), UVISOR_TACLDEF_PERIPH},
{UART0, sizeof(*UART0), UVISOR_TACLDEF_PERIPH},
{PIT, sizeof(*PIT), UVISOR_TACLDEF_PERIPH},
};
/* Enable uVisor, using the ACLs we just created. */
UVISOR_SET_MODE_ACL(UVISOR_ENABLED, g_public_box_acls);
/* Rest of the existing code */
...
```
In the code above, we specified two elements:
1. Public box Access Control Lists (ACLs). With uVisor enabled, everything runs in unprivileged mode, so make sure the public box and peripherals the OS accesses are allowed. These peripherals are specified using a list like the one in the snippet above. This example provides the list of all the ACLs you need. For other platforms or other applications, you need to determine those ACLs following the process in [The main box ACLs](#the-main-box-acls).
1. App-specific uVisor configurations: `UVISOR_SET_MODE_ACL`. This macro sets the uVisor mode (enabled) and associates the list of ACLs you just created with the public box.
Before compiling, you need to override the original `K64F` target to enable the uVisor feature. To do so, add the file `~/code/uvisor-example/mbed_app.json` with the following content:
```JSON
{
"target_overrides": {
"*": {
"target.features_add": ["UVISOR"],
"target.extra_labels_add": ["UVISOR_SUPPORTED"]
}
},
"macros": [
"FEATURE_UVISOR=1",
"TARGET_UVISOR_SUPPORTED=1"
]
}
```
The macros `FEATURE_UVISOR` and `TARGET_UVISOR_SUPPORTED` in the configuration file above are automatically defined for C and C++ files but not for assembly files. Because the uVisor relies on those symbols in some assembly code, you need to define them manually.
---
**Checkpoint**
Compile the application again. This time, the `K64F` target includes the new features and labels you provided in `mbed_app.json`;
```bash
$ mbed compile -m K64F -t GCC_ARM
```
The binary is located at:
```bash
~/code/uvisor-example/BUILD/K64F/GCC_ARM/uvisor-example.bin
```
Reflash the device, and press the reset button. The device LED blinks as in the previous case.
---
If you enable uVisor in the `blinky` app as it was written above, you do not get any particular security feature. All code and resources share the same security context, which we call the *public box*.
A lot happens unseen, though. All the user code now runs in unprivileged mode, and the systems services, such as the `NVIC` APIs and the OS SVCalls, are routed through the uVisor.
## Add a secure box
[Go to top](#overview)
Now that uVisor is enabled, you can finally add a *secure box*.
A secure box is a special compartment with exclusive access to peripherals, memories and interrupts. Private resources are only accessible when the *context* of the secure box is active. The uVisor is the only one that can enable a secure box context, for example upon thread switching or interrupt handling.
uVisor does not obfuscate code that belongs to a box, so it is still readable and executable from outside of the box. In addition, declaring an object in the same file that configures a secure box does not protect that object automatically.
Instead, we provide specific APIs to instruct the uVisor to protect a private resource. The `uvisor-example` app will show how to use these APIs.
### Configure the secure box
For this example, we want to create a secure box called `private_button`. The `private_button` box has exclusive access to the push-button on the NXP FRDM-K64F board, which means that other boxes cannot access its corresponding peripheral.
Each secure box must have at least one thread, which we call the box's main thread. In our `private_button` box, we only use this thread throughout the whole program. The thread runs every second and counts the number of times it has been called between two button presses. The thread count is saved in a variable private to the box. Whenever we press the `SW2` button on the board, the current thread count is stored into a private buffer and restarts. For debug purposes, the program prints the content of the buffer every time it fills up.
You want the box to have exclusive access to the following resources:
- The push-button peripheral (as specified by a peripheral ACL). Nobody else should be able to access the push-button port.
- The push-button interrupt (as specified by an IRQ ACL). You want the button IRQ to reroute to our box-specific ISR.
- The private dynamically allocated buffer (as specified by a dynamic memory ACL).
- The private variables (as specified by a static memory ACL).
Create a new source file, `~/code/uvisor-example/source/secure_box.cpp`. You will configure the secure box inside this file. The secure box name for this example is `private_button`.
```C
/* ~/code/uvisor-example/source/secure_box.cpp */
#include "mbed.h"
#include "uvisor-lib/uvisor-lib.h"
/* Private static memory for the secure box */
typedef struct {
uint32_t * buffer; /* Static private memory, pointing to dynamically allocated private memory */
uint32_t counter; /* Static private memory */
int index; /* Static private memory */
RawSerial * pc; /* Static private memory, pointing to dynamically allocated private memory */
} PrivateButtonStaticMemory;
/* ACLs list for the secure box: Timer (PIT). */
static const UvisorBoxAclItem g_private_button_acls[] = {
{PORTC, sizeof(*PORTC), UVISOR_TACLDEF_PERIPH}, /* Private peripheral */
{(void *) PORTC_IRQn, 0, UVISOR_TACL_IRQ}, /* Private IRQ */
};
static void private_button_main_thread(const void *);
/* Secure box configuration */
UVISOR_BOX_NAMESPACE(NULL); /* We won't specify a box namespace for this example. */
UVISOR_BOX_HEAPSIZE(4096); /* Heap size for the secure box */
UVISOR_BOX_MAIN(private_button_main_thread, /* Main thread for the secure box */
osPriorityNormal, /* Priority of the secure box's main thread */
1024); /* Stack size for the secure box's main thread */
UVISOR_BOX_CONFIG(private_button, /* Name of the secure box */
g_private_button_acls, /* ACLs list for the secure box */
1024, /* Stack size for the secure box */
PrivateButtonStaticMemory); /* Private static memory for the secure box. */
```
### Create the secure box's main thread function
In general, you can decide what to do in your box's main thread. You can run it once and then stop it or use it to configure memories or peripherals or to create other threads. In this app, the box's main thread is the only thread for the `private_button` box, and it runs throughout the program.
The `private_button_main_thread` function configures the push-button to trigger an interrupt when pressed, allocates the dynamic buffer to hold the thread count values and initializes its private static memory, `PrivateButtonStaticMemory`. A spinning loop updates the counter value every second.
```C
/* ~/code/uvisor-example/source/secure_box.cpp */
/* The previous code goes here. */
...
#define uvisor_ctx ((PrivateButtonStaticMemory *) __uvisor_ctx)
#define PRIVATE_BUTTON_BUFFER_COUNT 8
static void private_button_on_press(void)
{
/* Store the thread count into the buffer and reset it. */
uvisor_ctx->buffer[uvisor_ctx->index] = uvisor_ctx->counter;
uvisor_ctx->counter = 0;
/* Update the index. Behave as a circular buffer. */
if (uvisor_ctx->index < PRIVATE_BUTTON_BUFFER_COUNT - 1) {
uvisor_ctx->index++;
} else {
uvisor_ctx->index = 0;
/* For debug purposes: Print the content of the buffer. */
uvisor_ctx->pc->printf("Thread count between button presses: ");
for (int i = 0; i < PRIVATE_BUTTON_BUFFER_COUNT; ++i) {
uvisor_ctx->pc->printf("%lu ", uvisor_ctx->buffer[i]);
}
uvisor_ctx->pc->printf("\n");
}
}
/* Main thread for the secure box */
static void private_button_main_thread(const void *)
{
/* Allocate serial port to ensure that code in this secure box
* won't touch handle in the default security context when printing */
if (!(uvisor_ctx->pc = new RawSerial(USBTX, USBRX))) {
return;
}
/* Create the buffer and cache its pointer to the private static memory. */
uvisor_ctx->buffer = (uint32_t *) malloc(PRIVATE_BUTTON_BUFFER_COUNT * sizeof(uint32_t));
if (uvisor_ctx->buffer == NULL) {
uvisor_ctx->pc->printf("ERROR: Failed to allocate memory for the button buffer\n");
mbed_die();
}
uvisor_ctx->index = 0;
uvisor_ctx->counter = 0;
/* Setup the push-button callback. */
InterruptIn button(SW2); /* Private IRQ */
button.mode(PullUp);
button.fall(&private_button_on_press);
/* Increment the private counter every second. */
while (1) {
uvisor_ctx->counter++;
wait(1.0);
}
}
```
A few things to note in the code above:
- If code runs in the context of `private_button`, then any object instantiated inside that code belongs to the `private_button` heap and stack. This means that in the example above, the `InterruptIn` object is private to the `private_button` box. The same applies to the dynamically allocated buffer `uvisor_ctx->buffer`.
- You can access the content of the private memory `PrivateButtonStaticMemory` using the `void * const __uvisor_ctx` pointer, which uVisor maintains. You need to cast this pointer to your own context type. In this example we used a pre-processor symbol to improve readability.
- The `InterruptIn` object triggers the registration of an interrupt slot using the NVIC APIs. If you want to use the IRQ APIs directly, read the [NVIC APIs section](#the-nvic-apis) below. We registered the push-button IRQ to the `private_button` box through an IRQ ACL, and hence only code from this box can access it. Changing the push-button IRQ state from the public box causes a uVisor fault.
- Even if the `private_button_on_press` function runs in the context of `private_button`, you can still use the `printf` function, which accesses the `UART0` peripheral, owned by the public box. This is because all ACLs declared in the public box are by default shared with all the other secure boxes. This also means that the messages we are printing on the serial port are not secure because other boxes have access to that peripheral.
> **Warning**: Instantiating an object in the `secure_box.cpp` global scope automatically maps it to the public box context, not the `private_button` one. If you want an object to be private to a box, you need to instantiate it inside the code that runs in the context of that box (such as the `InterruptIn` object), or alternatively statically initialize it in the box private static memory (such as the `buffer`, `index` and `counter` variables in `PrivateButtonStaticMemory`).
---
**Checkpoint**
Compile the application again:
```bash
$ mbed compile -m K64F -t GCC_ARM
```
Reflash the device, and press the reset button. The device LED blinks.
If the LED doens't blink, it means the application halted somewhere, probably because uVisor captured a fault. You can set up the uVisor debug messages to see if there is a problem. See [Debugging uVisor on mbed OS](DEBUGGING.md) for a step-by-step guide.
If the LED is blinking, the app is running correctly. If you press the `SW2` button on the NXP FRDM-K64F board, the `private_button_on_press` function executes, printing the values in the timer buffer after `PRIVATE_BUTTON_BUFFER_COUNT` presses. You can observe these values by opening a serial port connection to the device, with a baud rate of 9600.
## Expose public secure entry points to the secure box
[Go to top](#overview)
So far, the code in the secure box cannot communicate to other boxes. To let other boxes call functions in our secure box, you can define public secure entry points. These entry points can map to private functions within the context of a secure box, and an RPC protocol automatically serializes the arguments and return values to ensure no private memory can leak to external boxes.
You can define a public secure entry point to retrieve the index value from the secure box. This index value increases every time you press the `SW2` button.
### Defining a secure entry point
Create a new source file, `~/code/uvisor-example/source/secure_box.h`, where you will define the functions that you can call through RPC.
```cpp
/* ~/code/uvisor-example/source/secure_box.h */
#ifndef SECURE_BOX_H_
#define SECURE_BOX_H_
#include "uvisor-lib/uvisor-lib.h"
UVISOR_EXTERN int (*secure_get_index)(void);
#endif
```
### Implementing a secure entry point
Now that you have defined the secure entry point, you can map the entry point to a function running in the secure box. You can do this through the `UVISOR_BOX_RPC_GATEWAY_SYNC` macro. Open `~/code/uvisor-example/source/secure_box.cpp`, and replace the line with `#define PRIVATE_BUTTON_BUFFER_COUNT 8` by:
```cpp
/* ~/code/uvisor-example/source/secure_box.cpp */
/* Function called through RPC */
static int get_index() {
/* Access to private memory here */
return uvisor_ctx->index;
}
UVISOR_BOX_RPC_GATEWAY_SYNC (private_button, secure_get_index, get_index, int, void);
#define PRIVATE_BUTTON_BUFFER_COUNT 8
```
### Listening for RPC messages
To receive RPC messages, you need to spin up a new thread, running in the secure box context. You can do this in the main thread of the secure box. In `~/code/uvisor-example/source/secure_box.cpp`, replace the first five lines of `private_button_main_thread` with:
```cpp
/* ~/code/uvisor-example/source/secure_box.cpp */
static void listen_for_rpc() {
/* List of functions to wait for */
static const TFN_Ptr my_fn_array[] = {
(TFN_Ptr) get_index
};
while (1) {
int caller_id;
int status = rpc_fncall_waitfor(my_fn_array, 1, &caller_id, UVISOR_WAIT_FOREVER);
if (status) {
uvisor_error(USER_NOT_ALLOWED);
}
}
}
/* Main thread for the secure box */
static void private_button_main_thread(const void *)
{
/* allocate serial port to ensure that code in this secure box
* won't touch handle in the default security context when printing */
if (!(uvisor_ctx->pc = new RawSerial(USBTX, USBRX)))
return;
/* Start listening for RPC messages in a separate thread */
Thread rpc_thread(osPriorityNormal, 1024);
rpc_thread.start(&listen_for_rpc);
/* ... Rest of the private_button_main_thread function ... */
```
### Calling the public secure entry point
To call the public secure entry point from any other box, you can use the `secure_get_index` function. It will automatically do an RPC call into the secure box and serialize the return value. You can try this out from the public box. In `~/code/uvisor-example/source/main.cpp`, first include the header file for the secure box:
```cpp
/* ~/code/uvisor-example/source/main.cpp */
#include "secure_box.h"
```
Then replace the `main` function with:
```cpp
/* ~/code/uvisor-example/source/main.cpp */
int main(void)
{
while (true) {
led = !led;
printf("Secure index is %d\n", secure_get_index());
Thread::wait(500);
}
}
```
You can observe the secure index by opening a serial port connection to the device with a baud rate of 9600. When you press the `SW2` button, the index will increase.
## The NVIC APIs
The ARM CMSIS header files provide APIs to configure, enable and disable IRQs in the NVIC module. These APIs all begin with `NVIC_`, and you can find them in the `core_cm*.h` files in your CMSIS module. The CMSIS header files also provide APIs to set and get an interrupt vector at runtime. This requires the relocation of the interrupt vector table, which is usually located in flash, to SRAM.
When the uVisor is enabled, all NVIC APIs are rerouted to the corresponding uVisor vIRQ APIs, which virtualize the interrupt module. The uVisor interrupt model has the following features:
- The uVisor owns the interrupt vector table.
- All ISRs are relocated to SRAM.
- Code in a box can only change the state of an IRQ (enable it, change its priority and so on) if the box registered that IRQ with uVisor through an IRQ ACL.
- An IRQ that belongs to a box can only be modified when that box context is active.
Although this behavior is different from that of the original NVIC, it is backward compatible. Legacy code (such as a device HAL) still works after uVisor is enabled.
All IRQ slots that are not listed in any box ACL list are considered unclaimed. Boxes can gain exclusive ownership of unclaimed IRQs on a first-come first-served basis through the use of the NVIC APIs.
## The *public box* ACLs
The code samples in this guide provide a list of ACLs for the public box. The list includes peripherals necessary to make the example app work, and they are specific to the NXP FRDM-K64F target.
To generate the ACLs list for a different target or a different app, use the code provided in the [Enable uVisor](#enable-uvisor) section, but start with an empty ACLs list:
```C
static const UvisorBoxAclItem g_public_box_acls[] = {
}
```
Compile your application using uVisor in debug mode. This operation requires some more advanced steps. Please read [Debugging uVisor on mbed OS](DEBUGGING.md) for the detailed instructions.
Once the uVisor debug messages are enabled, your application fails. The failure is due to the first missing ACL being hit by the public box code. The message will look like:
```
***********************************************************
BUS FAULT
***********************************************************
* Active Box ID: 0
* FAULT SYNDROME REGISTERS
CFSR: 0x00008200
BFAR: 0x40048044
--> PRECISERR: precise data access.
...
```
Look up the faulty address (the value of BFAR) in the target device reference manual.
Once you know which peripheral is causing the fault (the `SIM` peripheral, in this example), add its entry to the ACLs list:
```C
static const UvisorBoxAclItem g_public_box_acls[] = {
{SIM, sizeof(*SIM), UVISOR_TACLDEF_PERIPH},
};
```
> **Note**: If the fault debug screen does not show the name of the peripheral, look it up in the target device reference manual.
For readability, do not use the hard-coded addresses of your peripherals. Instead, use the symbols that the target CMSIS module provides.
Repeat the process multiple times until all ACLs have been added to the list. When no other ACL is needed, the system runs without hitting a uVisor fault.
## Additional resources
[Go to top](#overview)
- [uVisor API documentation](API.md).
- [Debugging uVisor on mbed OS](DEBUGGING.md).
- [Using nonvolatile storage from uVisor on mbed OS](manual/Flash.md).
If you found any bug or inconsistency in this guide, please [raise an issue](https://github.com/ARMmbed/uvisor/issues/new).

View File

@ -1 +0,0 @@
v0.31.1

View File

@ -1,130 +0,0 @@
###########################################################################
#
# Copyright (c) 2013-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.
#
###########################################################################
# Toolchain
PREFIX:=arm-none-eabi-
GDB:=$(PREFIX)gdb
OBJDUMP:=$(PREFIX)objdump
# Translate between uVisor namespace and mbed namespace
TARGET_TRANSLATION:=MCU_K64F.kinetis EFM32.efm32 STM32F4.stm32 ARM_BEETLE_SOC.beetle M480.m480
TARGET_PREFIX:=../
TARGET_SUPPORTED:=$(TARGET_PREFIX)targets/TARGET_UVISOR_SUPPORTED
TARGET_UNSUPPORTED:=$(TARGET_PREFIX)targets/TARGET_UVISOR_UNSUPPORTED
TARGET_INC:=$(TARGET_PREFIX)includes/uvisor/api
TARGET_LIB_SRC:=$(TARGET_PREFIX)source
TARGET_LIB_INC:=$(TARGET_PREFIX)includes/uvisor-lib
# uVisor source directory - hidden from mbed via TARGET_IGNORE
UVISOR_GIT_URL:=https://github.com/ARMmbed/uvisor
UVISOR_GIT_BRANCH:=master
UVISOR_DIR:=TARGET_IGNORE/uvisor
UVISOR_API:=$(UVISOR_DIR)/api
UVISOR_GIT_CFG=$(UVISOR_DIR)/.git/config
# Derive variables from user configuration
TARGET_LIST:=$(subst .,,$(suffix $(TARGET_TRANSLATION)))
TARGET_LIST_DIR_SRC:=$(addprefix $(UVISOR_API)/lib/,$(TARGET_LIST))
TARGET_LIST_DIR_DST:=$(addprefix $(TARGET_SUPPORTED)/,$(TARGET_LIST))
TARGET_LIST_RELEASE:=$(addsuffix /release,$(TARGET_LIST_DIR_DST))
TARGET_LIST_DEBUG:=$(addsuffix /debug,$(TARGET_LIST_DIR_DST))
# mbed OS paths
MBED_OS_ROOT:=../../..
MBED_OS_CMSIS:=$(MBED_OS_ROOT)/cmsis
.PHONY: all deploy rsync publish uvisor uvisor-compile clean cache update
all: uvisor
uvisor: uvisor-compile publish
rsync:
#
# Copying uVisor into mbed library...
rm -rf $(TARGET_SUPPORTED)
mkdir -p $(TARGET_SUPPORTED)
rsync -a --exclude='*.txt' $(TARGET_LIST_DIR_SRC) $(TARGET_SUPPORTED)
#
# Copying uVisor headers to mbed includes...
rm -rf $(TARGET_INC)
mkdir -p $(TARGET_INC)
rsync -a --delete $(UVISOR_API)/inc $(TARGET_INC)
rsync -a --delete $(UVISOR_API)/rtx/inc/ $(TARGET_LIB_INC)/rtx
#
# Copying uVisor unsupported sources to unsupported target source...
mkdir -p $(TARGET_UNSUPPORTED)
cp $(UVISOR_API)/src/unsupported.c $(TARGET_UNSUPPORTED)/
#
# Copying uVisor shared sources to mbed source...
rm -rf $(TARGET_LIB_SRC)
mkdir -p $(TARGET_LIB_SRC)
cp $(UVISOR_DIR)/core/system/src/page_allocator.c $(TARGET_LIB_SRC)/page_allocator.c_inc
cp $(UVISOR_DIR)/core/system/inc/page_allocator_config.h $(TARGET_LIB_SRC)/page_allocator_config.h
rsync -a --delete $(UVISOR_API)/rtx/src/ $(TARGET_LIB_SRC)/rtx
#
# Copying the secure API header file...
# Note: This will not be needed when we upstream the file to CMSIS.
cp $(UVISOR_DIR)/core/cmsis/inc/core_cmSecureAccess.h $(MBED_OS_CMSIS)/
#
# Copying the documentation...
cp $(UVISOR_DIR)/docs/*/QUICKSTART.md $(TARGET_PREFIX)/README.md
#
# Copying licenses
cp $(UVISOR_DIR)/LICENSE* $(TARGET_SUPPORTED)
TARGET_M%: TARGET_LIBS_FIND=$(wildcard $(TARGET_SUPPORTED)/*/*/*_cortex_m$(subst TARGET_M,,$@)*.a)
TARGET_M%: rsync
@printf "#\n# Copying $@ files...\n"
mkdir $(foreach file,$(TARGET_LIBS_FIND),$(dir $(file))$@)
$(foreach file,$(TARGET_LIBS_FIND),mv $(file) $(dir $(file))$@/lib$(notdir $(file));)
publish: TARGET_M3 TARGET_M4
#
# Rename release directorires to TARGET_RELEASE filters...
$(foreach dir, $(TARGET_LIST_RELEASE),mv $(dir) $(dir $(dir))TARGET_RELEASE;)
#
# Rename debug directorires to TARGET_DEBUG filters...
$(foreach dir, $(TARGET_LIST_DEBUG),mv $(dir) $(dir $(dir))TARGET_DEBUG;)
#
# Rename target directorires to TARGET_* filters...
$(foreach target, $(TARGET_TRANSLATION),mv $(TARGET_SUPPORTED)/$(subst .,,$(suffix $(target))) $(TARGET_SUPPORTED)/TARGET_$(basename $(target));)
#
# Updating checked out version tag
git -C $(UVISOR_DIR) describe --tags --abbrev=40 --dirty > $(TARGET_PREFIX)VERSION.txt
#
# Updated list of authors, sorted by contributions
git -C $(UVISOR_DIR) shortlog -s -n > $(TARGET_PREFIX)AUTHORS.txt
# Updated version of uvisor-tests
cp $(UVISOR_DIR)/tools/uvisor-tests.txt $(TARGET_PREFIX)uvisor-tests.txt
uvisor-compile: $(UVISOR_GIT_CFG)
make -C $(UVISOR_DIR)
update: $(UVISOR_GIT_CFG)
#
# Updating to latest uVisor library version
git -C $(UVISOR_DIR) pull --rebase
$(UVISOR_GIT_CFG):
rm -rf $(UVISOR_DIR)
git clone -b $(UVISOR_GIT_BRANCH) $(UVISOR_GIT_URL) $(UVISOR_DIR)
clean: $(UVISOR_GIT_CFG)
make -C $(UVISOR_DIR) clean

View File

@ -1,6 +0,0 @@
# Rebuilding the uVisor mbed Library
This directory contains scripts to import and rebuild the latest uVisor library to mbed Classic.
uVisor does not need to be re-deployed for normal application development.
For uVisor development and code contributions please visit the [uVisor repository](https://github.com/ARMmbed/uvisor).

View File

@ -1 +0,0 @@
/uvisor

View File

@ -1,46 +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.
*/
#ifndef __RTX_BOX_INDEX_H__
#define __RTX_BOX_INDEX_H__
#include "cmsis_os2.h"
#include "rtx_os.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
/* The uvisor box index must be placed at the beginning */
UvisorBoxIndex index;
/* ID of the mutex */
osMutexId_t mutex_id;
/* Attribute of the mutex */
osMutexAttr_t mutex_attr;
/* Internal data of the mutex */
osRtxMutex_t mutex_data;
} RtxBoxIndex;
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __RTX_BOX_INDEX_H__ */

View File

@ -1,100 +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.
*/
#ifndef __SECURE_ALLOCATOR_H__
#define __SECURE_ALLOCATOR_H__
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Contains the allocator data and backing page table. */
typedef void * SecureAllocator;
/** Create an allocator in-place in an existing pool without using pages.
* Use this to turn statically allocated memory into a heap.
* Or allocate a large piece of memory and then turn that into a heap.
*
* @param mem Pointer to the origin of the memory pool
* @param bytes Length of the memory pool in bytes
* @returns the allocator or `NULL` on failure
*/
SecureAllocator secure_allocator_create_with_pool(
void * mem,
size_t bytes);
/** Create an allocator using pages from the page heap.
* Use this to request secure dynamic memory for your process.
* Note that this memory is not guaranteed to be consecutive, therefore you
* must specify the maximum allocation size that you plan to use in this
* allocator. This function will then compute the number and size of required
* pages and request them from the secure page heap.
*
* @param total_size The minimal total size of the heap
* @param maximum_malloc_size The largest size to be allocated in one chunk
* @returns the allocator or `NULL` on failure (out of memory,
* maximum malloc size cannot be fulfilled)
*/
SecureAllocator secure_allocator_create_with_pages(
size_t total_size,
size_t maximum_malloc_size);
/** Destroy the allocator and free the backing pages.
* An attempt to destroy a memory-pool backed allocator will fail and return
* with an error code.
*
* @retval 0 Allocator successfully destroyed.
* @retval -1 Allocator is static (memory-pool), or freeing memory pages failed.
*/
int secure_allocator_destroy(
SecureAllocator allocator);
/** Drop-in for `malloc`. */
void * secure_malloc(
SecureAllocator allocator,
size_t size);
/** Drop-in for `aligned_alloc`. */
void * secure_aligned_alloc(
SecureAllocator allocator,
size_t alignment,
size_t size);
/** Drop-in for `calloc`. */
void * secure_calloc(
SecureAllocator allocator,
size_t nmemb,
size_t size);
/** Drop-in for `realloc`. */
void * secure_realloc(
SecureAllocator allocator,
void * ptr,
size_t size);
/** Drop-in for `free`. */
void secure_free(
SecureAllocator allocator,
void * ptr);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* __SECURE_ALLOCATOR_H__ */

View File

@ -1,46 +0,0 @@
/*
* Copyright (c) 2013-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 __UVISOR_LIB_UVISOR_LIB_H__
#define __UVISOR_LIB_UVISOR_LIB_H__
/* This file translates mbed-specific pre-processor symbols into
* uVisor-specific ones. Then the main uvisor-lib.h file is included. */
/* mbed uses UVISOR_SUPPORTED to determine whether the full uVisor binaries
* should be included or not. This symbol maps to the uVisor-internal symbol
* UVISOR_PRESENT. */
/* By default uVisor is not supported. */
#if !defined(FEATURE_UVISOR) || !defined(TARGET_UVISOR_SUPPORTED) || defined(TARGET_UVISOR_UNSUPPORTED)
#define UVISOR_PRESENT 0
#else
#define UVISOR_PRESENT 1
#endif
/* Detect the target using the mbed-specific symbols and determine the MPU
* architecture accordingly. */
#if defined(TARGET_KINETIS)
#define ARCH_MPU_KINETIS
#else
#define ARCH_MPU_ARMv7M
#endif
/* The uVisor API main header file will use the above definitions. */
#include "uvisor/api/inc/uvisor-lib.h"
#include "uvisor-lib/rtx/rtx_box_index.h"
#include "uvisor-lib/rtx/secure_allocator.h"
#endif /* __UVISOR_LIB_UVISOR_LIB_H__ */

View File

@ -1,106 +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.
*/
#ifndef __UVISOR_API_H__
#define __UVISOR_API_H__
#include "rt_OsEventObserver.h"
#include "api/inc/uvisor_exports.h"
#include "api/inc/virq_exports.h"
#include "api/inc/debug_exports.h"
#include "api/inc/halt_exports.h"
#include "api/inc/pool_queue_exports.h"
#include "api/inc/page_allocator_exports.h"
#include "api/inc/uvisor_spinlock_exports.h"
#include <stdint.h>
#define UVISOR_API_MAGIC 0x5C9411B4
#define UVISOR_API_VERSION (10)
UVISOR_EXTERN_C_BEGIN
extern void uvisor_init(void);
/* This method is an api method which initializes the g_semihosting_magic variable.
* This function will only work if called in privileged mode or from secure code,
* it is only intended to be called by debugger after reset.
*/
void debug_semihosting_enable(void);
typedef struct {
uint32_t magic;
uint32_t (*get_version)(uint32_t);
void (*init)(uint32_t caller);
void (*irq_enable)(uint32_t irqn);
void (*irq_disable)(uint32_t irqn);
void (*irq_disable_all)(void);
void (*irq_enable_all)(void);
void (*irq_set_vector)(uint32_t irqn, uint32_t vector);
uint32_t (*irq_get_vector)(uint32_t irqn);
void (*irq_set_priority)(uint32_t irqn, uint32_t priority);
uint32_t (*irq_get_priority)(uint32_t irqn);
void (*irq_set_pending)(uint32_t irqn);
uint32_t (*irq_get_pending)(uint32_t irqn);
void (*irq_clear_pending)(uint32_t irqn);
int (*irq_get_level)(void);
void (*irq_system_reset)(TResetReason reason);
int (*page_malloc)(UvisorPageTable * const table);
int (*page_free)(const UvisorPageTable * const table);
int (*box_namespace)(int box_id, char *box_namespace, size_t length);
int (*box_id_for_namespace)(int * const box_id, const char * const box_namespace);
void (*error)(THaltUserError reason);
void (*start)(void);
void (*vmpu_mem_invalidate)(void);
int (*pool_init)(uvisor_pool_t *, void *, size_t, size_t);
int (*pool_queue_init)(uvisor_pool_queue_t *, uvisor_pool_t *, void *, size_t, size_t);
uvisor_pool_slot_t (*pool_allocate)(uvisor_pool_t *);
uvisor_pool_slot_t (*pool_try_allocate)(uvisor_pool_t *);
uvisor_pool_slot_t (*pool_queue_enqueue)(uvisor_pool_queue_t *, uvisor_pool_slot_t);
uvisor_pool_slot_t (*pool_queue_try_enqueue)(uvisor_pool_queue_t *, uvisor_pool_slot_t);
uvisor_pool_slot_t (*pool_free)(uvisor_pool_t *, uvisor_pool_slot_t);
uvisor_pool_slot_t (*pool_try_free)(uvisor_pool_t *, uvisor_pool_slot_t);
uvisor_pool_slot_t (*pool_queue_dequeue)(uvisor_pool_queue_t *, uvisor_pool_slot_t);
uvisor_pool_slot_t (*pool_queue_try_dequeue)(uvisor_pool_queue_t *, uvisor_pool_slot_t);
uvisor_pool_slot_t (*pool_queue_dequeue_first)(uvisor_pool_queue_t *);
uvisor_pool_slot_t (*pool_queue_try_dequeue_first)(uvisor_pool_queue_t *);
uvisor_pool_slot_t (*pool_queue_find_first)(uvisor_pool_queue_t *, TQueryFN_Ptr, void *);
uvisor_pool_slot_t (*pool_queue_try_find_first)(uvisor_pool_queue_t *, TQueryFN_Ptr, void *);
void (*spin_init)(UvisorSpinlock * spinlock);
bool (*spin_trylock)(UvisorSpinlock * spinlock);
void (*spin_lock)(UvisorSpinlock * spinlock);
void (*spin_unlock)(UvisorSpinlock * spinlock);
void (*debug_semihosting_enable)(void);
OsEventObserver os_event_observer;
} UVISOR_PACKED UvisorApi;
extern UvisorApi uvisor_api;
static UVISOR_FORCEINLINE uint32_t uvisor_get_version(void)
{
return uvisor_api.get_version(UVISOR_API_VERSION);
}
UVISOR_EXTERN_C_END
#endif /* __UVISOR_API_H__ */

View File

@ -1,191 +0,0 @@
/*
* Copyright (c) 2013-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 __UVISOR_API_BOX_CONFIG_H__
#define __UVISOR_API_BOX_CONFIG_H__
#include "api/inc/uvisor_exports.h"
#include "api/inc/debug_exports.h"
#include "api/inc/page_allocator_exports.h"
#include "api/inc/rpc_exports.h"
#include <stddef.h>
#include <stdint.h>
#include <sys/reent.h>
UVISOR_EXTERN const uint32_t __uvisor_mode;
UVISOR_EXTERN void const * const public_box_cfg_ptr;
/* All pointers in the box index need to be 4-byte aligned.
* We therefore also need to round up all sizes to 4-byte multiples to
* provide the space to be able to align the pointers to 4-bytes. */
#define __UVISOR_BOX_ROUND_4(size) \
(((size) + 3UL) & ~3UL)
#define UVISOR_DISABLED 0
#define UVISOR_PERMISSIVE 1
#define UVISOR_ENABLED 2
#define UVISOR_SET_MODE(mode) \
UVISOR_SET_MODE_ACL_COUNT(mode, NULL, 0)
#define UVISOR_SET_MODE_ACL(mode, acl_list) \
UVISOR_SET_MODE_ACL_COUNT(mode, acl_list, UVISOR_ARRAY_COUNT(acl_list))
#define UVISOR_SET_MODE_ACL_COUNT(mode, acl_list, acl_list_count) \
uint8_t __attribute__((section(".keep.uvisor.bss.boxes"), aligned(32))) __reserved_stack[UVISOR_STACK_BAND_SIZE]; \
\
UVISOR_EXTERN const uint32_t __uvisor_mode = (mode); \
\
static const __attribute__((section(".keep.uvisor.cfgtbl"), aligned(4))) UvisorBoxConfig public_box_cfg = { \
UVISOR_BOX_MAGIC, \
UVISOR_BOX_VERSION, \
{ \
sizeof(RtxBoxIndex), \
0, \
0, \
sizeof(uvisor_rpc_t), \
sizeof(uvisor_ipc_t), \
0, \
}, \
0, \
NULL, \
NULL, \
acl_list, \
acl_list_count \
}; \
\
UVISOR_EXTERN const __attribute__((section(".keep.uvisor.cfgtbl_ptr_first"), aligned(4))) void * const public_box_cfg_ptr = &public_box_cfg;
/* Creates a global page heap with at least `minimum_number_of_pages` each of size `page_size` in bytes.
* The total page heap size is at least `minimum_number_of_pages * page_size`. */
#define UVISOR_SET_PAGE_HEAP(page_size, minimum_number_of_pages) \
const uint32_t __uvisor_page_size = (page_size); \
uint8_t __attribute__((section(".keep.uvisor.page_heap"))) \
public_page_heap_reserved[ (page_size) * (minimum_number_of_pages) ]
/* this macro selects an overloaded macro (variable number of arguments) */
#define __UVISOR_BOX_MACRO(_1, _2, _3, _4, NAME, ...) NAME
#define __UVISOR_BOX_CONFIG(box_name, acl_list, acl_list_count, stack_size, context_size) \
\
uint8_t __attribute__((section(".keep.uvisor.bss.boxes"), aligned(32))) \
box_name ## _reserved[ \
UVISOR_STACK_SIZE_ROUND( \
( \
(UVISOR_MIN_STACK(stack_size) + \
__UVISOR_BOX_ROUND_4(context_size) + \
__UVISOR_BOX_ROUND_4(__uvisor_box_heapsize) + \
__UVISOR_BOX_ROUND_4(sizeof(RtxBoxIndex)) + \
__UVISOR_BOX_ROUND_4(sizeof(uvisor_rpc_outgoing_message_queue_t)) + \
__UVISOR_BOX_ROUND_4(sizeof(uvisor_rpc_incoming_message_queue_t)) + \
__UVISOR_BOX_ROUND_4(sizeof(uvisor_rpc_fn_group_queue_t)) + \
__UVISOR_BOX_ROUND_4(sizeof(struct _reent)) \
) \
* 8) \
/ 6)]; \
\
static const __attribute__((section(".keep.uvisor.cfgtbl"), aligned(4))) UvisorBoxConfig box_name ## _cfg = { \
UVISOR_BOX_MAGIC, \
UVISOR_BOX_VERSION, \
{ \
sizeof(RtxBoxIndex), \
context_size, \
sizeof(struct _reent), \
sizeof(uvisor_rpc_t), \
sizeof(uvisor_ipc_t), \
__uvisor_box_heapsize, \
}, \
UVISOR_MIN_STACK(stack_size), \
__uvisor_box_lib_config, \
__uvisor_box_namespace, \
acl_list, \
acl_list_count \
}; \
\
UVISOR_EXTERN const __attribute__((section(".keep.uvisor.cfgtbl_ptr"), aligned(4))) void * const box_name ## _cfg_ptr = &box_name ## _cfg;
#define UVISOR_BOX_EXTERN(box_name) \
UVISOR_EXTERN const __attribute__((section(".keep.uvisor.cfgtbl_ptr"), aligned(4))) void * const box_name ## _cfg_ptr;
#define __UVISOR_BOX_CONFIG_NOCONTEXT(box_name, acl_list, stack_size) \
__UVISOR_BOX_CONFIG(box_name, acl_list, UVISOR_ARRAY_COUNT(acl_list), stack_size, 0) \
#define __UVISOR_BOX_CONFIG_CONTEXT(box_name, acl_list, stack_size, context_type) \
__UVISOR_BOX_CONFIG(box_name, acl_list, UVISOR_ARRAY_COUNT(acl_list), stack_size, sizeof(context_type)) \
UVISOR_EXTERN context_type *const *const __uvisor_ps;
#define __UVISOR_BOX_CONFIG_NOACL(box_name, stack_size, context_type) \
__UVISOR_BOX_CONFIG(box_name, NULL, 0, stack_size, sizeof(context_type)) \
UVISOR_EXTERN context_type *const *const __uvisor_ps;
#define __UVISOR_BOX_CONFIG_NOACL_NOCONTEXT(box_name, stack_size) \
__UVISOR_BOX_CONFIG(box_name, NULL, 0, stack_size, 0)
#define UVISOR_BOX_CONFIG_ACL(...) \
__UVISOR_BOX_MACRO(__VA_ARGS__, __UVISOR_BOX_CONFIG_CONTEXT, \
__UVISOR_BOX_CONFIG_NOCONTEXT, \
__UVISOR_BOX_CONFIG_NOACL_NOCONTEXT)(__VA_ARGS__)
#define UVISOR_BOX_CONFIG_CTX(...) \
__UVISOR_BOX_MACRO(__VA_ARGS__, __UVISOR_BOX_CONFIG_CONTEXT, \
__UVISOR_BOX_CONFIG_NOACL, \
__UVISOR_BOX_CONFIG_NOACL_NOCONTEXT)(__VA_ARGS__)
#define UVISOR_BOX_CONFIG(...) \
UVISOR_BOX_CONFIG_ACL(__VA_ARGS__)
/* Use this macro before box defintion (for example, UVISOR_BOX_CONFIG) to
* define the name of your box. If you don't want a name, use this macro with
* box_namespace as NULL. */
#define UVISOR_BOX_NAMESPACE(box_namespace) \
static const char *const __uvisor_box_namespace = box_namespace
/* 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, stack_size) \
static const uvisor_box_main_t __uvisor_box_main = { \
function, \
priority, \
stack_size, \
}; \
static const void * const __uvisor_box_lib_config = &__uvisor_box_main;
#define UVISOR_BOX_HEAPSIZE(heap_size) \
static const uint32_t __uvisor_box_heapsize = heap_size;
#define __uvisor_ctx (((UvisorBoxIndex *) __uvisor_ps)->bss.address_of.context)
/* Use this macro after calling the box configuration macro, in order to register your box as a debug box.
* It will create a valid debug driver struct with the halt_error_func parameter as its halt_error() function */
#define UVISOR_DEBUG_DRIVER(box_name, halt_error_func) \
UVISOR_EXTERN TUvisorDebugDriver const __uvisor_debug_driver; \
TUvisorDebugDriver const __uvisor_debug_driver = { \
UVISOR_DEBUG_BOX_MAGIC, \
UVISOR_DEBUG_BOX_VERSION, \
&box_name ## _cfg, \
halt_error_func \
};
/* Use this macro after calling the box configuration macro, in order to
* register the public box as a debug box. */
#define UVISOR_PUBLIC_BOX_DEBUG_DRIVER(halt_error_func) \
UVISOR_DEBUG_DRIVER(public_box, halt_error_func)
#endif /* __UVISOR_API_BOX_CONFIG_H__ */

View File

@ -1,50 +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.
*/
#ifndef __UVISOR_API_BOX_ID_H__
#define __UVISOR_API_BOX_ID_H__
#include "api/inc/api.h"
UVISOR_EXTERN_C_BEGIN
/* Return the numeric box ID of the current box. */
int uvisor_box_id_self(void);
/* Return the numeric box ID of the box that is calling through the most recent
* secure gateway. Return -1 if there is no secure gateway calling box. */
int uvisor_box_id_caller(void) UVISOR_DEPRECATED;
/* Copy the box namespace of the specified box ID to the memory provided by
* box_namespace. The box_namespace's length must be at least
* MAX_BOX_NAMESPACE_LENGTH bytes. Return how many bytes were copied into
* box_namespace. Return UVISOR_ERROR_INVALID_BOX_ID if the provided box ID is
* invalid. Return UVISOR_ERROR_BUFFER_TOO_SMALL if the provided box_namespace
* is too small to hold MAX_BOX_NAMESPACE_LENGTH bytes. Return
* UVISOR_ERROR_BOX_NAMESPACE_ANONYMOUS if the box is anonymous. */
static UVISOR_FORCEINLINE int uvisor_box_namespace(int box_id, char *box_namespace, size_t length)
{
return uvisor_api.box_namespace(box_id, box_namespace, length);
}
static UVISOR_FORCEINLINE int uvisor_box_id_for_namespace(int * const box_id, const char * const box_namespace)
{
return uvisor_api.box_id_for_namespace(box_id, box_namespace);
}
UVISOR_EXTERN_C_END
#endif /* __UVISOR_API_BOX_ID_H__ */

View File

@ -1,24 +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.
*/
#ifndef __UVISOR_API_BOX_INIT_H__
#define __UVISOR_API_BOX_INIT_H__
#include "api/inc/uvisor-lib.h"
UVISOR_EXTERN void __uvisor_lib_box_init(void * lib_config);
#endif

View File

@ -1,54 +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.
*/
#ifndef __UVISOR_API_NVIC_VIRTUAL_H__
#define __UVISOR_API_NVIC_VIRTUAL_H__
#include "api/inc/interrupts.h"
#include "api/inc/virq_exports.h"
/* The NVIC APIs are only wrapped on ARMv7-M. */
#if !defined(ARCH_CORE_ARMv8M) && !defined(TARGET_M33)
#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping
#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping
#define NVIC_EnableIRQ vIRQ_EnableIRQ
#define NVIC_DisableIRQ vIRQ_DisableIRQ
#define NVIC_GetPendingIRQ vIRQ_GetPendingIRQ
#define NVIC_SetPendingIRQ vIRQ_SetPendingIRQ
#define NVIC_ClearPendingIRQ vIRQ_ClearPendingIRQ
#define NVIC_GetActive __NVIC_GetActive
#define NVIC_SetPriority vIRQ_SetPriority
#define NVIC_GetPriority vIRQ_GetPriority
#define NVIC_SystemReset() vIRQ_SystemReset(RESET_REASON_NO_REASON)
#else
#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping
#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping
#define NVIC_EnableIRQ __NVIC_EnableIRQ
#define NVIC_DisableIRQ __NVIC_DisableIRQ
#define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ
#define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ
#define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ
#define NVIC_GetActive __NVIC_GetActive
#define NVIC_SetPriority __NVIC_SetPriority
#define NVIC_GetPriority __NVIC_GetPriority
#define NVIC_SystemReset() __NVIC_SystemReset()
#endif
#endif /* __UVISOR_API_NVIC_VIRTUAL_H__ */

View File

@ -1,35 +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.
*/
#ifndef __UVISOR_API_VECTAB_VIRTUAL_H__
#define __UVISOR_API_VECTAB_VIRTUAL_H__
#include "api/inc/interrupts.h"
/* The NVIC APIs are only wrapped on ARMv7-M. */
#if !defined(ARCH_CORE_ARMv8M) && !defined(TARGET_M33)
#define NVIC_SetVector vIRQ_SetVector
#define NVIC_GetVector vIRQ_GetVector
#else
#define NVIC_SetVector __NVIC_SetVector
#define NVIC_GetVector __NVIC_GetVector
#endif
#endif /* __UVISOR_API_VECTAB_VIRTUAL_H__ */

View File

@ -1,26 +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.
*/
#ifndef __UVISOR_CONTEX_EXPORTS_H__
#define __UVISOR_CONTEX_EXPORTS_H__
/** Maximum number of nested context switches.
*
* The same state stack is kept for all kinds of context switches that are bound
* to a function, for which uVisor keeps an internal state. */
#define UVISOR_CONTEXT_MAX_DEPTH 16
#endif /* __UVISOR_CONTEX_EXPORTS_H__ */

View File

@ -1,41 +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.
*/
#ifndef __UVISOR_API_DEBUG_EXPORTS_H__
#define __UVISOR_API_DEBUG_EXPORTS_H__
#include "api/inc/halt_exports.h"
#include <stdint.h>
#include "api/inc/vmpu_exports.h"
#define UVISOR_DEBUG_BOX_VERSION (1)
/* Debug box driver
* A constant instance of this struct must be instantiated by the unprivileged
* code to setup a debug box.*/
typedef struct TUvisorDebugDriver {
const uint32_t magic;
const uint32_t version;
const UvisorBoxConfig * const box_cfg_ptr;
void (*halt_error)(THaltError, const THaltInfo *);
} TUvisorDebugDriver;
/* Number of handlers in the debug box driver */
#define DEBUG_BOX_HANDLERS_NUMBER (sizeof(TUvisorDebugDriver) / sizeof(void *))
#endif /* __UVISOR_API_DEBUG_EXPORTS_H__ */

View File

@ -1,31 +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.
*/
#ifndef __UVISOR_API_DISABLED_H__
#define __UVISOR_API_DISABLED_H__
#include "api/inc/uvisor_exports.h"
#include <stdint.h>
UVISOR_EXTERN void uvisor_disabled_switch_in(const uint32_t *dst_box_cfgtbl_ptr);
UVISOR_EXTERN void uvisor_disabled_switch_out(void);
/* The host OS can override the implementations of these functions in case a
* different handling of IRQs is required when uVisor is disabled. */
UVISOR_EXTERN void uvisor_disabled_set_vector(uint32_t irqn, uint32_t vector);
UVISOR_EXTERN uint32_t uvisor_disabled_get_vector(uint32_t irqn);
#endif /* __UVISOR_API_DISABLED_H__ */

View File

@ -1,33 +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.
*/
#ifndef __UVISOR_API_ERROR_H__
#define __UVISOR_API_ERROR_H__
#include "api/inc/halt_exports.h"
#include "api/inc/uvisor_exports.h"
#include "api/inc/api.h"
UVISOR_EXTERN_C_BEGIN
static UVISOR_FORCEINLINE void uvisor_error(THaltUserError reason)
{
uvisor_api.error(reason);
}
UVISOR_EXTERN_C_END
#endif /* __UVISOR_API_ERROR_H__ */

View File

@ -1,106 +0,0 @@
/*
* Copyright (c) 2015, 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 __UVISOR_API_HALT_EXPORTS_H__
#define __UVISOR_API_HALT_EXPORTS_H__
#include "uvisor_exports.h"
#define UVISOR_ERROR_INVALID_BOX_ID (-2)
#define UVISOR_ERROR_BUFFER_TOO_SMALL (-3)
#define UVISOR_ERROR_BOX_NAMESPACE_ANONYMOUS (-4)
#define UVISOR_ERROR_BAD_MAGIC (-5)
#define UVISOR_ERROR_BAD_VERSION (-6)
#define UVISOR_ERROR_OUT_OF_STRUCTURES (-7)
#define UVISOR_ERROR_INVALID_PARAMETERS (-8)
#define UVISOR_ERROR_NOT_IMPLEMENTED (-9)
#define UVISOR_ERROR_TIMEOUT (-10)
#define UVISOR_ERROR_CLASS_MASK (0xFFFF0000UL)
#define UVISOR_ERROR_MASK (0x0000FFFFUL)
#define UVISOR_ERROR_CLASS_PAGE (1UL << 16)
typedef enum {
USER_NOT_ALLOWED = 1,
DEBUG_BOX_HALT,
} THaltUserError;
typedef enum {
HALT_NO_ERROR = 0,
PERMISSION_DENIED = 1,
SANITY_CHECK_FAILED,
NOT_IMPLEMENTED,
NOT_ALLOWED,
FAULT_MEMMANAGE,
FAULT_BUS,
FAULT_USAGE,
FAULT_HARD,
FAULT_DEBUG,
FAULT_SECURE,
__THALTERROR_MAX /* always keep as the last element of the enum */
} THaltError;
/** A basic exception frame
*
* This struct contains the registers always saved during an exception in the
* order they are placed in the memory.
* If FPU state is also saved it's placed after this register block.
* On ARMv8-M in certain cases an additional state context may be placed on
* the stack before this block.
*/
typedef struct {
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r12;
uint32_t lr;
uint32_t retaddr;
uint32_t retpsr;
} UVISOR_PACKED exception_frame_t;
/* A pointer to this structure will be given to halt_error() handler
* of the debug box driver. */
typedef struct {
/* A basic exception stack frame that is always present with a valid stack. */
exception_frame_t stack_frame;
/* A few registers that may be useful for debug. */
uint32_t lr;
uint32_t control;
uint32_t ipsr;
/* Fault status registers. */
uint32_t mmfar;
uint32_t bfar;
uint32_t cfsr;
uint32_t hfsr;
uint32_t dfsr;
uint32_t afsr;
/* Bitmask telling which of the above regions are valid. */
uint32_t valid_data;
} UVISOR_PACKED THaltInfo;
/* Bitmask to specify which HaltInfo regions are valid. */
typedef enum {
HALT_INFO_STACK_FRAME = 0x1,
HALT_INFO_REGISTERS = 0x2
} THaltInfoValidMask;
#endif /* __UVISOR_API_HALT_EXPORTS_H__ */

View File

@ -1,123 +0,0 @@
/*
* Copyright (c) 2013-2015, 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 __UVISOR_API_INTERRUPTS_H__
#define __UVISOR_API_INTERRUPTS_H__
#include "api/inc/virq_exports.h"
#include "api/inc/uvisor_exports.h"
#include "api/inc/api.h"
#include <stdint.h>
UVISOR_EXTERN_C_BEGIN
static UVISOR_FORCEINLINE void vIRQ_SetVector(uint32_t irqn, uint32_t vector)
{
uvisor_api.irq_set_vector(irqn, vector);
}
static UVISOR_FORCEINLINE uint32_t vIRQ_GetVector(uint32_t irqn)
{
return uvisor_api.irq_get_vector(irqn);
}
static UVISOR_FORCEINLINE void vIRQ_EnableIRQ(uint32_t irqn)
{
uvisor_api.irq_enable(irqn);
}
static UVISOR_FORCEINLINE void vIRQ_DisableIRQ(uint32_t irqn)
{
uvisor_api.irq_disable(irqn);
}
static UVISOR_FORCEINLINE void vIRQ_ClearPendingIRQ(uint32_t irqn)
{
uvisor_api.irq_clear_pending(irqn);
}
static UVISOR_FORCEINLINE void vIRQ_SetPendingIRQ(uint32_t irqn)
{
uvisor_api.irq_set_pending(irqn);
}
static UVISOR_FORCEINLINE uint32_t vIRQ_GetPendingIRQ(uint32_t irqn)
{
return uvisor_api.irq_get_pending(irqn);
}
static UVISOR_FORCEINLINE void vIRQ_SetPriority(uint32_t irqn, uint32_t priority)
{
uvisor_api.irq_set_priority(irqn, priority);
}
static UVISOR_FORCEINLINE uint32_t vIRQ_GetPriority(uint32_t irqn)
{
return uvisor_api.irq_get_priority(irqn);
}
static UVISOR_FORCEINLINE int vIRQ_GetLevel(void)
{
return uvisor_api.irq_get_level();
}
/** Disable all interrupts for the currently active box.
*
* Calling this function from a box only affects the interrupts of that box.
* System interrupts and interrupts owned by other boxes are left untouched.
*
* Successive calls to this function increase an internal counter that is used
* by uVisor to decide when to re-enable IRQs. The related call
* ::vIRQ_EnableIRQ() decreases this counter. Only when the counter is 0 the
* interrupts are re-enabled for that box.
*
* This guarantees that code that disables IRQs will not accidentally have them
* re-enabled by a nested function that it calls before the expected call to
* ::vIRQ_EnableAll(). Example:
*
* vIRQ_DisableAll(); counter = 1; IRQs are now disabled.
* some_function(); counter = 2, then counter = 1; IRQs are still disabled.
* vIRQ_EnableAll(); counter = 0; IRQs are now re-enabled.
*
* where some_function() also has a disable/enable pair. */
static UVISOR_FORCEINLINE void vIRQ_DisableAll(void)
{
uvisor_api.irq_disable_all();
}
/** Re-enable all interrupts that were previously disabled for the currently
* active box.
*
* This function only re-enables interrupt if the uVisor internal counter is set
* to 0, to make sure that nested disabling of IRQs is still effective. See
* ::vIRQ_DisableAll for more information. */
static UVISOR_FORCEINLINE void vIRQ_EnableAll(void)
{
uvisor_api.irq_enable_all();
}
/** Reset the device.
* @warning Currently only the debug box can reset the device.
* @param reason[in] Reason for rebooting. Currently not used.
*/
static UVISOR_FORCEINLINE void vIRQ_SystemReset(TResetReason reason)
{
return uvisor_api.irq_system_reset(reason);
}
UVISOR_EXTERN_C_END
#endif /* __UVISOR_API_INTERRUPTS_H__ */

View File

@ -1,80 +0,0 @@
/*
* Copyright (c) 2017, 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 __UVISOR_API_IPC_H__
#define __UVISOR_API_IPC_H__
#include "api/inc/ipc_exports.h"
#include "api/inc/uvisor_exports.h"
#include <stdint.h>
#include <stddef.h>
/** Wait for any of the specified IPC operations to complete.
*
* @note This function currently spins, burning through power.
*
* @param[in] wait_tokens a bitfield of tokens to wait on
* @param[out] done_tokens a bitfield which tokens completed
* @param[in] timeout_ms how long to wait (in ms) for an IPC operation
* before returning. 0 means don't wait at all. Any
* other value means wait forever.
* @return 0 on success, non-zero error code otherwise
*/
UVISOR_EXTERN int ipc_waitforany(uint32_t wait_tokens, uint32_t * done_tokens, uint32_t timeout_ms);
/** Wait for all of the specified IPC operations to complete.
*
* @note This function currently spins, burning through power.
*
* @param[in] wait_tokens a bitfield of tokens to wait on
* @param[out] done_tokens a bitfield which tokens completed
* @param[in] timeout_ms how long to wait (in ms) for an IPC operation
* before returning. 0 means don't wait at all.
* Any other value means wait forever.
* @return 0 on success, non-zero error code otherwise
*/
UVISOR_EXTERN int ipc_waitforall(uint32_t wait_tokens, uint32_t * done_tokens, uint32_t timeout_ms);
/** Asynchronously send an IPC message
*
* @note The memory used for receiving the message (pointed to by msg) and the
* IPC descriptor (pointed to by desc) must be valid until after the send is
* complete. In addition, each IPC message should use its own IPC descriptor.
* Reusing an IPC descriptor will lead to unpredictable behaviours.
*
* @param[inout] desc an IPC descriptor for the message
* @param[in] msg the message to send
*
* @return 0 on success, non-zero error code otherwise
* */
UVISOR_EXTERN int ipc_send(uvisor_ipc_desc_t * desc, const void * msg);
/** Asynchronously receive an IPC message
*
* @note The memory used for receiving the message (pointed to by msg) and the
* IPC descriptor (pointed to by desc) must be valid until after the receive is
* complete. In addition, each IPC message should use its own IPC descriptor.
* Reusing an IPC descriptor will lead to unpredictable behaviours.
*
* @param[inout] desc an IPC descriptor for the message
* @param[out] msg the memory to copy the message to
*
* @return 0 on success, non-zero error code otherwise
*/
UVISOR_EXTERN int ipc_recv(uvisor_ipc_desc_t * desc, void * msg);
#endif /* __UVISOR_API_IPC_H__ */

View File

@ -1,117 +0,0 @@
/*
* Copyright (c) 2017, 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 __UVISOR_API_IPC_EXPORTS_H__
#define __UVISOR_API_IPC_EXPORTS_H__
#include "api/inc/pool_queue_exports.h"
#include "api/inc/uvisor_spinlock_exports.h"
#include "api/inc/vmpu_exports.h"
#include <stddef.h>
/* Use the invalid box ID to mean "receive from any" box. */
#define UVISOR_BOX_ID_ANY UVISOR_BOX_ID_INVALID
#define UVISOR_IPC_SEND_SLOTS 16
#define UVISOR_IPC_RECV_SLOTS 16
/* The value UVISOR_IPC_INVALID_TOKEN is defined to should be useful as a null
* token, and preferably not having any other legitimate use. Due to the
* internal bitfield representation of tokens, it makes a lot of sense to use 0
* as the null token. ipc_allocate_token() returns 0 if no tokens are
* available. Freeing 0 bits means nothing ('&= ~0' is a no-op). No other value
* makes as much sense to use as 0. If tokens become represented internally as
* something other than a bitfield, it would make sense to reconsider the value
* used here. */
#define UVISOR_IPC_INVALID_TOKEN 0
typedef enum uvisor_ipc_io_state {
UVISOR_IPC_IO_STATE_INVALID,
UVISOR_IPC_IO_STATE_IDLE,
UVISOR_IPC_IO_STATE_READY_TO_SEND, /* Enqueued and waiting for delivery */
UVISOR_IPC_IO_STATE_READY_TO_RECV, /* Enqueued and waiting for delivery */
UVISOR_IPC_IO_STATE_VALID, /* uVisor has copied the message */
} uvisor_ipc_io_state_t;
/* IPC Descriptor Structure
* When sending:
* @param[in] box_id the ID of the destination box
* @param[in] port the port to send the message to
* @param[in] len the length of the message
* @param[out] token a token that can be used to wait at a later time for
* the send to complete
*
* When receiving before a message has been received:
* @param[in] box_id an ID of a box that is allowed to send to this box, or
* UVISOR_BOX_ID_ANY to allow messages from any box
* @param[in] port the port to listen for messages on
* @param[in] len the maximum length of message to receive
* @param[out] token a token that can be used to wait at a later time for
* the recv to complete
*
* When receiving after a message has been received:
* @param[out] box_id the box ID of the sender
* @param[out] port the port the message arrived on
* @param[out] len the length of the message
* @param[out] token not modified
*/
typedef struct uvisor_ipc_desc {
int box_id;
size_t port;
size_t len;
uint32_t token;
} uvisor_ipc_desc_t;
/* IPC IO Request Structure */
typedef struct uvisor_ipc_io {
uvisor_ipc_desc_t * desc;
void * msg;
uvisor_ipc_io_state_t state;
} uvisor_ipc_io_t;
#define UVISOR_IPC_SEND_TYPE(slots) \
struct { \
uvisor_pool_queue_t queue; \
uvisor_pool_t pool; \
uvisor_pool_queue_entry_t entries[slots]; \
uvisor_ipc_io_t io[slots]; \
}
#define UVISOR_IPC_RECV_TYPE(slots) \
struct { \
uvisor_pool_queue_t queue; \
uvisor_pool_t pool; \
uvisor_pool_queue_entry_t entries[slots]; \
uvisor_ipc_io_t io[slots]; \
}
typedef UVISOR_IPC_SEND_TYPE(UVISOR_IPC_SEND_SLOTS) uvisor_ipc_send_queue_t;
typedef UVISOR_IPC_RECV_TYPE(UVISOR_IPC_RECV_SLOTS) uvisor_ipc_recv_queue_t;
typedef struct uvisor_ipc {
uvisor_ipc_send_queue_t send_queue;
uvisor_ipc_recv_queue_t recv_queue;
UvisorSpinlock tokens_lock; /* Protect access to tokens. */
uint32_t allocated_tokens; /* Endpoints read and write. */
uint32_t completed_tokens; /* uVisor and endpoints read and write. */
} uvisor_ipc_t;
static inline uvisor_ipc_t * uvisor_ipc(UvisorBoxIndex * const index)
{
return (uvisor_ipc_t *) index->bss.address_of.ipc;
}
#endif

View File

@ -1,36 +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.
*/
#ifndef __UVISOR_API_LIB_HOOK_EXPORTS_H__
#define __UVISOR_API_LIB_HOOK_EXPORTS_H__
#include <stdint.h>
/* Predeclaration */
typedef struct uvisor_semaphore UvisorSemaphore;
/*
* uVisor library hooks
*
* All functions that uVisor needs to call that are implemented in uvisor-lib.
* These functions will be run by unprivileged code only. */
typedef struct {
void (*box_init)(void * lib_config);
int (*semaphore_init)(UvisorSemaphore * semaphore, uint32_t initial_count, uint32_t max_count);
int (*semaphore_pend)(UvisorSemaphore * semaphore, uint32_t timeout_ms);
} UvisorLibHooks;
#endif

View File

@ -1,56 +0,0 @@
/*
* Copyright (c) 2017, 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 __UVISOR_API_LINKER_EXPORTS_H__
#define __UVISOR_API_LINKER_EXPORTS_H__
/* FIXME Consider supporting other aliasing schemes. This is dependent on the
* IDAU implementation. Not all aliasing is guaranteed to work the same way. We
* currently only support a 1-bit MSB IDAU. */
#if defined (ARCH_CORE_ARMv8M) || defined (TARGET_M33)
# define SECURE_ALIAS_OFFSET 0x10000000
#else
# define SECURE_ALIAS_OFFSET 0
#endif
/** @returns the non-secure alias of the input address. */
#define UVISOR_GET_NS_ALIAS(addr) ((typeof(addr)) ((uint32_t) (addr) & ~SECURE_ALIAS_OFFSET))
/** @returns the secure alias of the input address. */
#define UVISOR_GET_S_ALIAS(addr) ((typeof(addr)) ((uint32_t) (addr) | SECURE_ALIAS_OFFSET))
/** @returns `true` if address is a secure alias. */
#define UVISOR_IS_S_ALIAS(addr) ((uint32_t) (addr) & SECURE_ALIAS_OFFSET)
/** @returns an address targeting the non-secure state. */
#define UVISOR_GET_NS_ADDRESS(addr) ((addr) & ~1UL)
/** @returns the secure alias of the input address for uVisor core builds, and
* the non-secure alias for non-uVisor core builds.
* This is useful for code shared across secure and non-secure aliases. */
#if UVISOR_CORE_BUILD
#define UVISOR_AUTO_ALIAS(addr) UVISOR_GET_S_ALIAS(addr)
#else
#define UVISOR_AUTO_ALIAS(addr) UVISOR_GET_NS_ALIAS(addr)
#endif
/** @returns the secure alias of the input address for uVisor core builds, and
* assumes the addr supplied is already a non-secure alias for non-uVisor core builds.
* This is useful for code shared across secure and non-secure aliases. */
#if UVISOR_CORE_BUILD
#define UVISOR_AUTO_NS_ALIAS(addr) UVISOR_GET_S_ALIAS(addr)
#else
#define UVISOR_AUTO_NS_ALIAS(addr) addr
#endif
#endif

View File

@ -1,46 +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.
*/
#ifndef __UVISOR_API_MAGIC_EXPORTS_H__
#define __UVISOR_API_MAGIC_EXPORTS_H__
#include <stdint.h>
/* udf imm16
* UDF - ARMv7M ARM section A7.7.191
* 111 1;0 111;1111; <imm4>; 1 01 0; <imm12> (Encoding T2)
*/
#define UDF_OPCODE(imm16) \
((uint32_t) (0xA000F7F0UL | (((uint32_t) (imm16) & 0xFFFU) << 16U) | (((uint32_t) (imm16) & 0xF000UL) >> 12)))
/** Magics
*
* The following magics are used to verify various things within uVisor.The
* magics are chosen to be one of the explicitly undefined Thumb-2
* instructions.
*/
#if defined(__thumb__) && defined(__thumb2__)
#define UVISOR_RPC_GATEWAY_MAGIC_ASYNC UDF_OPCODE(0x07C2)
#define UVISOR_RPC_GATEWAY_MAGIC_SYNC UDF_OPCODE(0x07C3)
#define UVISOR_POOL_MAGIC UDF_OPCODE(0x07C4)
#define UVISOR_POOL_QUEUE_MAGIC UDF_OPCODE(0x07C5)
#define UVISOR_DEBUG_BOX_MAGIC UDF_OPCODE(0x07C6)
#else
#error "Unsupported instruction set. The ARM Thumb-2 instruction set must be supported."
#endif /* __thumb__ && __thumb2__ */
#endif /* __UVISOR_API_MAGIC_EXPORTS_H__ */

View File

@ -1,54 +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.
*/
#ifndef __UVISOR_API_PAGE_ALLOCATOR_H__
#define __UVISOR_API_PAGE_ALLOCATOR_H__
#include "api/inc/uvisor_exports.h"
#include "api/inc/page_allocator_exports.h"
#include "api/inc/api.h"
#include <stdint.h>
UVISOR_EXTERN_C_BEGIN
/* Allocate a number of requested pages with the requested page size.
* @param table.page_size[in] Must be equal to the current page size
* @param table.page_count[in] The number of pages to be allocated
* @param table.page_origins[out] Pointers to the page origins. The table must be large enough to hold page_count entries.
* @returns Non-zero on failure with failure class `UVISOR_ERROR_CLASS_PAGE`. See `UVISOR_ERROR_PAGE_*`.
*/
static UVISOR_FORCEINLINE int uvisor_page_malloc(UvisorPageTable * const table)
{
return uvisor_api.page_malloc(table);
}
/* Free the pages associated with the table, only if it passes validation.
* @returns Non-zero on failure with failure class `UVISOR_ERROR_CLASS_PAGE`. See `UVISOR_ERROR_PAGE_*`.
*/
static UVISOR_FORCEINLINE int uvisor_page_free(const UvisorPageTable * const table)
{
return uvisor_api.page_free(table);
}
/* @returns the active page size for one page. */
static UVISOR_FORCEINLINE uint32_t uvisor_get_page_size(void)
{
return __uvisor_page_size;
}
UVISOR_EXTERN_C_END
#endif /* __UVISOR_API_PAGE_ALLOCATOR_H__ */

View File

@ -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.
*/
#ifndef __UVISOR_API_PAGE_ALLOCATOR_EXPORTS_H__
#define __UVISOR_API_PAGE_ALLOCATOR_EXPORTS_H__
#include "api/inc/halt_exports.h"
#include <stdint.h>
#include <stddef.h>
#define UVISOR_ERROR_PAGE_OK (0)
#define UVISOR_ERROR_PAGE_OUT_OF_MEMORY (UVISOR_ERROR_CLASS_PAGE + 1)
#define UVISOR_ERROR_PAGE_INVALID_PAGE_TABLE (UVISOR_ERROR_CLASS_PAGE + 2)
#define UVISOR_ERROR_PAGE_INVALID_PAGE_SIZE (UVISOR_ERROR_CLASS_PAGE + 3)
#define UVISOR_ERROR_PAGE_INVALID_PAGE_ORIGIN (UVISOR_ERROR_CLASS_PAGE + 4)
#define UVISOR_ERROR_PAGE_INVALID_PAGE_OWNER (UVISOR_ERROR_CLASS_PAGE + 5)
#define UVISOR_ERROR_PAGE_INVALID_PAGE_COUNT (UVISOR_ERROR_CLASS_PAGE + 6)
/* Contains the uVisor page size.
* @warning Do not read directly, instead use `uvisor_get_page_size()` accessor! */
UVISOR_EXTERN const uint32_t __uvisor_page_size;
typedef struct {
uint32_t page_size; /* The page size in bytes. Must be multiple of `UVISOR_PAGE_SIZE`! */
uint32_t page_count; /* The number of pages in the page table. */
void * page_origins[1]; /* Table of pointers to the origin of each page. */
} UvisorPageTable;
#endif /* __UVISOR_API_PAGE_ALLOCATOR_EXPORTS_H__ */

View File

@ -1,187 +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.
*/
#ifndef UVISOR_POOL_QUEUE_EXPORTS_H
#define UVISOR_POOL_QUEUE_EXPORTS_H
#include "api/inc/magic_exports.h"
#include "api/inc/uvisor_exports.h"
#include "api/inc/uvisor_spinlock_exports.h"
#include <stdint.h>
#include <stddef.h>
#define UVISOR_POOL_QUEUE_NON_BLOCKING (0)
#define UVISOR_POOL_QUEUE_BLOCKING (1)
#define UVISOR_POOL_SLOT_INVALID ((uint8_t) 0xFFU)
#define UVISOR_POOL_SLOT_IS_DEQUEUED ((uint8_t) 0xFEU)
#define UVISOR_POOL_SLOT_IS_FREE ((uint8_t) 0xFDU)
#define UVISOR_POOL_MAX_VALID ((uint8_t) 0xFCU)
typedef uint8_t uvisor_pool_slot_t;
typedef struct uvisor_pool_queue_entry {
union {
struct {
/* The next slot in the queue */
uvisor_pool_slot_t next;
/* The previous slot in the queue */
uvisor_pool_slot_t prev;
} queued;
struct {
/* If the slot is free, the next available slot in the free list */
uvisor_pool_slot_t next;
/* If the slot is free or dequeued */
uvisor_pool_slot_t state;
} dequeued;
};
} uvisor_pool_queue_entry_t;
/* These are assumed to only be statically allocated, so the management array
* in in-place. */
typedef struct uvisor_pool {
/* Magic that identifies this as a uvisor_pool type. */
uint32_t magic;
/* The array holds slots of data. */
void const * array;
/* The distance between elements in the array. */
size_t stride;
/* The maximum number of elements that could be in the array. */
uvisor_pool_slot_t num;
/* The number of items currently allocated from the pool. For testing and
* debug purposes only. */
uvisor_pool_slot_t num_allocated;
/* The first free slot. */
uvisor_pool_slot_t first_free;
/* The spinlock serializes updates to the management array. */
UvisorSpinlock spinlock;
/* This must be at the end so we can allocate memory for pools by
* allocating enough room for the size of the pool appended by an array of
* entries. */
uvisor_pool_queue_entry_t management_array[];
} uvisor_pool_t;
typedef struct uvisor_pool_queue {
/* Magic that identifies this as a uvisor_pool_queue type. */
uint32_t magic;
/* The first allocated slot */
uvisor_pool_slot_t head;
/* The last allocated slot */
uvisor_pool_slot_t tail;
uvisor_pool_t * pool;
} uvisor_pool_queue_t;
/* Intialize a pool.
* Return 0 on success, non-zero otherwise. */
UVISOR_EXTERN int uvisor_pool_init(uvisor_pool_t * pool, void * array, size_t stride, size_t num);
/* Initialize a pool queue.
* Return 0 on success, non-zero otherwise. */
UVISOR_EXTERN int uvisor_pool_queue_init(uvisor_pool_queue_t * pool_queue, uvisor_pool_t * pool, void * array, size_t stride, size_t num);
/* Allocate a slot from the pool. This doesn't put anything in the slot for
* you. It's up to you to do that. Return the index of the allocated slot, or
* UVISOR_POOL_SLOT_INVALID if there is no available slot. This function will
* spin until the spin lock serializing access to the pool can be taken. */
UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_allocate(uvisor_pool_t * pool);
/* Attempt to allocate a slot. This function will fail if the spin lock
* serializing access to the pool can not be taken. */
UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_try_allocate(uvisor_pool_t * pool);
/* Enqueue the specified slot into the queue. */
UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_queue_enqueue(uvisor_pool_queue_t * pool_queue, uvisor_pool_slot_t slot);
UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_queue_try_enqueue(uvisor_pool_queue_t * pool_queue, uvisor_pool_slot_t slot);
/* Free the specified slot back into the pool. Invalid slots are ignored.
* Return the slot that was freed, or UVISOR_POOL_SLOT_IS_FREE if the slot was
* already freed, or UVISOR_POOL_SLOT_INVALID if the slot being requested to
* free is outside the range of the queue. */
UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_free(uvisor_pool_t * pool, uvisor_pool_slot_t slot);
UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_try_free(uvisor_pool_t * pool, uvisor_pool_slot_t slot);
/* Remove the specified slot from the queue. This function does not free the
* specified slot back into the pool. Return the slot that was dequeued, or
* UVISOR_POOL_SLOT_IS_DEQUEUED if the slot was already dequeued, or
* UVISOR_POOL_SLOT_INVALID if the slot being requested to dequeue is outside
* the range of the queue. */
UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_queue_try_dequeue(uvisor_pool_queue_t * pool_queue, uvisor_pool_slot_t slot);
UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_queue_dequeue(uvisor_pool_queue_t * pool_queue, uvisor_pool_slot_t slot);
/* Remove the first slot from the queue. This function does not free the
* specified slot back into the pool. Return the slot that was dequeued or
* UVISOR_POOL_SLOT_INVALID if the slot being requested to dequeue is outside
* the range of the queue. */
UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_queue_dequeue_first(uvisor_pool_queue_t * pool_queue);
UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_queue_try_dequeue_first(uvisor_pool_queue_t * pool_queue);
/* Find the first (in queue order) slot that the supplied query function
* returns non-zero for. The query function is provided with `context` on every
* invocation. This allows query functions to access additional data without
* having to use global variables. `uvisor_pool_queue_find_first` is reentrant. */
typedef int (*TQueryFN_Ptr)(uvisor_pool_slot_t slot, void * context);
UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_queue_try_find_first(uvisor_pool_queue_t * pool_queue,
TQueryFN_Ptr query_fn, void * context);
UVISOR_EXTERN uvisor_pool_slot_t uvisor_pool_queue_find_first(uvisor_pool_queue_t * pool_queue,
TQueryFN_Ptr query_fn, void * context);
/* Inline helper function to make allocating slots for pool queues easier and
* better encapsulated (clients don't need to pull the pool out of the pool
* queue, or even realize pool_queue is implemented with a pool) */
static inline uvisor_pool_slot_t uvisor_pool_queue_allocate(uvisor_pool_queue_t * pool_queue)
{
return uvisor_pool_allocate(pool_queue->pool);
}
static inline uvisor_pool_slot_t uvisor_pool_queue_try_allocate(uvisor_pool_queue_t * pool_queue)
{
return uvisor_pool_try_allocate(pool_queue->pool);
}
/* Inline helper function to make freeing slots for pool queues easier and
* better encapsulated (clients don't need to pull the pool out of the pool
* queue, or even realize pool_queue is implemented with a pool) */
static inline uvisor_pool_slot_t uvisor_pool_queue_free(uvisor_pool_queue_t * pool_queue, uvisor_pool_slot_t slot)
{
return uvisor_pool_free(pool_queue->pool, slot);
}
static inline uvisor_pool_slot_t uvisor_pool_queue_try_free(uvisor_pool_queue_t * pool_queue, uvisor_pool_slot_t slot)
{
return uvisor_pool_try_free(pool_queue->pool, slot);
}
/* Return a pointer to the specified slot within the pool. */
static inline void * uvisor_pool_pointer_to(uvisor_pool_t * pool, uvisor_pool_slot_t slot)
{
if (slot >= pool->num) {
return NULL;
}
return (uint8_t *) pool->array + pool->stride * slot;
}
#endif

View File

@ -1,54 +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.
*/
#ifndef __UVISOR_API_PRIV_SYS_HOOK_EXPORTS_H__
#define __UVISOR_API_PRIV_SYS_HOOK_EXPORTS_H__
/* Predeclaration */
typedef struct uvisor_semaphore UvisorSemaphore;
/*
* Privileged system hooks
*
* In this version of uVisor, uVisor lives alongside an RTOS that requires
* running privileged code. In order for the RTOS to run any privileged code,
* uVisor must allow the RTOS to handle a subset of privileged system
* interrupts or system calls. Only the following system interrupts and system
* calls are hookable. Code called by these hooks circumvents uVisor security.
* HANDLE WITH CARE. */
typedef struct {
void (*priv_svc_0)(void);
void (*priv_pendsv)(void);
void (*priv_systick)(void);
int32_t (*priv_os_suspend)(void);
int (*priv_uvisor_semaphore_post)(UvisorSemaphore * semaphore);
} UvisorPrivSystemHooks;
/* Use this macro to register privileged system IRQ hooks. If you don't want to
* register a particular privileged system IRQ hook, you can supply NULL for
* that hook parameter. */
#define UVISOR_SET_PRIV_SYS_HOOKS(priv_svc_0_, priv_pendsv_, priv_systick_, priv_os_suspend_, priv_uvisor_semaphore_post_) \
UVISOR_EXTERN_C_BEGIN \
const UvisorPrivSystemHooks __uvisor_priv_sys_hooks = { \
.priv_svc_0 = priv_svc_0_, \
.priv_pendsv = priv_pendsv_, \
.priv_systick = priv_systick_, \
.priv_os_suspend = priv_os_suspend_, \
.priv_uvisor_semaphore_post = priv_uvisor_semaphore_post_, \
}; \
UVISOR_EXTERN_C_END
#endif

View File

@ -1,243 +0,0 @@
/*
* Copyright (c) 2015-2015, 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 __UVISOR_API_REGISTER_GATEWAY_H__
#define __UVISOR_API_REGISTER_GATEWAY_H__
#include "api/inc/register_gateway_exports.h"
#include "api/inc/uvisor_exports.h"
#include "api/inc/svc_exports.h"
#include <stdint.h>
/** Get the offset of a struct member.
* @internal
*/
#define __UVISOR_OFFSETOF(type, member) ((uint32_t) (&(((type *)(0))->member)))
/** Generate the SVCall opcode from the SVC ID. */
#define UVISOR_SVC_OPCODE(id) ((uint16_t) (0xDF00 | ((id) & 0xFF)))
/** Generate the opcode of the 16-bit Thumb-2 16-bit T2 encoding of the branch
* instruction.
* @internal
* @note The branch instruction is encoded according to the Thumb-2 immediate
* encoding rules:
* <instr_addr>: B.N <label>
* imm = (<label>_addr - PC) / 2
* Where:
* PC = <instr>_addr + 4
* The +4 is to account for the pipelined PC at the time of the branch
* instruction. See ARM DDI 0403E.b page A4-102 for more details.
* @param instr[in] Address of the branch instruction
* @param label[in] Address of the label
* @returns the 16-bit encoding of the B.N <label> instruction.
*/
#define BRANCH_OPCODE(instr, label) \
(uint16_t) (0xE000 | (uint8_t) ((((uint32_t) (label) - ((uint32_t) (instr) + 4)) / 2) & 0xFF))
/** `BX LR` encoding
* @internal
*/
#define BXLR ((uint16_t) 0x4770)
/** Register Gateway - Read operation
*
* This macro provides an API to perform 32-bit read operations on restricted
* registers. Such accesses are assembled into a read-only flash structure that
* is read and validated by uVisor before performing the operation.
*
* @warning This API currently only supports link-time known value for the
* address, operation and mask.
*
* @param box_name[in] The name of the source box as decalred in
* `UVISOR_BOX_CONFIG`.
* @param shared[in] Whether the gateway can be shared with other boxes or
* not. Two values are available: UVISOR_RGW_SHARED,
* UVISOR_RGW_EXCLUSIVE.
* @param addr[in] The address for the data access.
* @param operation[in] The operation to perform at the address for the read. It
* is chosen among the `UVISOR_RGW_OP_*` macros.
* @param mask[in] The mask to apply for the read operation.
* @returns The value read from address using the operation and mask provided
* (or their respective defaults if they have not been provided).
*/
#define uvisor_read(box_name, shared, addr, op, msk) \
({ \
/* Instanstiate the gateway. This gets resolved at link-time. */ \
UVISOR_ALIGN(4) static TRegisterGateway const register_gateway = { \
.svc_opcode = UVISOR_SVC_OPCODE(UVISOR_SVC_ID_REGISTER_GATEWAY), \
.branch = BRANCH_OPCODE(__UVISOR_OFFSETOF(TRegisterGateway, branch), \
__UVISOR_OFFSETOF(TRegisterGateway, bxlr)), \
.magic = UVISOR_REGISTER_GATEWAY_MAGIC, \
.box_ptr = (uint32_t) & box_name ## _cfg_ptr, \
.address = (uint32_t) addr, \
.mask = msk, \
.operation = UVISOR_RGW_OP(op, sizeof(*addr), shared), \
.bxlr = BXLR \
}; \
\
/* Pointer to the register gateway we just created. The pointer is
* located in a discoverable linker section. */ \
__attribute__((section(".keep.uvisor.register_gateway_ptr"))) \
static uint32_t const register_gateway_ptr = (uint32_t) &register_gateway; \
(void) register_gateway_ptr; \
\
/* Call the actual gateway. */ \
uint32_t result = ((uint32_t (*)(void)) ((uint32_t) &register_gateway | 1))(); \
(typeof(*addr)) result; \
})
/** Register Gateway - Write operation
*
* This macro provides an API to perform 32-bit write operations on restricted
* registers. Such accesses are assembled into a read-only flash structure that
* is read and validated by uVisor before performing the operation.
*
* @warning This API currently only supports link-time known value for the
* address, operation and mask.
*
* @param box_name[in] The name of the source box as decalred in
* `UVISOR_BOX_CONFIG`.
* @param shared[in] Whether the gateway can be shared with other boxes or
* not. Two values are available: UVISOR_RGW_SHARED,
* UVISOR_RGW_EXCLUSIVE.
* @param addr[in] The address for the data access.
* @param val[in] The value to write at address.
* @param operation[in] The operation to perform at the address for the read. It
* is chosen among the `UVISOR_RGW_OP_*` macros.
* @param mask[in] The mask to apply for the write operation.
*/
#define uvisor_write(box_name, shared, addr, val, op, msk) \
{ \
/* Instanstiate the gateway. This gets resolved at link-time. */ \
UVISOR_ALIGN(4) static TRegisterGateway const register_gateway = { \
.svc_opcode = UVISOR_SVC_OPCODE(UVISOR_SVC_ID_REGISTER_GATEWAY), \
.branch = BRANCH_OPCODE(__UVISOR_OFFSETOF(TRegisterGateway, branch), \
__UVISOR_OFFSETOF(TRegisterGateway, bxlr)), \
.magic = UVISOR_REGISTER_GATEWAY_MAGIC, \
.box_ptr = (uint32_t) & box_name ## _cfg_ptr, \
.address = (uint32_t) addr, \
.mask = msk, \
.operation = UVISOR_RGW_OP(op, sizeof(*addr), shared), \
.bxlr = BXLR \
}; \
\
/* Pointer to the register gateway we just created. The pointer is
* located in a discoverable linker section. */ \
__attribute__((section(".keep.uvisor.register_gateway_ptr"))) \
static uint32_t const register_gateway_ptr = (uint32_t) &register_gateway; \
(void) register_gateway_ptr; \
\
/* Call the actual gateway.
* The value is passed as the first argument. */ \
((void (*)(uint32_t)) ((uint32_t) ((uint32_t) &register_gateway | 1)))((uint32_t) (val)); \
}
/** Get the selected bits at the target address.
* @param box_name[in] Box name as defined by the uVisor box configuration
* macro `UVISOR_BOX_CONFIG`
* @param shared[in] Whether the gateway can be shared with other boxes or
* not. Two values are available: UVISOR_RGW_SHARED,
* UVISOR_RGW_EXCLUSIVE.
* @param address[in] Target address
* @param mask[in] Bits to select out of the target address
* @returns The value `*address & mask`.
*/
#define UVISOR_BITS_GET(box_name, shared, address, mask) \
/* Register gateway implementation:
* *address & mask */ \
uvisor_read(box_name, shared, address, UVISOR_RGW_OP_READ_AND, mask)
/** Check the selected bits at the target address.
* @param box_name[in] Box name as defined by the uVisor box configuration
* macro `UVISOR_BOX_CONFIG`
* @param shared[in] Whether the gateway can be shared with other boxes or
* not. Two values are available: UVISOR_RGW_SHARED,
* UVISOR_RGW_EXCLUSIVE.
* @param address[in] Address at which to check the bits
* @param mask[in] Bits to select out of the target address
* @returns The value `((*address & mask) == mask)`.
*/
#define UVISOR_BITS_CHECK(box_name, shared, address, mask) \
((UVISOR_BITS_GET(box_name, shared, address, mask)) == (mask))
/** Set the selected bits to 1 at the target address.
*
* Equivalent to: `*address |= mask`.
* @param box_name[in] Box name as defined by the uVisor box configuration
* macro `UVISOR_BOX_CONFIG`
* @param shared[in] Whether the gateway can be shared with other boxes or
* not. Two values are available: UVISOR_RGW_SHARED,
* UVISOR_RGW_EXCLUSIVE.
* @param address[in] Target address
* @param mask[in] Bits to select out of the target address
*/
#define UVISOR_BITS_SET(box_name, shared, address, mask) \
/* Register gateway implementation:
* *address |= (mask & mask) */ \
uvisor_write(box_name, shared, address, mask, UVISOR_RGW_OP_WRITE_OR, mask)
/** Clear the selected bits at the target address.
*
* Equivalent to: `*address &= ~mask`.
* @param box_name[in] Box name as defined by the uVisor box configuration
* macro `UVISOR_BOX_CONFIG`
* @param shared[in] Whether the gateway can be shared with other boxes or
* not. Two values are available: UVISOR_RGW_SHARED,
* UVISOR_RGW_EXCLUSIVE.
* @param address[in] Target address
* @param mask[in] Bits to select out of the target address
*/
#define UVISOR_BITS_CLEAR(box_name, shared, address, mask) \
/* Register gateway implementation:
* *address &= (0x00000000 | ~mask) */ \
uvisor_write(box_name, shared, address, 0x00000000, UVISOR_RGW_OP_WRITE_AND, mask)
/** Set the selected bits at the target address to the given value.
*
* Equivalent to: `*address = (*address & ~mask) | (value & mask)`.
* @param box_name[in] Box name as defined by the uVisor box configuration
* macro `UVISOR_BOX_CONFIG`
* @param shared[in] Whether the gateway can be shared with other boxes or
* not. Two values are available: UVISOR_RGW_SHARED,
* UVISOR_RGW_EXCLUSIVE.
* @param address[in] Target address
* @param mask[in] Bits to select out of the target address
* @param value[in] Value to write at the address location. Note: The value
* must be already shifted to the correct bit position
*/
#define UVISOR_BITS_SET_VALUE(box_name, shared, address, mask, value) \
/* Register gateway implementation:
* *address = (*address & ~mask) | (value & mask) */ \
uvisor_write(box_name, shared, address, value, UVISOR_RGW_OP_WRITE_REPLACE, mask)
/** Toggle the selected bits at the target address.
*
* Equivalent to: `*address ^= mask`.
* @param box_name[in] Box name as defined by the uVisor box configuration
* macro `UVISOR_BOX_CONFIG`
* @param shared[in] Whether the gateway can be shared with other boxes or
* not. Two values are available: UVISOR_RGW_SHARED,
* UVISOR_RGW_EXCLUSIVE.
* @param address[in] Target address
* @param mask[in] Bits to select out of the target address
*/
#define UVISOR_BITS_TOGGLE(box_name, shared, address, mask) \
/* Register gateway implementation:
* *address ^= (0xFFFFFFFF & mask) */ \
uvisor_write(box_name, shared, address, 0xFFFFFFFF, UVISOR_RGW_OP_WRITE_XOR, mask)
#endif /* __UVISOR_API_REGISTER_GATEWAY_H__ */

View File

@ -1,95 +0,0 @@
/*
* Copyright (c) 2015-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 __UVISOR_API_REGISTER_GATEWAY_EXPORTS_H__
#define __UVISOR_API_REGISTER_GATEWAY_EXPORTS_H__
/** Register gateway magic
*
* The following magic is used to verify a register gateway structure. It has
* been generated starting from the ARM Thumb/Thumb-2 invalid opcode.
* ARM Thumb (with the Thumb-2 extension): 0xF7FxAxxx (32 bits)
* The 'x's can be freely chosen (they have been chosen randomly here). This
* requires the Thumb-2 extensions because otherwise only 16 bits opcodes are
* accepted.
*/
#if defined(__thumb__) && defined(__thumb2__)
#define UVISOR_REGISTER_GATEWAY_MAGIC 0xF7F3A89E
#else
#error "Unsupported instruction set. The ARM Thumb-2 instruction set must be supported."
#endif /* __thumb__ && __thumb2__ */
/** Register gateway structure
*
* This struct is packed because we must ensure that the `svc_opcode` field has
* no padding before itself, and that the `bxlr` field is at a pre-determined
* offset from the `branch` field.
*/
typedef struct {
uint16_t svc_opcode;
uint16_t branch;
uint32_t magic;
uint32_t box_ptr;
uint32_t address;
uint32_t mask;
uint16_t operation;
uint16_t bxlr;
} UVISOR_PACKED UVISOR_ALIGN(4) TRegisterGateway;
/** Register gateway operation - Masks
* @internal
* These are used to extract the operation fields.
*/
#define __UVISOR_RGW_OP_TYPE_MASK ((uint16_t) 0x00FF)
#define __UVISOR_RGW_OP_TYPE_POS 0
#define __UVISOR_RGW_OP_WIDTH_MASK ((uint16_t) 0x3F00)
#define __UVISOR_RGW_OP_WIDTH_POS 8
#define __UVISOR_RGW_OP_SHARED_MASK ((uint16_t) 0x8000)
#define __UVISOR_RGW_OP_SHARED_POS 15
/** Register gateway operations
* The user can specify the following properties:
* - Access type: read/write, and-, or-, xor-, replac-ed.
* - Access width: 8, 16, 32 bits.
* - Access shared: Whether the gateway can be shared with other boxes.
* These parameters are stored in a 16-bit value as follows:
*
* 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
* | |__________________| |____________________|
* | | |
* shared width type
*
* @note The operation value must be hardcoded.
*/
#define UVISOR_RGW_OP(type, width, shared) \
((uint16_t) ((((uint16_t) (type) << __UVISOR_RGW_OP_TYPE_POS) & __UVISOR_RGW_OP_TYPE_MASK) | \
(((uint16_t) (width) << __UVISOR_RGW_OP_WIDTH_POS) & __UVISOR_RGW_OP_WIDTH_MASK) | \
(((uint16_t) (shared) << __UVISOR_RGW_OP_SHARED_POS) & __UVISOR_RGW_OP_SHARED_MASK)))
/** Register gateway operation - Shared */
#define UVISOR_RGW_SHARED 1
#define UVISOR_RGW_EXCLUSIVE 0
/** Register gateway operation - Type */
#define UVISOR_RGW_OP_READ 0 /**< value = *address */
#define UVISOR_RGW_OP_READ_AND 1 /**< value = *address & mask */
#define UVISOR_RGW_OP_WRITE 2 /**< *address = value */
#define UVISOR_RGW_OP_WRITE_AND 3 /**< *address &= value | mask */
#define UVISOR_RGW_OP_WRITE_OR 4 /**< *address |= value & ~mask */
#define UVISOR_RGW_OP_WRITE_XOR 5 /**< *address ^= value & mask */
#define UVISOR_RGW_OP_WRITE_REPLACE 6 /**< *address = (*address & ~mask) | (value & mask) */
#endif /* __UVISOR_API_REGISTER_GATEWAY_EXPORTS_H__ */

View File

@ -1,56 +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.
*/
#ifndef __UVISOR_API_RPC_H__
#define __UVISOR_API_RPC_H__
#include "api/inc/rpc_exports.h"
#include "api/inc/uvisor_exports.h"
#include <stdint.h>
#include <stddef.h>
/** Wait for incoming RPC.
*
* @param fn_ptr_array an array of RPC function targets that this call to
* `rpc_fncall_waitfor` should handle RPC to
* @param fn_count the number of function targets in this array
* @param box_id_caller[out] a memory location to store the box ID of the
* calling box (the source box of the RPC). This is
* set before the RPC is dispatched, so that the RPC
* target function can read from this location to
* determine the calling box ID. Optional.
* @param timeout_ms specifies how long to wait (in ms) for an incoming
* RPC message before returning
*/
UVISOR_EXTERN int rpc_fncall_waitfor(const TFN_Ptr fn_ptr_array[], size_t fn_count, int * box_id_caller, uint32_t timeout_ms);
/** Wait for an outgoing RPC to finish.
*
* Wait for the result of a previously started asynchronous RPC. After this
* call, ret will contain the return value of the RPC. The return value of this
* function may indicate that there was an error or a timeout with non-zero.
*
* @param result[in] The token to wait on for the result of an asynchronous RPC
* @param timeout_ms[in] How long to wait (in ms) for the asynchronous RPC
* message to finish before returning
* @param ret[out] The return value resulting from the finished RPC to
* the target function
* @returns Non-zero on error or timeout, zero on successful wait
*/
UVISOR_EXTERN int rpc_fncall_wait(uvisor_rpc_result_t result, uint32_t timeout_ms, uint32_t * ret);
#endif /* __UVISOR_API_RPC_H__ */

View File

@ -1,160 +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.
*/
#ifndef __UVISOR_API_RPC_EXPORTS_H__
#define __UVISOR_API_RPC_EXPORTS_H__
#include "api/inc/pool_queue_exports.h"
#include "api/inc/uvisor_semaphore_exports.h"
#include "api/inc/rpc_gateway_exports.h"
#include "api/inc/vmpu_exports.h"
typedef uint32_t (*TFN_Ptr)(uint32_t, uint32_t, uint32_t, uint32_t);
#define UVISOR_RESULT_SLOT_BITS 10
#define UVISOR_RESULT_SLOT_MASK ((1 << UVISOR_RESULT_SLOT_BITS) - 1)
#define UVISOR_RESULT_COUNTER_MASK (0xFFFFFFFFUL << UVISOR_RESULT_SLOT_BITS)
/* Increment by 2 because we never want to overflow into the invalid value. */
#define UVISOR_RESULT_COUNTER_INCREMENT (2 << UVISOR_RESULT_SLOT_BITS)
#define UVISOR_RESULT_INVALID_COUNTER (UVISOR_RESULT_COUNTER_MASK)
/* This is the token to wait on for the result of an asynchronous RPC. */
typedef uint32_t uvisor_rpc_result_t;
static inline uvisor_pool_slot_t uvisor_result_slot(uvisor_rpc_result_t result)
{
return result & UVISOR_RESULT_SLOT_MASK;
}
static inline uint32_t uvisor_result_counter(uvisor_rpc_result_t result)
{
return result & UVISOR_RESULT_COUNTER_MASK;
}
static inline uvisor_rpc_result_t uvisor_result_build(uint32_t counter, uvisor_pool_slot_t slot)
{
return (counter & UVISOR_RESULT_COUNTER_MASK) | (slot & UVISOR_RESULT_SLOT_MASK);
}
typedef enum {
/* Who sets this value for caller (outgoing queue), Who sets this value for (incoming queue) callee. */
UVISOR_RPC_MESSAGE_STATE_INVALID, /* nobody, nobody */
UVISOR_RPC_MESSAGE_STATE_IDLE, /* caller receive function before freeing, uvisor when delivers back */
UVISOR_RPC_MESSAGE_STATE_READY_TO_SEND, /* send function, nobody */
UVISOR_RPC_MESSAGE_STATE_SENT, /* uvisor, uvisor */
UVISOR_RPC_MESSAGE_STATE_DONE, /* waitfor_fngroup function, uvisor when delivers back */
} uvisor_rpc_message_state_t;
typedef struct uvisor_rpc_message {
/* NOTE: These are set by the caller, and read by the callee. */
uint32_t p0;
uint32_t p1;
uint32_t p2;
uint32_t p3;
const TRPCGateway * gateway;
/* The box ID of the other box. For callers, this is the destination box
* ID. For callees, this is the source box ID. */
int other_box_id;
/* The semaphore to post to when a result is ready */
UvisorSemaphore semaphore;
/* This cookie keeps track of which result to wait for. It changes
* atomically to an invalid cookie when being waited on, to prevent
* multiple waits for the same result. */
uvisor_rpc_result_t wait_cookie;
/* This is an extra copy of the above cookie, used by uVisor to verify that
* a certain result matches a certain caller. This identifies to uVisor
* which RPC it should complete. uVisor must verify this information of
* course, to see if this box is currently being called into and is allowed
* to complete the RPC. */
uvisor_rpc_result_t match_cookie;
uvisor_rpc_message_state_t state;
uint32_t result;
} uvisor_rpc_message_t;
typedef struct uvisor_rpc_fn_group {
/* A pointer to the function group */
TFN_Ptr const * fn_ptr_array;
size_t fn_count;
/* The semaphore to wait on for this function group */
UvisorSemaphore semaphore;
} uvisor_rpc_fn_group_t;
#define UVISOR_RPC_OUTGOING_MESSAGE_SLOTS (8)
#define UVISOR_RPC_INCOMING_MESSAGE_SLOTS (8)
#define UVISOR_RPC_FN_GROUP_SLOTS (8)
#define UVISOR_RPC_OUTGOING_MESSAGE_TYPE(slots) \
struct { \
uvisor_pool_queue_t queue; \
uvisor_pool_t pool; \
uvisor_pool_queue_entry_t entries[slots]; \
uvisor_rpc_message_t messages[slots]; \
}
#define UVISOR_RPC_INCOMING_MESSAGE_TYPE(slots) \
struct { \
uvisor_pool_queue_t todo_queue; \
uvisor_pool_queue_t done_queue; \
uvisor_pool_t pool; \
uvisor_pool_queue_entry_t entries[slots]; \
uvisor_rpc_message_t messages[slots]; \
}
#define UVISOR_RPC_FN_GROUP_TYPE(slots) \
struct { \
uvisor_pool_queue_t queue; \
uvisor_pool_t pool; \
uvisor_pool_queue_entry_t entries[slots]; \
uvisor_rpc_fn_group_t fn_groups[slots]; \
}
typedef UVISOR_RPC_OUTGOING_MESSAGE_TYPE(UVISOR_RPC_OUTGOING_MESSAGE_SLOTS) uvisor_rpc_outgoing_message_queue_t;
typedef UVISOR_RPC_INCOMING_MESSAGE_TYPE(UVISOR_RPC_INCOMING_MESSAGE_SLOTS) uvisor_rpc_incoming_message_queue_t;
typedef UVISOR_RPC_FN_GROUP_TYPE(UVISOR_RPC_FN_GROUP_SLOTS) uvisor_rpc_fn_group_queue_t;
typedef struct uvisor_rpc_t {
/* Outgoing message queue */
uvisor_rpc_outgoing_message_queue_t outgoing_message_queue;
/* Incoming message queue */
uvisor_rpc_incoming_message_queue_t incoming_message_queue;
/* Function group queue */
uvisor_rpc_fn_group_queue_t fn_group_queue;
/* Counter to avoid waiting on the same RPC result twice by accident. */
uint32_t result_counter;
} uvisor_rpc_t;
static inline uvisor_rpc_t * uvisor_rpc(UvisorBoxIndex * const index)
{
return (uvisor_rpc_t *) index->bss.address_of.rpc;
}
#endif

View File

@ -1,272 +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.
*/
#ifndef __UVISOR_API_RPC_GATEWAY_H__
#define __UVISOR_API_RPC_GATEWAY_H__
#include "api/inc/rpc_gateway_exports.h"
#include "api/inc/rpc.h"
#include "api/inc/uvisor_exports.h"
#include <stdint.h>
/** Synchronous RPC Gateway
*
* This macro declares a new function pointer (with no name mangling) named
* `gw_name` to perform a remote procedure call (RPC) to the target function
* given by `fn_name`. RPCs are assembled into a read-only flash structure that
* is read and validated by uVisor before performing the operation.
*
* Create function with following signature:
* UVISOR_EXTERN fn_ret gw_name(uint32_t a, uint32_t b);
*
* @param box_name[in] The name of the source box as declared in
* `UVISOR_BOX_CONFIG`
* @param gw_name[in] The new, callable function pointer for initiating an RPC from the caller's box
* @param fn_name[in] The function that will run in the callee's box as an RPC target
* @param fn_ret[in] The return type of the function being designated as an
* RPC target
* @param __VA_ARGS__ The type of each parameter passed to the target
* function. There can be up to 4 parameters in a target
* function. Each parameter must be no more than uint32_t
* in size. If the RPC target function accepts no
* arguments, pass `void` here.
*/
#define UVISOR_BOX_RPC_GATEWAY_SYNC(box_name, gw_name, fn_name, fn_ret, ...) \
UVISOR_STATIC_ASSERT(sizeof(fn_ret) <= sizeof(uint32_t), gw_name ## _return_type_too_big); \
_UVISOR_BOX_RPC_GATEWAY_ARG_CHECK(gw_name, __VA_ARGS__) \
_UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_DECL(fn_name, gw_name ## _rpc_gateway, __VA_ARGS__) \
/* Instanstiate the gateway. This gets resolved at link-time. */ \
UVISOR_EXTERN TRPCGateway const gw_name ## _rpc_gateway = { \
.ldr_pc = LDR_PC_PC_IMM_OPCODE(__UVISOR_OFFSETOF(TRPCGateway, ldr_pc), \
__UVISOR_OFFSETOF(TRPCGateway, caller)), \
.magic = UVISOR_RPC_GATEWAY_MAGIC_SYNC, \
.box_ptr = (uint32_t) &box_name ## _cfg_ptr, \
.target = (uint32_t) fn_name, \
.caller = (uint32_t) _sgw_sync_ ## fn_name, \
}; \
_UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER(fn_name, gw_name ## _rpc_gateway, __VA_ARGS__) \
\
/* Pointer to the gateway we just created. The pointer is located in a
* discoverable linker section. */ \
__attribute__((section(".keep.uvisor.rpc_gateway_ptr"))) \
uint32_t const gw_name ## _rpc_gateway_ptr = (uint32_t) &gw_name ## _rpc_gateway; \
\
/* Declare the actual gateway. */ \
UVISOR_EXTERN_C_BEGIN \
fn_ret (*gw_name)(__VA_ARGS__) __attribute__((section(".rodata"))) = (fn_ret (*)(__VA_ARGS__)) ((uint32_t) &gw_name ## _rpc_gateway + 1); \
UVISOR_EXTERN_C_END
/** Asynchronous RPC Gateway
*
* This macro declares a new function pointer (with no name mangling) named
* `gw_name` to perform a remote procedure call (RPC) to the target function
* given by `fn_name`. RPCs are assembled into a read-only flash structure that
* is read and validated by uVisor before performing the operation.
*
* Create function with following signature:
* UVISOR_EXTERN uvisor_rpc_result_t gw_name(uint32_t a, uint32_t b);
*
* @param box_name[in] The name of the source box as declared in
* `UVISOR_BOX_CONFIG`
* @param gw_name[in] The new, callable function pointer for initiating an RPC from the caller's box
* @param fn_name[in] The function that will run in the callee's box as an RPC target
* @param fn_ret[in] The return type of the function being designated as an
* RPC target
* @param __VA_ARGS__ The type of each parameter passed to the target
* function. There can be up to 4 parameters in a target
* function. Each parameter must be no more than uint32_t
* in size. If the RPC target function accepts no
* arguments, pass `void` here.
*/
#define UVISOR_BOX_RPC_GATEWAY_ASYNC(box_name, gw_name, fn_name, fn_ret, ...) \
UVISOR_STATIC_ASSERT(sizeof(fn_ret) <= sizeof(uint32_t), gw_name ## _return_type_too_big); \
_UVISOR_BOX_RPC_GATEWAY_ARG_CHECK(gw_name, __VA_ARGS__) \
_UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_DECL(fn_name, gw_name ## _rpc_gateway, __VA_ARGS__) \
/* Instanstiate the gateway. This gets resolved at link-time. */ \
UVISOR_EXTERN TRPCGateway const gw_name ## _rpc_gateway = { \
.ldr_pc = LDR_PC_PC_IMM_OPCODE(__UVISOR_OFFSETOF(TRPCGateway, ldr_pc), \
__UVISOR_OFFSETOF(TRPCGateway, caller)), \
.magic = UVISOR_RPC_GATEWAY_MAGIC_ASYNC, \
.box_ptr = (uint32_t) &box_name ## _cfg_ptr, \
.target = (uint32_t) fn_name, \
.caller = (uint32_t) _sgw_async_ ## fn_name, \
}; \
_UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER(fn_name, gw_name ## _rpc_gateway, __VA_ARGS__) \
\
/* Pointer to the gateway we just created. The pointer is located in a
* discoverable linker section. */ \
__attribute__((section(".keep.uvisor.rpc_gateway_ptr"))) \
uint32_t const gw_name ## _rpc_gateway_ptr = (uint32_t) &gw_name ## _rpc_gateway; \
\
/* Declare the actual gateway. */ \
UVISOR_EXTERN_C_BEGIN \
uvisor_rpc_result_t (*gw_name)(__VA_ARGS__) __attribute__((section(".rodata"))) = (uvisor_rpc_result_t (*)(__VA_ARGS__)) ((uint32_t) &gw_name ## _rpc_gateway + 1); \
UVISOR_EXTERN_C_END
#define _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK(gw_name, ...) \
__UVISOR_BOX_MACRO(__VA_ARGS__, _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_4, \
_UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_3, \
_UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_2, \
_UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_1, \
_UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_0)(gw_name, __VA_ARGS__)
#define _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_0(gw_name)
#define _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_1(gw_name, p0_type) \
UVISOR_STATIC_ASSERT(sizeof(p0_type) <= sizeof(uint32_t), gw_name ## _param_0_too_big);
#define _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_2(gw_name, p0_type, p1_type) \
UVISOR_STATIC_ASSERT(sizeof(p0_type) <= sizeof(uint32_t), gw_name ## _param_0_too_big); \
UVISOR_STATIC_ASSERT(sizeof(p1_type) <= sizeof(uint32_t), gw_name ## _param_1_too_big);
#define _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_3(gw_name, p0_type, p1_type, p2_type) \
UVISOR_STATIC_ASSERT(sizeof(p0_type) <= sizeof(uint32_t), gw_name ## _param_0_too_big); \
UVISOR_STATIC_ASSERT(sizeof(p1_type) <= sizeof(uint32_t), gw_name ## _param_1_too_big); \
UVISOR_STATIC_ASSERT(sizeof(p2_type) <= sizeof(uint32_t), gw_name ## _param_2_too_big);
#define _UVISOR_BOX_RPC_GATEWAY_ARG_CHECK_4(gw_name, p0_type, p1_type, p2_type, p3_type) \
UVISOR_STATIC_ASSERT(sizeof(p0_type) <= sizeof(uint32_t), gw_name ## _param_0_too_big); \
UVISOR_STATIC_ASSERT(sizeof(p1_type) <= sizeof(uint32_t), gw_name ## _param_1_too_big); \
UVISOR_STATIC_ASSERT(sizeof(p2_type) <= sizeof(uint32_t), gw_name ## _param_2_too_big); \
UVISOR_STATIC_ASSERT(sizeof(p3_type) <= sizeof(uint32_t), gw_name ## _param_3_too_big);
#define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_DECL(fn_name, gateway, ...) \
__UVISOR_BOX_MACRO(__VA_ARGS__, _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_4_DECL, \
_UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_3_DECL, \
_UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_2_DECL, \
_UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_1_DECL, \
_UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_0_DECL)(fn_name, gateway, __VA_ARGS__)
#define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER(fn_name, gateway, ...) \
__UVISOR_BOX_MACRO(__VA_ARGS__, _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_4, \
_UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_3, \
_UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_2, \
_UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_1, \
_UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_0)(fn_name, gateway, __VA_ARGS__)
#define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_0_DECL(fn_name, gateway, ...) \
static uint32_t _sgw_sync_ ## fn_name(void);
#define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_0(fn_name, gateway, ...) \
static uint32_t _sgw_sync_ ## fn_name(void) \
{ \
return rpc_fncall_sync(0, 0, 0, 0, &gateway); \
}
#define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_1_DECL(fn_name, gateway, ...) \
static uint32_t _sgw_sync_ ## fn_name(uint32_t p0);
#define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_1(fn_name, gateway, ...) \
static uint32_t _sgw_sync_ ## fn_name(uint32_t p0) \
{ \
return rpc_fncall_sync(p0, 0, 0, 0, &gateway); \
}
#define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_2_DECL(fn_name, gateway, ...) \
static uint32_t _sgw_sync_ ## fn_name(uint32_t p0, uint32_t p1);
#define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_2(fn_name, gateway, ...) \
static uint32_t _sgw_sync_ ## fn_name(uint32_t p0, uint32_t p1) \
{ \
return rpc_fncall_sync(p0, p1, 0, 0, &gateway); \
}
#define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_3_DECL(fn_name, gateway, ...) \
static uint32_t _sgw_sync_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2);
#define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_3(fn_name, gateway, ...) \
static uint32_t _sgw_sync_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2) \
{ \
return rpc_fncall_sync(p0, p1, p2, 0, &gateway); \
}
#define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_4_DECL(fn_name, gateway, ...) \
static uint32_t _sgw_sync_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3);
#define _UVISOR_BOX_RPC_GATEWAY_SYNC_CALLER_4(fn_name, gateway, ...) \
static uint32_t _sgw_sync_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3) \
{ \
return rpc_fncall_sync(p0, p1, p2, p3, &gateway); \
}
#define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_DECL(fn_name, gateway, ...) \
__UVISOR_BOX_MACRO(__VA_ARGS__, _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_4_DECL, \
_UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_3_DECL, \
_UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_2_DECL, \
_UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_1_DECL, \
_UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_0_DECL)(fn_name, gateway, __VA_ARGS__)
#define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER(fn_name, gateway, ...) \
__UVISOR_BOX_MACRO(__VA_ARGS__, _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_4, \
_UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_3, \
_UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_2, \
_UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_1, \
_UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_0)(fn_name, gateway, __VA_ARGS__)
#define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_0_DECL(fn_name, gateway, ...) \
static uvisor_rpc_result_t _sgw_async_ ## fn_name(void);
#define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_0(fn_name, gateway, ...) \
static uvisor_rpc_result_t _sgw_async_ ## fn_name(void) \
{ \
return rpc_fncall_async(0, 0, 0, 0, &gateway); \
}
#define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_1_DECL(fn_name, gateway, ...) \
static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0);
#define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_1(fn_name, gateway, ...) \
static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0) \
{ \
return rpc_fncall_async(p0, 0, 0, 0, &gateway); \
}
#define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_2_DECL(fn_name, gateway, ...) \
static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0, uint32_t p1);
#define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_2(fn_name, gateway, ...) \
static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0, uint32_t p1) \
{ \
return rpc_fncall_async(p0, p1, 0, 0, &gateway); \
}
#define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_3_DECL(fn_name, gateway, ...) \
static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2);
#define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_3(fn_name, gateway, ...) \
static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2) \
{ \
return rpc_fncall_async(p0, p1, p2, 0, &gateway); \
}
#define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_4_DECL(fn_name, gateway, ...) \
static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3);
#define _UVISOR_BOX_RPC_GATEWAY_ASYNC_CALLER_4(fn_name, gateway, ...) \
static uvisor_rpc_result_t _sgw_async_ ## fn_name(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3) \
{ \
return rpc_fncall_async(p0, p1, p2, p3, &gateway); \
}
/* This function is private to uvisor-lib, but needs to be publicly visible for
* the RPC gateway creation macros to work. */
UVISOR_EXTERN uint32_t rpc_fncall_sync(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, const TRPCGateway * gateway);
/* This function is private to uvisor-lib, but needs to be publicly visible for
* the RPC gateway creation macros to work. */
UVISOR_EXTERN uvisor_rpc_result_t rpc_fncall_async(uint32_t p0, uint32_t p1, uint32_t p2, uint32_t p3, const TRPCGateway * gateway);
#endif /* __UVISOR_API_RPC_GATEWAY_H__ */

View File

@ -1,45 +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.
*/
#ifndef __UVISOR_API_RPC_GATEWAY_EXPORTS_H__
#define __UVISOR_API_RPC_GATEWAY_EXPORTS_H__
#include "api/inc/uvisor_exports.h"
#include "api/inc/magic_exports.h"
#include <stdint.h>
/* ldr pc, [pc, #<label - instr + 4>]
* LDR (immediate) - ARMv7M ARM section A7.7.42
* 1111;1 00 0; 0 10 1; <Rn - 1111>; <Rt - 1111>; <imm12> (Encoding T3) */
#define LDR_PC_PC_IMM_OPCODE(instr, label) \
((uint32_t) (0xF000F8DFUL | ((((uint32_t) (label) - ((uint32_t) (instr) + 4)) & 0xFFFUL) << 16)))
/** RPC gateway structure
*
* This struct is packed because we must ensure that the `ldr_pc` field has no
* padding before itself and will be located at a valid instruction location,
* and that the `caller` and `target` field are at a pre-determined offset from
* the `ldr_pc` field.
*/
typedef struct RPCGateway {
uint32_t ldr_pc;
uint32_t magic;
uint32_t box_ptr;
uint32_t target;
uint32_t caller; /* This is not for use by anything other than the ldr_pc. It's like a pretend literal pool. */
} UVISOR_PACKED UVISOR_ALIGN(4) TRPCGateway;
#endif /* __UVISOR_API_RPC_GATEWAY_EXPORTS_H__ */

View File

@ -1,91 +0,0 @@
/*
* Copyright (c) 2015, 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 __UVISOR_API_SECURE_ACCESS_H__
#define __UVISOR_API_SECURE_ACCESS_H__
#include "api/inc/uvisor_exports.h"
#include "api/inc/vmpu_exports.h"
#include <stddef.h>
#include <stdint.h>
static UVISOR_FORCEINLINE void uvisor_write32(uint32_t volatile * volatile addr, uint32_t val)
{
UVISOR_ASM_MEMORY_ACCESS(str, uint32_t, addr, val);
}
static UVISOR_FORCEINLINE void uvisor_write16(uint16_t volatile * volatile addr, uint16_t val)
{
UVISOR_ASM_MEMORY_ACCESS(strh, uint16_t, addr, val);
}
static UVISOR_FORCEINLINE void uvisor_write8(uint8_t volatile * volatile addr, uint8_t val)
{
UVISOR_ASM_MEMORY_ACCESS(strb, uint8_t, addr, val);
}
static UVISOR_FORCEINLINE uint32_t uvisor_read32(uint32_t volatile * volatile addr)
{
return UVISOR_ASM_MEMORY_ACCESS(ldr, uint32_t, addr);
}
static UVISOR_FORCEINLINE uint16_t uvisor_read16(uint16_t volatile * volatile addr)
{
return UVISOR_ASM_MEMORY_ACCESS(ldrh, uint16_t, addr);
}
static UVISOR_FORCEINLINE uint8_t uvisor_read8(uint8_t volatile * volatile addr)
{
return UVISOR_ASM_MEMORY_ACCESS(ldrb, uint8_t, addr);
}
/* The switch statement will be optimised away since the compiler already knows
* the sizeof_type. */
static UVISOR_FORCEINLINE void __address_write(size_t sizeof_type, volatile uint32_t *addr, uint32_t val)
{
switch(sizeof_type) {
case 4:
uvisor_write32((volatile uint32_t * volatile) addr, (uint32_t) val);
break;
case 2:
uvisor_write16((volatile uint16_t * volatile) addr, (uint16_t) val);
break;
case 1:
uvisor_write8((volatile uint8_t * volatile) addr, (uint8_t) val);
break;
default:
uvisor_error(USER_NOT_ALLOWED);
break;
}
}
#define ADDRESS_WRITE(type, addr, val) __address_write(sizeof(type), (volatile uint32_t *) addr, (uint32_t) val)
/* the conditional statement will be optimised away since the compiler already
* knows the sizeof(type) */
#define ADDRESS_READ(type, addr) \
(sizeof(type) == 4 ? uvisor_read32((uint32_t volatile * volatile) (addr)) : \
sizeof(type) == 2 ? uvisor_read16((uint16_t volatile * volatile) (addr)) : \
sizeof(type) == 1 ? uvisor_read8((uint8_t volatile * volatile) (addr)) : 0)
#define UNION_READ(type, addr, fieldU, fieldB) \
({ \
type res; \
res.fieldU = ADDRESS_READ(type, addr); \
res.fieldB; \
})
#endif /* __UVISOR_API_SECURE_ACCESS_H__ */

View File

@ -1,103 +0,0 @@
/*
* Copyright (c) 2013-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 __UVISOR_API_SVC_EXPORTS_H__
#define __UVISOR_API_SVC_EXPORTS_H__
#include "api/inc/uvisor_exports.h"
#include "api/inc/api.h"
#include <stdint.h>
/* An SVCall takes a 8bit immediate, which is used as follows:
*
* For fast APIs:
*
* 7 6 5 4 3 2 1 0
* .---.---.---.---.---.---.---.---.
* | 1 | N | N | N | h | h | h | h |
* '---'---'---'---'---'---'---'---'
* | |_______| |___________|
* | | |
* | | |
* | | |
* | | (h) Handler index in the hardcoded table (max 16)
* | |
* | (N) Number of arguments to pass to the handler (max 4)
* |
* SVCall mode: Fast
*
* For slow APIs:
*
* 7 6 5 4 3 2 1 0
* .---.---.---.---.---.---.---.---.
* | 0 | c | c | c | c | c | c | c |
* '---'---'---'---'---'---'---'---'
* | |_______________________|
* | |
* | |
* | (c) Handler index in the custom table (max 128)
* |
* SVCall mode: Slow
*/
/* 1 bit of the SVCall imm8 field is used to determine the mode, fast/slow. */
#define UVISOR_SVC_MODE_FAST 1
#define UVISOR_SVC_MODE_SLOW 0
#define UVISOR_SVC_MODE_BIT 7
#define UVISOR_SVC_MODE_MASK ((uint8_t) (1 << UVISOR_SVC_MODE_BIT))
#define UVISOR_SVC_MODE(mode) ((uint8_t) (((mode) << UVISOR_SVC_MODE_BIT) & UVISOR_SVC_MODE_MASK))
/* 7 or 4 bits of the SVCall imm8 field are used to determine the table index,
* depending on the mode, fast/slow. */
#define UVISOR_SVC_FAST_INDEX_MAX (1 << 4)
#define UVISOR_SVC_SLOW_INDEX_MAX (1 << 7)
#define UVISOR_SVC_FAST_INDEX_BIT 0
#define UVISOR_SVC_FAST_INDEX_MASK ((uint8_t) (0xF << UVISOR_SVC_FAST_INDEX_BIT))
#define UVISOR_SVC_SLOW_INDEX_BIT 0
#define UVISOR_SVC_SLOW_INDEX_MASK ((uint8_t) (0x7F << UVISOR_SVC_SLOW_INDEX_BIT))
#define UVISOR_SVC_FAST_INDEX(index) ((uint8_t) (((index) << UVISOR_SVC_FAST_INDEX_BIT) & UVISOR_SVC_FAST_INDEX_MASK))
#define UVISOR_SVC_SLOW_INDEX(index) ((uint8_t) (((index) << UVISOR_SVC_SLOW_INDEX_BIT) & UVISOR_SVC_SLOW_INDEX_MASK))
/* When the SVC mode is "fast", the imm8 field also contains a specification of
* the call interface (number of arguments).
* This is needed for context switches, since the stack manipulation routines
* need to know how many arguments to copy from source to destination. */
#define UVISOR_SVC_FAST_NARGS_BIT 4
#define UVISOR_SVC_FAST_NARGS_MASK ((uint8_t) (0x7 << UVISOR_SVC_FAST_NARGS_BIT))
#define UVISOR_SVC_FAST_NARGS_SET(nargs) ((uint8_t) (((nargs) << UVISOR_SVC_FAST_NARGS_BIT) & UVISOR_SVC_FAST_NARGS_MASK))
#define UVISOR_SVC_FAST_NARGS_GET(svc_id) (((uint8_t) (svc_id) & UVISOR_SVC_FAST_NARGS_MASK) >> UVISOR_SVC_FAST_NARGS_BIT)
/* Macros to build the SVCall imm8 field.
* For slow APIs only the SVC handler index is needed.
* For fast APIs the SVC handler index and the number of arguments are needed. */
#define UVISOR_SVC_CUSTOM_TABLE(index) ((uint8_t) (UVISOR_SVC_MODE(UVISOR_SVC_MODE_SLOW) | \
UVISOR_SVC_SLOW_INDEX(index)))
#define UVISOR_SVC_FIXED_TABLE(index, nargs) ((uint8_t) (UVISOR_SVC_MODE(UVISOR_SVC_MODE_FAST) | \
UVISOR_SVC_FAST_INDEX(index) | \
UVISOR_SVC_FAST_NARGS_SET(nargs)))
/* SVC immediate values for hardcoded table (call from unprivileged) */
#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)
#endif /* __UVISOR_API_SVC_EXPORTS_H__ */

View File

@ -1,203 +0,0 @@
/*
* Copyright (c) 2015-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 __UVISOR_API_UNSUPPORTED_H__
#define __UVISOR_API_UNSUPPORTED_H__
#include "uvisor/api/inc/uvisor_exports.h"
#include <stddef.h>
#include <stdint.h>
/* uVisor hook for unsupported platforms */
UVISOR_EXTERN void uvisor_init(void);
/*******************************************************************************
* Re-definitions from:
******************************************************************************/
/* uvisor-lib/box-config.h */
UVISOR_EXTERN const uint32_t __uvisor_mode;
#define UVISOR_DISABLED 0
#define UVISOR_SET_MODE(mode) \
UVISOR_SET_MODE_ACL_COUNT(mode, NULL, 0)
#define UVISOR_SET_MODE_ACL(mode, acl_list) \
UVISOR_SET_MODE_ACL_COUNT(mode, acl_list, UVISOR_ARRAY_COUNT(acl_list))
#define UVISOR_SET_MODE_ACL_COUNT(mode, acl_list, acl_list_count) \
UVISOR_EXTERN const uint32_t __uvisor_mode = UVISOR_DISABLED; \
static const void *public_box_acl = acl_list; \
extern const __attribute__((section(".keep.uvisor.cfgtbl_ptr_first"), aligned(4))) void * const public_box_cfg_ptr = &public_box_acl;
#define __UVISOR_BOX_CONFIG_NOCONTEXT(box_name, acl_list, stack_size) \
static const void *box_acl_ ## box_name = acl_list; \
extern const __attribute__((section(".keep.uvisor.cfgtbl_ptr"), aligned(4))) void * const box_name ## _cfg_ptr = &box_acl_ ## box_name;
#define __UVISOR_BOX_CONFIG_CONTEXT(box_name, acl_list, stack_size, context_type) \
context_type box_ctx_ ## box_name; \
context_type * const uvisor_ctx = &box_ctx_ ## box_name; \
static const void *box_acl_ ## box_name = acl_list; \
const __attribute__((section(".keep.uvisor.cfgtbl_ptr"), aligned(4))) volatile void *box_name ## _cfg_ptr = \
&box_acl_ ## box_name;
#define __UVISOR_BOX_MACRO(_1, _2, _3, _4, NAME, ...) NAME
#define UVISOR_BOX_CONFIG(...) \
__UVISOR_BOX_MACRO(__VA_ARGS__, __UVISOR_BOX_CONFIG_CONTEXT, \
__UVISOR_BOX_CONFIG_NOCONTEXT)(__VA_ARGS__)
#define UVISOR_BOX_CONFIG_ACL(...) UVISOR_BOX_CONFIG(__VA_ARGS__)
#define UVISOR_BOX_CONFIG_CTX(...) UVISOR_BOX_CONFIG(__VA_ARGS__)
#define UVISOR_BOX_NAMESPACE(...)
#define UVISOR_BOX_HEAPSIZE(...)
/* uvisor-lib/interrupts.h */
#define vIRQ_SetVector(irqn, vector) NVIC_SetVector((IRQn_Type) (irqn), (uint32_t) (vector))
#define vIRQ_GetVector(irqn) NVIC_GetVector((IRQn_Type) (irqn))
#define vIRQ_EnableIRQ(irqn) NVIC_EnableIRQ((IRQn_Type) (irqn))
#define vIRQ_DisableIRQ(irqn) NVIC_DisableIRQ((IRQn_Type) (irqn))
#define vIRQ_DisableAll __disable_irq
#define vIRQ_EnableAll __enable_irq
#define vIRQ_ClearPendingIRQ(irqn) NVIC_ClearPendingIRQ((IRQn_Type) (irqn))
#define vIRQ_SetPendingIRQ(irqn) NVIC_SetPendingIRQ((IRQn_Type) (irqn))
#define vIRQ_GetPendingIRQ(irqn) NVIC_GetPendingIRQ((IRQn_Type) (irqn))
#define vIRQ_SetPriority(irqn, priority) NVIC_SetPriority((IRQn_Type) (irqn), (uint32_t) (priority))
#define vIRQ_GetPriority(irqn) NVIC_GetPriority((IRQn_Type) (irqn))
/* uvisor-lib/register_gateway.h */
#define UVISOR_OP_READ(op) (op)
#define UVISOR_OP_WRITE(op) ((1 << 4) | (op))
#define UVISOR_OP_NOP 0x0
#define UVISOR_OP_AND 0x1
#define UVISOR_OP_OR 0x2
#define UVISOR_OP_XOR 0x3
/* Default mask for whole register operatins */
#define __UVISOR_OP_DEFAULT_MASK 0x0
static UVISOR_FORCEINLINE uint32_t uvisor_read(uint32_t addr, uint32_t op, uint32_t mask)
{
switch(op)
{
case UVISOR_OP_READ(UVISOR_OP_NOP):
return *((uint32_t *) addr);
case UVISOR_OP_READ(UVISOR_OP_AND):
return *((uint32_t *) addr) & mask;
case UVISOR_OP_READ(UVISOR_OP_OR):
return *((uint32_t *) addr) | mask;
case UVISOR_OP_READ(UVISOR_OP_XOR):
return *((uint32_t *) addr) ^ mask;
default:
/* FIXME */
return 0;
}
}
#define uvisor_read(addr) uvisor_read((uint32_t) (addr), UVISOR_OP_READ(UVISOR_OP_NOP), __UVISOR_OP_DEFAULT_MASK)
static UVISOR_FORCEINLINE void uvisor_write(uint32_t addr, uint32_t val, uint32_t op, uint32_t mask)
{
switch(op)
{
case UVISOR_OP_WRITE(UVISOR_OP_NOP):
*((uint32_t *) addr) = val;
case UVISOR_OP_WRITE(UVISOR_OP_AND):
*((uint32_t *) addr) &= val | ~mask;
case UVISOR_OP_WRITE(UVISOR_OP_OR):
*((uint32_t *) addr) |= val & mask;
case UVISOR_OP_WRITE(UVISOR_OP_XOR):
*((uint32_t *) addr) ^= val & mask;
default:
/* FIXME */
return;
}
}
#define uvisor_write(addr, val) uvisor_write((uint32_t) (addr), (uint32_t) (val), \
UVISOR_OP_WRITE(UVISOR_OP_NOP), __UVISOR_OP_DEFAULT_MASK)
/* uvisor-lib/secure_access.h */
static UVISOR_FORCEINLINE void uvisor_write32(uint32_t volatile *addr, uint32_t val)
{
*(addr) = val;
}
static UVISOR_FORCEINLINE void uvisor_write16(uint16_t volatile *addr, uint16_t val)
{
*(addr) = val;
}
static UVISOR_FORCEINLINE void uvisor_write8(uint8_t volatile *addr, uint8_t val)
{
*(addr) = val;
}
static UVISOR_FORCEINLINE uint32_t uvisor_read32(uint32_t volatile *addr)
{
return *(addr);
}
static UVISOR_FORCEINLINE uint16_t uvisor_read16(uint16_t volatile *addr)
{
return *(addr);
}
static UVISOR_FORCEINLINE uint8_t uvisor_read8(uint8_t volatile *addr)
{
return *(addr);
}
/* The conditional statement will be optimised away since the compiler already
* knows the sizeof(type). */
#define ADDRESS_READ(type, addr) \
(sizeof(type) == 4 ? uvisor_read32((volatile uint32_t *) (addr)) : \
sizeof(type) == 2 ? uvisor_read16((volatile uint16_t *) (addr)) : \
sizeof(type) == 1 ? uvisor_read8((volatile uint8_t *) (addr)) : 0)
/* The switch statement will be optimised away since the compiler already knows
* the sizeof_type. */
static UVISOR_FORCEINLINE void __address_write(size_t sizeof_type, volatile uint32_t *addr, uint32_t val)
{
switch(sizeof_type) {
case 4:
uvisor_write32((volatile uint32_t *) addr, (uint32_t) val);
break;
case 2:
uvisor_write16((volatile uint16_t *) addr, (uint16_t) val);
break;
case 1:
uvisor_write8((volatile uint8_t *) addr, (uint8_t) val);
break;
}
}
#define ADDRESS_WRITE(type, addr, val) __address_write(sizeof(type), (volatile uint32_t *) addr, (uint32_t) val)
#define UNION_READ(type, addr, fieldU, fieldB) ((*((volatile type *) (addr))).fieldB)
/* uvisor-lib/secure_gateway.h */
#define secure_gateway(dst_box, dst_fn, ...) dst_fn(__VA_ARGS__)
#endif /* __UVISOR_API_UNSUPPORTED_H__ */

View File

@ -1,74 +0,0 @@
/*
* Copyright (c) 2013-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 __UVISOR_API_UVISOR_LIB_H__
#define __UVISOR_API_UVISOR_LIB_H__
/* This file includes all the uVisor library header files at once.
* If uVisor is used on a host OS that includes unsupported targets, then
* unsupported.h is included, which defines a fallback version of those APIs,
* with no security feature. */
#if defined(UVISOR_PRESENT) && UVISOR_PRESENT == 1
/* Library header files */
#include "api/inc/api.h"
#include "api/inc/box_config.h"
#include "api/inc/box_id.h"
#include "api/inc/disabled.h"
#include "api/inc/error.h"
#include "api/inc/interrupts.h"
#include "api/inc/register_gateway.h"
#include "api/inc/rpc.h"
#include "api/inc/ipc.h"
#include "api/inc/rpc_gateway.h"
#include "api/inc/secure_access.h"
#include "api/inc/uvisor_semaphore.h"
#include "api/inc/vmpu.h"
#else /* defined(UVISOR_PRESENT) && UVISOR_PRESENT == 1 */
#include "api/inc/unsupported.h"
#endif /* defined(UVISOR_PRESENT) && UVISOR_PRESENT == 1 */
/* On ARMv7-M, the host startup needs to call this after osKernelInitialize to
* initialize uvisor-lib. The function can fail. It's up the the host startup
* to decide what to do with any failures. */
UVISOR_EXTERN int uvisor_lib_init(void); /* FIXME: Remove this when we move ARMv7-M to the hypervisor model. */
/* The host startup needs to call this after osKernelInitialize to start
* uVisor. The function will halt if errors are encountered. */
UVISOR_EXTERN void uvisor_start(void);
#include "api/inc/page_allocator.h"
/* Include all exported header files used by uVisor internally.
* These are included independently on whether uVisor is supported or not by the
* target platform. */
#include "api/inc/debug_exports.h"
#include "api/inc/context_exports.h"
#include "api/inc/halt_exports.h"
#include "api/inc/register_gateway_exports.h"
#include "api/inc/rpc_gateway_exports.h"
#include "api/inc/priv_sys_hooks_exports.h"
#include "api/inc/virq_exports.h"
#include "api/inc/uvisor_exports.h"
#include "api/inc/vmpu_exports.h"
#include "api/inc/page_allocator_exports.h"
#include "api/inc/pool_queue_exports.h"
#endif /* __UVISOR_API_UVISOR_LIB_H__ */

View File

@ -1,25 +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.
*/
#ifndef __UVISOR_DEPRECATION_H__
#define __UVISOR_DEPRECATION_H__
#if defined(UVISOR_PRESENT) && UVISOR_PRESENT == 1
#warning "Warning: uVisor is superseded by the Secure Partition Manager (SPM) defined in the ARM Platform Security Architecture (PSA). \
uVisor is deprecated as of Mbed OS 5.10, and being replaced by a native PSA-compliant implementation of SPM."
#endif
#endif // __UVISOR_DEPRECATION_H__

View File

@ -1,214 +0,0 @@
/*
* Copyright (c) 2013-2015, 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 __UVISOR_API_UVISOR_EXPORTS_H__
#define __UVISOR_API_UVISOR_EXPORTS_H__
#include <stdint.h>
#include <stddef.h>
/* maximum number of boxes allowed: 1 is the minimum (unprivileged box) */
#define UVISOR_MAX_BOXES 5U
#define UVISOR_WAIT_FOREVER (0xFFFFFFFFUL)
/* extern keyword */
#ifdef __cplusplus
#define UVISOR_EXTERN extern "C"
#else
#define UVISOR_EXTERN extern
#endif/*__CPP__*/
/** Extern C block macros
*
* Use these macros to disable name mangling in C++. Use these macros instead
* of UVISOR_EXTERN when you also need to initialize the object. C++ compilers
* warn when initializing an object declared as `extern`. Use of these macros
* enables the defining of global non-name-mangled symbols in C++ without
* affecting C code (which doesn't ever name mangle). */
#ifdef __cplusplus
#define UVISOR_EXTERN_C_BEGIN extern "C" {
#define UVISOR_EXTERN_C_END }
#else
#define UVISOR_EXTERN_C_BEGIN
#define UVISOR_EXTERN_C_END
#endif
/* asm keyword */
#ifndef asm
#define asm __asm__
#endif
/* Shared compiler attributes */
#if defined(__ICCARM__)
#define UVISOR_ALIGN(x) __align(x)
#define UVISOR_FORCEINLINE inline
#define UVISOR_PACKED __packed
#define UVISOR_WEAK __weak
#define UVISOR_NORETURN __noreturn
#define UVISOR_RAMFUNC __ramfunc
#define UVISOR_DEPRECATED
#else
#define UVISOR_ALIGN(x) __attribute__((aligned(x)))
#define UVISOR_FORCEINLINE inline __attribute__((always_inline))
#define UVISOR_PACKED __attribute__((packed))
#define UVISOR_WEAK __attribute__((weak))
#define UVISOR_NORETURN __attribute__((noreturn))
#define UVISOR_RAMFUNC __attribute__ ((section (".ramfunc"), noinline))
#define UVISOR_DEPRECATED __attribute__((deprecated))
#endif
/* array count macro */
#define UVISOR_ARRAY_COUNT(x) (sizeof(x)/sizeof(x[0]))
/** Static Assertion Macro
*
* This macro works from both inside and outside function scope.
* The implementations differ due to compilation differences, C++ static_assert
* is known from C++11 (__cplusplus > 199711L) while mbed-os compiles with c++98,
* and C _Static_assert is known from GCC version 4.6.0. */
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
#if (__cplusplus > 199711L)
#define UVISOR_STATIC_ASSERT(cond, msg) static_assert(cond, #msg)
#elif (!__cplusplus && GCC_VERSION > 40600)
#define UVISOR_STATIC_ASSERT(cond, msg) _Static_assert(cond, #msg)
#else
#define UVISOR_STATIC_ASSERT(cond, msg) typedef char STATIC_ASSERT_##msg[(cond)?1:-1]
#endif
/* convert macro argument to string */
/* note: this needs one level of indirection, accomplished with the helper macro
* __UVISOR_TO_STRING */
#define __UVISOR_TO_STRING(x) #x
#define UVISOR_TO_STRING(x) __UVISOR_TO_STRING(x)
/* select an overloaded macro, so that 0 to 4 arguments can be used */
#define __UVISOR_MACRO_SELECT(_0, _1, _2, _3, _4, NAME, ...) NAME
/* count macro arguments */
#define UVISOR_MACRO_NARGS(...) \
__UVISOR_MACRO_SELECT(_0, ##__VA_ARGS__, 4, 3, 2, 1, 0)
/* declare explicit callee-saved registers to hold input arguments (0 to 4) */
/* note: sizeof(type) must be less than or equal to 4 */
#define UVISOR_MACRO_REGS_ARGS(type, ...) \
__UVISOR_MACRO_SELECT(_0, ##__VA_ARGS__, __UVISOR_MACRO_REGS_ARGS4, \
__UVISOR_MACRO_REGS_ARGS3, \
__UVISOR_MACRO_REGS_ARGS2, \
__UVISOR_MACRO_REGS_ARGS1, \
__UVISOR_MACRO_REGS_ARGS0)(type, ##__VA_ARGS__)
#define __UVISOR_MACRO_REGS_ARGS0(type)
#define __UVISOR_MACRO_REGS_ARGS1(type, a0) \
register type r0 asm("r0") = (type) a0;
#define __UVISOR_MACRO_REGS_ARGS2(type, a0, a1) \
register type r0 asm("r0") = (type) a0; \
register type r1 asm("r1") = (type) a1;
#define __UVISOR_MACRO_REGS_ARGS3(type, a0, a1, a2) \
register type r0 asm("r0") = (type) a0; \
register type r1 asm("r1") = (type) a1; \
register type r2 asm("r2") = (type) a2;
#define __UVISOR_MACRO_REGS_ARGS4(type, a0, a1, a2, a3) \
register type r0 asm("r0") = (type) a0; \
register type r1 asm("r1") = (type) a1; \
register type r2 asm("r2") = (type) a2; \
register type r3 asm("r3") = (type) a3;
/* declare explicit callee-saved registers to hold output values */
/* note: currently only one output value is allowed, up to 32bits */
#define UVISOR_MACRO_REGS_RETVAL(type, name) \
register type name asm("r0");
UVISOR_FORCEINLINE void uvisor_noreturn(void)
{
volatile int var = 1;
while(var);
}
/* declare callee-saved input/output operands for gcc-style inline asm */
/* note: this macro requires that a C variable having the same name of the
* corresponding callee-saved register is declared; these operands follow
* the official ABI for ARMv7M (e.g. 2 input arguments of 32bits each max,
* imply that registers r0 and r1 are used) */
/* note: gcc only */
/* note: for 0 inputs a dummy immediate is passed to avoid errors on a misplaced
* comma in the inline assembly */
#ifdef __GNUC__
#define UVISOR_MACRO_GCC_ASM_INPUT(...) \
__UVISOR_MACRO_SELECT(_0, ##__VA_ARGS__, __UVISOR_MACRO_GCC_ASM_INPUT4, \
__UVISOR_MACRO_GCC_ASM_INPUT3, \
__UVISOR_MACRO_GCC_ASM_INPUT2, \
__UVISOR_MACRO_GCC_ASM_INPUT1, \
__UVISOR_MACRO_GCC_ASM_INPUT0)(__VA_ARGS__)
#define __UVISOR_MACRO_GCC_ASM_INPUT0() [__dummy] "I" (0)
#define __UVISOR_MACRO_GCC_ASM_INPUT1(a0) [r0] "r" (r0)
#define __UVISOR_MACRO_GCC_ASM_INPUT2(a0, a1) [r0] "r" (r0), [r1] "r" (r1)
#define __UVISOR_MACRO_GCC_ASM_INPUT3(a0, a1, a2) [r0] "r" (r0), [r1] "r" (r1), [r2] "r" (r2)
#define __UVISOR_MACRO_GCC_ASM_INPUT4(a0, a1, a2, a3) [r0] "r" (r0), [r1] "r" (r1), [r2] "r" (r2), [r3] "r" (r3)
#define UVISOR_MACRO_GCC_ASM_OUTPUT(name) [res] "=r" (name)
#endif /* __GNUC__ */
/* this macro multiplexes read/write opcodes depending on the number of
* arguments */
#define UVISOR_ASM_MEMORY_ACCESS(opcode, type, ...) \
__UVISOR_MACRO_SELECT(_0, ##__VA_ARGS__, /* no macro for 4 args */ , \
/* no macro for 3 args */ , \
__UVISOR_ASM_MEMORY_ACCESS_W, \
__UVISOR_ASM_MEMORY_ACCESS_R, \
/* no macro for 0 args */ )(opcode, type, ##__VA_ARGS__)
/* the macros that actually generate the assembly code for the memory access are
* toolchain-specific */
#if defined(__CC_ARM)
/* TODO/FIXME */
#elif defined(__GNUC__)
#define __UVISOR_ASM_MEMORY_ACCESS_R(opcode, type, ...) \
({ \
UVISOR_MACRO_REGS_ARGS(uint32_t, ##__VA_ARGS__); \
UVISOR_MACRO_REGS_RETVAL(type, res); \
asm volatile( \
UVISOR_TO_STRING(opcode)" %[res], [%[r0]]\n" \
UVISOR_NOP_GROUP \
: UVISOR_MACRO_GCC_ASM_OUTPUT(res) \
: UVISOR_MACRO_GCC_ASM_INPUT(__VA_ARGS__) \
); \
res; \
})
#define __UVISOR_ASM_MEMORY_ACCESS_W(opcode, type, ...) \
UVISOR_MACRO_REGS_ARGS(uint32_t, ##__VA_ARGS__); \
asm volatile( \
UVISOR_TO_STRING(opcode)" %[r1], [%[r0]]\n" \
UVISOR_NOP_GROUP \
: \
: UVISOR_MACRO_GCC_ASM_INPUT(__VA_ARGS__) \
);
#endif /* defined(__CC_ARM) || defined(__GNUC__) */
typedef struct {
void (*function)(const void *);
size_t priority;
size_t stack_size;
} uvisor_box_main_t;
#endif /* __UVISOR_API_UVISOR_EXPORTS_H__ */

View File

@ -1,33 +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.
*/
#ifndef __UVISOR_API_UVISOR_SEMAPHORE_H__
#define __UVISOR_API_UVISOR_SEMAPHORE_H__
#include "api/inc/uvisor_semaphore_exports.h"
/* Initialize a semaphore with the specified initial count. This function is
* not safe to call from interrupt context. */
UVISOR_EXTERN int __uvisor_semaphore_init(UvisorSemaphore * semaphore, uint32_t initial_count, uint32_t max_count);
/* This function is not safe to call from interrupt context, even if the
* timeout is zero. */
UVISOR_EXTERN int __uvisor_semaphore_pend(UvisorSemaphore * semaphore, uint32_t timeout_ms);
/* This function is safe to call from interrupt context. */
UVISOR_EXTERN int __uvisor_semaphore_post(UvisorSemaphore * semaphore);
#endif

View File

@ -1,31 +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.
*/
#ifndef __UVISOR_API_UVISOR_SEMAPHORE_EXPORTS_H__
#define __UVISOR_API_UVISOR_SEMAPHORE_EXPORTS_H__
#include "api/inc/uvisor_exports.h"
/* This must be big enough for all operating systems uVisor runs on. */
#define UVISOR_SEMAPHORE_INTERNAL_SIZE (36)
/* An opaque structure, that one knows the size of so that they can allocate
* memory. */
typedef struct uvisor_semaphore {
uint8_t internal[UVISOR_SEMAPHORE_INTERNAL_SIZE];
} UVISOR_ALIGN(4) UvisorSemaphore;
#endif

View File

@ -1,42 +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.
*/
#ifndef __UVISOR_API_UVISOR_SPINLOCK_H__
#define __UVISOR_API_UVISOR_SPINLOCK_H__
#include "api/inc/uvisor_exports.h"
#include <stdbool.h>
typedef struct {
bool acquired;
} UvisorSpinlock;
/* This function is safe to call from interrupt context. */
UVISOR_EXTERN void uvisor_spin_init(UvisorSpinlock * spinlock);
/* Attempt to spin lock once. Return true if the lock was obtained, false if
* otherwise. This function is safe to call from interrupt context. */
UVISOR_EXTERN bool uvisor_spin_trylock(UvisorSpinlock * spinlock);
/* Spin in a tight loop until the lock is obtained. This function is safe to
* call from interrupt context, but probably not wise. */
UVISOR_EXTERN void uvisor_spin_lock(UvisorSpinlock * spinlock);
/* Unlock the spin lock. This function is safe to call from interrupt context.
* */
UVISOR_EXTERN void uvisor_spin_unlock(UvisorSpinlock * spinlock);
#endif /* __UVISOR_API_UVISOR_SPINLOCK_H__ */

View File

@ -1,41 +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.
*/
#ifndef __UVISOR_API_UNVIC_EXPORTS_H__
#define __UVISOR_API_UNVIC_EXPORTS_H__
#include <stdint.h>
/* this value refers to the minimum allowable priority in the physical NVIC
* module, but not in the virtualised one (vIRQ) */
#define __UVISOR_NVIC_MIN_PRIORITY ((uint32_t) 2)
/* this is the maximum priority allowed for the vIRQ module */
/* users of uVisor APIs can use this to determine the maximum level of
* priorities available to them */
#define UVISOR_VIRQ_MAX_PRIORITY ((uint32_t) (1 << __NVIC_PRIO_BITS) - 1 - __UVISOR_NVIC_MIN_PRIORITY)
/* Reasons for rebooting */
typedef enum {
RESET_REASON_NO_REASON = 0,
RESET_REASON_HALT,
__TRESETREASON_MAX /* Always keep the last element of the enum. */
} TResetReason;
/* Offset of NVIC interrupts with respect to handler 0 */
#define NVIC_OFFSET 16
#endif /* __UVISOR_API_UNVIC_EXPORTS_H__ */

View File

@ -1,34 +0,0 @@
/*
* Copyright (c) 2013-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 __UVISOR_API_VMPU_H__
#define __UVISOR_API_VMPU_H__
#include "api/inc/uvisor_exports.h"
#include "api/inc/api.h"
UVISOR_EXTERN_C_BEGIN
/* Invalidate all regions in the MPU, forcing subsequent memory accesses to
* fault. */
static UVISOR_FORCEINLINE void uvisor_vmpu_mem_invalidate(void)
{
uvisor_api.vmpu_mem_invalidate();
}
UVISOR_EXTERN_C_END
#endif /* __UVISOR_API_VMPU_H__ */

View File

@ -1,250 +0,0 @@
/*
* Copyright (c) 2013-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 __UVISOR_API_VMPU_EXPORTS_H__
#define __UVISOR_API_VMPU_EXPORTS_H__
#include "api/inc/uvisor_exports.h"
#include <stdint.h>
/* The maximum box namespace length is 37 so that it is exactly big enough for
* a human-readable hex string GUID (as formatted by RFC 4122) followed by a
* terminating NULL. */
#define UVISOR_MAX_BOX_NAMESPACE_LENGTH 37
/** Invalid box id for use in marking objects with invalid ownership. */
#define UVISOR_BOX_ID_INVALID ((uint8_t) -1)
/* supervisor user access modes */
#define UVISOR_TACL_UEXECUTE 0x0001UL
#define UVISOR_TACL_UWRITE 0x0002UL
#define UVISOR_TACL_UREAD 0x0004UL
#define UVISOR_TACL_UACL (UVISOR_TACL_UREAD |\
UVISOR_TACL_UWRITE |\
UVISOR_TACL_UEXECUTE)
/* supervisor access modes */
#define UVISOR_TACL_SEXECUTE 0x0008UL
#define UVISOR_TACL_SWRITE 0x0010UL
#define UVISOR_TACL_SREAD 0x0020UL
#define UVISOR_TACL_SACL (UVISOR_TACL_SREAD |\
UVISOR_TACL_SWRITE |\
UVISOR_TACL_SEXECUTE)
#define UVISOR_TACL_EXECUTE (UVISOR_TACL_UEXECUTE |\
UVISOR_TACL_SEXECUTE)
/* all possible access control flags */
#define UVISOR_TACL_ACCESS (UVISOR_TACL_UACL |\
UVISOR_TACL_SACL)
/* various modes */
#define UVISOR_TACL_STACK 0x0040UL
#define UVISOR_TACL_SIZE_ROUND_UP 0x0080UL
#define UVISOR_TACL_SIZE_ROUND_DOWN 0x0100UL
#define UVISOR_TACL_PERIPHERAL 0x0200UL
#define UVISOR_TACL_SHARED 0x0400UL
#define UVISOR_TACL_USER 0x0800UL
#define UVISOR_TACL_IRQ 0x1000UL
#if defined(UVISOR_PRESENT) && UVISOR_PRESENT == 1
#endif /* defined(UVISOR_PRESENT) && UVISOR_PRESENT == 1 */
#define UVISOR_TACLDEF_SECURE_BSS (UVISOR_TACL_UREAD |\
UVISOR_TACL_UWRITE |\
UVISOR_TACL_SREAD |\
UVISOR_TACL_SWRITE |\
UVISOR_TACL_SIZE_ROUND_UP)
#define UVISOR_TACLDEF_SECURE_CONST (UVISOR_TACL_UREAD |\
UVISOR_TACL_SREAD |\
UVISOR_TACL_SIZE_ROUND_UP)
#define UVISOR_TACLDEF_DATA UVISOR_TACLDEF_SECURE_BSS
#define UVISOR_TACLDEF_PERIPH (UVISOR_TACL_PERIPHERAL |\
UVISOR_TACL_UREAD |\
UVISOR_TACL_UWRITE |\
UVISOR_TACL_SREAD |\
UVISOR_TACL_SWRITE |\
UVISOR_TACL_SIZE_ROUND_UP)
#define UVISOR_TACLDEF_STACK (UVISOR_TACL_STACK |\
UVISOR_TACL_UREAD |\
UVISOR_TACL_UWRITE |\
UVISOR_TACL_SREAD |\
UVISOR_TACL_SWRITE)
#define UVISOR_PAD32(x) (32 - (sizeof(x) & ~0x1FUL))
#define UVISOR_BOX_MAGIC 0x42CFB66FUL
#define UVISOR_BOX_VERSION 100
#define UVISOR_STACK_BAND_SIZE 128
#define UVISOR_MEM_SIZE_ROUND(x) UVISOR_REGION_ROUND_UP(x)
#define UVISOR_MIN_STACK_SIZE 1024
#define UVISOR_MIN_STACK(x) (((x) < UVISOR_MIN_STACK_SIZE) ? UVISOR_MIN_STACK_SIZE : (x))
#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_ARMv8M) || defined(ARCH_MPU_KINETIS)
#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"
#endif
#else /* defined(UVISOR_PRESENT) && UVISOR_PRESENT == 1 */
#define UVISOR_REGION_ROUND_DOWN(x) (x)
#define UVISOR_REGION_ROUND_UP(x) (x)
#define UVISOR_STACK_SIZE_ROUND(x) (x)
#endif
#ifndef UVISOR_BOX_STACK_SIZE
#define UVISOR_BOX_STACK_SIZE UVISOR_MIN_STACK_SIZE
#endif/*UVISOR_BOX_STACK*/
/* NOPs added for write buffering synchronization (2 are for dsb. 16bits) */
#define UVISOR_NOP_CNT (2 + 3)
#define UVISOR_NOP_GROUP \
"dsb\n" \
"nop\n" \
"nop\n" \
"nop\n"
typedef uint32_t UvisorBoxAcl;
typedef struct {
void * param1;
uint32_t param2;
UvisorBoxAcl acl;
} UVISOR_PACKED UvisorBoxAclItem;
/* This struct contains all the BSS sections that uVisor allocates for a secure
* box. It can be used to keep the sizes of the sections or their pointers. */
typedef struct uvisor_bss_sections_t {
uint32_t index;
uint32_t context;
uint32_t newlib_reent;
uint32_t rpc;
uint32_t ipc;
uint32_t heap;
} UVISOR_PACKED UvisorBssSections;
/* The number of per-box BSS sections. */
#define UVISOR_BSS_SECTIONS_COUNT (sizeof(UvisorBssSections) / sizeof(uint32_t))
/* Compile-time per-box configuration table
* Each box has one of this table in flash. Every other data structure that this
* table might point to must be in flash as well. The uVisor core must check the
* sanity of the table before trusting its fields. */
typedef struct {
const uint32_t magic;
const uint32_t version;
/* The UvisorBssSections struct is union-ed with a size_t array to allow for
* loops to scan the sizes of all the BSS sections and allocate the
* necessary space for each of them. */
union {
size_t sizes[UVISOR_BSS_SECTIONS_COUNT];
UvisorBssSections size_of;
} const bss;
/* Contains the size of the secure box static stack. */
/* Note: This does not include guards. */
/* Note: It is kept separately from the BSS sections as it's implementation
* specific where the stack sits with respect to the BSS. */
const uint32_t stack_size;
/* Opaque-to-uVisor data that potentially contains uvisor-lib-specific or
* OS-specific per-box configuration */
const void * const lib_config;
const char * const box_namespace;
const UvisorBoxAclItem * const acl_list;
const uint32_t acl_count;
} UVISOR_PACKED UvisorBoxConfig;
/* Enumeration-time per-box index table
* Each box has one of this table in SRAM. The index tables are initialized at
* box enumeration time and are then managed by the secure boxes themselves. */
/* Note: Each box is able to read and write its own version of this table. Do
* not trust these pointers in the uVisor core. */
typedef struct {
/* The UvisorSramPointers struct is union-ed with a void * array to allow
* for loops to scan the pointers to all the SRAM sections and access them
* individually. */
union {
void * pointers[UVISOR_BSS_SECTIONS_COUNT];
UvisorBssSections address_of;
} bss;
/* Size of the box heap */
uint32_t box_heap_size;
/* Pointer to the currently active heap.
* This is set to `NULL` by uVisor, signalling to the user lib that the
* box heap needs to be initialized before use! */
void * active_heap;
/* Box ID */
int box_id_self;
/* Pointer to the box config */
const UvisorBoxConfig * config;
} UVISOR_PACKED UvisorBoxIndex;
/*
* only use this macro for rounding const values during compile time:
* for variables please use uvisor_region_bits(x) instead
*/
#define UVISOR_REGION_BITS(x) (((x)<=32UL)?5:(((x)<=64UL)?\
6:(((x)<=128UL)?7:(((x)<=256UL)?8:(((x)<=512UL)?9:(((x)<=1024UL)?\
10:(((x)<=2048UL)?11:(((x)<=4096UL)?12:(((x)<=8192UL)?\
13:(((x)<=16384UL)?14:(((x)<=32768UL)?15:(((x)<=65536UL)?\
16:(((x)<=131072UL)?17:(((x)<=262144UL)?18:(((x)<=524288UL)?\
19:(((x)<=1048576UL)?20:(((x)<=2097152UL)?21:(((x)<=4194304UL)?\
22:(((x)<=8388608UL)?23:(((x)<=16777216UL)?24:(((x)<=33554432UL)?\
25:(((x)<=67108864UL)?26:(((x)<=134217728UL)?27:(((x)<=268435456UL)?\
28:(((x)<=536870912UL)?29:(((x)<=1073741824UL)?30:(((x)<=2147483648UL)?\
31:32)))))))))))))))))))))))))))
#if defined(UVISOR_PRESENT) && UVISOR_PRESENT == 1
static UVISOR_FORCEINLINE int vmpu_bits(uint32_t size)
{
/* If size is 0, the result of __builtin_clz is undefined */
return (0 == size) ? 0: 32 - __builtin_clz(size);
}
#endif /* defined(UVISOR_PRESENT) && UVISOR_PRESENT == 1 */
#endif /* __UVISOR_API_VMPU_EXPORTS_H__ */

View File

@ -1,4 +0,0 @@
{
"name": "uvisor-lib",
"macros": ["CMSIS_NVIC_VIRTUAL", "CMSIS_VECTAB_VIRTUAL"]
}

View File

@ -1,298 +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.
*/
/* 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. */
#if defined(UVISOR_PRESENT) && (UVISOR_PRESENT == 1)
#include <uvisor.h>
#include "page_allocator.h"
#include "page_allocator_faults.h"
#include "vmpu_unpriv_access.h"
#include "vmpu.h"
#include "halt.h"
#include "context.h"
/* Since the page table memory is provided by the user, all accesses to it
* are depriviledged! */
#define page_table_read vmpu_unpriv_uint32_read
#define page_table_write vmpu_unpriv_uint32_write
/* For uVisor in supported mode the page allocator is always called through a
* SVC call, which automagically serializes access to it. */
#define UVISOR_PAGE_ALLOCATOR_MUTEX_AQUIRE {}
#define UVISOR_PAGE_ALLOCATOR_MUTEX_RELEASE {}
#define UVISOR_PAGE_UNUSED UVISOR_BOX_ID_INVALID
#endif /* defined(UVISOR_PRESENT) && (UVISOR_PRESENT == 1) */
#include "page_allocator_config.h"
/* Contains the page usage mapped by owner. */
uint32_t g_page_owner_map[UVISOR_MAX_BOXES][UVISOR_PAGE_MAP_COUNT];
/* Contains total page usage. */
uint32_t g_page_usage_map[UVISOR_PAGE_MAP_COUNT];
/* Contains the configured page size. */
uint32_t g_page_size;
/* Points to the beginning of the page heap. */
const void * g_page_heap_start;
/* Points to the end of the page heap. */
const void * g_page_heap_end;
/* Contains the number of free pages. */
uint8_t g_page_count_free;
/* Contains the total number of available pages. */
uint8_t g_page_count_total;
/* Contains the shift of the page owner mask. */
uint8_t g_page_map_shift;
/* Contains the rounded up page end address for ARMv7-M MPU region alignment. */
uint32_t g_page_head_end_rounded;
/* 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)
{
if (!page_size || !vmpu_public_flash_addr((uint32_t) page_size)) {
HALT_ERROR(SANITY_CHECK_FAILED,
"Page size pointer (0x%08x) is not in flash memory.\n",
(unsigned int) page_size);
}
if (!heap_start || !vmpu_public_sram_addr((uint32_t) heap_start)) {
HALT_ERROR(SANITY_CHECK_FAILED,
"Page heap start pointer (0x%08x) is not in sram memory.\n",
(unsigned int) heap_start);
}
if (!heap_end || !vmpu_public_sram_addr((uint32_t) heap_end)) {
HALT_ERROR(SANITY_CHECK_FAILED,
"Page heap end pointer (0x%08x) is not in sram memory.\n",
(unsigned int) heap_end);
}
if (heap_end < heap_start) {
HALT_ERROR(SANITY_CHECK_FAILED,
"Page heap end pointer (0x%08x) is smaller than heap start pointer (0x%08x).\n",
(unsigned int) heap_end,
(unsigned int) heap_start);
}
if ((*page_size < UVISOR_PAGE_SIZE_MINIMUM) || !vmpu_is_region_size_valid(*page_size)) {
HALT_ERROR(SANITY_CHECK_FAILED,
"Page size (%uB) not supported by this platform!\n",
*page_size);
}
uint32_t start = vmpu_round_up_region((uint32_t) heap_start, *page_size);
if (start == 0) {
HALT_ERROR(SANITY_CHECK_FAILED,
"Page heap start address 0x%08x cannot be aligned with page size %uB!\n",
(unsigned int) heap_start,
(unsigned int) *page_size);
}
g_page_size = *page_size;
/* This is the page heap start address. */
g_page_heap_start = (void *) start;
/* How many pages can we fit in here? */
if (start > (0xFFFFFFFFUL - g_page_size) || (start + g_page_size) > (uint32_t) heap_end) {
g_page_count_total = 0;
} else {
g_page_count_total = ((uint32_t) heap_end - start) / g_page_size;
}
/* Clamp page count to table size. */
if (g_page_count_total > UVISOR_PAGE_MAX_COUNT) {
DPRINTF("uvisor_page_init: Clamping available page count from %u to %u!\n", g_page_count_total, UVISOR_PAGE_MAX_COUNT);
/* Move the heap start address forward so that the last clamped page is located nearest to the heap end. */
g_page_heap_start += (g_page_count_total - UVISOR_PAGE_MAX_COUNT) * g_page_size;
/* Clamp the page count. */
g_page_count_total = UVISOR_PAGE_MAX_COUNT;
}
g_page_count_free = g_page_count_total;
/* Remember the end of the heap. */
g_page_heap_end = g_page_heap_start + g_page_count_total * g_page_size;
g_page_head_end_rounded = vmpu_round_up_region((uint32_t) g_page_heap_end, g_page_size * 8);
/* Compute the page map shift.
* This initial shift fully left aligns the page map. */
g_page_map_shift = UVISOR_PAGE_MAP_COUNT * 32 - g_page_count_total;
g_page_map_shift -= (g_page_head_end_rounded - (uint32_t) g_page_heap_end) / g_page_size;
DPRINTF(
"page heap: [0x%08x, 0x%08x] %ukB -> %u %ukB pages\n",
(unsigned int) g_page_heap_start,
(unsigned int) g_page_heap_end,
(unsigned int) (g_page_count_free * g_page_size / 1024),
(unsigned int) g_page_count_total,
(unsigned int) (g_page_size / 1024)
);
/* Force a reset of owner and usage page maps. */
memset(g_page_owner_map, 0, sizeof(g_page_owner_map));
memset(g_page_usage_map, 0, sizeof(g_page_usage_map));
}
int page_allocator_malloc(UvisorPageTable * const table)
{
UVISOR_PAGE_ALLOCATOR_MUTEX_AQUIRE;
uint32_t pages_required = page_table_read((uint32_t) &(table->page_count));
uint32_t page_size = page_table_read((uint32_t) &(table->page_size));
/* Check if the user even wants any pages. */
if (pages_required == 0) {
DPRINTF("uvisor_page_malloc: FAIL: No pages requested!\n\n");
UVISOR_PAGE_ALLOCATOR_MUTEX_RELEASE;
return UVISOR_ERROR_PAGE_INVALID_PAGE_COUNT;
}
/* Check if we can fulfill the requested page size. */
if (page_size != g_page_size) {
DPRINTF("uvisor_page_malloc: FAIL: Requested page size %uB is not the configured page size %uB!\n\n", page_size, g_page_size);
UVISOR_PAGE_ALLOCATOR_MUTEX_RELEASE;
return UVISOR_ERROR_PAGE_INVALID_PAGE_SIZE;
}
/* Check if we have enough pages available. */
if (pages_required > g_page_count_free) {
DPRINTF("uvisor_page_malloc: FAIL: Cannot serve %u pages with only %u free pages!\n\n", pages_required, g_page_count_free);
UVISOR_PAGE_ALLOCATOR_MUTEX_RELEASE;
return UVISOR_ERROR_PAGE_OUT_OF_MEMORY;
}
/* Get the calling box id. */
const page_owner_t box_id = g_active_box;
DPRINTF("uvisor_page_malloc: Requesting %u pages with size %uB for box %u\n", pages_required, page_size, box_id);
/* Update the free pages count. */
g_page_count_free -= pages_required;
/* Point to the first entry in the table. */
void * * page_table = &(table->page_origins[0]);
/* Iterate through the page table and find the empty pages. */
uint32_t page = 0;
for (; (page < g_page_count_total) && pages_required; page++) {
/* If the page is unused, map_get returns zero. */
if (!page_allocator_map_get(g_page_usage_map, page)) {
/* Remember this page as used. */
page_allocator_map_set(g_page_usage_map, page);
/* Pages of box 0 are accessible to all other boxes! */
if (box_id == 0) {
uint32_t ii = 0;
for (; ii < UVISOR_MAX_BOXES; ii++) {
page_allocator_map_set(g_page_owner_map[ii], page);
}
} else {
/* Otherwise, remember ownership only for active box. */
page_allocator_map_set(g_page_owner_map[box_id], page);
}
/* 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. */
memset(ptr, 0, g_page_size);
/* Write the pages address to the table in the first page. */
page_table_write((uint32_t) page_table, (uint32_t) ptr);
page_table++;
/* One less page required. */
pages_required--;
DPRINTF("uvisor_page_malloc: Found an empty page 0x%08x entry at index %u\n", (unsigned int) ptr, page);
}
}
DPRINTF("uvisor_page_malloc: %u free pages remaining.\n\n", g_page_count_free);
UVISOR_PAGE_ALLOCATOR_MUTEX_RELEASE;
return UVISOR_ERROR_PAGE_OK;
}
int page_allocator_free(const UvisorPageTable * const table)
{
UVISOR_PAGE_ALLOCATOR_MUTEX_AQUIRE;
if (g_page_count_free == g_page_count_total) {
DPRINTF("uvisor_page_free: FAIL: There are no pages to free!\n\n");
UVISOR_PAGE_ALLOCATOR_MUTEX_RELEASE;
return UVISOR_ERROR_PAGE_INVALID_PAGE_TABLE;
}
uint32_t page_count = page_table_read((uint32_t) &(table->page_count));
uint32_t page_size = page_table_read((uint32_t) &(table->page_size));
if (page_size != g_page_size) {
DPRINTF("uvisor_page_free: FAIL: Requested page size %uB is not the configured page size %uB!\n\n", page_size, g_page_size);
UVISOR_PAGE_ALLOCATOR_MUTEX_RELEASE;
return UVISOR_ERROR_PAGE_INVALID_PAGE_SIZE;
}
if (page_count == 0) {
DPRINTF("uvisor_page_free: FAIL: Pointer table is empty!\n\n");
UVISOR_PAGE_ALLOCATOR_MUTEX_RELEASE;
return UVISOR_ERROR_PAGE_INVALID_PAGE_COUNT;
}
if (page_count > (unsigned) (g_page_count_total - g_page_count_free)) {
DPRINTF("uvisor_page_free: FAIL: Pointer table too large!\n\n");
UVISOR_PAGE_ALLOCATOR_MUTEX_RELEASE;
return UVISOR_ERROR_PAGE_INVALID_PAGE_TABLE;
}
/* Get the calling box id. */
const page_owner_t box_id = g_active_box;
/* Iterate over the table and validate each pointer. */
void * const * page_table = &(table->page_origins[0]);
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_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;
}
/* Check if the page belongs to the caller. */
if (page_allocator_map_get(g_page_owner_map[box_id], page_index)) {
/* Clear the owner and usage page maps for this page. */
page_allocator_map_clear(g_page_usage_map, page_index);
/* If the page was owned by box 0, we need to remove it from all other boxes! */
if (box_id == 0) {
uint32_t ii = 0;
for (; ii < UVISOR_MAX_BOXES; ii++) {
page_allocator_map_clear(g_page_owner_map[ii], page_index);
}
} else {
/* Otherwise, only remove for the active box. */
page_allocator_map_clear(g_page_owner_map[box_id], page_index);
}
g_page_count_free++;
DPRINTF("uvisor_page_free: Freeing page at index %u\n", page_index);
}
else {
/* Abort if the page doesn't belong to the caller. */
if (!page_allocator_map_get(g_page_usage_map, page_index)) {
DPRINTF("uvisor_page_free: FAIL: Page %u is not allocated!\n\n", page_index);
} else {
DPRINTF("uvisor_page_free: FAIL: Page %u is not owned by box %u!\n\n", page_index, box_id);
}
UVISOR_PAGE_ALLOCATOR_MUTEX_RELEASE;
return UVISOR_ERROR_PAGE_INVALID_PAGE_OWNER;
}
}
DPRINTF("uvisor_page_free: %u free pages available.\n\n", g_page_count_free);
UVISOR_PAGE_ALLOCATOR_MUTEX_RELEASE;
return UVISOR_ERROR_PAGE_OK;
}

View File

@ -1,86 +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.
*/
#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_MAX_COUNT
#define UVISOR_PAGE_MAX_COUNT (16UL)
#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 (1024UL)
#endif
/* Defines the number of uint32_t page owner masks in the owner map.
* +8 is used for ARMv7-M MPUs, where a shift of up to 7-bits may be required
* to align MPU regions. */
#define UVISOR_PAGE_MAP_COUNT ((UVISOR_PAGE_MAX_COUNT + 31 + 8) / 32)
/* The page box_id is the box id which is 8-bit large. */
typedef uint8_t page_owner_t;
/* Contains the total number of available pages. */
extern uint8_t g_page_count_total;
/* Contains the shift of the page owner mask. */
extern uint8_t g_page_map_shift;
/* Contains the ARMv7-MPU rounded page end. */
extern uint32_t g_page_head_end_rounded;
/** Sets the page bit in the page map array.
* @param map an array of `uint32_t` containing the page map
* @param page the index of the page to be set
*/
static inline void page_allocator_map_set(uint32_t * const map, uint8_t page)
{
page += g_page_map_shift;
map[page / 32] |= (1UL << (page % 32));
}
/** Clears the page bit in the page map array.
* @param map an array of `uint32_t` containing the page map
* @param page the index of the page to be set
*/
static inline void page_allocator_map_clear(uint32_t * const map, uint8_t page)
{
page += g_page_map_shift;
map[page / 32] &= ~(1UL << (page % 32));
}
/** Check if the page bit is set int the page map array.
* @param map an array of `uint32_t` containing the page map
* @param page the index of the page to be set
* @retval 0 if page bit is not set
* @retval 1 if page bit is set
*/
static inline int page_allocator_map_get(const uint32_t * const map, uint8_t page)
{
page += g_page_map_shift;
return (map[page / 32] >> (page % 32)) & 0x1;
}
#endif /* __PAGE_ALLOCATOR_CONFIG_H__ */

View File

@ -1,148 +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 "api/inc/pool_queue_exports.h"
#include "api/inc/rpc_exports.h"
#include "api/inc/uvisor_semaphore.h"
#include "api/inc/box_config.h"
#include "api/inc/uvisor_deprecation.h"
#include "mbed_interface.h"
#include "cmsis_os2.h"
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
/* Register the OS with uVisor */
extern void SVC_Handler(void);
extern void PendSV_Handler(void);
extern void SysTick_Handler(void);
extern int32_t svcRtxKernelLock(void);
UVISOR_SET_PRIV_SYS_HOOKS(SVC_Handler, PendSV_Handler, SysTick_Handler, svcRtxKernelLock, __uvisor_semaphore_post);
extern RtxBoxIndex * const __uvisor_ps;
void __uvisor_initialize_rpc_queues(void)
{
#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U)
// TODO Initialize RPC queues on ARMv8-M (via uvisor_start).
return;
#endif
UvisorBoxIndex * const index = &__uvisor_ps->index;
uvisor_pool_slot_t i;
uvisor_rpc_outgoing_message_queue_t * rpc_outgoing_msg_queue = &(uvisor_rpc(index)->outgoing_message_queue);
uvisor_rpc_incoming_message_queue_t * rpc_incoming_msg_queue = &(uvisor_rpc(index)->incoming_message_queue);
uvisor_rpc_fn_group_queue_t * rpc_fn_group_queue = &(uvisor_rpc(index)->fn_group_queue);
/* Initialize the outgoing RPC message queue. */
if (uvisor_pool_queue_init(&rpc_outgoing_msg_queue->queue,
&rpc_outgoing_msg_queue->pool,
rpc_outgoing_msg_queue->messages,
sizeof(*rpc_outgoing_msg_queue->messages),
UVISOR_RPC_OUTGOING_MESSAGE_SLOTS)) {
uvisor_error(USER_NOT_ALLOWED);
}
/* Initialize all the result semaphores. */
for (i = 0; i < UVISOR_RPC_OUTGOING_MESSAGE_SLOTS; i++) {
UvisorSemaphore * semaphore = &rpc_outgoing_msg_queue->messages[i].semaphore;
if (__uvisor_semaphore_init(semaphore, 1, 0)) {
uvisor_error(USER_NOT_ALLOWED);
}
}
/* Initialize the incoming RPC message queues. */
if (uvisor_pool_queue_init(&rpc_incoming_msg_queue->todo_queue,
&rpc_incoming_msg_queue->pool,
rpc_incoming_msg_queue->messages,
sizeof(*rpc_incoming_msg_queue->messages),
UVISOR_RPC_INCOMING_MESSAGE_SLOTS)) {
uvisor_error(USER_NOT_ALLOWED);
}
/* This is a double init of the pool. We need a function that just inits
* the queue, not the pool, and init everybody separately. */
if (uvisor_pool_queue_init(&rpc_incoming_msg_queue->done_queue,
&rpc_incoming_msg_queue->pool,
rpc_incoming_msg_queue->messages,
sizeof(*rpc_incoming_msg_queue->messages),
UVISOR_RPC_INCOMING_MESSAGE_SLOTS)) {
uvisor_error(USER_NOT_ALLOWED);
}
/* Initialize the function group pool. */
if (uvisor_pool_queue_init(&rpc_fn_group_queue->queue,
&rpc_fn_group_queue->pool,
rpc_fn_group_queue->fn_groups,
sizeof(*rpc_fn_group_queue->fn_groups),
UVISOR_RPC_FN_GROUP_SLOTS)) {
uvisor_error(USER_NOT_ALLOWED);
}
/* Initialize all the function group semaphores. */
for (i = 0; i < UVISOR_RPC_FN_GROUP_SLOTS; i++) {
UvisorSemaphore * semaphore = &rpc_fn_group_queue->fn_groups[i].semaphore;
if (__uvisor_semaphore_init(semaphore, 1, 0)) {
uvisor_error(USER_NOT_ALLOWED);
}
}
}
/* 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_t thread_id;
uvisor_box_main_t * box_main = lib_config;
osThreadAttr_t thread_attr = { 0 };
__uvisor_initialize_rpc_queues();
thread_attr.name = "uvisor_box_main_thread";
thread_attr.priority = box_main->priority;
thread_attr.stack_size = box_main->stack_size;
/* 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 box heap. This memory is
* never freed, even if the box's main thread exits. */
thread_attr.stack_mem = malloc(thread_attr.stack_size);
if (thread_attr.stack_mem == NULL) {
/* No process heap memory available for thread stack */
uvisor_error(USER_NOT_ALLOWED);
}
/* Allocate memory for the main thread control block from the box heap.
* This memory is never freed, even if the box's main thread exits. */
thread_attr.cb_size = sizeof(osRtxThread_t);
thread_attr.cb_mem = malloc(thread_attr.cb_size);
if (thread_attr.cb_mem == NULL) {
/* No process heap memory available for thread control block. */
uvisor_error(USER_NOT_ALLOWED);
}
thread_id = osThreadNew((osThreadFunc_t) box_main->function, NULL, &thread_attr);
if (thread_id == NULL) {
/* Failed to create thread */
uvisor_error(USER_NOT_ALLOWED);
}
}

View File

@ -1,207 +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 "cmsis_os2.h"
#include "uvisor-lib/uvisor-lib.h"
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
#include <reent.h>
/*
* These are the C standard memory functions:
* - void *calloc(size_t nmemb, size_t size);
* - void free(void *ptr);
* - void *malloc(size_t size);
* - void *realloc(void *ptr, size_t size);
*/
/* Use printf with caution inside malloc: printf may allocate memory itself,
so using printf in malloc may lead to recursive calls! */
#define DPRINTF(...) {};
extern RtxBoxIndex * const __uvisor_ps;
/** @retval 0 The kernel is not initialized.
* @retval 1 The kernel is initialized.. */
static int is_kernel_initialized()
{
/* TODO: Bare-bone boxes must not call any RTX2 functions for now.
* Each box should instead provide `heap_lock` and `heap_unlock` functions
* as part of the box context. These would just be empty for boxes without
* the need for heap locking. */
if (__uvisor_ps->index.box_id_self != 0) {
return 0;
}
static uint8_t kernel_running = 0;
if (kernel_running) {
return 1;
}
if (osKernelGetState() == osKernelRunning) {
kernel_running = 1;
return 1;
}
return 0;
}
static int init_allocator()
{
int ret = 0;
if (__uvisor_ps == NULL) {
#if defined(UVISOR_PRESENT) && (UVISOR_PRESENT == 1)
return -1;
#else
extern void secure_malloc_init(void);
secure_malloc_init();
#endif
}
if ((__uvisor_ps->mutex_id == NULL) && is_kernel_initialized()) {
/* Point the mutex attr to the data. */
__uvisor_ps->mutex_attr.name = "uvisor_malloc_mutex";
__uvisor_ps->mutex_attr.attr_bits = 0; /* Non-recursive */
__uvisor_ps->mutex_attr.cb_mem = &__uvisor_ps->mutex_data;
__uvisor_ps->mutex_attr.cb_size = sizeof(__uvisor_ps->mutex_data);
/* Create mutex if not already done. */
__uvisor_ps->mutex_id = osMutexNew(&__uvisor_ps->mutex_attr);
/* Mutex failed to be created. */
if (__uvisor_ps->mutex_id == NULL) {
return -1;
}
}
if (__uvisor_ps->index.active_heap == NULL) {
/* We need to initialize the process heap. */
if ((void *) __uvisor_ps->index.bss.address_of.heap != NULL) {
/* Lock the mutex during initialization. */
int kernel_initialized = is_kernel_initialized();
if (kernel_initialized) {
osMutexAcquire(__uvisor_ps->mutex_id, osWaitForever);
}
/* Initialize the process heap. */
SecureAllocator allocator = secure_allocator_create_with_pool(
(void *) __uvisor_ps->index.bss.address_of.heap,
__uvisor_ps->index.box_heap_size);
/* Set the allocator. */
ret = allocator ? 0 : -1;
__uvisor_ps->index.active_heap = allocator;
/* Release the mutex. */
if (kernel_initialized) {
osMutexRelease(__uvisor_ps->mutex_id);
}
}
else {
DPRINTF("uvisor_allocator: No process heap available!\n");
ret = -1;
}
}
return ret;
}
typedef enum {
MEMOP_MALLOC,
MEMOP_MEMALIGN,
MEMOP_CALLOC,
MEMOP_REALLOC,
MEMOP_FREE
} MemoryOperation;
static void * memory(MemoryOperation operation, uint32_t * args)
{
/* Buffer the return value. */
void * ret = NULL;
/* Initialize allocator. */
if (init_allocator()) {
return NULL;
}
/* Check if we need to aquire the mutex. */
int mutexed = is_kernel_initialized();
void * allocator = __uvisor_ps->index.active_heap;
/* Aquire the mutex if required.
* TODO: Mutex use is very coarse here. It may be sufficient to guard
* the `rt_alloc_mem` and `rt_free_mem` functions in `uvisor_allocator.c`.
* However, it is simpler to do it here for now. */
if (mutexed) {
osMutexAcquire(__uvisor_ps->mutex_id, osWaitForever);
}
/* Perform the required operation. */
switch(operation)
{
case MEMOP_MALLOC:
ret = secure_malloc(allocator, (size_t) args[0]);
break;
case MEMOP_MEMALIGN:
ret = secure_aligned_alloc(allocator, (size_t) args[0], (size_t) args[1]);
break;
case MEMOP_CALLOC:
ret = secure_calloc(allocator, (size_t) args[0], (size_t) args[1]);
break;
case MEMOP_REALLOC:
ret = secure_realloc(allocator, (void *) args[0], (size_t) args[1]);
break;
case MEMOP_FREE:
secure_free(allocator, (void *) args[0]);
break;
default:
break;
}
/* Release the mutex if required. */
if (mutexed) {
osMutexRelease(__uvisor_ps->mutex_id);
}
return ret;
}
/* Wrapped memory management functions. */
#if defined (__GNUC__)
void * __wrap__malloc_r(struct _reent * r, size_t size) {
(void) r;
return memory(MEMOP_MALLOC, (uint32_t *) &size);
}
void * __wrap__memalign_r(struct _reent * r, size_t alignment, size_t bytes) {
(void) r;
uint32_t args[2] = {(uint32_t) alignment, (uint32_t) bytes};
return memory(MEMOP_MEMALIGN, args);
}
void * __wrap__calloc_r(struct _reent * r, size_t nmemb, size_t size) {
(void) r;
uint32_t args[2] = {(uint32_t) nmemb, (uint32_t) size};
return memory(MEMOP_CALLOC, args);
}
void * __wrap__realloc_r(struct _reent * r, void * ptr, size_t size) {
(void) r;
uint32_t args[2] = {(uint32_t) ptr, (uint32_t) size};
return memory(MEMOP_REALLOC, args);
}
void __wrap__free_r(struct _reent * r, void * ptr) {
(void) r;
memory(MEMOP_FREE, (uint32_t *) &ptr);
}
#elif defined (__CC_ARM)
/* TODO: Find out how to do function wrapping for ARMCC. See microlib libc. */
# warning "Using uVisor allocator is not available for ARMCC. Falling back to default allocator."
#elif defined (__ICCARM__)
/* TODO: Find out how to do function wrapping for IARCC. */
# warning "Using uVisor allocator is not available for IARCC. Falling back to default allocator."
#endif

View File

@ -1,290 +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 "rtx_lib.h"
/* uVisor uses rtx_memory instead of implementing its own dynamic,
* non-fixed-size memory allocator. To do this, uVisor creates multiple
* non-fixed-size allocator pools (one per page) and allocates memory from
* these pools. uVisor must manage the memory for these pools' control blocks,
* so it must know the size of these control blocks. */
/* The following memory pool control block structs are copied from
* rtx_memory.c, so that uVisor can manage the memory for these control blocks
* within pages. */
typedef struct mem_head_s {
uint32_t size; // Memory Pool size
uint32_t used; // Used Memory
} mem_head_t;
// Memory Block Header structure
typedef struct mem_block_s {
struct mem_block_s *next; // Next Memory Block in list
uint32_t info; // Info: length = <31:2>:'00', type = <1:0>
} mem_block_t;
/* End copy */
#include "secure_allocator.h"
#include "uvisor-lib/uvisor-lib.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Use printf with caution inside malloc: printf may allocate memory itself,
so using printf in malloc may lead to recursive calls! */
#define DPRINTF(...) {}
/* offsetof is a gcc built-in function, this is the manual implementation */
#define OFFSETOF(type, member) ((uint32_t) (&(((type *)(0))->member)))
/* Internal structure currently only contains the page table. */
typedef struct {
UvisorPageTable table;
} SecureAllocatorInternal;
static inline UvisorPageTable * table(SecureAllocator allocator) {
return &(((SecureAllocatorInternal *) allocator)->table);
}
SecureAllocator secure_allocator_create_with_pool(
void * mem,
size_t bytes)
{
SecureAllocatorInternal * allocator = mem;
/* Signal that this is non-page allocated memory. */
allocator->table.page_size = bytes;
allocator->table.page_count = 0;
/* The internal rtx_Memory memory pool structure must be placed AFTER
* table.page_origins[0] !!! */
size_t offset = OFFSETOF(SecureAllocatorInternal, table.page_origins) + sizeof(((UvisorPageTable) {0}).page_origins);
uintptr_t page_origin = (uintptr_t) mem + offset;
/* Align page_origin to a multiple of 8 (because RTX requries 8-byte
* alignment of the origin). */
page_origin = (page_origin + (0x8 - 1)) & -0x8;
offset = page_origin - (uintptr_t) mem;
size_t size = bytes - offset;
/* Align size to a multiple of 8 (because RTX requires 8-byte alignment of
* the size) */
size &= -0x8;
/* Create pool allocator structure inside the memory. */
if (!osRtxMemoryInit((void *) page_origin, size)) {
/* Abort if failed. */
DPRINTF("secure_allocator_create_with_pool: pool allocator %p with offset %d creation failed (size %u bytes)\n\n", page_origin, offset, bytes - offset);
return NULL;
}
/* Remember the pool allocator pointer though. */
allocator->table.page_origins[0] = (void *) page_origin;
DPRINTF("secure_allocator_create_with_pool: Created pool allocator %p with offset %d\n\n", page_origin, offset);
return allocator;
}
SecureAllocator secure_allocator_create_with_pages(
size_t size,
size_t maximum_malloc_size)
{
const uint32_t page_size = uvisor_get_page_size();
/* The rtx_Memory allocator puts one pool allocator structure at both the
* beginning and end of the memory pool. */
const size_t block_overhead = 2 * sizeof(mem_block_t);
const size_t page_size_with_overhead = page_size + block_overhead;
/* Calculate the integer part of required the page count. */
size_t page_count = size / page_size_with_overhead;
/* Add another page if the remainder is not zero. */
if (size - page_count * page_size_with_overhead) {
page_count++;
}
DPRINTF("secure_allocator_create_with_pages: Requesting %u pages for at least %uB\n", page_count, size);
/* Compute the maximum allocation within our blocks. */
size_t maximum_allocation_size = page_size - block_overhead;
/* If the required maximum allocation is larger than we can provide, abort. */
if (maximum_malloc_size > maximum_allocation_size) {
DPRINTF("secure_allocator_create_with_pages: Maximum allocation request %uB is larger then available %uB\n\n", maximum_malloc_size, maximum_allocation_size);
return NULL;
}
/* Compute the required memory size for the page table. */
size_t allocator_type_size = sizeof(SecureAllocatorInternal);
/* Add size for each additional page. */
allocator_type_size += (page_count - 1) * sizeof(((UvisorPageTable) {0}).page_origins);
/* Allocate this much memory. */
SecureAllocatorInternal * const allocator = malloc(allocator_type_size);
/* If malloc failed, abort. */
if (allocator == NULL) {
DPRINTF("secure_allocator_create_with_pages: SecureAllocatorInternal failed to be allocated!\n\n");
return NULL;
}
/* Prepare the page table. */
allocator->table.page_size = page_size;
allocator->table.page_count = page_count;
/* Get me some pages. */
if (uvisor_page_malloc((UvisorPageTable *) &(allocator->table))) {
free(allocator);
DPRINTF("secure_allocator_create_with_pages: Not enough free pages available!\n\n");
return NULL;
}
/* Initialize a memory pool structure in all pages. */
for(size_t ii = 0; ii < page_count; ii++) {
/* Add each page as a pool. */
osStatus_t status = osRtxMemoryInit(allocator->table.page_origins[ii], page_size);
if (status == osOK) {
DPRINTF("secure_allocator_create_with_pages: Created memory pool allocator %p with offset %d page %u\n", allocator->table.page_origins[ii], 0, ii);
} else {
DPRINTF("secure_allocator_create_with_pages: Failed creating memory pool allocator %p with offset %d page %u\n", allocator->table.page_origins[ii], 0, ii);
}
}
DPRINTF("\n");
/* Aaaand across the line. */
return (SecureAllocator) allocator;
}
int secure_allocator_destroy(
SecureAllocator allocator)
{
DPRINTF("secure_allocator_destroy: Destroying memory pool allocator at %p\n", table(allocator)->page_origins[0]);
/* Check if we are working on statically allocated memory. */
SecureAllocatorInternal * alloc = (SecureAllocatorInternal * const) allocator;
if (alloc->table.page_count == 0) {
DPRINTF("secure_allocator_destroy: %p is not page-backed memory, not freeing!\n", allocator);
return -1;
}
/* Free all pages. */
if (uvisor_page_free(&(alloc->table))) {
DPRINTF("secure_allocator_destroy: Unable to free pages!\n\n");
return -1;
}
/* Free the allocator structure. */
free(allocator);
DPRINTF("\n");
return 0;
}
void * secure_malloc(
SecureAllocator allocator,
size_t size)
{
size_t index = 0;
do {
/* Search in this page. */
void * mem = osRtxMemoryAlloc(table(allocator)->page_origins[index], size, 0);
/* Return if we found something. */
if (mem) {
DPRINTF("secure_malloc: Found %4uB in page %u at %p\n", size, index, mem);
return mem;
}
/* Otherwise, go to the next page. */
index++;
} /* Continue search if more pages are available. */
while (index < table(allocator)->page_count);
DPRINTF("secure_malloc: Out of memory in allocator %p \n", allocator);
/* We found nothing. */
return NULL;
}
void * secure_aligned_alloc(
SecureAllocator allocator,
size_t alignment,
size_t size)
{
/* Alignment must be a power of two! */
if (alignment & ((1UL << ((31UL - __builtin_clz(alignment)) - 1)))) {
return NULL;
}
/* TODO: THIS IS A NAIVE IMPLEMENTATION, which wastes much memory. */
void * ptr = secure_malloc(allocator, size + alignment - 1);
if (ptr == NULL) {
return NULL;
}
return (void *) (((uint32_t) ptr + alignment - 1) & ~(alignment - 1));
}
void * secure_calloc(
SecureAllocator allocator,
size_t nmemb,
size_t size)
{
if ((uint64_t) nmemb * size > SIZE_MAX) {
/* (size * nmemb) has overflowed. */
return NULL;
}
void * ptr = secure_malloc(allocator, size * nmemb);
if (ptr == NULL) {
return NULL;
}
memset(ptr, 0, size * nmemb);
return ptr;
}
void * secure_realloc(
SecureAllocator allocator,
void * ptr,
size_t new_size)
{
/* TODO: THIS IS A NAIVE IMPLEMENTATION, which always allocates new
memory, and copies the memory, then frees the old memory. */
/* Allocate new memory. */
void * new_ptr = secure_malloc(allocator, new_size);
/* If memory allocation failed, abort. */
if (new_ptr == NULL) {
return NULL;
}
/* Passing NULL as ptr is legal, realloc acts as malloc then. */
if (ptr) {
/* Get the size of the ptr memory. */
size_t size = ((mem_block_t *) ((uint32_t) ptr - sizeof(mem_block_t)))->info & ~0x3;
/* Copy the memory to the new location, min(new_size, size). */
memcpy(new_ptr, ptr, new_size < size ? new_size : size);
/* Free the previous memory. */
secure_free(allocator, ptr);
}
return new_ptr;
}
void secure_free(
SecureAllocator allocator,
void * ptr)
{
size_t index = 0;
do {
/* Search in this page. */
int ret = osRtxMemoryFree(table(allocator)->page_origins[index], ptr);
/* Return if free was successful. */
if (ret == 1) {
DPRINTF("secure_free: Freed %p in page %u.\n", ptr, index);
return;
}
/* Otherwise, go to the next page. */
index++;
} /* Continue search if more pages are available. */
while (index < table(allocator)->page_count);
DPRINTF("secure_free: %p not found in allocator %p!\n", ptr, allocator);
/* We found nothing. */
return;
}

View File

@ -1,42 +0,0 @@
/*
* Copyright (c) 2017, 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 "tz_context.h"
#include <stdint.h>
/* Provide do-nothing stubs for RTX's trustzone context saving hooks. uVisor
* doesn't use these on ARMv8-M. */
uint32_t TZ_InitContextSystem_S(void) {
return 1; /* Success */
}
TZ_MemoryId_t TZ_AllocModuleContext_S(TZ_ModuleId_t module) {
return 1; /* Always hand out slot 1. */
}
uint32_t TZ_FreeModuleContext_S(TZ_MemoryId_t id) {
return 1; /* Success */
}
uint32_t TZ_LoadContext_S(TZ_MemoryId_t id) {
return 1; /* Success */
}
uint32_t TZ_StoreContext_S(TZ_MemoryId_t id) {
return 1; /* Success */
}

View File

@ -1,79 +0,0 @@
/*
* Copyright (c) 2015-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"
#if !(defined(UVISOR_PRESENT) && (UVISOR_PRESENT == 1))
#include <string.h> /* for memset */
/* Forward declaration of the page allocator API. */
extern void page_allocator_init(void * const heap_start, void * const heap_end, const uint32_t * const page_size);
extern uint32_t __end__[]; /* __heap_start */
extern uint32_t __HeapLimit[]; /* __heap_end */
extern uint32_t __StackLimit[]; /* bottom of stack */
/* There is only one box index for box 0. */
RtxBoxIndex * __uvisor_ps UVISOR_ALIGN(4);
static void box_index_init(void *box_bss, uint32_t heap_size)
{
const uint32_t index_size = sizeof(RtxBoxIndex);
/* Adjust size for overhead of box index */
heap_size -= index_size;
/* The box index is at the beginning of the bss section */
RtxBoxIndex *const indexOS = box_bss;
/* Zero the _entire_ index, so that we know to initialize the mutex on
* first use! */
memset(box_bss, 0, index_size);
/* Initialize user context */
indexOS->index.ctx = NULL;
/* Initialize box heap */
indexOS->index.box_heap = box_bss + index_size;
indexOS->index.box_heap_size = heap_size;
/* Active heap pointer is NULL */
indexOS->index.active_heap = NULL;
/* There is no box config for unsupported! */
indexOS->index.config = NULL;
/* Set the index */
__uvisor_ps = indexOS;
}
void secure_malloc_init(void)
{
/* get the public heap size from the linker script */
uint32_t heap_size = ((uint32_t) __HeapLimit -
(uint32_t) __end__);
/* Public heap size is aligned to page boundaries n*UVISOR_PAGE_SIZE */
uint32_t heap_start = (uint32_t) __StackLimit - heap_size;
/* align the start address of the public heap to a page boundary */
heap_start &= ~(UVISOR_PAGE_SIZE - 1);
/* adjust the heap size to the new heap start address */
heap_size = (uint32_t) __StackLimit - heap_start;
/* page heap now extends from the previous public heap start address
* to the new public heap start address */
extern uint32_t __uvisor_page_size;
page_allocator_init(__end__, (void *) heap_start, &__uvisor_page_size);
box_index_init((void *) heap_start, heap_size);
}
#endif

View File

@ -1,111 +0,0 @@
/*
* Copyright (c) 2015-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"
#if !(defined(UVISOR_PRESENT) && (UVISOR_PRESENT == 1))
#include "cmsis.h"
/* This is the fallback implementation for using the page allocator from uVisor
* inside an OS as a normal function.
* Be aware that the page allocator is not re-entrant, so the OS must provide a
* mutex implementation to enable thread-safety!
*/
#define DPRINTF(...) {}
#define g_active_box 0
#define vmpu_is_box_id_valid(...) 0
#define vmpu_public_flash_addr(...) 1
#define vmpu_sram_addr(...) 1
#define vmpu_public_sram_addr(...) 1
#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);
int page_allocator_free(const UvisorPageTable * const table);
int uvisor_page_malloc(UvisorPageTable *const table)
{
return page_allocator_malloc(table);
}
int uvisor_page_free(const UvisorPageTable *const table)
{
return page_allocator_free(table);
}
/* Implement mutex for page allocator. */
static osMutexId_t g_page_allocator_mutex_id = NULL;
static osRtxMutex_t g_page_allocator_mutex_data;
static osMutexDef_t g_page_allocator_mutex_attr = {
.name = "uvisor_malloc_mutex",
.attr_bits = 0, /* Non-recursive */
.cb_mem = &g_page_allocator_mutex_data,
.cb_size = sizeof(g_page_allocator_mutex_data)
};
static void page_allocator_mutex_aquire()
{
if (g_page_allocator_mutex_id == NULL) {
/* Create mutex if not already done. */
g_page_allocator_mutex_id = osMutexNew(&g_page_allocator_mutex_attr);
if (g_page_allocator_mutex_id == NULL) {
/* Mutex failed to be created. */
return;
}
}
osMutexAcquire(g_page_allocator_mutex_id, osWaitForever);
}
/* Alignment of MPU regions is not required anymore, however we still require
* a 32B alignment, to have some page size granularity. */
static inline int vmpu_is_region_size_valid(uint32_t size)
{
return ((size & ~31) == size);
}
static inline uint32_t vmpu_round_up_region(uint32_t addr, uint32_t size)
{
if (!vmpu_is_region_size_valid(size)) {
return 0;
}
const uint32_t mask = size - 1;
/* Adding the mask can overflow. */
const uint32_t rounded_addr = addr + mask;
/* Check for overflow. */
if (rounded_addr < addr) {
/* This means the address was too large to align. */
return 0;
}
/* Mask the rounded address to get the aligned address. */
return (rounded_addr & ~mask);
}
static inline uint32_t page_table_read(uint32_t addr)
{
return *((uint32_t *) addr);
}
static inline void page_table_write(uint32_t addr, uint32_t data)
{
*((uint32_t *) addr) = data;
}
/* Include the original page allocator source directly. */
#include "../page_allocator.c_inc"
#endif

View File

@ -1,51 +0,0 @@
#include "api/inc/uvisor_semaphore_exports.h"
#include "api/inc/uvisor_exports.h"
#include "api/inc/halt_exports.h"
#include "cmsis_os2.h"
#include "rtx_lib.h"
#include <string.h>
typedef struct uvisor_semaphore_internal {
osSemaphoreId_t id;
osSemaphoreAttr_t attr;
osRtxSemaphore_t data;
} UVISOR_ALIGN(4) uvisor_semaphore_internal_t;
UVISOR_STATIC_ASSERT(UVISOR_SEMAPHORE_INTERNAL_SIZE >= sizeof(UvisorSemaphore), semaphore_size_too_small);
int __uvisor_semaphore_init(UvisorSemaphore * s, uint32_t max_count, uint32_t initial_count)
{
uvisor_semaphore_internal_t * semaphore = (uvisor_semaphore_internal_t *) s;
memset(&semaphore->data, 0, sizeof(semaphore->data));
memset(&semaphore->attr, 0, sizeof(semaphore->attr));
semaphore->attr.name = "uvisor_semaphore";
semaphore->attr.cb_size = sizeof(semaphore->data);
semaphore->attr.cb_mem = &semaphore->data;
semaphore->id = osSemaphoreNew(max_count, initial_count, &semaphore->attr);
/* Error when semaphore->id is NULL */
return semaphore->id == NULL ? UVISOR_ERROR_OUT_OF_STRUCTURES : 0;
}
int __uvisor_semaphore_pend(UvisorSemaphore * s, uint32_t timeout_ms)
{
uvisor_semaphore_internal_t * semaphore = (uvisor_semaphore_internal_t *) s;
osStatus_t status = osSemaphoreAcquire(semaphore->id, timeout_ms);
if (status == osErrorTimeout) {
return UVISOR_ERROR_TIMEOUT;
} else if (status == osErrorParameter) {
return UVISOR_ERROR_INVALID_PARAMETERS;
} else if (status != osOK) {
return -1; /* Other error */
}
return 0;
}
int __uvisor_semaphore_post(UvisorSemaphore * s) {
uvisor_semaphore_internal_t * semaphore = (uvisor_semaphore_internal_t *) s;
return osSemaphoreRelease(semaphore->id);
}

View File

@ -1,26 +0,0 @@
Copyright (c) 2013-2016 ARM Limited
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.
License Exceptions:
- 3-clause BSD License (see LICENSE-BSD.txt):
- core/cmsis/inc/arm* and core/cmsis/inc/core*:
Copyright (c) 2009-2016 ARM Limited
- core/cmsis/inc/mpu_kinetis.h:
Copyright (c) 1997-2014 Freescale Semiconductor, Inc
- core/lib/printf:
Copyright (c) 2004, 2012 Kustaa Nyholm / SpareTimeLabs

View File

@ -1,27 +0,0 @@
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@ -1,27 +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 "mbed.h"
EXTERN void uvisor_disabled_set_vector(uint32_t irqn, uint32_t vector)
{
NVIC_SetVector((IRQn_Type) irqn, vector);
}
EXTERN uint32_t uvisor_disabled_get_vector(uint32_t irqn)
{
return NVIC_GetVector((IRQn_Type) irqn);
}

View File

@ -1,59 +0,0 @@
/*
* Copyright (c) 2015-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 "rt_OsEventObserver.h"
#if !(defined(UVISOR_PRESENT) && (UVISOR_PRESENT == 1))
/* Note: This file is not included in the uVisor release library. Instead, the
* host OS needs to compile it separately if a platform does not support
* uVisor (but uVisor API header files are still used). */
/* uVisor hook for unsupported platforms */
UVISOR_EXTERN void uvisor_init(void)
{
return;
}
extern RtxBoxIndex * __uvisor_ps;
static void thread_switch(void *context)
{
if (context == NULL) return;
/* If the active_heap is NULL, then the process heap needs to be
* initialized. The initializer sets the active heap itself. */
if (__uvisor_ps->index.active_heap) {
__uvisor_ps->index.active_heap = context;
}
}
static OsEventObserver os_event_observer = {
.version = 0,
.pre_start = 0,
.thread_create = 0,
.thread_destroy = 0,
.thread_switch = thread_switch,
};
int uvisor_lib_init(void)
{
osRegisterForOsEvents(&os_event_observer);
return 0;
}
#endif

View File

@ -1 +0,0 @@
6d61583c3fae7f2b3f96cc5c5ca9b0107b981e6d

View File

@ -38,7 +38,7 @@ static int32_t test_cfstore_flush(void)
ARM_CFSTORE_CAPABILITIES test_cfstore_get_capabilities(void)
{
static ARM_CFSTORE_CAPABILITIES cfstore_caps_g = { .asynchronous_ops = 1, .uvisor_support_enabled = 0 };
static ARM_CFSTORE_CAPABILITIES cfstore_caps_g = { .asynchronous_ops = 1 };
return cfstore_caps_g;
}

View File

@ -33,11 +33,6 @@
#include "greentea-client/test_env.h"
#include "cfstore_utest.h"
#ifdef YOTTA_CFG_CFSTORE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#include "cfstore_uvisor.h"
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -49,16 +44,6 @@ using namespace utest::v1;
static char cfstore_add_del_utest_msg_g[CFSTORE_UTEST_MSG_BUF_SIZE];
#ifdef YOTTA_CFG_CFSTORE_UVISOR
/* Create the main box ACL list for the application.
* The main ACL gets inherited by all the other boxes
*/
CFSTORE_UVISOR_MAIN_ACL(cfstore_acl_uvisor_box_add_del_g);
/* Enable uVisor. */
UVISOR_SET_MODE_ACL(UVISOR_ENABLED, cfstore_acl_uvisor_box_add_del_g);
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
static cfstore_kv_data_t cfstore_add_del_test_07_data[] = {
CFSTORE_INIT_1_TABLE_MID_NODE,
{ NULL, NULL},

View File

@ -32,10 +32,6 @@
#include "greentea-client/test_env.h"
#include "cfstore_utest.h"
#ifdef YOTTA_CFG_CFSTORE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
@ -44,12 +40,6 @@ using namespace utest::v1;
static char cfstore_close_utest_msg_g[CFSTORE_UTEST_MSG_BUF_SIZE];
/* Configure secure box. */
#ifdef YOTTA_CFG_CFSTORE_UVISOR
UVISOR_BOX_NAMESPACE("com.arm.mbed.cfstore.test.close.box1");
UVISOR_BOX_CONFIG(cfstore_close_box1, UVISOR_BOX_STACK_SIZE);
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
/* KV data for test_01 */
static cfstore_kv_data_t cfstore_close_test_01_kv_data[] = {
{ "yotta.hello-world.animal{wobbly-dog}{foot}frontLeft", "first_data_"},

View File

@ -36,10 +36,6 @@
#include "greentea-client/test_env.h"
#include "cfstore_utest.h"
#ifdef YOTTA_CFG_CFSTORE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -56,13 +52,6 @@ using namespace utest::v1;
static char cfstore_create_utest_msg_g[CFSTORE_UTEST_MSG_BUF_SIZE];
/* Configure secure box. */
#ifdef YOTTA_CFG_CFSTORE_UVISOR
UVISOR_BOX_NAMESPACE("com.arm.mbed.cfstore.test.create.box1");
UVISOR_BOX_CONFIG(cfstore_create_box1, UVISOR_BOX_STACK_SIZE);
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
/// @cond CFSTORE_DOXYGEN_DISABLE
#define CFSTORE_CREATE_TEST_01_TABLE_HEAD_ENTRY_01 { "Lefkada.Vathi.Meganisi.Atokos.Vathi.Ithaki.PeriPigathi.AgiosAndreas.Sami.Kefalonia.AgiaEffimia.AgiaSofia.Fiskardo.Frikes.Kioni.Meganissi.Lefkada", "Penelope"}
#define CFSTORE_CREATE_TEST_01_TABLE_HEAD_ENTRY_02 { "Iolcus.Lemnos.Salmydessus.Cyzicus.Cios.Berbryces.Symplegadese.IsleAres.Colchis.Anenea.Sirens.Scylia.Charybdis.Phaeacia.Triton.Iolcus", "Medea"}

View File

@ -30,9 +30,6 @@
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#include "cfstore_utest.h"
#ifdef YOTTA_CFG_CFSTORE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
#include <stdio.h>
#include <stdlib.h>

View File

@ -68,10 +68,6 @@
#include "utest/utest.h"
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#ifdef YOTTA_CFG_CFSTORE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#include "cfstore_uvisor.h"
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
#include <stdio.h>
#include <stdlib.h>
@ -136,10 +132,6 @@ int main()
#include "Driver_Common.h"
#endif /* CFSTORE_CONFIG_BACKEND_FLASH_ENABLED */
#ifdef YOTTA_CFG_CONFIG_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#endif /* YOTTA_CFG_CONFIG_UVISOR */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View File

@ -41,9 +41,6 @@
#include "utest/utest.h"
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#ifdef YOTTA_CFG_CONFIG_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#endif /* YOTTA_CFG_CONFIG_UVISOR */
#include <stdio.h>
#include <stdlib.h>

View File

@ -71,9 +71,6 @@
#include "cfstore_test.h"
#include "configuration_store.h"
#ifdef YOTTA_CFG_CONFIG_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#endif /* YOTTA_CFG_CONFIG_UVISOR */
#include <stdio.h>
#include <stdlib.h>

View File

@ -41,9 +41,6 @@
#include "utest/utest.h"
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#ifdef YOTTA_CFG_CONFIG_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#endif /* YOTTA_CFG_CONFIG_UVISOR */
#include <stdio.h>
#include <stdlib.h>

View File

@ -33,9 +33,6 @@
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#include "cfstore_utest.h"
#ifdef YOTTA_CFG_CFSTORE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
#include <stdio.h>
#include <stdlib.h>
@ -47,11 +44,6 @@ using namespace utest::v1;
static char cfstore_find_utest_msg_g[CFSTORE_UTEST_MSG_BUF_SIZE];
/* Configure secure box. */
#ifdef YOTTA_CFG_CFSTORE_UVISOR
UVISOR_BOX_NAMESPACE("com.arm.mbed.cfstore.test.find.box1");
UVISOR_BOX_CONFIG(cfstore_find_box1, UVISOR_BOX_STACK_SIZE);
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
/* report whether built/configured for flash sync or async mode */

View File

@ -31,9 +31,6 @@
#include "utest/utest.h"
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#ifdef YOTTA_CFG_CFSTORE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
#include <stdio.h>
#include <stdlib.h>
@ -45,11 +42,6 @@ using namespace utest::v1;
static char cfstore_find2_utest_msg_g[CFSTORE_UTEST_MSG_BUF_SIZE];
/* Configure secure box. */
#ifdef YOTTA_CFG_CFSTORE_UVISOR
UVISOR_BOX_NAMESPACE("com.arm.mbed.cfstore.test.find2.box1");
UVISOR_BOX_CONFIG(cfstore_find2_box1, UVISOR_BOX_STACK_SIZE);
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
/// @cond CFSTORE_DOXYGEN_DISABLE
#ifdef CFSTORE_DEBUG

View File

@ -36,9 +36,6 @@
#include "Driver_Common.h"
#endif /* CFSTORE_CONFIG_BACKEND_FLASH_ENABLED */
#ifdef YOTTA_CFG_CFSTORE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
#include <stdio.h>
#include <stdlib.h>
@ -47,11 +44,6 @@
using namespace utest::v1;
/* Configure secure box. */
#ifdef YOTTA_CFG_CFSTORE_UVISOR
UVISOR_BOX_NAMESPACE("com.arm.mbed.cfstore.test.flash.box1");
UVISOR_BOX_CONFIG(cfstore_flash_box1, UVISOR_BOX_STACK_SIZE);
#endif /* YOTTA_CFG_CFSTORE_UVISOR */

View File

@ -29,10 +29,6 @@
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#include "cfstore_utest.h"
#ifdef YOTTA_CFG_CFSTORE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#include "cfstore_uvisor.h"
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
#include <stdio.h>
#include <stdlib.h>
@ -41,15 +37,6 @@
using namespace utest::v1;
#ifdef YOTTA_CFG_CFSTORE_UVISOR
/* Create the main box ACL list for the application.
* The main ACL gets inherited by all the other boxes
*/
CFSTORE_UVISOR_MAIN_ACL(cfstore_acl_uvisor_box_flash_set_g);
/* Enable uVisor. */
UVISOR_SET_MODE_ACL(UVISOR_ENABLED, cfstore_acl_uvisor_box_flash_set_g);
#endif /* YOTTA_CFG_CFSTORE_UVISOR */

View File

@ -33,10 +33,6 @@
#include "utest/utest.h"
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#ifdef YOTTA_CFG_CFSTORE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#include "cfstore_uvisor.h"
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
#include <stdio.h>
#include <stdlib.h>
@ -88,9 +84,6 @@ int main()
#include "utest/utest.h"
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#ifdef YOTTA_CFG_CFSTORE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
#include <stdio.h>
#include <stdlib.h>
@ -122,11 +115,6 @@ using namespace utest::v1;
*/
char cfstore_flush_utest_msg_g[CFSTORE_FLUSH_UTEST_MSG_BUF_SIZE];
/* Configure secure box. */
#ifdef YOTTA_CFG_CFSTORE_UVISOR
UVISOR_BOX_NAMESPACE("com.arm.mbed.cfstore.test.flush.box1");
UVISOR_BOX_CONFIG(cfstore_flush_box1, UVISOR_BOX_STACK_SIZE);
#endif /* YOTTA_CFG_CFSTORE_UVISOR */

View File

@ -29,10 +29,6 @@
#include "greentea-client/test_env.h"
#include "cfstore_test.h"
#include "cfstore_debug.h"
#include "cfstore_utest.h"
#ifdef YOTTA_CFG_CFSTORE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
#include <stdio.h>
#include <stdlib.h>
@ -49,11 +45,6 @@ using namespace utest::v1;
#define cfstore_flush_fsm_null NULL
#define CFSTORE_FLUSH_CASE_TIMEOUT_MS 10000
/* Configure secure box. */
#ifdef YOTTA_CFG_CFSTORE_UVISOR
UVISOR_BOX_NAMESPACE("com.arm.mbed.cfstore.test.flush2.box1");
UVISOR_BOX_CONFIG(cfstore_flush2_box1, UVISOR_BOX_STACK_SIZE);
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
/*

View File

@ -39,10 +39,6 @@
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#ifdef YOTTA_CFG_CFSTORE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#include "cfstore_uvisor.h"
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
#include <stdio.h>
#include <stdlib.h>
@ -53,16 +49,6 @@ using namespace utest::v1;
static char cfstore_flush3_utest_msg_g[CFSTORE_UTEST_MSG_BUF_SIZE];
#ifdef YOTTA_CFG_CFSTORE_UVISOR
/* Create the main box ACL list for the application.
* The main ACL gets inherited by all the other boxes
*/
CFSTORE_UVISOR_MAIN_ACL(cfstore_acl_uvisor_box_flush3_g);
/* Enable uVisor. */
UVISOR_SET_MODE_ACL(UVISOR_ENABLED, cfstore_acl_uvisor_box_flush3_g);
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
/// @cond CFSTORE_DOXYGEN_DISABLE
#ifdef CFSTORE_DEBUG
#define CFSTORE_FLUSH3_GREENTEA_TIMEOUT_S 1000
@ -305,11 +291,6 @@ int32_t cfstore_flush3_start(void)
CFSTORE_DBGLOG("%s:Please configure CFstore to work in synchronous mode. This can be change in config.json file.\n", __func__);
status = ARM_DRIVER_ERROR;
goto out;
}
if(caps.uvisor_support_enabled == true){
CFSTORE_DBGLOG("%s:Please enable uvisor spv box.\n", __func__);
status = ARM_DRIVER_ERROR;
goto out;
}
CFSTORE_DBGLOG("%s:OUT: returning ARM_DRIVER_OK\n", __func__);
return ARM_DRIVER_OK; /* init succeeded */

View File

@ -30,9 +30,6 @@
#include "utest/utest.h"
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#ifdef YOTTA_CFG_CONFIG_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#endif /* YOTTA_CFG_CONFIG_UVISOR */
#include <stdio.h>
#include <stdlib.h>

View File

@ -32,10 +32,6 @@
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#include "cfstore_utest.h"
#ifdef YOTTA_CFG_CFSTORE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#include "cfstore_uvisor.h"
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
#include <stdio.h>
#include <string.h>
@ -45,15 +41,6 @@ using namespace utest::v1;
static char cfstore_misc_utest_msg_g[CFSTORE_UTEST_MSG_BUF_SIZE];
#ifdef YOTTA_CFG_CFSTORE_UVISOR
/* Create the main box ACL list for the application.
* The main ACL gets inherited by all the other boxes
*/
CFSTORE_UVISOR_MAIN_ACL(cfstore_acl_uvisor_box_misc_g);
/* Enable uVisor. */
UVISOR_SET_MODE_ACL(UVISOR_ENABLED, cfstore_acl_uvisor_box_misc_g);
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
/* report whether built/configured for flash sync or async mode */

View File

@ -31,9 +31,6 @@
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#include "cfstore_utest.h"
#ifdef YOTTA_CFG_CFSTORE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
#include <stdio.h>
#include <string.h>
@ -44,11 +41,6 @@ using namespace utest::v1;
static char cfstore_open_utest_msg_g[CFSTORE_UTEST_MSG_BUF_SIZE];
/* Configure secure box. */
#ifdef YOTTA_CFG_CFSTORE_UVISOR
UVISOR_BOX_NAMESPACE("com.arm.mbed.cfstore.test.open.box1");
UVISOR_BOX_CONFIG(cfstore_open_box1, UVISOR_BOX_STACK_SIZE);
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
/// @cond CFSTORE_DOXYGEN_DISABLE

View File

@ -31,9 +31,6 @@
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#include "cfstore_utest.h"
#ifdef YOTTA_CFG_CFSTORE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
#include <stdio.h>
#include <string.h>
@ -43,11 +40,6 @@ using namespace utest::v1;
static char cfstore_read_utest_msg_g[CFSTORE_UTEST_MSG_BUF_SIZE];
/* Configure secure box. */
#ifdef YOTTA_CFG_CFSTORE_UVISOR
UVISOR_BOX_NAMESPACE("com.arm.mbed.cfstore.test.read.box1");
UVISOR_BOX_CONFIG(cfstore_read_box1, UVISOR_BOX_STACK_SIZE);
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
/* KV data for test_01 */

View File

@ -31,9 +31,6 @@
#include "unity/unity.h"
#include "greentea-client/test_env.h"
#include "cfstore_utest.h"
#ifdef YOTTA_CFG_CFSTORE_UVISOR
#include "uvisor-lib/uvisor-lib.h"
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
#include <stdio.h>
#include <string.h>
@ -43,11 +40,6 @@ using namespace utest::v1;
static char cfstore_write_utest_msg_g[CFSTORE_UTEST_MSG_BUF_SIZE];
/* Configure secure box. */
#ifdef YOTTA_CFG_CFSTORE_UVISOR
UVISOR_BOX_NAMESPACE("com.arm.mbed.cfstore.test.write.box1");
UVISOR_BOX_CONFIG(cfstore_write_box1, UVISOR_BOX_STACK_SIZE);
#endif /* YOTTA_CFG_CFSTORE_UVISOR */
/*

View File

@ -31,8 +31,6 @@ define __SCRIPT_GDB
monitor flash device = $(CPU)
load $(TARGET)
file $(TARGET)
$(GDB_DEBUG_UVISOR)
b vmpu_init_post
b app_start
endef
export __SCRIPT_GDB

Some files were not shown because too many files have changed in this diff Show More