Skip to content

Commit e69aa15

Browse files
authored
Merge pull request #8744 from kfnta/psa_spm_base
PSA Secure partition manager and services
2 parents 86915d9 + 2b3822e commit e69aa15

File tree

102 files changed

+11412
-23
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+11412
-23
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,6 @@ log
9494

9595
# Icetea related file
9696
test_suite.json
97+
98+
# default delivery dir
99+
DELIVERY/

TESTS/mbed_hal/spm/fault_functions.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/* Copyright (c) 2017-2018 ARM Limited
2+
*
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#ifndef __MBED_HAL_SPM_FAULT_FUNCTIONS__
19+
#define __MBED_HAL_SPM_FAULT_FUNCTIONS__
20+
21+
#include "cmsis_compiler.h"
22+
23+
#ifdef __cplusplus
24+
extern "C" {
25+
#endif
26+
27+
// Retruns the value of the LR register
28+
// Used to determine which stack the exception happend in
29+
__STATIC_FORCEINLINE uint32_t __get_LR(void);
30+
31+
// This function is required as we need a symbol/address
32+
// to jump to from fault handler.
33+
void do_nothing(void);
34+
35+
// Test exception handler
36+
static void hard_fault_handler_test();
37+
38+
// Using naked function as it will not be executed from beginning to the end.
39+
// The execution flow expected to be interrupted by exception and we will
40+
// return to other function.
41+
// compiler will not produce prolog and epilog code for naked function
42+
// and thus will preserve stack in un-corrupted state
43+
__attribute__((naked)) void call_mem(uint32_t addr);
44+
45+
#ifdef __cplusplus
46+
}
47+
#endif
48+
49+
#endif // __MBED_HAL_SPM_FAULT_FUNCTIONS__

TESTS/mbed_hal/spm/main.cpp

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/* Copyright (c) 2017-2018 ARM Limited
2+
*
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#if !defined(COMPONENT_PSA_SRV_IPC)
19+
#error [NOT_SUPPORTED] Test supported only on PSA targets
20+
#endif
21+
22+
#if (defined( __CC_ARM ) || defined(__ARMCC_VERSION) || defined( __ICCARM__ ))
23+
#error [NOT_SUPPORTED] this test is supported on GCC only
24+
#endif
25+
26+
#include "utest/utest.h"
27+
#include "unity/unity.h"
28+
#include "greentea-client/test_env.h"
29+
#include "cmsis.h"
30+
#include "spm_api.h"
31+
#include <stdlib.h>
32+
#include "fault_functions.h"
33+
34+
using namespace utest::v1;
35+
36+
37+
#define HARDFAULT_IRQn ((IRQn_Type)-13)
38+
#define EXC_RETURN_RETURN_STACK_MSK ((uint32_t)(0x00000004))
39+
#define PC_INDEX_IN_STACK_FRAME 6
40+
41+
volatile uint32_t fault_occurred;
42+
uint32_t real_hard_fault_handler;
43+
44+
__STATIC_FORCEINLINE uint32_t __get_LR(void)
45+
{
46+
uint32_t result;
47+
48+
__ASM volatile("MOV %0, lr" : "=r"(result));
49+
return (result);
50+
}
51+
52+
void do_nothing(void)
53+
{
54+
__NOP();
55+
}
56+
57+
static void hard_fault_handler_test()
58+
{
59+
fault_occurred++;
60+
// LR is set EXC_RETURN
61+
// lowest bits identify PSP vs MSP stack used for stacking
62+
uint32_t lr = __get_LR();
63+
uint32_t sp;
64+
65+
if (lr & EXC_RETURN_RETURN_STACK_MSK) {
66+
sp = __get_PSP();
67+
} else {
68+
sp = __get_MSP();
69+
}
70+
71+
// Overwrite return address.
72+
// Fake return to a our special function since current
73+
// instruction under test will always fail due to memory protection
74+
((uint32_t *)sp)[PC_INDEX_IN_STACK_FRAME] = (uint32_t)do_nothing;
75+
}
76+
77+
__attribute__((naked)) void call_mem(uint32_t addr)
78+
{
79+
// Only first instruction will be executed in positive flow,
80+
// since exception will be generated for invalid memory access.
81+
// Other instructions are for calling do_nothing function according to AAPCS.
82+
__ASM(
83+
"LDR r1, [r0]\n"
84+
"BX lr\n"
85+
);
86+
}
87+
88+
static void test_memory(uint32_t addr, uint32_t expected_fatal_count)
89+
{
90+
call_mem(addr);
91+
// Although call_mem is a "naked" function, it is called using AAPCS.
92+
// Thus we can assume LR will point to next instruction, and caller save registers are backed up
93+
TEST_ASSERT_EQUAL(expected_fatal_count, fault_occurred);
94+
}
95+
96+
static void secure_ram_fault_test(void)
97+
{
98+
test_memory(PSA_SECURE_RAM_START, 1);
99+
}
100+
101+
static void secure_flash_fault_test(void)
102+
{
103+
test_memory(PSA_SECURE_ROM_START, 1);
104+
}
105+
106+
static void non_secure_ram_fault_test(void)
107+
{
108+
test_memory(PSA_NON_SECURE_RAM_START, 0);
109+
}
110+
111+
static void non_secure_flash_fault_test(void)
112+
{
113+
test_memory(PSA_NON_SECURE_ROM_START, 0);
114+
}
115+
116+
utest::v1::status_t fault_override_setup(const Case *const source, const size_t index_of_case)
117+
{
118+
// Save old hard fault handler and replace it with a new one
119+
// NOTE: only works when VTOR is set to RAM
120+
real_hard_fault_handler = NVIC_GetVector(HARDFAULT_IRQn);
121+
NVIC_SetVector(HARDFAULT_IRQn, (uint32_t)&hard_fault_handler_test);
122+
fault_occurred = 0;
123+
124+
return greentea_case_setup_handler(source, index_of_case);
125+
}
126+
127+
utest::v1::status_t fault_override_teardown(const Case *const source, const size_t passed, const size_t failed,
128+
const failure_t reason)
129+
{
130+
// Restore real hard fault handler
131+
NVIC_SetVector(HARDFAULT_IRQn, real_hard_fault_handler);
132+
133+
return greentea_case_teardown_handler(source, passed, failed, reason);
134+
}
135+
136+
Case cases[] = {
137+
Case("SPM - Access secure RAM", fault_override_setup, secure_ram_fault_test, fault_override_teardown),
138+
Case("SPM - Access secure Flash", fault_override_setup, secure_flash_fault_test, fault_override_teardown),
139+
Case("SPM - Access non-secure RAM", fault_override_setup, non_secure_ram_fault_test, fault_override_teardown),
140+
Case("SPM - Access non-secure Flash", fault_override_setup, non_secure_flash_fault_test, fault_override_teardown),
141+
};
142+
143+
utest::v1::status_t greentea_test_setup(const size_t number_of_cases)
144+
{
145+
#ifndef NO_GREENTEA
146+
GREENTEA_SETUP(20, "default_auto");
147+
#endif
148+
return greentea_test_setup_handler(number_of_cases);
149+
}
150+
151+
Specification specification(greentea_test_setup, cases, greentea_test_teardown_handler);
152+
153+
int main()
154+
{
155+
Harness::run(specification);
156+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/* Copyright (c) 2017-2018 ARM Limited
2+
*
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
/***********************************************************************************************************************
19+
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
20+
* THIS FILE IS AN AUTO-GENERATED FILE - DO NOT MODIFY IT.
21+
* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
22+
* Template Version 1.0
23+
* Generated by tools/spm/generate_partition_code.py Version 1.0
24+
**********************************************************************************************************************/
25+
26+
#include "spm_panic.h"
27+
#include "spm_internal.h"
28+
#include "handles_manager.h"
29+
#include "cmsis.h"
30+
#include "psa_test_its_reset_partition.h"
31+
#include "psa_its_partition.h"
32+
33+
34+
spm_partition_t g_partitions[2] = {
35+
{
36+
.partition_id = TEST_ITS_RESET_ID,
37+
.thread_id = 0,
38+
.flags_rot_srv = TEST_ITS_RESET_WAIT_ANY_SID_MSK,
39+
.flags_interrupts = 0,
40+
.rot_services = NULL,
41+
.rot_services_count = TEST_ITS_RESET_ROT_SRV_COUNT,
42+
.extern_sids = NULL,
43+
.extern_sids_count = TEST_ITS_RESET_EXT_ROT_SRV_COUNT,
44+
.irq_mapper = NULL,
45+
},
46+
{
47+
.partition_id = ITS_ID,
48+
.thread_id = 0,
49+
.flags_rot_srv = ITS_WAIT_ANY_SID_MSK,
50+
.flags_interrupts = 0,
51+
.rot_services = NULL,
52+
.rot_services_count = ITS_ROT_SRV_COUNT,
53+
.extern_sids = NULL,
54+
.extern_sids_count = ITS_EXT_ROT_SRV_COUNT,
55+
.irq_mapper = NULL,
56+
},
57+
};
58+
59+
/* Check all the defined memory regions for overlapping. */
60+
61+
/* A list of all the memory regions. */
62+
const mem_region_t *mem_regions = NULL;
63+
64+
const uint32_t mem_region_count = 0;
65+
66+
// forward declaration of partition initializers
67+
void test_its_reset_init(spm_partition_t *partition);
68+
void its_init(spm_partition_t *partition);
69+
70+
uint32_t init_partitions(spm_partition_t **partitions)
71+
{
72+
if (NULL == partitions) {
73+
SPM_PANIC("partitions is NULL!\n");
74+
}
75+
76+
test_its_reset_init(&(g_partitions[0]));
77+
its_init(&(g_partitions[1]));
78+
79+
*partitions = g_partitions;
80+
return 2;
81+
}
82+
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/* Copyright (c) 2017-2018 ARM Limited
2+
*
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#include "spm_client.h"
19+
#include "psa_prot_internal_storage.h"
20+
#include "test_pits.h"
21+
#include "psa_test_its_reset_ifs.h"
22+
23+
psa_its_status_t test_psa_its_reset(void)
24+
{
25+
psa_handle_t conn = psa_connect(TEST_PSA_ITS_RESET, 1);
26+
if (conn <= PSA_NULL_HANDLE) {
27+
return PSA_ITS_ERROR_STORAGE_FAILURE;
28+
}
29+
30+
psa_error_t status = psa_call(conn, NULL, 0, NULL, 0);
31+
if (status == PSA_DROP_CONNECTION) {
32+
status = PSA_ITS_ERROR_STORAGE_FAILURE;
33+
}
34+
35+
psa_close(conn);
36+
return status;
37+
}

0 commit comments

Comments
 (0)