Merge pull request #8745 from kfnta/feature-new-target-future-sequana-psa

Add new target future sequana PSA
pull/8994/head
Cruz Monrreal 2018-12-06 13:13:36 -06:00 committed by GitHub
commit 78d6018ecc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 37740 additions and 32 deletions

View File

@ -23,6 +23,10 @@
#error [NOT_SUPPORTED] this test is supported on GCC only
#endif
#if defined(TARGET_FUTURE_SEQUANA_PSA)
#error [NOT_SUPPORTED] Disable this Test until FUTURE_SEQUANA_PSA enables Memory protection
#endif
#include "utest/utest.h"
#include "unity/unity.h"
#include "greentea-client/test_env.h"

View File

@ -66,6 +66,33 @@
using namespace utest::v1;
#if (defined(TARGET_PSA) && defined(COMPONENT_PSA_SRV_IPC) && defined(MBEDTLS_PSA_CRYPTO_C))
#include "entropy.h"
#include "entropy_poll.h"
#include "crypto.h"
#if !defined(MAX)
#define MAX(a,b) (((a)>(b))?(a):(b))
#endif
/* Calculating the minimum allowed entropy size in bytes */
#define MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE \
MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_BLOCK_SIZE)
void inject_entropy_for_psa()
{
if (psa_crypto_init() == PSA_ERROR_INSUFFICIENT_ENTROPY) {
uint8_t seed[MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE] = {0};
/* inject some a seed for test*/
for (int i = 0; i < MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE; ++i) {
seed[i] = i;
}
/* don't really care if this succeed this is just to make crypto init pass*/
mbedtls_psa_inject_entropy(seed, MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE);
}
}
#endif // (defined(TARGET_PSA) && defined(COMPONENT_PSA_SRV_IPC) && defined(MBEDTLS_PSA_CRYPTO_C))
static int fill_buffer_trng(uint8_t *buffer, trng_t *trng_obj, size_t trng_len)
{
size_t temp_size = 0, output_length = 0;
@ -241,7 +268,13 @@ Specification specification(greentea_test_setup, cases, greentea_test_teardown_h
int main()
{
#if (defined(TARGET_PSA) && defined(COMPONENT_PSA_SRV_IPC) && defined(MBEDTLS_PSA_CRYPTO_C))
inject_entropy_for_psa();
#endif
bool ret = !Harness::run(specification);
return ret;
}

View File

@ -33,6 +33,8 @@ using namespace utest::v1;
#define THREAD_STACK_SIZE 512
#elif defined(__ARM_FM)
#define THREAD_STACK_SIZE 512
#elif defined(TARGET_FUTURE_SEQUANA_PSA)
#define THREAD_STACK_SIZE 512
#else
#define THREAD_STACK_SIZE 320 /* larger stack cause out of heap memory on some 16kB RAM boards in multi thread test*/
#endif

View File

@ -41,6 +41,8 @@ volatile bool thread_should_continue = true;
#define THREAD_STACK_SIZE 512
#elif defined(__ARM_FM)
#define THREAD_STACK_SIZE 512
#elif defined(TARGET_FUTURE_SEQUANA_PSA)
#define THREAD_STACK_SIZE 512
#else
#define THREAD_STACK_SIZE 256
#endif

View File

@ -36,6 +36,8 @@
#define PARALLEL_THREAD_STACK_SIZE 512
#elif defined(__ARM_FM)
#define PARALLEL_THREAD_STACK_SIZE 512
#elif defined(TARGET_FUTURE_SEQUANA_PSA)
#define PARALLEL_THREAD_STACK_SIZE 512
#else
#define PARALLEL_THREAD_STACK_SIZE 384
#endif

View File

@ -84,6 +84,32 @@ Case cases[] = {
#endif /* MBEDTLS_SELF_TEST */
};
#if (defined(MBEDTLS_ENTROPY_C) && defined(TARGET_PSA) && defined(COMPONENT_PSA_SRV_IPC) && defined(MBEDTLS_PSA_CRYPTO_C))
#include "crypto.h"
#if !defined(MAX)
#define MAX(a,b) (((a)>(b))?(a):(b))
#endif
/* Calculating the minimum allowed entropy size in bytes */
#define MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE \
MAX(MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_BLOCK_SIZE)
void inject_entropy_for_psa()
{
if (psa_crypto_init() == PSA_ERROR_INSUFFICIENT_ENTROPY) {
uint8_t seed[MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE] = {0};
/* inject some a seed for test*/
for (int i = 0; i < MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE; ++i) {
seed[i] = i;
}
/* don't really care if this succeed this is just to make crypto init pass*/
mbedtls_psa_inject_entropy(seed, MBEDTLS_PSA_INJECT_ENTROPY_MIN_SIZE);
}
}
#endif // (defined(MBEDTLS_ENTROPY_C) && defined(TARGET_PSA) && defined(COMPONENT_PSA_SRV_IPC) && defined(MBEDTLS_PSA_CRYPTO_C))
utest::v1::status_t test_setup(const size_t num_cases)
{
GREENTEA_SETUP(120, "default_auto");
@ -101,6 +127,11 @@ int main()
return 1;
}
#endif
#if (defined(MBEDTLS_ENTROPY_C) && defined(TARGET_PSA) && defined(COMPONENT_PSA_SRV_IPC) && defined(MBEDTLS_PSA_CRYPTO_C))
inject_entropy_for_psa();
#endif
ret = (Harness::run(specification) ? 0 : 1);
#if defined(MBEDTLS_PLATFORM_C)
mbedtls_platform_teardown(NULL);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,9 @@
"K64F": {
"storage_type": "FILESYSTEM"
},
"FUTURE_SEQUANA_M0_PSA": {
"storage_type": "TDB_INTERNAL"
},
"K66F": {
"storage_type": "TDB_INTERNAL"
}

View File

@ -9,5 +9,11 @@
"help": "If default, the base address is set to the first sector after the application code ends.",
"value": "0"
}
},
"target_overrides": {
"FUTURE_SEQUANA_M0_PSA": {
"internal_size": "0x8000",
"internal_base_address": "0x10078000"
}
}
}

View File

@ -43,6 +43,12 @@
"area_1_size": 16384,
"area_2_address": "0x1007C000",
"area_2_size": 16384
},
"FUTURE_SEQUANA_PSA": {
"enabled" : false
},
"FUTURE_SEQUANA_M0_PSA": {
"enabled" : false
}
}
}

View File

