Skip to content

Commit c0f8290

Browse files
authored
Merge pull request ARMmbed#10 from niklas-arm/uvisor_supported
Add secure access to CMSIS and use in K64F HAL
2 parents 51be86e + 69b45b7 commit c0f8290

File tree

6 files changed

+394
-116
lines changed

6 files changed

+394
-116
lines changed

hal/targets/cmsis/TARGET_Freescale/TARGET_K64F/cmsis_nvic.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@
3232

3333
extern void InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler);
3434

35-
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) {
35+
void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) {
3636
InstallIRQHandler(IRQn, vector);
3737
}
3838

39-
uint32_t NVIC_GetVector(IRQn_Type IRQn) {
39+
uint32_t __NVIC_GetVector(IRQn_Type IRQn) {
4040
uint32_t *vectors = (uint32_t*)SCB->VTOR;
4141
return vectors[IRQn + 16];
4242
}

hal/targets/cmsis/TARGET_Freescale/TARGET_K64F/cmsis_nvic.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@
4141
extern "C" {
4242
#endif
4343

44-
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector);
45-
uint32_t NVIC_GetVector(IRQn_Type IRQn);
44+
void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector);
45+
uint32_t __NVIC_GetVector(IRQn_Type IRQn);
4646

4747
#ifdef __cplusplus
4848
}