@ -30,6 +30,22 @@
;* SPDX-License-Identifier: Apache-2.0
;******************************************************************************/
#if !defined(MBED_ROM_START)
#define MBED_ROM_START 0x10000000
#endif
#if !defined(MBED_ROM_SIZE)
#define MBED_ROM_SIZE 0x80000
#endif
#if !defined(MBED_RAM_START)
#define MBED_RAM_START 0x08000000
#endif
#if !defined(MBED_RAM_SIZE)
#define MBED_RAM_SIZE 0x10000
#endif
; The defines below describe the location and size of blocks of memory in the target.
; Use these defines to specify the memory regions available for allocation.
@ -39,14 +55,14 @@
; where 'xx' is the device group; for example, 'cy8c6xx7_cm4_dual.scat'.
; RAM
; RAM
#define RAM_START 0x08000000
#define RAM_SIZE 0x00010000
#define RAM_START MBED_RAM_START
#define RAM_SIZE MBED_RAM_SIZE
; Flash
; Flash
#define FLASH_START 0x10000000
#define FLASH_SIZE 0x00078000
#define FLASH_START MBED_ROM_START
#define FLASH_SIZE MBED_ROM_SIZE
; The following defines describe a 32K flash region used for EEPROM emulation.
; The following defines describe a 32K flash region used for EEPROM emulation.
; This region can also be used as the general purpose flash.
; You can assign sections to this memory region for only one of the cores.
; Note some middleware (e.g. BLE, Emulated EEPROM) can place their data into this memory region.
@ -84,7 +100,7 @@
#define EFUSE_SIZE 0x100000
LR_IROM1 FLASH_START FLASH_SIZE
LR_IROM1 FLASH_START (FLASH_SIZE - 0x8000)
{
.cy_app_header +0
{

View File

@ -28,6 +28,21 @@ SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
ENTRY(Reset_Handler)
#if !defined(MBED_ROM_START)
#define MBED_ROM_START 0x10000000
#endif
#if !defined(MBED_ROM_SIZE)
#define MBED_ROM_SIZE 0x80000
#endif
#if !defined(MBED_RAM_START)
#define MBED_RAM_START 0x08000000
#endif
#if !defined(MBED_RAM_SIZE)
#define MBED_RAM_SIZE 0x10000
#endif
/* Force symbol to be entered in the output file as an undefined symbol. Doing
* this may, for example, trigger linking of additional modules from standard
@ -47,8 +62,8 @@ MEMORY
* Your changes must be aligned with the corresponding memory regions for the CM4 core in 'xx_cm4_dual.ld',
* where 'xx' is the device group; for example, 'cy8c6xx7_cm4_dual.ld'.
*/
ram (rwx) : ORIGIN = 0x08000000, LENGTH = 0x10000
flash (rx) : ORIGIN = 0x10000000, LENGTH = 0x78000
ram (rwx) : ORIGIN = MBED_RAM_START, LENGTH = MBED_RAM_SIZE
flash (rx) : ORIGIN = MBED_ROM_START, LENGTH = (MBED_ROM_SIZE - 0x8000)
/* This is a 32K flash region used for EEPROM emulation. This region can also be used as the general purpose flash.
* You can assign sections to this memory region for only one of the cores.
@ -333,7 +348,7 @@ SECTIONS
KEEP(*(.cy_toc_part2))
} > sflash_toc_2
/* Supervisory Flash: Table of Content # 2 Copy */
.cy_rtoc_part2 :
{

View File

@ -29,6 +29,22 @@
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
if (!isdefinedsymbol(MBED_ROM_START)) {
define symbol MBED_ROM_START = 0x10000000;
}
if (!isdefinedsymbol(MBED_ROM_SIZE)) {
define symbol MBED_ROM_SIZE = 0x80000;
}
if (!isdefinedsymbol(MBED_RAM_START)) {
define symbol MBED_RAM_START = 0x08000000;
}
if (!isdefinedsymbol(MBED_RAM_SIZE)) {
define symbol MBED_RAM_SIZE = 0x10000;
}
/* The symbols below define the location and size of blocks of memory in the target.
* Use these symbols to specify the memory regions available for allocation.
*/
@ -39,11 +55,11 @@ define symbol __ICFEDIT_intvec_start__ = 0x00000000;
* where 'xx' is the device group; for example, 'cy8c6xx7_cm4_dual.icf'.
*/
/* RAM */
define symbol __ICFEDIT_region_IRAM1_start__ = 0x08000000;
define symbol __ICFEDIT_region_IRAM1_end__ = 0x08010000;
define symbol __ICFEDIT_region_IRAM1_start__ = MBED_RAM_START;
define symbol __ICFEDIT_region_IRAM1_end__ = (MBED_RAM_START + MBED_RAM_SIZE);
/* Flash */
define symbol __ICFEDIT_region_IROM1_start__ = 0x10000000;
define symbol __ICFEDIT_region_IROM1_end__ = 0x10078000;
define symbol __ICFEDIT_region_IROM1_start__ = MBED_ROM_START;
define symbol __ICFEDIT_region_IROM1_end__ = (MBED_ROM_START + MBED_ROM_SIZE - 0x8000);
/* The following symbols define a 32K flash region used for EEPROM emulation.
* This region can also be used as the general purpose flash.

View File

@ -153,6 +153,9 @@ void mbed_sdk_init(void)
ipcrpc_init();
}
#if defined(COMPONENT_SPM_MAILBOX)
void mailbox_init(void);
#endif
/*******************************************************************************
* Function Name: SystemInit
@ -189,6 +192,10 @@ void SystemInit(void)
Cy_SystemInit();
SystemCoreClockUpdate();
#if defined(COMPONENT_SPM_MAILBOX)
mailbox_init();
#endif
#if defined(CY_DEVICE_PSOC6ABLE2)
#if !defined(CY_IPC_DEFAULT_CFG_DISABLE)
/* Allocate and initialize semaphores for the system operations. */

View File

@ -30,6 +30,22 @@
;* SPDX-License-Identifier: Apache-2.0
;******************************************************************************/
#if !defined(MBED_ROM_START)
#define MBED_ROM_START 0x10080000
#endif
#if !defined(MBED_ROM_SIZE)
#define MBED_ROM_SIZE 0x78000
#endif
#if !defined(MBED_RAM_START)
#define MBED_RAM_START 0x08010000
#endif
#if !defined(MBED_RAM_SIZE)
#define MBED_RAM_SIZE 0x37800
#endif
; The defines below describe the location and size of blocks of memory in the target.
; Use these defines to specify the memory regions available for allocation.
@ -41,12 +57,12 @@
; where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.scat'.
; RAM
; RAM
#define RAM_START 0x08010000
#define RAM_SIZE 0x00037800
#define RAM_START MBED_RAM_START
#define RAM_SIZE MBED_RAM_SIZE
; Flash
; Flash
#define FLASH_START 0x10080000
#define FLASH_SIZE 0x00078000
#define FLASH_START MBED_ROM_START
#define FLASH_SIZE MBED_ROM_SIZE
; The following defines describe a 32K flash region used for EEPROM emulation.
; This region can also be used as the general purpose flash.

View File

@ -28,6 +28,21 @@ SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
ENTRY(Reset_Handler)
#if !defined(MBED_ROM_START)
#define MBED_ROM_START 0x10080000
#endif
#if !defined(MBED_ROM_SIZE)
#define MBED_ROM_SIZE 0x78000
#endif
#if !defined(MBED_RAM_START)
#define MBED_RAM_START 0x08010000
#endif
#if !defined(MBED_RAM_SIZE)
#define MBED_RAM_SIZE 0x37800
#endif
/* Force symbol to be entered in the output file as an undefined symbol. Doing
* this may, for example, trigger linking of additional modules from standard
@ -49,8 +64,8 @@ MEMORY
* Your changes must be aligned with the corresponding memory regions for CM0+ core in 'xx_cm0plus.ld',
* where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.ld'.
*/
ram (rwx) : ORIGIN = 0x08010000, LENGTH = 0x37800
flash (rx) : ORIGIN = 0x10080000, LENGTH = 0x78000
ram (rwx) : ORIGIN = MBED_RAM_START, LENGTH = MBED_RAM_SIZE
flash (rx) : ORIGIN = MBED_ROM_START, LENGTH = MBED_ROM_SIZE
/* This is a 32K flash region used for EEPROM emulation. This region can also be used as the general purpose flash.
* You can assign sections to this memory region for only one of the cores.
@ -339,7 +354,7 @@ SECTIONS
KEEP(*(.cy_toc_part2))
} > sflash_toc_2
/* Supervisory Flash: Table of Content # 2 Copy */
.cy_rtoc_part2 :
{

View File

@ -29,6 +29,22 @@
/*-Specials-*/
define symbol __ICFEDIT_intvec_start__ = 0x00000000;
if (!isdefinedsymbol(MBED_ROM_START)) {
define symbol MBED_ROM_START = 0x10080000;
}
if (!isdefinedsymbol(MBED_ROM_SIZE)) {
define symbol MBED_ROM_SIZE = 0x78000;
}
if (!isdefinedsymbol(MBED_RAM_START)) {
define symbol MBED_RAM_START = 0x08010000;
}
if (!isdefinedsymbol(MBED_RAM_SIZE)) {
define symbol MBED_RAM_SIZE = 0x37800;
}
/* The symbols below define the location and size of blocks of memory in the target.
* Use these symbols to specify the memory regions available for allocation.
*/
@ -41,11 +57,11 @@ define symbol __ICFEDIT_intvec_start__ = 0x00000000;
* where 'xx' is the device group; for example, 'cy8c6xx7_cm0plus.icf'.
*/
/* RAM */
define symbol __ICFEDIT_region_IRAM1_start__ = 0x08010000;
define symbol __ICFEDIT_region_IRAM1_end__ = 0x08047800;
define symbol __ICFEDIT_region_IRAM1_start__ = MBED_RAM_START;
define symbol __ICFEDIT_region_IRAM1_end__ = (MBED_RAM_START + MBED_RAM_SIZE);
/* Flash */
define symbol __ICFEDIT_region_IROM1_start__ = 0x10080000;
define symbol __ICFEDIT_region_IROM1_end__ = 0x100F8000;
define symbol __ICFEDIT_region_IROM1_start__ = MBED_ROM_START;
define symbol __ICFEDIT_region_IROM1_end__ = (MBED_ROM_START + MBED_ROM_SIZE);
/* The following symbols define a 32K flash region used for EEPROM emulation.
* This region can also be used as the general purpose flash.

View File

@ -124,6 +124,9 @@ uint32_t cy_delay32kMs = CY_DELAY_MS_OVERFLOW_THRESHOLD *
#define CY_ROOT_PATH_SRC_DSI_MUX_PILO (19UL)
#endif /* (SRSS_PILO_PRESENT == 1U) */
#if defined(COMPONENT_SPM_MAILBOX)
void mailbox_init(void);
#endif
/*******************************************************************************
* Function Name: SystemInit
@ -161,6 +164,10 @@ void SystemInit(void)
Cy_SystemInit();
SystemCoreClockUpdate();
#if defined(COMPONENT_SPM_MAILBOX)
mailbox_init();
#endif
}

View File

@ -0,0 +1,983 @@
/* mbed Microcontroller Library
*
* \copyright
* (c) 2018, Cypress Semiconductor Corporation
* or a subsidiary of Cypress Semiconductor Corporation. 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 "cyprotection.h"
/* configure SMPU */
cy_en_prot_status_t smpu_protect(cy_smpu_region_config_t smpu_config_arr[], uint32_t arr_length)
{
cy_en_prot_status_t ret = CY_PROT_SUCCESS;
uint32_t i;
cy_stc_smpu_cfg_t smpu_cfg;
for (i = 0; i < arr_length; i++)
{
smpu_cfg.address = smpu_config_arr[i].address;
smpu_cfg.regionSize = smpu_config_arr[i].regionSize;
smpu_cfg.subregions = smpu_config_arr[i].subregions;
smpu_cfg.userPermission = smpu_config_arr[i].userPermission;
smpu_cfg.privPermission = smpu_config_arr[i].privPermission;
smpu_cfg.secure = smpu_config_arr[i].secure;
smpu_cfg.pcMatch = smpu_config_arr[i].pcMatch;
smpu_cfg.pcMask = smpu_config_arr[i].pcMask;
ret = Cy_Prot_ConfigSmpuSlaveStruct(smpu_config_arr[i].prot_region, &smpu_cfg);
if (ret != CY_PROT_SUCCESS)
{
break;
}
smpu_cfg.userPermission = smpu_config_arr[i].userMstPermission;
smpu_cfg.privPermission = smpu_config_arr[i].privMstPermission;
ret = Cy_Prot_ConfigSmpuMasterStruct(smpu_config_arr[i].prot_region, &smpu_cfg);
if (ret != CY_PROT_SUCCESS)
{
break;
}
ret = Cy_Prot_EnableSmpuSlaveStruct(smpu_config_arr[i].prot_region);
if (ret != CY_PROT_SUCCESS)
{
break;
}
ret = Cy_Prot_EnableSmpuMasterStruct(smpu_config_arr[i].prot_region);
if (ret != CY_PROT_SUCCESS)
{
break;
}
}
return ret;
}
/* configure PPU Fixed Region */
cy_en_prot_status_t ppu_fixed_rg_protect(cy_ppu_fixed_rg_cfg_t ppu_config_arr[], uint32_t arr_length)
{
cy_en_prot_status_t ret = CY_PROT_SUCCESS;
uint32_t i;
cy_stc_ppu_rg_cfg_t ppu_cfg;
for (i = 0; i < arr_length; i++)
{
ppu_cfg.userPermission = ppu_config_arr[i].userPermission;
ppu_cfg.privPermission = ppu_config_arr[i].privPermission;
ppu_cfg.secure = ppu_config_arr[i].secure;
ppu_cfg.pcMatch = ppu_config_arr[i].pcMatch;
ppu_cfg.pcMask = ppu_config_arr[i].pcMask;
ret = Cy_Prot_ConfigPpuFixedRgSlaveStruct(ppu_config_arr[i].pPpuStr, &ppu_cfg);
if (ret != CY_PROT_SUCCESS)
{
break;
}
ppu_cfg.userPermission = ppu_config_arr[i].userMstPermission;
ppu_cfg.privPermission = ppu_config_arr[i].privMstPermission;
ppu_cfg.secure = ppu_config_arr[i].secureMst;
ppu_cfg.pcMask = ppu_config_arr[i].pcMstMask;
ret = Cy_Prot_ConfigPpuFixedRgMasterStruct(ppu_config_arr[i].pPpuStr, &ppu_cfg);
if (ret != CY_PROT_SUCCESS)
{
break;
}
ret = Cy_Prot_EnablePpuFixedRgSlaveStruct(ppu_config_arr[i].pPpuStr);
if (ret != CY_PROT_SUCCESS)
{
break;
}
ret = Cy_Prot_EnablePpuFixedRgMasterStruct(ppu_config_arr[i].pPpuStr);
if (ret != CY_PROT_SUCCESS)
{
break;
}
}
return ret;
}
/* configure PPU Fixed Slave */
cy_en_prot_status_t ppu_fixed_sl_protect(cy_ppu_fixed_sl_cfg_t ppu_config_arr[], uint32_t arr_length)
{
cy_en_prot_status_t ret = CY_PROT_SUCCESS;
uint32_t i;
cy_stc_ppu_sl_cfg_t ppu_cfg;
for (i = 0; i < arr_length; i++)
{
ppu_cfg.userPermission = ppu_config_arr[i].userPermission;
ppu_cfg.privPermission = ppu_config_arr[i].privPermission;
ppu_cfg.secure = ppu_config_arr[i].secure;
ppu_cfg.pcMatch = ppu_config_arr[i].pcMatch;
ppu_cfg.pcMask = ppu_config_arr[i].pcMask;
ret = Cy_Prot_ConfigPpuFixedSlSlaveStruct(ppu_config_arr[i].pPpuStr, &ppu_cfg);
if (ret != CY_PROT_SUCCESS)
{
break;
}
ppu_cfg.userPermission = ppu_config_arr[i].userMstPermission;
ppu_cfg.privPermission = ppu_config_arr[i].privMstPermission;
ppu_cfg.secure = ppu_config_arr[i].secureMst;
ppu_cfg.pcMask = ppu_config_arr[i].pcMstMask;
ret = Cy_Prot_ConfigPpuFixedSlMasterStruct(ppu_config_arr[i].pPpuStr, &ppu_cfg);
if (ret != CY_PROT_SUCCESS)
{
break;
}
ret = Cy_Prot_EnablePpuFixedSlSlaveStruct(ppu_config_arr[i].pPpuStr);
if (ret != CY_PROT_SUCCESS)
{
break;
}
ret = Cy_Prot_EnablePpuFixedSlMasterStruct(ppu_config_arr[i].pPpuStr);
if (ret != CY_PROT_SUCCESS)
{
break;
}
}
return ret;
}
/* configure PPU Programmable */
cy_en_prot_status_t ppu_prog_protect(cy_ppu_prog_cfg_t ppu_config_arr[], uint32_t arr_length)
{
cy_en_prot_status_t ret = CY_PROT_SUCCESS;
uint32_t i;
cy_stc_ppu_prog_cfg_t ppu_cfg;
for (i = 0; i < arr_length; i++)
{
ppu_cfg.address = ppu_config_arr[i].address;
ppu_cfg.regionSize = ppu_config_arr[i].regionSize;
ppu_cfg.subregions = ppu_config_arr[i].subregions;
ppu_cfg.userPermission = ppu_config_arr[i].userPermission;
ppu_cfg.privPermission = ppu_config_arr[i].privPermission;
ppu_cfg.secure = ppu_config_arr[i].secure;
ppu_cfg.pcMatch = ppu_config_arr[i].pcMatch;
ppu_cfg.pcMask = ppu_config_arr[i].pcMask;
ret = Cy_Prot_ConfigPpuProgSlaveStruct(ppu_config_arr[i].pPpuStr, &ppu_cfg);
if (ret != CY_PROT_SUCCESS)
{
break;
}
ppu_cfg.userPermission = ppu_config_arr[i].userMstPermission;
ppu_cfg.privPermission = ppu_config_arr[i].privMstPermission;
ppu_cfg.secure = ppu_config_arr[i].secureMst;
ppu_cfg.pcMask = ppu_config_arr[i].pcMstMask;
ret = Cy_Prot_ConfigPpuProgMasterStruct(ppu_config_arr[i].pPpuStr, &ppu_cfg);
if (ret != CY_PROT_SUCCESS)
{
break;
}
ret = Cy_Prot_EnablePpuProgSlaveStruct(ppu_config_arr[i].pPpuStr);
if (ret != CY_PROT_SUCCESS)
{
break;
}
ret = Cy_Prot_EnablePpuProgMasterStruct(ppu_config_arr[i].pPpuStr);
if (ret != CY_PROT_SUCCESS)
{
break;
}
}
return ret;
}
/* configure PPU Fixed Group */
cy_en_prot_status_t ppu_fixed_gr_protect(cy_ppu_fixed_gr_cfg_t ppu_config_arr[], uint32_t arr_length)
{
cy_en_prot_status_t ret = CY_PROT_SUCCESS;
uint32_t i;
cy_stc_ppu_gr_cfg_t ppu_cfg;
for (i = 0; i < arr_length; i++)
{
ppu_cfg.userPermission = ppu_config_arr[i].userPermission;
ppu_cfg.privPermission = ppu_config_arr[i].privPermission;
ppu_cfg.secure = ppu_config_arr[i].secure;
ppu_cfg.pcMatch = ppu_config_arr[i].pcMatch;
ppu_cfg.pcMask = ppu_config_arr[i].pcMask;
ret = Cy_Prot_ConfigPpuFixedGrSlaveStruct(ppu_config_arr[i].pPpuStr, &ppu_cfg);
if (ret != CY_PROT_SUCCESS)
{
break;
}
ppu_cfg.userPermission = ppu_config_arr[i].userMstPermission;
ppu_cfg.privPermission = ppu_config_arr[i].privMstPermission;
ppu_cfg.secure = ppu_config_arr[i].secureMst;
ppu_cfg.pcMask = ppu_config_arr[i].pcMstMask;
ret = Cy_Prot_ConfigPpuFixedGrMasterStruct(ppu_config_arr[i].pPpuStr, &ppu_cfg);
if (ret != CY_PROT_SUCCESS)
{
break;
}
ret = Cy_Prot_EnablePpuFixedGrSlaveStruct(ppu_config_arr[i].pPpuStr);
if (ret != CY_PROT_SUCCESS)
{
break;
}
ret = Cy_Prot_EnablePpuFixedGrMasterStruct(ppu_config_arr[i].pPpuStr);
if (ret != CY_PROT_SUCCESS)
{
break;
}
}
return ret;
}
/* Set protection contexts for bus masters */
cy_en_prot_status_t bus_masters_protect(cy_bus_master_config_t bus_masters_config_arr[], uint32_t arr_length)
{
cy_en_prot_status_t ret = CY_PROT_SUCCESS;
uint32_t i;
for (i = 0; i < arr_length; i++)
{
ret = Cy_Prot_ConfigBusMaster(bus_masters_config_arr[i].busMaster, bus_masters_config_arr[i].privileged,
bus_masters_config_arr[i].secure, bus_masters_config_arr[i].pcMask);
if (ret != CY_PROT_SUCCESS)
{
break;
}
ret = Cy_Prot_SetActivePC(bus_masters_config_arr[i].busMaster, bus_masters_config_arr[i].act_pc);
if (ret != CY_PROT_SUCCESS)
{
break;
}
}
return ret;
}
/******************************************************************************
* Function Name: isProtRangeMatched
******************************************************************************
* Summary:
* The function checks whether a memory region is closed by SMPU for a master
*
* Parameters:
* uint32_t startAddrMem: memory address to be accessed
* uint32_t memSize: memory size to be accessed
* uint32_t startAddrSMPU: memory address from SMPU
* cy_en_prot_size_t log2RegionSizeSMPU: memory size from SMPU
* uint8_t regionDisableSMPU: disabled regions bitmap
*
* Return:
* uint8_t rangeMatches (values: 0 (no) /1 (yes))
*
* Calls:
* none
*
* Called by:
* isAccessAllowedSMPU, isAccessAllowedMPU
*
* Note:
*
*
*****************************************************************************/
static uint8_t isProtRangeMatched(uint32_t startAddrMem, uint32_t memSize, uint32_t startAddrSMPU,
cy_en_prot_size_t log2RegionSizeSMPU, uint8_t regionDisableSMPU)
{
uint8_t rangeMatches = 0;
uint8_t i;
uint64_t endAddrMem, endAddrSMPU;
uint64_t subRangeStartAddr, subRangeEndAddr;
endAddrMem = startAddrMem + memSize;
endAddrSMPU = startAddrSMPU + (1 << (log2RegionSizeSMPU + 1u));
if (((startAddrMem >= startAddrSMPU) && (startAddrMem <= endAddrSMPU)) ||
((startAddrSMPU >= startAddrMem) && (startAddrSMPU < endAddrMem)))
{
rangeMatches = 1;
}
/* log2RegionSizeSMPU should be >= 7 according to spec */
if ((rangeMatches == 1) && (log2RegionSizeSMPU > 1u))
{
rangeMatches = 0;
for (i = 0; i < MPU_SMPU_SUBREGIONS_NUMB; i++)
{
if (regionDisableSMPU & (1 << i))
{
continue;
}
subRangeStartAddr = startAddrSMPU + i * (1 << (log2RegionSizeSMPU - 2u));
subRangeEndAddr = startAddrSMPU + (i + 1) * (1 << (log2RegionSizeSMPU - 2u));
if (((startAddrMem >= subRangeStartAddr) && (startAddrMem <= subRangeEndAddr)) ||
((subRangeStartAddr >= startAddrMem) && (subRangeStartAddr < endAddrMem)))
{
rangeMatches = 1;
break;
}
}
}
return rangeMatches;
}
/******************************************************************************
* Function Name: isAccessAllowedFixedRgPPU
******************************************************************************
* Summary:
* The function checks whether a peripheral region is closed by Fixed Region PPU
*
* Parameters:
* uint32_t perStartAddr: peripheral region address to be accessed by master
* uint32_t perSize: peripheral memory size to be accessed by master
* uint8_t privModeFlag: Priviliged or nonproviliged master
* uint8_t nsecureFlag: Non-secure or secure master
* enum cy_en_prot_pc_t protectionCtx: Protection context of master
* cy_en_prot_perm_t accessType
*
* Return:
* uint8_t accessAllowed (values: 0 (no) /1 (yes))
*
* Calls:
* isProtRangeMatched
*
* Called by:
* isPeripheralAccessAllowed
*
* Note:
*
*
*****************************************************************************/
static uint8_t isAccessAllowedFixedRgPPU(uint32_t perStartAddr, uint32_t perSize,
uint8_t privModeFlag, uint8_t nsecureFlag, enum cy_en_prot_pc_t protectionCtx, cy_en_prot_perm_t accessType)
{
uint8_t accessAllowed = 1;
uint8_t i;
uint32_t att0, addr0, ppuAddr;
PERI_GR_PPU_RG_Type* pPpuRgStr;
uint32_t startAddrPPU, pcMaskPPU;
cy_en_prot_size_t log2RegionSizePPU;
uint8_t pcMatchPPU, nonSecureFlagPPU, regionDisablePPU;
cy_en_prot_perm_t permisionsPPU;
if (protectionCtx >= CY_PROT_PC1) /* if client is not in protection context 0 */
{
/* Matching process */
for (i = CPUSS_PROT_PPU_FX_RG_STRUCT_NR; i > 0; i--)
{
ppuAddr = CPUSS_PROT_PPU_FX_RG_START_ADDR + (i - 1) * PERI_GR_PPU_RG_SECTION_SIZE;
pPpuRgStr = (PERI_GR_PPU_RG_Type*) ppuAddr;
addr0 = pPpuRgStr->ADDR0;
att0 = pPpuRgStr->ATT0;
if (_FLD2VAL(PERI_PPU_PR_ATT0_ENABLED, att0) > 0)
{
pcMatchPPU = _FLD2VAL(PERI_PPU_PR_ATT0_PC_MATCH, att0);
pcMaskPPU = _FLD2VAL(PERI_PPU_PR_ATT0_PC_MASK_15_TO_1, att0);
if (!pcMatchPPU || (pcMatchPPU && (pcMaskPPU & (1 << (protectionCtx - 1u)))))
{
startAddrPPU = _FLD2VAL(PERI_PPU_PR_ADDR0_ADDR24, addr0) << CY_PROT_ADDR_SHIFT;
regionDisablePPU = _FLD2VAL(PERI_PPU_PR_ADDR0_SUBREGION_DISABLE, addr0);
log2RegionSizePPU = _FLD2VAL(PERI_PPU_PR_ATT0_REGION_SIZE, att0);
if (isProtRangeMatched(perStartAddr, perSize, startAddrPPU, log2RegionSizePPU, regionDisablePPU))
{
break;
}
}
}
}
if (i > 0)
{
/* Evaluation process */
nonSecureFlagPPU = _FLD2VAL(PERI_PPU_PR_ATT0_NS, att0);
if (privModeFlag)
{
permisionsPPU = ((att0 >> CY_PROT_ATT_PRIV_PERMISSION_SHIFT) & CY_PROT_ATT_PERMISSION_MASK);
}
else
{
permisionsPPU = (att0 & CY_PROT_ATT_PERMISSION_MASK);
}
if ((!(pcMaskPPU & (1 << (protectionCtx - 1u)))) ||
((!nonSecureFlagPPU) && nsecureFlag) ||
((accessType & permisionsPPU) != accessType))
{
accessAllowed = 0;
}
}
}
return accessAllowed;
}
/******************************************************************************
* Function Name: isAccessAllowedFixedSlPPU
******************************************************************************
* Summary:
* The function checks whether a peripheral region is closed by Fixed Slave PPU
*
* Parameters:
* uint32_t perStartAddr: peripheral region address to be accessed by master
* uint32_t perSize: peripheral memory size to be accessed by master
* uint8_t privModeFlag: Priviliged or nonproviliged master
* uint8_t nsecureFlag: Non-secure or secure master
* enum cy_en_prot_pc_t protectionCtx: Protection context of master
* cy_en_prot_perm_t accessType
*
* Return:
* uint8_t accessAllowed (values: 0 (no) /1 (yes))
*
* Calls:
* isProtRangeMatched
*
* Called by:
* isPeripheralAccessAllowed
*
* Note:
*
*
*****************************************************************************/
static uint8_t isAccessAllowedFixedSlPPU(uint32_t perStartAddr, uint32_t perSize,
uint8_t privModeFlag, uint8_t nsecureFlag, enum cy_en_prot_pc_t protectionCtx, cy_en_prot_perm_t accessType)
{
uint8_t accessAllowed = 1;
uint8_t i, j;
uint32_t att0, addr0;
uint32_t grAddr0, ppuAddr;
PERI_GR_PPU_SL_Type* pPpuSlStr;
uint32_t startAddrPPU, pcMaskPPU;
cy_en_prot_size_t log2RegionSizePPU;
uint8_t pcMatchPPU, nonSecureFlagPPU, regionDisablePPU;
cy_en_prot_perm_t permisionsPPU;
const uint32_t fixedRgMasks[CPUSS_PROT_PPU_GR_STRUCT_NR] = {
0x0,
PERI_PPU_GR_MMIO1_EXIST_BITMASK,
PERI_PPU_GR_MMIO2_EXIST_BITMASK,
PERI_PPU_GR_MMIO3_EXIST_BITMASK,
PERI_PPU_GR_MMIO4_EXIST_BITMASK,
0x0,
PERI_PPU_GR_MMIO6_EXIST_BITMASK,
0x0,
0x0,
PERI_PPU_GR_MMIO9_EXIST_BITMASK,
PERI_PPU_GR_MMIO10_EXIST_BITMASK,
0x0,
0x0,
0x0,
0x0,
0x0
};
if (protectionCtx >= CY_PROT_PC1) /* if client is not in protection context 0 */
{
/* Matching process */
for (i = CPUSS_PROT_PPU_GR_STRUCT_NR; i > 0; i--)
{
if (PERI_PPU_GR_MMIO_EXIST_BITMASK & (1<<(i - 1)))
{
grAddr0 = PERI->PPU_GR[i - 1].ADDR0;
for (j = CPUSS_PROT_PPU_FX_SL_STRUCT_NR; j > 0; j--)
{
if (fixedRgMasks[i - 1] & (1<<(j - 1)))
{
ppuAddr = grAddr0 + (j - 1) * PERI_GR_PPU_RG_SECTION_SIZE;
pPpuSlStr = (PERI_GR_PPU_SL_Type*) ppuAddr;
addr0 = pPpuSlStr->ADDR0;
att0 = pPpuSlStr->ATT0;
if (_FLD2VAL(PERI_GR_PPU_SL_ATT0_ENABLED, att0) > 0)
{
pcMatchPPU = _FLD2VAL(PERI_GR_PPU_SL_ATT0_PC_MATCH, att0);
pcMaskPPU = _FLD2VAL(PERI_GR_PPU_SL_ATT0_PC_MASK_15_TO_1, att0);
if (!pcMatchPPU || (pcMatchPPU && (pcMaskPPU & (1 << (protectionCtx - 1u)))))
{
startAddrPPU = _FLD2VAL(PERI_GR_PPU_SL_ADDR0_ADDR24, addr0) << CY_PROT_ADDR_SHIFT;
regionDisablePPU = _FLD2VAL(PERI_GR_PPU_SL_ADDR0_SUBREGION_DISABLE, addr0);
log2RegionSizePPU = _FLD2VAL(PERI_GR_PPU_SL_ATT0_REGION_SIZE, att0);
if (isProtRangeMatched(perStartAddr, perSize, startAddrPPU, log2RegionSizePPU, regionDisablePPU))
{
break;
}
}
}
}
}
if (j > 0)
{
break;
}
}
}
if (i > 0)
{
/* Evaluation process */
nonSecureFlagPPU = _FLD2VAL(PERI_GR_PPU_SL_ATT0_NS, att0);
if (privModeFlag)
{
permisionsPPU = ((att0 >> CY_PROT_ATT_PRIV_PERMISSION_SHIFT) & CY_PROT_ATT_PERMISSION_MASK);
}
else
{
permisionsPPU = (att0 & CY_PROT_ATT_PERMISSION_MASK);
}
if ((!(pcMaskPPU & (1 << (protectionCtx - 1u)))) ||
((!nonSecureFlagPPU) && nsecureFlag) ||
((accessType & permisionsPPU) != accessType))
{
accessAllowed = 0;
}
}
}
return accessAllowed;
}
/******************************************************************************
* Function Name: isAccessAllowedProgPPU
******************************************************************************
* Summary:
* The function checks whether a peripheral region is closed by Programmable PPU
*
* Parameters:
* uint32_t perStartAddr: peripheral region address to be accessed by master
* uint32_t perSize: peripheral memory size to be accessed by master
* uint8_t privModeFlag: Priviliged or nonproviliged master
* uint8_t nsecureFlag: Non-secure or secure master
* enum cy_en_prot_pc_t protectionCtx: Protection context of master
* cy_en_prot_perm_t accessType
*
* Return:
* uint8_t accessAllowed (values: 0 (no) /1 (yes))
*
* Calls:
* isProtRangeMatched
*
* Called by:
* isPeripheralAccessAllowed
*
* Note:
*
*
*****************************************************************************/
static uint8_t isAccessAllowedProgPPU(uint32_t perStartAddr, uint32_t perSize,
uint8_t privModeFlag, uint8_t nsecureFlag, enum cy_en_prot_pc_t protectionCtx, cy_en_prot_perm_t accessType)
{
uint8_t accessAllowed = 1;
uint8_t i;
uint32_t att0, addr0;
uint32_t startAddrPPU, pcMaskPPU;
cy_en_prot_size_t log2RegionSizePPU;
uint8_t pcMatchPPU, nonSecureFlagPPU, regionDisablePPU;
cy_en_prot_perm_t permisionsPPU;
if (protectionCtx >= CY_PROT_PC1) /* if client is not in protection context 0 */
{
/* Matching process */
for (i = CPUSS_PROT_PPU_PROG_STRUCT_NR; i > 0; i--)
{
addr0 = PERI->PPU_PR[i - 1].ADDR0;
att0 = PERI->PPU_PR[i - 1].ATT0;
if (_FLD2VAL(PERI_PPU_PR_ATT0_ENABLED, att0) > 0)
{
pcMatchPPU = _FLD2VAL(PERI_PPU_PR_ATT0_PC_MATCH, att0);
pcMaskPPU = _FLD2VAL(PERI_PPU_PR_ATT0_PC_MASK_15_TO_1, att0);
if (!pcMatchPPU || (pcMatchPPU && (pcMaskPPU & (1 << (protectionCtx - 1u)))))
{
startAddrPPU = _FLD2VAL(PERI_PPU_PR_ADDR0_ADDR24, addr0) << CY_PROT_ADDR_SHIFT;
regionDisablePPU = _FLD2VAL(PERI_PPU_PR_ADDR0_SUBREGION_DISABLE, addr0);
log2RegionSizePPU = _FLD2VAL(PERI_PPU_PR_ATT0_REGION_SIZE, att0);
if (isProtRangeMatched(perStartAddr, perSize, startAddrPPU, log2RegionSizePPU, regionDisablePPU))
{
break;
}
}
}
}
if (i > 0)
{
/* Evaluation process */
nonSecureFlagPPU = _FLD2VAL(PERI_PPU_PR_ATT0_NS, att0);
if (privModeFlag)
{
permisionsPPU = ((att0 >> CY_PROT_ATT_PRIV_PERMISSION_SHIFT) & CY_PROT_ATT_PERMISSION_MASK);
}
else
{
permisionsPPU = (att0 & CY_PROT_ATT_PERMISSION_MASK);
}
if ((!(pcMaskPPU & (1 << (protectionCtx - 1u)))) ||
((!nonSecureFlagPPU) && nsecureFlag) ||
((accessType & permisionsPPU) != accessType))
{
accessAllowed = 0;
}
}
}
return accessAllowed;
}
/******************************************************************************
* Function Name: isAccessAllowedGrPPU
******************************************************************************
* Summary:
* The function checks whether a peripheral region is closed by Group PPU
*
* Parameters:
* uint32_t perStartAddr: peripheral region address to be accessed by master
* uint32_t perSize: peripheral memory size to be accessed by master
* uint8_t privModeFlag: Priviliged or nonproviliged master
* uint8_t nsecureFlag: Non-secure or secure master
* enum cy_en_prot_pc_t protectionCtx: Protection context of master
* cy_en_prot_perm_t accessType
*
* Return:
* uint8_t accessAllowed (values: 0 (no) /1 (yes))
*
* Calls:
* isProtRangeMatched
*
* Called by:
* isPeripheralAccessAllowed
*
* Note:
*
*
*****************************************************************************/
static uint8_t isAccessAllowedGrPPU(uint32_t perStartAddr, uint32_t perSize,
uint8_t privModeFlag, uint8_t nsecureFlag, enum cy_en_prot_pc_t protectionCtx, cy_en_prot_perm_t accessType)
{
uint8_t accessAllowed = 1;
uint8_t i;
uint32_t att0, addr0;
uint32_t startAddrPPU, pcMaskPPU;
cy_en_prot_size_t log2RegionSizePPU;
uint8_t pcMatchPPU, nonSecureFlagPPU, regionDisablePPU;
cy_en_prot_perm_t permisionsPPU;
if (protectionCtx >= CY_PROT_PC1) /* if client is not in protection context 0 */
{
/* Matching process */
for (i = CPUSS_PROT_PPU_GR_STRUCT_NR; i > 0; i--)
{
if (PERI_PPU_GR_MMIO_EXIST_BITMASK & (1<<(i - 1)))
{
addr0 = PERI->PPU_GR[i - 1].ADDR0;
att0 = PERI->PPU_GR[i - 1].ATT0;
if (_FLD2VAL(PERI_PPU_GR_ATT0_ENABLED, att0) > 0)
{
pcMatchPPU = _FLD2VAL(PERI_PPU_GR_ATT0_PC_MATCH, att0);
pcMaskPPU = _FLD2VAL(PERI_PPU_GR_ATT0_PC_MASK_15_TO_1, att0);
if (!pcMatchPPU || (pcMatchPPU && (pcMaskPPU & (1 << (protectionCtx - 1u)))))
{
startAddrPPU = _FLD2VAL(PERI_PPU_GR_ADDR0_ADDR24, addr0) << CY_PROT_ADDR_SHIFT;
regionDisablePPU = _FLD2VAL(PERI_PPU_GR_ADDR0_SUBREGION_DISABLE, addr0);
log2RegionSizePPU = _FLD2VAL(PERI_PPU_GR_ATT0_REGION_SIZE, att0);
if (isProtRangeMatched(perStartAddr, perSize, startAddrPPU, log2RegionSizePPU, regionDisablePPU))
{
break;
}
}
}
}
}
if (i > 0)
{
/* Evaluation process */
nonSecureFlagPPU = _FLD2VAL(PERI_PPU_GR_ATT0_NS, att0);
if (privModeFlag)
{
permisionsPPU = ((att0 >> CY_PROT_ATT_PRIV_PERMISSION_SHIFT) & CY_PROT_ATT_PERMISSION_MASK);
}
else
{
permisionsPPU = (att0 & CY_PROT_ATT_PERMISSION_MASK);
}
if ((!(pcMaskPPU & (1 << (protectionCtx - 1u)))) ||
((!nonSecureFlagPPU) && nsecureFlag) ||
((accessType & permisionsPPU) != accessType))
{
accessAllowed = 0;
}
}
}
return accessAllowed;
}
/******************************************************************************
* Function Name: isPeripheralAccessAllowed
******************************************************************************
* Summary:
* Checks if the given peripheral region is protected by PPU
*
* Parameters:
* uint32_t perStartAddr: peripheral region address to be accessed by master
* uint32_t perSize: peripheral memory size to be accessed by master
* uint8_t privModeFlag: Priviliged or nonproviliged master
* uint8_t nsecureFlag: Non-secure or secure master
* enum cy_en_prot_pc_t protectionCtx: Protection context of master
* cy_en_prot_perm_t accessType
*
* Return:
* uint8_t accessAllowed (values: 0 (no) /1 (yes))
*
* Calls:
* isAccessAllowedGrPPU, isAccessAllowedProgPPU, isAccessAllowedFixedPPU,
* isAccessAllowedRegionPPU
*
* Called by:
* none
*
* Note:
*
*
*****************************************************************************/
uint8_t isPeripheralAccessAllowed(uint32_t perStartAddr, uint32_t perSize,
uint8_t privModeFlag, uint8_t nsecureFlag, enum cy_en_prot_pc_t protectionCtx, cy_en_prot_perm_t accessType)
{
uint8_t accessAllowed;
accessAllowed = isAccessAllowedGrPPU(perStartAddr, perSize, privModeFlag, nsecureFlag, protectionCtx, accessType);
if (accessAllowed)
{
accessAllowed = isAccessAllowedProgPPU(perStartAddr, perSize, privModeFlag, nsecureFlag, protectionCtx, accessType);
}
if (accessAllowed)
{
accessAllowed = isAccessAllowedFixedSlPPU(perStartAddr, perSize, privModeFlag, nsecureFlag, protectionCtx, accessType);
}
if (accessAllowed)
{
accessAllowed = isAccessAllowedFixedRgPPU(perStartAddr, perSize, privModeFlag, nsecureFlag, protectionCtx, accessType);
}
return accessAllowed;
}
/******************************************************************************
* Function Name: isAccessAllowedSMPU
******************************************************************************
* Summary:
* The function checks whether a memory region is closed by SMPU for a master
*
* Parameters:
* uint32_t memStartAddr: memory address to be accessed by master
* uint32_t memSize: memory size to be accessed by master
* uint8_t privModeFlag: Priviliged or nonproviliged master
* uint8_t nsecureFlag: Non-secure or secure master
* enum cy_en_prot_pc_t protectionCtx: Protection context of master
* cy_en_prot_perm_t accessType
*
* Return:
* uint8_t accessAllowed (values: 0 (no) /1 (yes))
*
* Calls:
* isProtRangeMatched
*
* Called by:
* CheckMemoryProtection
*
* Note:
*
*
*****************************************************************************/
static uint8_t isAccessAllowedSMPU(uint32_t memStartAddr, uint32_t memSize,
uint8_t privModeFlag, uint8_t nsecureFlag, enum cy_en_prot_pc_t protectionCtx, cy_en_prot_perm_t accessType)
{
uint8_t accessAllowed = 1;
uint8_t i;
uint32_t att0, addr0;
uint32_t startAddrSMPU, pcMaskSMPU;
cy_en_prot_size_t log2RegionSizeSMPU;
uint8_t pcMatchSMPU, nonSecureFlagSMPU, regionDisableSMPU;
cy_en_prot_perm_t permisionsSMPU;
if (protectionCtx >= CY_PROT_PC1) /* if client is not in protection context 0 */
{
/* Matching process */
/* SMPU with higher index has higher priority */
for (i = CPUSS_PROT_SMPU_STRUCT_NR; i > 0; i--)
{
addr0 = PROT->SMPU.SMPU_STRUCT[i - 1].ADDR0;
att0 = PROT->SMPU.SMPU_STRUCT[i - 1].ATT0;
if (_FLD2VAL(PROT_SMPU_SMPU_STRUCT_ATT0_ENABLED, att0) > 0)
{
pcMatchSMPU = _FLD2VAL(PROT_SMPU_SMPU_STRUCT_ATT0_PC_MATCH, att0);
pcMaskSMPU = _FLD2VAL(PROT_SMPU_SMPU_STRUCT_ATT0_PC_MASK_15_TO_1, att0);
if (!pcMatchSMPU || (pcMatchSMPU && (pcMaskSMPU & (1 << (protectionCtx - 1u)))))
{
startAddrSMPU = _FLD2VAL(PROT_SMPU_SMPU_STRUCT_ADDR0_ADDR24, addr0) << CY_PROT_ADDR_SHIFT;
regionDisableSMPU = _FLD2VAL(PROT_SMPU_SMPU_STRUCT_ADDR0_SUBREGION_DISABLE, addr0);
log2RegionSizeSMPU = _FLD2VAL(PROT_SMPU_SMPU_STRUCT_ATT0_REGION_SIZE, att0);
if (isProtRangeMatched(memStartAddr, memSize, startAddrSMPU, log2RegionSizeSMPU, regionDisableSMPU))
{
break;
}
}
}
}
if (i > 0)
{
/* Evaluation process */
nonSecureFlagSMPU = _FLD2VAL(PROT_SMPU_SMPU_STRUCT_ATT0_NS, att0);
if (privModeFlag)
{
permisionsSMPU = ((att0 >> CY_PROT_ATT_PRIV_PERMISSION_SHIFT) & CY_PROT_ATT_PERMISSION_MASK);
}
else
{
permisionsSMPU = (att0 & CY_PROT_ATT_PERMISSION_MASK);
}
if ((!(pcMaskSMPU & (1 << (protectionCtx - 1u)))) ||
((!nonSecureFlagSMPU) && nsecureFlag) ||
((accessType & permisionsSMPU) != accessType))
{
accessAllowed = 0;
}
}
}
return accessAllowed;
}
/******************************************************************************
* Function Name: isAccessAllowedMPU
******************************************************************************
* Summary:
* The function checks whether a memory region is closed by MPU for a master
*
* Parameters:
* uint32_t memStartAddr: memory address to be accessed by master
* uint32_t memSize: memory size to be accessed by master
* uint8_t privModeFlag: Priviliged or nonproviliged master
* uint8_t nsecureFlag: Non-secure or secure master
* cy_en_prot_perm_t accessType
*
* Return:
* uint8_t accessAllowed (values: 0 (no) /1 (yes))
*
* Calls:
* isProtRangeMatched
*
* Called by:
* CheckMemoryProtection
*
* Note:
*
*
*****************************************************************************/
static uint8_t isAccessAllowedMPU(uint32_t memStartAddr, uint32_t memSize,
uint8_t privModeFlag, uint8_t nsecureFlag, cy_en_prot_perm_t accessType)
{
uint8_t accessAllowed = 1;
uint8_t i;
uint32_t att, addr;
uint32_t startAddrMPU;
cy_en_prot_size_t log2RegionSizeMPU;
uint8_t nonSecureFlagMPU, regionDisableMPU;
cy_en_prot_perm_t permisionsMPU;
/* Matching process */
/* MPU with higher index has higher priority */
for (i = CPUSS_PROT_MPU_STRUCT_NR; i > 0; i--)
{
addr = PROT->CYMPU[1].MPU_STRUCT[i - 1].ADDR;
att = PROT->CYMPU[1].MPU_STRUCT[i - 1].ATT;
if (_FLD2VAL(PROT_MPU_MPU_STRUCT_ATT_ENABLED, att) > 0)
{
startAddrMPU = _FLD2VAL(PROT_MPU_MPU_STRUCT_ADDR_ADDR24, addr) << CY_PROT_ADDR_SHIFT;
regionDisableMPU = _FLD2VAL(PROT_MPU_MPU_STRUCT_ADDR_SUBREGION_DISABLE, addr);
log2RegionSizeMPU = _FLD2VAL(PROT_MPU_MPU_STRUCT_ATT_REGION_SIZE, att);
if (isProtRangeMatched(memStartAddr, memSize, startAddrMPU, log2RegionSizeMPU, regionDisableMPU))
{
break;
}
}
}
if (i > 0)
{
/* Evaluation process */
nonSecureFlagMPU = _FLD2VAL(PROT_MPU_MPU_STRUCT_ATT_NS, att);
if (privModeFlag)
{
permisionsMPU = ((att >> CY_PROT_ATT_PRIV_PERMISSION_SHIFT) & CY_PROT_ATT_PERMISSION_MASK);
}
else
{
permisionsMPU = (att & CY_PROT_ATT_PERMISSION_MASK);
}
if (((!nonSecureFlagMPU) && nsecureFlag) ||
((accessType & permisionsMPU) != accessType))
{
accessAllowed = 0;
}
}
return accessAllowed;
}
/******************************************************************************
* Function Name: isMemoryAccessAllowed
******************************************************************************
* Summary:
* Checks if the given memory region is protected
*
* Parameters:
* uint32_t memStartAddr: memory address to be accessed by master
* uint32_t memSize: memory size to be accessed by master
* uint8_t privModeFlag: Priviliged or nonproviliged master
* uint8_t nsecureFlag: Non-secure or secure master
* enum cy_en_prot_pc_t protectionCtx: Protection context of master
* cy_en_prot_perm_t accessType
*
* Return:
* uint8_t accessAllowed (values: 0 (no) /1 (yes))
*
* Calls:
* CheckEnabledMPUProtection, isAccessAllowedSMPU
*
* Called by:
* none
*
* Note:
*
*
*****************************************************************************/
uint8_t isMemoryAccessAllowed(uint32_t memStartAddr, uint32_t memSize,
uint8_t privModeFlag, uint8_t nsecureFlag, enum cy_en_prot_pc_t protectionCtx, cy_en_prot_perm_t accessType)
{
uint8_t accessAllowed;
accessAllowed = isAccessAllowedMPU(memStartAddr, memSize, privModeFlag, nsecureFlag, accessType);
if (accessAllowed)
{
accessAllowed = isAccessAllowedSMPU(memStartAddr, memSize, privModeFlag, nsecureFlag, protectionCtx, accessType);
}
return accessAllowed;
}

View File

@ -0,0 +1,164 @@
/* mbed Microcontroller Library
*
* \copyright
* (c) 2018, Cypress Semiconductor Corporation
* or a subsidiary of Cypress Semiconductor Corporation. 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 _CYPROTECTION_H_
#define _CYPROTECTION_H_
#include "cy_prot.h"
#define MPU_SMPU_SUBREGIONS_NUMB (8u)
/* MPU is not used yet */
#define CPUSS_PROT_MPU_STRUCT_NR (0u)
#define CPUSS_PROT_PPU_GR_STRUCT_NR (16u)
#define CPUSS_PROT_PPU_PROG_STRUCT_NR (16u)
#define CPUSS_PROT_PPU_FX_SL_STRUCT_NR (16u)
#define CPUSS_PROT_PPU_FX_RG_STRUCT_NR (29u)
#define CPUSS_PROT_PPU_FX_RG_START_ADDR (0x40201000UL)
#define PRIVILEGED_MODE (1u)
#define UNPRIVILEGED_MODE (0u)
#define NONSECURE_MODE (1u)
#define SECURE_MODE (0u)
/* PPU Group existing bitmask - 11001011111 */
#define PERI_PPU_GR_MMIO_EXIST_BITMASK 0x65F
/* PPU MMIO1 Group Fixed Region existing bitmask - 10 */
#define PERI_PPU_GR_MMIO1_EXIST_BITMASK 0x2
/* PPU MMIO2 Group Fixed Region existing bitmask - 11001111111111 */
#define PERI_PPU_GR_MMIO2_EXIST_BITMASK 0x33FF
/* PPU MMIO3 Group Fixed Region existing bitmask - 1111101111111 */
#define PERI_PPU_GR_MMIO3_EXIST_BITMASK 0x1F7F
/* PPU MMIO4 Group Fixed Region existing bitmask - 101 */
#define PERI_PPU_GR_MMIO4_EXIST_BITMASK 0x5
/* PPU MMIO6 Group Fixed Region existing bitmask - 1111111111 */
#define PERI_PPU_GR_MMIO6_EXIST_BITMASK 0x3FF
/* PPU MMIO9 Group Fixed Region existing bitmask - 11 */
#define PERI_PPU_GR_MMIO9_EXIST_BITMASK 0x3
/* PPU MMIO10 Group Fixed Region existing bitmask - 111 */
#define PERI_PPU_GR_MMIO10_EXIST_BITMASK 0x7
/* TODO: There is no SWPU configuration part */
typedef struct {
uint32_t* address; /**< Base address of the memory region (Only applicable to slave) */
cy_en_prot_size_t regionSize; /**< Size of the memory region (Only applicable to slave) */
uint8_t subregions; /**< Mask of the 8 subregions to disable (Only applicable to slave) */
cy_en_prot_perm_t userPermission; /**< User permissions for the region */
cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
bool secure; /**< Non Secure = 0, Secure = 1 */
bool pcMatch; /**< Access evaluation = 0, Matching = 1 */
uint16_t pcMask; /**< Mask of allowed protection context(s) */
PROT_SMPU_SMPU_STRUCT_Type* prot_region; /* protection region */
cy_en_prot_perm_t userMstPermission; /**< User permissions for the region */
cy_en_prot_perm_t privMstPermission; /**< Privileged permissions for the region */
} cy_smpu_region_config_t;
/*
* See Cy_Prot_ConfigBusMaster function description for parameters meaning
*
* act_pcMask specifies active PC for Cy_Prot_SetActivePC function
*/
typedef struct {
en_prot_master_t busMaster;
bool privileged;
bool secure;
uint32_t pcMask;
uint32_t act_pc;
} cy_bus_master_config_t;
/** Configuration structure for Fixed Group (GR) PPU (PPU_GR) struct initialization */
typedef struct
{
cy_en_prot_perm_t userPermission; /**< User permissions for the region */
cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
bool secure; /**< Non Secure = 0, Secure = 1 */
bool pcMatch; /**< Access evaluation = 0, Matching = 1 */
uint16_t pcMask; /**< Mask of allowed protection context(s) */
cy_en_prot_perm_t userMstPermission; /**< Master User permissions for the region */
cy_en_prot_perm_t privMstPermission; /**< Master Privileged permissions for the region */
bool secureMst; /**< Non Secure = 0, Secure = 1 Master */
uint16_t pcMstMask; /**< Master Mask of allowed protection context(s) */
PERI_PPU_GR_Type *pPpuStr; /**< Ppu structure address */
} cy_ppu_fixed_gr_cfg_t;
/** Configuration structure for Fixed Region (RG) PPU (PPU_RG) struct initialization */
typedef struct
{
cy_en_prot_perm_t userPermission; /**< User permissions for the region */
cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
bool secure; /**< Non Secure = 0, Secure = 1 */
bool pcMatch; /**< Access evaluation = 0, Matching = 1 */
uint16_t pcMask; /**< Mask of allowed protection context(s) */
cy_en_prot_perm_t userMstPermission; /**< Master User permissions for the region */
cy_en_prot_perm_t privMstPermission; /**< Master Privileged permissions for the region */
bool secureMst; /**< Non Secure = 0, Secure = 1 Master */
uint16_t pcMstMask; /**< Master Mask of allowed protection context(s) */
PERI_GR_PPU_RG_Type *pPpuStr; /**< Ppu structure address */
} cy_ppu_fixed_rg_cfg_t;
/** Configuration structure for Fixed Slave (SL) PPU (PPU_SL) struct initialization */
typedef struct
{
cy_en_prot_perm_t userPermission; /**< User permissions for the region */
cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
bool secure; /**< Non Secure = 0, Secure = 1 */
bool pcMatch; /**< Access evaluation = 0, Matching = 1 */
uint16_t pcMask; /**< Mask of allowed protection context(s) */
cy_en_prot_perm_t userMstPermission; /**< Master User permissions for the region */
cy_en_prot_perm_t privMstPermission; /**< Master Privileged permissions for the region */
bool secureMst; /**< Non Secure = 0, Secure = 1 Master */
uint16_t pcMstMask; /**< Master Mask of allowed protection context(s) */
PERI_GR_PPU_SL_Type *pPpuStr; /**< Ppu structure address */
} cy_ppu_fixed_sl_cfg_t;
/** Configuration structure for Programmable (PROG) PPU (PPU_PR) struct initialization */
typedef struct
{
uint32_t* address; /**< Base address of the memory region (Only applicable to slave) */
cy_en_prot_size_t regionSize; /**< Size of the memory region (Only applicable to slave) */
uint8_t subregions; /**< Mask of the 8 subregions to disable (Only applicable to slave) */
cy_en_prot_perm_t userPermission; /**< User permissions for the region */
cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
bool secure; /**< Non Secure = 0, Secure = 1 */
bool pcMatch; /**< Access evaluation = 0, Matching = 1 */
uint16_t pcMask; /**< Mask of allowed protection context(s) */
cy_en_prot_perm_t userMstPermission; /**< Master User permissions for the region */
cy_en_prot_perm_t privMstPermission; /**< Master Privileged permissions for the region */
bool secureMst; /**< Non Secure = 0, Secure = 1 Master */
uint16_t pcMstMask; /**< Master Mask of allowed protection context(s) */
PERI_PPU_PR_Type *pPpuStr; /**< Ppu structure address */
} cy_ppu_prog_cfg_t;
cy_en_prot_status_t smpu_protect(cy_smpu_region_config_t smpu_config_arr[], uint32_t arr_length);
cy_en_prot_status_t ppu_fixed_rg_protect(cy_ppu_fixed_rg_cfg_t ppu_config_arr[], uint32_t arr_length);
cy_en_prot_status_t ppu_fixed_sl_protect(cy_ppu_fixed_sl_cfg_t ppu_config_arr[], uint32_t arr_length);
cy_en_prot_status_t ppu_prog_protect(cy_ppu_prog_cfg_t ppu_config_arr[], uint32_t arr_length);
cy_en_prot_status_t ppu_fixed_gr_protect(cy_ppu_fixed_gr_cfg_t ppu_config_arr[], uint32_t arr_length);
cy_en_prot_status_t bus_masters_protect(cy_bus_master_config_t bus_masters_config_arr[], uint32_t arr_length);
uint8_t isPeripheralAccessAllowed(uint32_t perStartAddr, uint32_t perSize,
uint8_t privModeFlag, uint8_t nsecureFlag, enum cy_en_prot_pc_t protectionCtx, cy_en_prot_perm_t accessType);
uint8_t isMemoryAccessAllowed(uint32_t memStartAddr, uint32_t memSize,
uint8_t privModeFlag, uint8_t nsecureFlag, enum cy_en_prot_pc_t protectionCtx, cy_en_prot_perm_t accessType);
#endif /* _CYPROTECTION_H_ */

View File

@ -0,0 +1,78 @@
/* Copyright (c) 2017-2018 ARM Limited
*
* 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.
*/
/* -------------------------------------- Includes ----------------------------------- */
#include "cy_sysint.h"
#include "spm_internal.h"
#ifdef PU_ENABLE
#include "cyprotection_config.h"
#endif // PU_ENABLE
/* -------------------------------------- HAL API ------------------------------------ */
// These implementations are meant to be used only for SPM running on PSoC6 M0+ core.
void spm_hal_start_nspe(void)
{
Cy_SysEnableCM4(CY_CORTEX_M4_APPL_ADDR);
}
void spm_hal_memory_protection_init(void)
{
#ifdef PU_ENABLE
cy_en_prot_status_t status;
/* smpu */
status = smpu_protect((cy_smpu_region_config_t *)flash_spm_smpu_config, sizeof(flash_spm_smpu_config) / sizeof(flash_spm_smpu_config[0]));
CY_ASSERT(status == CY_PROT_SUCCESS); // TODO: Panic instead
status = smpu_protect((cy_smpu_region_config_t *)sram_spm_smpu_config, sizeof(sram_spm_smpu_config) / sizeof(sram_spm_smpu_config[0]));
CY_ASSERT(status == CY_PROT_SUCCESS); // TODO: Panic instead
/* fixed region ppu */
status = ppu_fixed_rg_protect((cy_ppu_fixed_rg_cfg_t *)fixed_rg_pc0_ppu_config, sizeof(fixed_rg_pc0_ppu_config) / sizeof(fixed_rg_pc0_ppu_config[0]));
CY_ASSERT(status == CY_PROT_SUCCESS); // TODO: Panic instead
status = ppu_fixed_rg_protect((cy_ppu_fixed_rg_cfg_t *)fixed_rg_spm_ppu_config, sizeof(fixed_rg_spm_ppu_config) / sizeof(fixed_rg_spm_ppu_config[0]));
CY_ASSERT(status == CY_PROT_SUCCESS); // TODO: Panic instead
status = ppu_fixed_rg_protect((cy_ppu_fixed_rg_cfg_t *)fixed_rg_any_ppu_config, sizeof(fixed_rg_any_ppu_config) / sizeof(fixed_rg_any_ppu_config[0]));
CY_ASSERT(status == CY_PROT_SUCCESS); // TODO: Panic instead
/* fixed slave ppu */
status = ppu_fixed_sl_protect((cy_ppu_fixed_sl_cfg_t *)fixed_sl_pc0_ppu_config, sizeof(fixed_sl_pc0_ppu_config) / sizeof(fixed_sl_pc0_ppu_config[0]));
CY_ASSERT(status == CY_PROT_SUCCESS); // TODO: Panic instead
status = ppu_fixed_sl_protect((cy_ppu_fixed_sl_cfg_t *)fixed_sl_spm_ppu_config, sizeof(fixed_sl_spm_ppu_config) / sizeof(fixed_sl_spm_ppu_config[0]));
CY_ASSERT(status == CY_PROT_SUCCESS); // TODO: Panic instead
status = ppu_fixed_sl_protect((cy_ppu_fixed_sl_cfg_t *)fixed_sl_any_ppu_config, sizeof(fixed_sl_any_ppu_config) / sizeof(fixed_sl_any_ppu_config[0]));
CY_ASSERT(status == CY_PROT_SUCCESS); // TODO: Panic instead
/* programmable ppu */
status = ppu_prog_protect((cy_ppu_prog_cfg_t *)prog_pc0_ppu_config, sizeof(prog_pc0_ppu_config) / sizeof(prog_pc0_ppu_config[0]));
CY_ASSERT(status == CY_PROT_SUCCESS); // TODO: Panic instead
status = ppu_prog_protect((cy_ppu_prog_cfg_t *)prog_spm_ppu_config, sizeof(prog_spm_ppu_config) / sizeof(prog_spm_ppu_config[0]));
CY_ASSERT(status == CY_PROT_SUCCESS); // TODO: Panic instead
/* fixed group ppu */
status = ppu_fixed_gr_protect((cy_ppu_fixed_gr_cfg_t *)fixed_gr_pc0_ppu_config, sizeof(fixed_gr_pc0_ppu_config) / sizeof(fixed_gr_pc0_ppu_config[0]));
CY_ASSERT(status == CY_PROT_SUCCESS); // TODO: Panic instead
status = ppu_fixed_gr_protect((cy_ppu_fixed_gr_cfg_t *)fixed_gr_spm_ppu_config, sizeof(fixed_gr_spm_ppu_config) / sizeof(fixed_gr_spm_ppu_config[0]));
CY_ASSERT(status == CY_PROT_SUCCESS); // TODO: Panic instead
/* bus masters */
status = bus_masters_protect((cy_bus_master_config_t *)bus_masters_config, sizeof(bus_masters_config) / sizeof(bus_masters_config[0]));
CY_ASSERT(status == CY_PROT_SUCCESS); // TODO: Panic instead
#endif // PU_ENABLE
}

View File

@ -0,0 +1,94 @@
/* Copyright (c) 2017-2018 ARM Limited
*
* 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.
*/
/* -------------------------------------- Includes ----------------------------------- */
#include "spm_api.h"
#include "cmsis.h"
#include "cyip_ipc.h"
#include "cy_ipc_drv.h"
#include "cy_syslib.h"
#include "cy_sysint.h"
/* ------------------------------------ Definitions ---------------------------------- */
#define SPM_IPC_CHANNEL 8u
#define SPM_IPC_NOTIFY_CM0P_INTR (CY_IPC_INTR_SPARE + 2) // CM4 to CM0+ notify interrupt number
#define SPM_IPC_NOTIFY_CM4_INTR (CY_IPC_INTR_SPARE + 1) // CM0+ to CM4 notify interrupt number
/* ---------------------------------- Static Globals --------------------------------- */
static IPC_STRUCT_Type *ipc_channel_handle;
static IPC_INTR_STRUCT_Type *ipc_interrupt_ptr;
/* ------------------------ Platform's Functions Implementation ---------------------- */
void ipc_interrupt_handler(void)
{
// Call ARM's interrupt handler
spm_mailbox_irq_callback();
// Clear the interrupt and make a dummy read to avoid double interrupt occurrence:
// - The double interrupts triggering is caused by buffered write operations on bus
// - The dummy read of the status register is indeed required to make sure previous write completed before leaving ISR
// Note: This is a direct clear using the IPC interrupt register and not clear of an NVIC register
Cy_IPC_Drv_ClearInterrupt(ipc_interrupt_ptr, CY_IPC_NO_NOTIFICATION, (1uL << SPM_IPC_CHANNEL));
}
void mailbox_init(void)
{
// Interrupts configuration for CM0+
// * See ce216795_common.h for occupied interrupts
// -----------------------------------------------
// Configure interrupts ISR / MUX and priority
cy_stc_sysint_t ipc_intr_Config;
ipc_intr_Config.intrSrc = (IRQn_Type)NvicMux3_IRQn; // Can be any Mux we choose
ipc_intr_Config.cm0pSrc = (cy_en_intr_t)cpuss_interrupts_ipc_0_IRQn + SPM_IPC_NOTIFY_CM0P_INTR; // Must match the interrupt we trigger using NOTIFY on CM4
ipc_intr_Config.intrPriority = 1;
(void)Cy_SysInt_Init(&ipc_intr_Config, ipc_interrupt_handler);
// Set specific NOTIFY interrupt mask only.
// Only the interrupt sources with their masks enabled can trigger the interrupt.
ipc_interrupt_ptr = Cy_IPC_Drv_GetIntrBaseAddr(SPM_IPC_NOTIFY_CM0P_INTR);
CY_ASSERT(ipc_interrupt_ptr != NULL);
Cy_IPC_Drv_SetInterruptMask(ipc_interrupt_ptr, 0x0, 1 << SPM_IPC_CHANNEL);
// Enable the interrupt
NVIC_EnableIRQ(ipc_intr_Config.intrSrc);
ipc_channel_handle = Cy_IPC_Drv_GetIpcBaseAddress(SPM_IPC_CHANNEL);
CY_ASSERT(ipc_channel_handle != NULL);
}
/* -------------------------------------- HAL API ------------------------------------ */
void spm_hal_mailbox_notify(void)
{
CY_ASSERT(ipc_channel_handle != NULL);
Cy_IPC_Drv_AcquireNotify(ipc_channel_handle, (1uL << SPM_IPC_NOTIFY_CM4_INTR));
}

View File

@ -0,0 +1,49 @@
Permissive Binary License
Version 1.0, December 2018
Redistribution. Redistribution and use in binary form, without
modification, are permitted provided that the following conditions are
met:
1) Redistributions must reproduce the above copyright notice and the
following disclaimer in the documentation and/or other materials
provided with the distribution.
2) Unless to the extent explicitly permitted by law, no reverse
engineering, decompilation, or disassembly of this software is
permitted.
3) Redistribution as part of a software development kit must include the
accompanying file named DEPENDENCIES and any dependencies listed in
that file.
4) 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.
Limited patent license. The copyright holders (and contributors) grant a
worldwide, non-exclusive, no-charge, royalty-free patent license to
make, have made, use, offer to sell, sell, import, and otherwise
transfer this software, where such license applies only to those patent
claims licensable by the copyright holders (and contributors) that are
necessarily infringed by this software. This patent license shall not
apply to any combinations that include this software. No hardware is
licensed hereunder.
If you institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the software
itself infringes your patent(s), then your rights granted under this
license shall terminate as of the date such litigation is filed.
DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS." 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
HOLDERS 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

@ -0,0 +1,20 @@
This directory tree contains Secure images released under Permissive Binary License.
Build by mbed-cli using GNU Arm Embedded - version 6.3.1
These images were compiled by the following command:
```
mbed compile -m TARGET_FUTURE_SEQUANA_M0_PSA -t GCC_ARM --profile debug/release
```
There are also prebuilt images for PSA tests.
Those images can be found in the test folder under a `TARGET_FUTURE_SEQUANA_PSA` directory
These images were compiled by the following command:
```
mbed test --compile -m TARGET_FUTURE_SEQUANA_M0_PSA -t GCC_ARM --profile debug -n *spm*
```

View File

@ -0,0 +1,93 @@
/* Copyright (c) 2017-2018 ARM Limited
*
* 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.
*/
/* -------------------------------------- Includes ----------------------------------- */
#include "spm_api.h"
#include "cmsis.h"
#include "cyip_ipc.h"
#include "cy_ipc_drv.h"
#include "cy_syslib.h"
#include "cy_sysint.h"
/* ------------------------------------ Definitions ---------------------------------- */
#define SPM_IPC_CHANNEL 8u
#define SPM_IPC_NOTIFY_CM0P_INTR (CY_IPC_INTR_SPARE + 2) // CM4 to CM0+ notify interrupt number
#define SPM_IPC_NOTIFY_CM4_INTR (CY_IPC_INTR_SPARE + 1) // CM0+ to CM4 notify interrupt number
/* ---------------------------------- Static Globals --------------------------------- */
static IPC_STRUCT_Type *ipc_channel_handle;
static IPC_INTR_STRUCT_Type *ipc_interrupt_ptr;
/* ------------------------ Platform's Functions Implementation ---------------------- */
void ipc_interrupt_handler(void)
{
// Call ARM's interrupt handler
spm_mailbox_irq_callback();
// Clear the interrupt and make a dummy read to avoid double interrupt occurrence:
// - The double interrupts triggering is caused by buffered write operations on bus
// - The dummy read of the status register is indeed required to make sure previous write completed before leaving ISR
// Note: This is a direct clear using the IPC interrupt register and not clear of an NVIC register
Cy_IPC_Drv_ClearInterrupt(ipc_interrupt_ptr, CY_IPC_NO_NOTIFICATION, (1uL << SPM_IPC_CHANNEL));
}
void mailbox_init(void)
{
// Interrupts configuration for CM4
// * See ce216795_common.h for occupied interrupts
// -----------------------------------------------
// Configure interrupts ISR / MUX and priority
cy_stc_sysint_t ipc_intr_Config;
ipc_intr_Config.intrSrc = (IRQn_Type)cpuss_interrupts_ipc_0_IRQn + SPM_IPC_NOTIFY_CM4_INTR;
ipc_intr_Config.intrPriority = 1;
(void)Cy_SysInt_Init(&ipc_intr_Config, ipc_interrupt_handler);
// Set specific NOTIFY interrupt mask only.
// Only the interrupt sources with their masks enabled can trigger the interrupt.
ipc_interrupt_ptr = Cy_IPC_Drv_GetIntrBaseAddr(SPM_IPC_NOTIFY_CM4_INTR);
CY_ASSERT(ipc_interrupt_ptr != NULL);
Cy_IPC_Drv_SetInterruptMask(ipc_interrupt_ptr, 0x0, 1 << SPM_IPC_CHANNEL);
// Enable the interrupt
NVIC_EnableIRQ(ipc_intr_Config.intrSrc);
ipc_channel_handle = Cy_IPC_Drv_GetIpcBaseAddress(SPM_IPC_CHANNEL);
CY_ASSERT(ipc_channel_handle != NULL);
}
/* -------------------------------------- HAL API ------------------------------------ */
void spm_hal_mailbox_notify(void)
{
CY_ASSERT(ipc_channel_handle != NULL);
Cy_IPC_Drv_AcquireNotify(ipc_channel_handle, (1uL << SPM_IPC_NOTIFY_CM0P_INTR));
}