hal/targets/cmsis/core_cm4.h

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,6 +1502,35 @@ typedef struct
15021502
@{
15031503
*/
15041504

1505+
#ifdef CMSIS_NVIC_VIRTUAL
1506+
#ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE
1507+
#define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h"
1508+
#endif
1509+
#include CMSIS_NVIC_VIRTUAL_HEADER_FILE
1510+
#else
1511+
#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping
1512+
#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping
1513+
#define NVIC_EnableIRQ __NVIC_EnableIRQ
1514+
#define NVIC_DisableIRQ __NVIC_DisableIRQ
1515+
#define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ
1516+
#define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ
1517+
#define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ
1518+
#define NVIC_GetActive __NVIC_GetActive
1519+
#define NVIC_SetPriority __NVIC_SetPriority
1520+
#define NVIC_GetPriority __NVIC_GetPriority
1521+
#endif /* CMSIS_NVIC_VIRTUAL */
1522+
1523+
#ifdef CMSIS_VECTAB_VIRTUAL
1524+
#ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE
1525+
#define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h"
1526+
#endif
1527+
#include CMSIS_VECTAB_VIRTUAL_HEADER_FILE
1528+
#else
1529+
#define NVIC_SetVector __NVIC_SetVector
1530+
#define NVIC_GetVector __NVIC_GetVector
1531+
#endif /* CMSIS_VECTAB_VIRTUAL */
1532+
1533+
15051534
/** \brief Set Priority Grouping
15061535
15071536
The function sets the priority grouping field using the required unlock sequence.
@@ -1512,7 +1541,7 @@ typedef struct
15121541
15131542
\param [in] PriorityGroup Priority grouping field.
15141543
*/
1515-
__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
1544+
__STATIC_INLINE void __NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
15161545
{
15171546
uint32_t reg_value;
15181547
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
@@ -1532,7 +1561,7 @@ __STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
15321561
15331562
\return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
15341563
*/
1535-
__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
1564+
__STATIC_INLINE uint32_t __NVIC_GetPriorityGrouping(void)
15361565
{
15371566
return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos));
15381567
}
@@ -1544,7 +1573,7 @@ __STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
15441573
15451574
\param [in] IRQn External interrupt number. Value cannot be negative.
15461575
*/
1547-
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
1576+
__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
15481577
{
15491578
NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
15501579
}
@@ -1556,7 +1585,7 @@ __STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
15561585
15571586
\param [in] IRQn External interrupt number. Value cannot be negative.
15581587
*/
1559-
__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
1588+
__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn)
15601589
{
15611590
NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
15621591
}
@@ -1572,7 +1601,7 @@ __STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
15721601
\return 0 Interrupt status is not pending.
15731602
\return 1 Interrupt status is pending.
15741603
*/
1575-
__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
1604+
__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn)
15761605
{
15771606
return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
15781607
}
@@ -1584,7 +1613,7 @@ __STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
15841613
15851614
\param [in] IRQn Interrupt number. Value cannot be negative.
15861615
*/
1587-
__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
1616+
__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn)
15881617
{
15891618
NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
15901619
}
@@ -1596,7 +1625,7 @@ __STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
15961625
15971626
\param [in] IRQn External interrupt number. Value cannot be negative.
15981627
*/
1599-
__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
1628+
__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn)
16001629
{
16011630
NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
16021631
}
@@ -1611,7 +1640,7 @@ __STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
16111640
\return 0 Interrupt status is not active.
16121641
\return 1 Interrupt status is active.
16131642
*/
1614-
__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
1643+
__STATIC_INLINE uint32_t __NVIC_GetActive(IRQn_Type IRQn)
16151644
{
16161645
return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
16171646
}
@@ -1626,7 +1655,7 @@ __STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
16261655
\param [in] IRQn Interrupt number.
16271656
\param [in] priority Priority to set.
16281657
*/
1629-
__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
1658+
__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
16301659
{
16311660
if((int32_t)IRQn < 0) {
16321661
SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8 - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
@@ -1648,7 +1677,7 @@ __STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
16481677
\return Interrupt Priority. Value is aligned automatically to the implemented
16491678
priority bits of the microcontroller.
16501679
*/
1651-
__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
1680+
__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn)
16521681
{
16531682

16541683
if((int32_t)IRQn < 0) {
Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
/**************************************************************************//**
2+
* @file core_cmSecureAccess.h
3+
* @brief CMSIS Cortex-M Core Secure Access Header File
4+
* @version XXX
5+
* @date 10. June 2016
6+
*
7+
* @note
8+
*
9+
******************************************************************************/
10+
/* Copyright (c) 2016 ARM LIMITED
11+
12+
All rights reserved.
13+
Redistribution and use in source and binary forms, with or without
14+
modification, are permitted provided that the following conditions are met:
15+
- Redistributions of source code must retain the above copyright
16+
notice, this list of conditions and the following disclaimer.
17+
- Redistributions in binary form must reproduce the above copyright
18+
notice, this list of conditions and the following disclaimer in the
19+
documentation and/or other materials provided with the distribution.
20+
- Neither the name of ARM nor the names of its contributors may be used
21+
to endorse or promote products derived from this software without
22+
specific prior written permission.
23+
*
24+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27+
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
28+
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31+
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32+
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33+
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34+
POSSIBILITY OF SUCH DAMAGE.
35+
---------------------------------------------------------------------------*/
36+
37+
38+
#ifndef __CORE_CM_SECURE_ACCESS_H
39+
#define __CORE_CM_SECURE_ACCESS_H
40+
41+
42+
/* ########################### Core Secure Access ########################### */
43+
44+
#ifdef FEATURE_UVISOR
45+
#include "uvisor-lib.h"
46+
47+
/* Secure uVisor implementation. */
48+
49+
/** Set the value at the target address.
50+
*
51+
* Equivalent to: `*address = value`.
52+
* @param address[in] Target address
53+
* @param value[in] Value to write at the address location.
54+
*/
55+
#define SECURE_WRITE(address, value) \
56+
uvisor_write(main, UVISOR_RGW_SHARED, address, value, UVISOR_RGW_OP_WRITE, 0xFFFFFFFFUL)
57+
58+
/** Get the value at the target address.
59+
*
60+
* @param address[in] Target address
61+
* @returns The value `*address`.
62+
*/
63+
#define SECURE_READ(address) \
64+
uvisor_read(main, UVISOR_RGW_SHARED, address, UVISOR_RGW_OP_READ, 0xFFFFFFFFUL)
65+
66+
/** Get the selected bits at the target address.
67+
*
68+
* @param address[in] Target address
69+
* @param mask[in] Bits to select out of the target address
70+
* @returns The value `*address & mask`.
71+
*/
72+
#define SECURE_BITS_GET(address, mask) \
73+
UVISOR_BITS_GET(main, UVISOR_RGW_SHARED, address, mask)
74+
75+
/** Check the selected bits at the target address.
76+
*
77+
* @param address[in] Address at which to check the bits
78+
* @param mask[in] Bits to select out of the target address
79+
* @returns The value `((*address & mask) == mask)`.
80+
*/
81+
#define SECURE_BITS_CHECK(address, mask) \
82+
UVISOR_BITS_CHECK(main, UVISOR_RGW_SHARED, address, mask)
83+
84+
/** Set the selected bits to 1 at the target address.
85+
*
86+
* Equivalent to: `*address |= mask`.
87+
* @param address[in] Target address
88+
* @param mask[in] Bits to select out of the target address
89+
*/
90+
#define SECURE_BITS_SET(address, mask) \
91+
UVISOR_BITS_SET(main, UVISOR_RGW_SHARED, address, mask)
92+
93+
/** Clear the selected bits at the target address.
94+
*
95+
* Equivalent to: `*address &= ~mask`.
96+
* @param address[in] Target address
97+
* @param mask[in] Bits to select out of the target address
98+
*/
99+
#define SECURE_BITS_CLEAR(address, mask) \
100+
UVISOR_BITS_CLEAR(main, UVISOR_RGW_SHARED, address, mask)
101+
102+
/** Set the selected bits at the target address to the given value.
103+
*
104+
* Equivalent to: `*address = (*address & ~mask) | (value & mask)`.
105+
* @param address[in] Target address
106+
* @param mask[in] Bits to select out of the target address
107+
* @param value[in] Value to write at the address location. Note: The value
108+
* must be already shifted to the correct bit position
109+
*/
110+
#define SECURE_BITS_SET_VALUE(address, mask, value) \
111+
UVISOR_BITS_SET_VALUE(main, UVISOR_RGW_SHARED, address, mask, value)
112+
113+
/** Toggle the selected bits at the target address.
114+
*
115+
* Equivalent to: `*address ^= mask`.
116+
* @param address[in] Target address
117+
* @param mask[in] Bits to select out of the target address
118+
*/
119+
#define SECURE_BITS_TOGGLE(address, mask) \
120+
UVISOR_BITS_TOGGLE(main, UVISOR_RGW_SHARED, address, mask)
121+
122+
#else
123+
124+
/* Insecure fallback implementation. */
125+
126+
/** Set the value at the target address.
127+
*
128+
* Equivalent to: `*address = value`.
129+
* @param address[in] Target address
130+
* @param value[in] Value to write at the address location.
131+
*/
132+
#define SECURE_WRITE(address, value) \
133+
*(address) = (value)
134+
135+
/** Get the value at the target address.
136+
*
137+
* @param address[in] Target address
138+
* @returns The value `*address`.
139+
*/
140+
#define SECURE_READ(address) \
141+
(*(address))
142+
143+
/** Get the selected bits at the target address.
144+
*
145+
* @param address[in] Target address
146+
* @param mask[in] Bits to select out of the target address
147+
* @returns The value `*address & mask`.
148+
*/
149+
#define SECURE_BITS_GET(address, mask) \
150+
(*(address) & (mask))
151+
152+
/** Check the selected bits at the target address.
153+
*
154+
* @param address[in] Address at which to check the bits
155+
* @param mask[in] Bits to select out of the target address
156+
* @returns The value `((*address & mask) == mask)`.
157+
*/
158+
#define SECURE_BITS_CHECK(address, mask) \
159+
((*(address) & (mask)) == (mask))
160+
161+
/** Set the selected bits to 1 at the target address.
162+
*
163+
* Equivalent to: `*address |= mask`.
164+
* @param address[in] Target address
165+
* @param mask[in] Bits to select out of the target address
166+
*/
167+
#define SECURE_BITS_SET(address, mask) \
168+
*(address) |= (mask)
169+
170+
/** Clear the selected bits at the target address.
171+
*
172+
* Equivalent to: `*address &= ~mask`.
173+
* @param address[in] Target address
174+
* @param mask[in] Bits to select out of the target address
175+
*/
176+
#define SECURE_BITS_CLEAR(address, mask) \
177+
*(address) &= ~(mask)
178+
179+
/** Set the selected bits at the target address to the given value.
180+
*
181+
* Equivalent to: `*address = (*address & ~mask) | (value & mask)`.
182+
* @param address[in] Target address
183+
* @param mask[in] Bits to select out of the target address
184+
* @param value[in] Value to write at the address location. Note: The value
185+
* must be already shifted to the correct bit position
186+
*/
187+
#define SECURE_BITS_SET_VALUE(address, mask, value) \
188+
*(address) = (*(address) & ~(mask)) | ((value) & (mask))
189+
190+
/** Toggle the selected bits at the target address.
191+
*
192+
* Equivalent to: `*address ^= mask`.
193+
* @param address[in] Target address
194+
* @param mask[in] Bits to select out of the target address
195+
*/
196+
#define SECURE_BITS_TOGGLE(address, mask) \
197+
*(address) ^= (mask)
198+
199+
#endif
200+
201+
#endif /* __CORE_CM_SECURE_ACCESS_H */

0 commit comments

Comments
 (0)