View File

@ -86,7 +86,7 @@ uint8_t flash_get_erase_value(const flash_t *obj)
{
(void)obj;
return 0xFF;
return 0x00;
}
#endif // DEVICE_FLASH

View File

@ -21,15 +21,27 @@
#if defined(TARGET_MCU_PSOC6_M0)
#ifdef TARGET_PSA
#ifndef INITIAL_SP
#define INITIAL_SP (PSA_SECURE_RAM_START + PSA_SECURE_RAM_SIZE)
#endif // INITIAL_SP
#else
#ifndef INITIAL_SP
#define INITIAL_SP (0x08000000 + 0x00010000) // Ram origin + length
#endif
#endif // INITIAL_SP
#endif // TARGET_PSA
#elif defined(TARGET_MCU_PSOC6_M4)
#ifdef TARGET_PSA
#ifndef INITIAL_SP
#define INITIAL_SP (PSA_NON_SECURE_RAM_START + PSA_NON_SECURE_RAM_SIZE)
#endif // INITIAL_SP
#else
#ifndef INITIAL_SP
#define INITIAL_SP (0x08010000 + 0x00037800) // Ram origin + length
#endif
#endif // INITIAL_SP
#endif // TARGET_PSA
#else

View File

@ -100,6 +100,7 @@ do { \
#define SRM_TCPWM(num) {(num), (0)}
#define DEFAULT_PORT_RES 0xff
#define DEFAULT_DIVIDER8_RES 0xff
#define DEFAULT_DIVIDER_RES 0xffff
#define DEFAULT_SCM_RES 1
#define DEFAULT_TCPWM_RES 1

View File

@ -7663,6 +7663,53 @@
}
}
},
"FUTURE_SEQUANA_M0_PSA": {
"inherits": ["SPE_Target", "FUTURE_SEQUANA_M0"],
"components_add": ["SPM_MAILBOX", "FLASHIAP"],
"extra_labels_add": ["PSA"],
"macros_add": [
"PSOC6_DYNSRM_DISABLE=1",
"MBEDTLS_PSA_CRYPTO_SPM",
"MBEDTLS_PSA_CRYPTO_C",
"MBEDTLS_ENTROPY_NV_SEED",
"MBEDTLS_PLATFORM_NV_SEED_READ_MACRO=mbed_default_seed_read",
"MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO=mbed_default_seed_write"
],
"deliver_to_target": "FUTURE_SEQUANA_PSA",
"overrides": {
"secure-rom-start": "0x10000000",
"secure-rom-size": "0x80000",
"non-secure-rom-start": "0x10080000",
"non-secure-rom-size": "0x78000",
"secure-ram-start": "0x08000000",
"secure-ram-size": "0x10000",
"non-secure-ram-start": "0x08010000",
"non-secure-ram-size": "0x37700",
"shared-ram-start": "0x08047700",
"shared-ram-size": "0x100"
}
},
"FUTURE_SEQUANA_PSA": {
"inherits": ["NSPE_Target", "FUTURE_SEQUANA"],
"sub_target": "FUTURE_SEQUANA_M0_PSA",
"extra_labels_add": ["PSA"],
"extra_labels_remove": ["CORDIO"],
"components_add": ["SPM_MAILBOX"],
"macros_add": ["PSOC6_DYNSRM_DISABLE=1", "MBEDTLS_PSA_CRYPTO_C"],
"m0_core_img": "psa_release_1.0.hex",
"overrides": {
"secure-rom-start": "0x10000000",
"secure-rom-size": "0x80000",
"non-secure-rom-start": "0x10080000",
"non-secure-rom-size": "0x78000",
"secure-ram-start": "0x08000000",
"secure-ram-size": "0x10000",
"non-secure-ram-start": "0x08010000",
"non-secure-ram-size": "0x37700",
"shared-ram-start": "0x08047700",
"shared-ram-size": "0x100"
}
},
"TMPM3HQ": {
"inherits": ["Target"],
"core": "Cortex-M3",

View File

@ -43,7 +43,7 @@ from .paths import (MBED_CMSIS_PATH, MBED_TARGETS_PATH, MBED_LIBRARIES,
BUILD_DIR)
from .resources import Resources, FileType, FileRef
from .notifier.mock import MockNotifier
from .targets import TARGET_NAMES, TARGET_MAP, CORE_ARCH
from .targets import TARGET_NAMES, TARGET_MAP, CORE_ARCH, Target
from .libraries import Library
from .toolchains import TOOLCHAIN_CLASSES
from .config import Config
@ -263,6 +263,7 @@ def get_mbed_official_release(version):
) for target in TARGET_NAMES \
if (hasattr(TARGET_MAP[target], 'release_versions')
and version in TARGET_MAP[target].release_versions)
and not Target.get_target(target).is_PSA_secure_target
)
)

View File

@ -99,17 +99,16 @@ def find_cm0_image(toolchain, resources, elf, hexf):
from tools.resources import FileType
hex_files = resources.get_file_paths(FileType.HEX)
m0hexf = next((f for f in hex_files if os.path.basename(f) == toolchain.target.m0_core_img), None)
if toolchain.target.name.endswith('_PSA'):
m0hexf = next((f for f in hex_files if os.path.basename(f) == os.path.basename(hexf)), m0hexf)
if m0hexf:
toolchain.notify.debug("M0 core image file found %s." % os.path.basename(m0hexf))
toolchain.notify.debug("M0 core image file found: %s." % os.path.basename(m0hexf))
else:
toolchain.notify.debug("M0 core hex image file %s not found. Aborting." % toolchain.target.m0_core_img)
raise ConfigException("Required M0 core hex image not found.")
return m0hexf
def complete(toolchain, elf0, hexf0, hexf1=None):
complete_func(toolchain.notify.debug, elf0, hexf0, hexf1)