1 /***************************************************************************//**
2 * \file cy_prot.h
3 * \version 1.60
4 *
5 * \brief
6 * Provides an API declaration of the Protection Unit driver
7 *
8 ********************************************************************************
9 * \copyright
10 * Copyright 2016-2020 Cypress Semiconductor Corporation
11 * SPDX-License-Identifier: Apache-2.0
12 *
13 * Licensed under the Apache License, Version 2.0 (the "License");
14 * you may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 *******************************************************************************/
25
26 /**
27 * \addtogroup group_prot
28 * \{
29 *
30 * The Protection Unit driver provides an API to configure the Memory Protection
31 * Units (MPU), Shared Memory Protection Units (SMPU), and Peripheral Protection
32 * Units (PPU). These are separate from the ARM Core MPUs and provide additional
33 * mechanisms for securing resource accesses. The Protection units address the
34 * following concerns in an embedded design:
35 * - <b>Security requirements:</b> This includes the prevention of malicious attacks
36 * to access secure memory or peripherals.
37 * - <b>Safety requirements:</b> This includes detection of accidental (non-malicious)
38 * SW errors and random HW errors. It is important to enable failure analysis
39 * to investigate the root cause of a safety violation.
40 *
41 * The functions and other declarations used in this driver are in cy_prot.h.
42 * You can include cy_pdl.h to get access to all functions
43 * and declarations in the PDL.
44 *
45 * \section group_prot_protection_type Protection Types
46 *
47 * Protection units are hardware configuration structures that control bus accesses
48 * to the resources that they protect. By combining these individual configuration
49 * structures, a system is built to allow strict restrictions on the capabilities
50 * of individual bus masters (e.g. CM0+, CM4, Crypt) and their operating modes.
51 * This architecture can then be integrated into the overall security system
52 * of the end application. To build this system, 3 main protection unit types
53 * are available; MPU, SMPU and PPU. When a resource is accessed (memory/register),
54 * it must pass the evaluation performed for each category. These access evaluations
55 * are prioritized, where MPU has the highest priority, followed by SMPU, followed
56 * by PPU. i.e. if an SMPU and a PPU protect the same resource and if access is
57 * denied by the SMPU, then the PPU access evaluation is skipped. This can lead to a
58 * denial-of-service scenario and the application should pay special attention in
59 * taking ownership of the protection unit configurations.
60 *
61 * \subsection group_prot_memory_protection Memory Protection
62 *
63 * Memory access control for a bus master is controlled using an MPU. These are
64 * most often used to distinguish user and privileged accesses from a single bus
65 * master such as task switching in an OS/kernel. For ARM cores (CM0+, CM4), the
66 * core MPUs are used to perform this task. For other non-ARM bus masters such
67 * as Crypto, MPU structs are available, which can be used in a similar manner
68 * as the ARM core MPUs. These MPUs however must be configured by the ARM cores.
69 * Other bus masters that do not have an MPU, such as DMA (DW), inherit the access
70 * control attributes of the bus master that configured the channel. Also note
71 * that unlike other protection units, MPUs do not support protection context
72 * evaluation. MPU structs have a descending priority, where larger index struct
73 * has higher priority access evaluation over lower index structs. E.g. MPU_STRUCT15
74 * has higher priority than MPU_STRUCT14 and its access will be evaluated before
75 * MPU_STRUCT14. If both target the same memory, then the higher index (MPU_STRUCT15)
76 * will be used, and the lower index (MPU_STRUCT14) will be ignored.
77 *
78 * \subsection group_prot_shared_memory_protection Shared Memory Protection
79 *
80 * In order to protect a region of memory from all bus masters, an SMPU is used.
81 * This protection effectively allows only those with correct bus master access
82 * settings to read/write/execute the memory region. This type of protection
83 * is used in general memory such as Flash and SRAM. Peripheral registers are
84 * best configured using the peripheral protection units instead. SMPU structs
85 * have a descending priority, where larger index struct has higher priority
86 * access evaluation over lower index structs. E.g. SMPU_STRUCT15 has higher priority
87 * than SMPU_STRUCT14 and its access will be evaluated before SMPU_STRUCT14.
88 * If both target the same memory, then the higher index (MPU_STRUCT15) will be
89 * used, and the lower index (SMPU_STRUCT14) will be ignored.
90 *
91 * \subsection group_prot_peripheral_protection Peripheral Protection
92 *
93 * Peripheral protection is provided by PPUs and allow control of peripheral
94 * register accesses by bus masters. Four types of PPUs are available.
95 * - <b>Fixed Group (GR) PPUs</b> are used to protect an entire peripheral MMIO group
96 * from invalid bus master accesses. The MMIO grouping information and which
97 * resource belongs to which group is device specific and can be obtained
98 * from the device technical reference manual (TRM). Group PPUs have the highest
99 * priority in the PPU category. Therefore their access evaluations take precedence
100 * over the other types of PPUs.
101 * - <b>Programmable (PROG) PPUs</b> are used to protect any peripheral memory region
102 * in a device from invalid bus master accesses. It is the most versatile
103 * type of peripheral protection unit. Programmable PPUs have the second highest
104 * priority and take precedence over Region PPUs and Slave PPUs. Similar to SMPUs,
105 * higher index PROG PPUs have higher priority than lower indexes PROG PPUs.
106 * - <b>Fixed Region (RG) PPUs</b> are used to protect an entire peripheral slave
107 * instance from invalid bus master accesses. For example, TCPWM0, TCPWM1,
108 * SCB0, and SCB1, etc. Region PPUs have the third highest priority and take precedence
109 * over Slave PPUs.
110 * - <b>Fixed Slave (SL) PPUs</b> are used to protect specified regions of peripheral
111 * instances. For example, individual DW channel structs, SMPU structs, and
112 * IPC structs, etc. Slave PPUs have the lowest priority in the PPU category and
113 * therefore are evaluated last.
114 *
115 * \section group_prot_protection_context Protection Context
116 *
117 * Protection context (PC) attribute is present in all bus masters and is evaluated
118 * when accessing memory protected by an SMPU or a PPU. There are no limitations
119 * to how the PC values are allocated to the bus masters and this makes it
120 * possible for multiple bus masters to essentially share protection context
121 * values. The exception to this rule is the PC value 0.
122 *
123 * \subsection group_prot_pc0 PC=0
124 *
125 * Protection context 0 is a hardware controlled protection context update
126 * mechanism that allows only a single entry point for transitioning into PC=0
127 * value. This mechanism is only present for the secure CM0+ core and is a
128 * fundamental feature in defining a security solution. While all bus masters
129 * are configured to PC=0 at device boot, it is up to the security solution
130 * to transition these bus masters to PC!=0 values. Once this is done, those
131 * bus masters can no longer revert back to PC=0 and can no longer access
132 * resources protected at PC=0.
133 *
134 * In order to enter PC=0, the CM0+ core must assign an interrupt vector or
135 * an exception handler address to the CPUSS.CM0_PC0_HANDLER register. This
136 * allows the hardware to check whether the executing code address matches the
137 * value in this register. If they match, the current PC value is saved and
138 * the CM0+ bus master automatically transitions to PC=0. It is then up to
139 * the executing code to decide if and when it will revert to a PC!=0 value.
140 * At that point, the only way to re-transition to PC=0 is through the defined
141 * exception/interrupt handler.
142 *
143 * \note Devices with CPUSS ver_2 have a hardware-controlled protection context
144 * update mechanism that allows only a single-entry point for transitioning
145 * into PC=0, 1, 2, and 3. The interrupt vector or the exception handler
146 * address can be assigned to the CPUSS.CM0_PC0_HANDLER, CPUSS.CM0_PC1_HANDLER,
147 * CPUSS.CM0_PC2_HANDLER or CPUSS.CM0_PC2_HANDLER register. Also, the control
148 * register CPUSS.CM0_PC_CTL of the CM0+ protection context must be set:
149 * bit 0 - the valid field for CM0_PC0_HANDLER,
150 * bit 1 - the valid field for CM0_PC1_HANDLER,
151 * bit 2 - the valid field for CM0_PC2_HANDLER,
152 * and bit 3 - the valid field for CM0_PC3_HANDLER.
153 *
154 * The example of using of the single entry point mechanism is shown below.
155 * \snippet prot/snippet/main.c snippet_Cy_Prot_ProtectionContext
156 *
157 * \section group_prot_access_evaluation Access Evaluation
158 *
159 * Each protection unit is capable of evaluating several access types. These can
160 * be used to build a system of logical evaluations for different kinds of
161 * bus master modes of operations. These access types can be divided into
162 * three broad access categories.
163 *
164 * - <b>User/Privileged access:</b> The ARM convention of user mode versus privileged
165 * mode is applied in the protection units. For ARM cores, switching between
166 * user and privileged modes is handled by updating its Control register or
167 * by exception entries. Other bus masters such as Crypto have their own
168 * user/privileged settings bit in the bus master control register. This is
169 * then controlled by the ARM cores. Bus masters that do not have
170 * user/privileged access controls, such as DMA, inherit their attributes
171 * from the bus master that configured it. The user/privileged distinction
172 * is used mainly in the MPUs for single bus master accesses but they can
173 * also be used in all other protection units.
174 * - <b>Secure/Non-secure access:</b> The secure/non-secure attribute is another
175 * identifier to distinguish between two separate modes of operations. Much
176 * like the user/privileged access, the secure/non-secure mode flag is present
177 * in the bus master control register. The ARM core does not have this
178 * attribute in its control register and must use the bus master control
179 * register instead. Bus masters that inherit their attributes, such as DMA,
180 * inherit the secure/non-secure attribute. The primary use-case for this
181 * access evaluation is to define a region to be secure or non-secure using
182 * an SMPU or a PPU. A bus master with a secure attribute can access
183 * both secure and non-secure regions, whereas a bus master with non-secure
184 * attribute can only access non-secure regions.
185 * - <b>Protection Context access:</b> Protection Context is an attribute
186 * that serves two purposes; To enter the hardware controlled secure PC=0
187 * mode of operation from non-secure modes and to provide finer granularity
188 * to the bus master access definitions. It is used in SMPU and PPU configuration
189 * to control which bus master protection context can access the resources
190 * that they protect.
191 *
192 * \section group_prot_protection_structure Protection Structure
193 *
194 * Each protection unit is comprised of a master struct and a slave struct pair.
195 * The exception to this rule is MPU structs, which only have the slave struct
196 * equivalent. The protection units apply their access evaluations in a decreasing
197 * index order. For example, if SMPU1 and SMPU2 both protect a specific memory region,
198 * the the higher index (SMPU2) will be evaluated first. In a secure system, the
199 * higher index protection structs would then provide the high level of security
200 * and the lower indexes would provide the lower level of security. Refer to the
201 * \ref group_prot_protection_type section for more information.
202 *
203 * \subsection group_prot_slave_struct Slave Struct
204 *
205 * The slave struct is used to configure the protection settings for the resource
206 * of interest (memory/registers). Depending on the type of protection unit,
207 * the available attributes differ. However all Slave protection units have the
208 * following general format.
209 *
210 * \subsubsection group_prot_slave_addr Slave Struct Address Definition
211 *
212 * - Address: For MPU, SMPU and PROG PPU, the address field is used to define
213 * the base memory region to apply the protection. This field has a dependency
214 * on the region size, which dictates the alignment of the protection unit. E.g.
215 * if the region size is 64KB, the address field is aligned to 64KB. Hence
216 * the lowest bits [15:0] are ignored. For instance, if the address is defined
217 * at 0x0800FFFF, the protection unit would apply its protection settings from
218 * 0x08000000. Thus alignment must be checked before defining the protection
219 * address. The address field for other PPUs are not used, as they are bound
220 * to their respective peripheral memory locations.
221 * - Region Size: For MPU, SMPU and PROG PPU, the region size is used to define
222 * the memory block size to apply the protection settings, starting from the
223 * defined base address. It is also used to define the 8 sub-regions for the
224 * chosen memory block. E.g. If the region size is 64KB, each subregion would
225 * be 8KB. This information can then be used to disable the protection
226 * settings for select subregions, which gives finer granularity to the
227 * memory regions. PPUs do not have region size definitions as they are bound
228 * to their respective peripheral memory locations.
229 * - Subregions: The memory block defined by the address and region size fields
230 * is divided into 8 (0 to 7) equally spaced subregions. The protection settings
231 * of the protection unit can be disabled for these subregions. E.g. for a
232 * given 64KB of memory block starting from address 0x08000000, disabling
233 * subregion 0 would result in the protection settings not affecting the memory
234 * located between 0x08000000 to 0x08001FFF. PPUs do not have subregion
235 * definitions as they are bound to their respective peripheral memory locations.
236 *
237 * \subsubsection group_prot_slave_attr Slave Struct Attribute Definition
238 *
239 * - User Permission: Protection units can control the access restrictions
240 * of the read (R), write (W) and execute (X) (subject to their availability
241 * depending on the type of protection unit) operations on the memory block
242 * when the bus master is operating in user mode. PPU structs do not provide
243 * execute attributes.
244 * - Privileged Permission: Similar to the user permission, protection units can
245 * control the access restrictions of the read (R), write (W) and execute (X)
246 * (subject to their availability depending on the type of protection unit)
247 * operations on the memory block when the bus master is operating in
248 * privileged mode. PPU structs do not provide execute attributes.
249 * - Secure/Non-secure: Applies the secure/non-secure protection settings to
250 * the defined memory region. Secure protection allows only bus masters that
251 * access the memory with secure attribute. Non-secure protection allows
252 * bus masters that have either secure or non-secure attributes.
253 * - PC match: This attribute allows the protection unit to either apply the
254 * 3 access evaluations (user/privileged, secure/non-secure, protection context)
255 * or to only provide an address range match. This is useful when multiple
256 * protection units protect an overlapping memory region and it's desirable
257 * to only have access evaluations applied from only one of these protection
258 * units. For example, SMPU1 protects memory A and SMPU2 protects memory B.
259 * There exists a region where A and B intersect and this is accessed by a
260 * bus master. Both SMPU1 and SMPU2 are configured to operate in "match" mode.
261 * In this scenario, the access evaluation will only be applied by the higher
262 * index protection unit (i.e. SMPU2) and the access attributes of SMPU1 will
263 * be ignored. If the bus master then tries to access a memory region A (that
264 * does not intersect with B), the access evaluation from SMPU1 will be used.
265 * Note that the PC match functionality is only available in SMPUs.
266 * - PC mask: Defines the allowed protection context values that can access the
267 * protected memory. The bus master attribute must be operating in one of the
268 * protection context values allowed by the protection unit. E.g. If SMPU1 is
269 * configured to allow only PC=1 and PC=5, a bus master (such as CM4) must
270 * be operating at PC=1 or PC=5 when accessing the protected memory region.
271 *
272 * \subsection group_prot_master_struct Master Struct
273 *
274 * The master struct protects its slave struct in the protection unit. This
275 * architecture makes possible for the slave configuration to be protected from
276 * reconfiguration by an unauthorized bus master. The configuration attributes
277 * and the format are similar to that of the slave structs.
278 *
279 * \subsubsection group_prot_master_addr Master Struct Address Definition
280 *
281 * - Address: The address definition for master struct is fixed to the slave
282 * struct that it protects.
283 * - Region Size: The region size is fixed to 256B region.
284 * - Subregion: This value is fixed to only enable the first 64B subregions,
285 * which applies the protection settings to the entire protection unit.
286 *
287 * \subsubsection group_prot_master_attr Master Struct Attribute Definition
288 *
289 * - User Permission: Only the write (W) access attribute is allowed for
290 * master structs, which controls whether a bus master operating in user
291 * mode has the write access.
292 * - Privileged Permission: Only the write (W) access attribute is allowed for
293 * master structs, which controls whether a bus master operating in privileged
294 * mode has the write access.
295 * - Secure/Non-Secure: Same behavior as slave struct.
296 * - PC match: Same behavior as slave struct.
297 * - PC mask: Same behavior as slave struct.
298 *
299 * \section group_prot_driver_usage Driver Usage
300 *
301 * Setting up and using protection units can be summed up in four stages:
302 *
303 * - Configure the bus master attributes. This defines the capabilities of
304 * the bus master when trying to access the protected resources.
305 * - Configure the slave struct of a given protection unit. This defines
306 * the protection attributes to be applied to the bus master accessing
307 * the protected resource and also defines the size and location of the
308 * memory block to protect.
309 * - Configure the master struct of the protection unit. This defines the
310 * attributes to be checked against the bus master that is trying to
311 * reconfigure the slave struct.
312 * - Set the active PC value of the bus master and place it in the correct
313 * mode of operation (user/privileged, secure/non-secure). Then access
314 * the protected memory.
315 *
316 * For example, by configuring the CM0+ bus master configuration to allow
317 * only protection contexts 2 and 3, the bus master will be able to
318 * set its protection context only to 2 or 3. During runtime, the CM0+ core
319 * can set its protection context to 2 by calling Cy_Prot_SetActivePC()
320 * and access all regions of protected memory that allow PC=2. A fault will
321 * be triggered if a resource is protected with different protection settings.
322 *
323 * Note that each protection unit is distinguished by its type (e.g.
324 * PROT_MPU_MPU_STRUCT_Type). The list of supported protection units can be
325 * obtained from the device definition header file. Choose a protection unit
326 * of interest, and call its corresponding Cy_Prot_Config<X>Struct() function
327 * with its software protection unit configuration structure populated. Then
328 * enable the protection unit by calling the Cy_Prot_Enable<X>Struct() function.
329 *
330 * Note that the bus master ID (en_prot_master_t) is defined in the device
331 * config header file.
332 *
333 * \section group_prot_configuration Configuration Considerations
334 *
335 * When a resource (memory/register) is accessed, it must pass evaluation of
336 * all three protection unit categories in the following order: MPU->SMPU->PPU.
337 * The application should ensure that a denial-of-service attack cannot be
338 * made on the PPU by the SMPU. For this reason, it is recommended that the
339 * application's security policy limit the ability for the non-secure client
340 * from configuring the SMPUs.
341 *
342 * Within each category, the priority hierarchy must be carefully considered
343 * to ensure that a higher priority protection unit cannot be configured to
344 * override the security configuration of a lower index protection unit.
345 * Therefore if a lower index protection unit is configured, relevant higher
346 * priority indexes should be configured (or protected from unwanted
347 * reconfiguration). E.g. If a PPU_SL is configured, PPU_RG and PPU_GR that
348 * overlaps with the protected registers should also be configured. SImilar
349 * to SMPUs, it is recommended that the configuration of PPU_PROG be limited.
350 * Otherwise they can be used to override the protection settings of PPU_RG
351 * and PPU_SL structs.
352 *
353 * All bus masters are set to PC=0 value at device reset and therefore have full
354 * access to all resources. It is up to the security solution to implement
355 * what privileges each bus master has. Once transitioned to a PC!=0 value,
356 * only the CM0+ core is capable of re-entering the PC=0 via the user-defined
357 * exception entry in the CPUSS.CM0_PC0_HANDLER register.
358 *
359 * - SMPU 15 and 14 are configured and enabled to only allow PC=0 accesses at
360 * device boot.
361 * - PROG PPU 15, 14, 13 and 12 are configured to only allow PC=0 accesses at
362 * device boot.
363 * - GR PPU 0 and 2 are configured to only allow PC=0 accesses at device boot.
364 *
365 * \section group_prot_more_information More Information
366 *
367 * Refer to Technical Reference Manual (TRM) and the device datasheet.
368 *
369 * \section group_prot_changelog Changelog
370 * <table class="doxtable">
371 * <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
372 * <tr>
373 * <td>1.60</td>
374 * <td>Modified \ref Cy_Prot_ConfigPpuProgMasterAtt() & \ref Cy_Prot_ConfigPpuFixedMasterAtt()
375 * functions to ignore unavailable protection context.</td>
376 * <td>Defect fix.</td>
377 * </tr>
378 * <tr>
379 * <td rowspan="3">1.50</td>
380 * <td>Updated implementation of the \ref Cy_Prot_ConfigPpuProgMasterAtt(),
381 * \ref Cy_Prot_ConfigPpuProgSlaveAtt(), \ref Cy_Prot_ConfigPpuFixedMasterAtt(),
382 * and \ref Cy_Prot_ConfigPpuFixedSlaveAtt() to start registers update from
383 * the higher-numbered PCs in order to prevent lockup for the case when registers
384 * are configured to read-only.</td>
385 * <td>Defect fix.</td>
386 * </tr>
387 * <tr>
388 * <td>Added macros for memory region size setting in \ref cy_en_prot_size_t initialization.</td>
389 * <td>The macros can be useful for the pre-processor checks.</td>
390 * </tr>
391 * <tr>
392 * <td>Fixed/Documented MISRA 2012 violations.</td>
393 * <td>MISRA 2012 compliance.</td>
394 * </tr>
395 * <tr>
396 * <td>1.40</td>
397 * <td>
398 * - Updated the \ref Cy_Prot_SetActivePC() function to report an error when called
399 * on the secure CYB06xx7 devices as no access privileges are available.
400 * - Updated the \ref Cy_Prot_GetActivePC() function for the secure CYB06xx7
401 * devices to access the protected registers via the \ref group_pra driver.
402 * </td>
403 * <td>Added PSoC 64 devices support.</td>
404 * </tr>
405 * <tr>
406 * <td>1.30.3</td>
407 * <td>Minor documentation updates.</td>
408 * <td>Documentation enhancement.</td>
409 * </tr>
410 * <tr>
411 * <td>1.30.2</td>
412 * <td>Clarified the description of the next API functions: \ref Cy_Prot_ConfigPpuProgMasterAtt,\n
413 * \ref Cy_Prot_ConfigPpuProgSlaveAtt, \ref Cy_Prot_ConfigPpuFixedMasterAtt, \ref Cy_Prot_ConfigPpuFixedSlaveAtt.</td>
414 * <td>API enhancement based on usability feedback.</td>
415 * </tr>
416 * <tr>
417 * <td>1.30.1</td>
418 * <td>Snippet updated.</td>
419 * <td>Old snippet outdated.</td>
420 * </tr>
421 * <tr>
422 * <td>1.30</td>
423 * <td>Defect in \ref Cy_Prot_GetPpuProgStruct() function due to faulty defines is fixed.</td>
424 * <td>Defect fixing.</td>
425 * </tr>
426 * <tr>
427 * <td rowspan="3">1.20</td>
428 * <td>Flattened the organization of the driver source code into the single
429 * source directory and the single include directory.</td>
430 * <td>Driver library directory-structure simplification.</td>
431 * </tr>
432 * <tr>
433 * <td>Added functions for CPUSS ver_2:
434 * - \ref Cy_Prot_ConfigPpuProgMasterAtt()
435 * - \ref Cy_Prot_ConfigPpuProgSlaveAddr()
436 * - \ref Cy_Prot_ConfigPpuProgSlaveAtt()
437 * - \ref Cy_Prot_EnablePpuProgSlaveRegion()
438 * - \ref Cy_Prot_DisablePpuProgSlaveRegion()
439 * - \ref Cy_Prot_ConfigPpuFixedMasterAtt()
440 * - \ref Cy_Prot_ConfigPpuFixedSlaveAtt()
441 * </td>
442 * <td>Added support for CPUSS ver_2.</td>
443 * </tr>
444 * <tr>
445 * <td>Added register access layer. Use register access macros instead
446 * of direct register access using dereferenced pointers.</td>
447 * <td>Makes register access device-independent, so that the PDL does
448 * not need to be recompiled for each supported part number.</td>
449 * </tr>
450 * <tr>
451 * <td rowspan="2">1.10</td>
452 * <td>Added input parameter validation to the API functions.<br>
453 * cy_en_prot_pcmask_t, cy_en_prot_subreg_t and cy_en_prot_pc_t
454 * types are set to typedef enum</td>
455 * <td>Improved debugging capability</td>
456 * </tr>
457 * <tr>
458 * <td>Expanded documentation</td>
459 * <td></td>
460 * </tr>
461 * <tr>
462 * <td>1.0</td>
463 * <td>Initial version</td>
464 * <td></td>
465 * </tr>
466 * </table>
467 *
468 * \defgroup group_prot_macros Macros
469 * \defgroup group_prot_functions Functions
470 * \{
471 * \defgroup group_prot_functions_busmaster Bus Master and PC Functions
472 * \defgroup group_prot_functions_mpu MPU Functions
473 * \defgroup group_prot_functions_smpu SMPU Functions
474 * \defgroup group_prot_functions_ppu_prog_v2 PPU Programmable (PROG) v2 Functions
475 * \defgroup group_prot_functions_ppu_fixed_v2 PPU Fixed (FIXED) v2 Functions
476 * \defgroup group_prot_functions_ppu_prog PPU Programmable (PROG) v1 Functions
477 * \defgroup group_prot_functions_ppu_gr PPU Group (GR) v1 Functions
478 * \defgroup group_prot_functions_ppu_sl PPU Slave (SL) v1 Functions
479 * \defgroup group_prot_functions_ppu_rg PPU Region (RG) v1 Functions
480 * \}
481 * \defgroup group_prot_data_structures Data Structures
482 * \defgroup group_prot_enums Enumerated Types
483 */
484
485 #if !defined (CY_CY_PROT_PDL_H)
486 #define CY_CY_PROT_PDL_H
487
488 #include "cy_device.h"
489
490 #if defined (CY_IP_M4CPUSS)
491
492 #include <stdbool.h>
493 #include <stddef.h>
494 #include "cy_device_headers.h"
495 #include "cy_syslib.h"
496
497 #if defined(__cplusplus)
498 extern "C" {
499 #endif
500
501 /** \addtogroup group_prot_macros
502 * \{
503 */
504
505 /** Driver major version */
506 #define CY_PROT_DRV_VERSION_MAJOR 1
507
508 /** Driver minor version */
509 #define CY_PROT_DRV_VERSION_MINOR 60
510
511 /** Prot driver ID */
512 #define CY_PROT_ID (CY_PDL_DRV_ID(0x30U))
513
514 /** \} group_prot_macros */
515
516 /**
517 * \addtogroup group_prot_enums
518 * \{
519 */
520
521 /**
522 * Prot Driver error codes
523 */
524 typedef enum
525 {
526 CY_PROT_SUCCESS = 0x00U, /**< Returned successful */
527 CY_PROT_BAD_PARAM = CY_PROT_ID | CY_PDL_STATUS_ERROR | 0x01U, /**< Bad parameter was passed */
528 CY_PROT_INVALID_STATE = CY_PROT_ID | CY_PDL_STATUS_ERROR | 0x02U, /**< The operation is not setup */
529 CY_PROT_FAILURE = CY_PROT_ID | CY_PDL_STATUS_ERROR | 0x03U, /**< The resource is locked */
530 CY_PROT_UNAVAILABLE = CY_PROT_ID | CY_PDL_STATUS_ERROR | 0x04U /**< The resource is unavailable */
531 } cy_en_prot_status_t;
532
533 /**
534 * User/Privileged permission
535 */
536 typedef enum
537 {
538 CY_PROT_PERM_DISABLED = 0x00U, /**< Read, Write and Execute disabled */
539 CY_PROT_PERM_R = 0x01U, /**< Read enabled */
540 CY_PROT_PERM_W = 0x02U, /**< Write enabled */
541 CY_PROT_PERM_RW = 0x03U, /**< Read and Write enabled */
542 CY_PROT_PERM_X = 0x04U, /**< Execute enabled */
543 CY_PROT_PERM_RX = 0x05U, /**< Read and Execute enabled */
544 CY_PROT_PERM_WX = 0x06U, /**< Write and Execute enabled */
545 CY_PROT_PERM_RWX = 0x07U /**< Read, Write and Execute enabled */
546 }cy_en_prot_perm_t;
547
548 /**
549 * Constants for memory region size setting.
550 * These may be useful for pre-processor-time tests.
551 */
552 #define PROT_SIZE_4B_BIT_SHIFT 1U /**< 4 bytes */
553 #define PROT_SIZE_8B_BIT_SHIFT 2U /**< 8 bytes */
554 #define PROT_SIZE_16B_BIT_SHIFT 3U /**< 16 bytes */
555 #define PROT_SIZE_32B_BIT_SHIFT 4U /**< 32 bytes */
556 #define PROT_SIZE_64B_BIT_SHIFT 5U /**< 64 bytes */
557 #define PROT_SIZE_128B_BIT_SHIFT 6U /**< 128 bytes */
558 #define PROT_SIZE_256B_BIT_SHIFT 7U /**< 256 bytes */
559 #define PROT_SIZE_512B_BIT_SHIFT 8U /**< 512 bytes */
560
561 #define PROT_SIZE_1KB_BIT_SHIFT 9U /**< 1 Kilobyte */
562 #define PROT_SIZE_2KB_BIT_SHIFT 10U /**< 2 Kilobytes */
563 #define PROT_SIZE_4KB_BIT_SHIFT 11U /**< 4 Kilobytes */
564 #define PROT_SIZE_8KB_BIT_SHIFT 12U /**< 8 Kilobytes */
565 #define PROT_SIZE_16KB_BIT_SHIFT 13U /**< 16 Kilobytes */
566 #define PROT_SIZE_32KB_BIT_SHIFT 14U /**< 32 Kilobytes */
567 #define PROT_SIZE_64KB_BIT_SHIFT 15U /**< 64 Kilobytes */
568 #define PROT_SIZE_128KB_BIT_SHIFT 16U /**< 128 Kilobytes */
569 #define PROT_SIZE_256KB_BIT_SHIFT 17U /**< 256 Kilobytes */
570 #define PROT_SIZE_512KB_BIT_SHIFT 18U /**< 512 Kilobytes */
571
572 #define PROT_SIZE_1MB_BIT_SHIFT 19U /**< 1 Megabyte */
573 #define PROT_SIZE_2MB_BIT_SHIFT 20U /**< 2 Megabytes */
574 #define PROT_SIZE_4MB_BIT_SHIFT 21U /**< 4 Megabytes */
575 #define PROT_SIZE_8MB_BIT_SHIFT 22U /**< 8 Megabytes */
576 #define PROT_SIZE_16MB_BIT_SHIFT 23U /**< 16 Megabytes */
577 #define PROT_SIZE_32MB_BIT_SHIFT 24U /**< 32 Megabytes */
578 #define PROT_SIZE_64MB_BIT_SHIFT 25U /**< 64 Megabytes */
579 #define PROT_SIZE_128MB_BIT_SHIFT 26U /**< 128 Megabytes */
580 #define PROT_SIZE_256MB_BIT_SHIFT 27U /**< 256 Megabytes */
581 #define PROT_SIZE_512MB_BIT_SHIFT 28U /**< 512 Megabytes */
582
583 #define PROT_SIZE_1GB_BIT_SHIFT 29U /**< 1 Gigabyte */
584 #define PROT_SIZE_2GB_BIT_SHIFT 30U /**< 2 Gigabytes */
585 #define PROT_SIZE_4GB_BIT_SHIFT 31U /**< 4 Gigabytes */
586
587 /**
588 * Memory region size
589 */
590 typedef enum
591 {
592 CY_PROT_SIZE_4B = PROT_SIZE_4B_BIT_SHIFT, /**< 4 bytes */
593 CY_PROT_SIZE_8B = PROT_SIZE_8B_BIT_SHIFT, /**< 8 bytes */
594 CY_PROT_SIZE_16B = PROT_SIZE_16B_BIT_SHIFT, /**< 16 bytes */
595 CY_PROT_SIZE_32B = PROT_SIZE_32B_BIT_SHIFT, /**< 32 bytes */
596 CY_PROT_SIZE_64B = PROT_SIZE_64B_BIT_SHIFT, /**< 64 bytes */
597 CY_PROT_SIZE_128B = PROT_SIZE_128B_BIT_SHIFT, /**< 128 bytes */
598 CY_PROT_SIZE_256B = PROT_SIZE_256B_BIT_SHIFT, /**< 256 bytes */
599 CY_PROT_SIZE_512B = PROT_SIZE_512B_BIT_SHIFT, /**< 512 bytes */
600 CY_PROT_SIZE_1KB = PROT_SIZE_1KB_BIT_SHIFT, /**< 1 Kilobyte */
601 CY_PROT_SIZE_2KB = PROT_SIZE_2KB_BIT_SHIFT, /**< 2 Kilobytes */
602 CY_PROT_SIZE_4KB = PROT_SIZE_4KB_BIT_SHIFT, /**< 4 Kilobytes */
603 CY_PROT_SIZE_8KB = PROT_SIZE_8KB_BIT_SHIFT, /**< 8 Kilobytes */
604 CY_PROT_SIZE_16KB = PROT_SIZE_16KB_BIT_SHIFT, /**< 16 Kilobytes */
605 CY_PROT_SIZE_32KB = PROT_SIZE_32KB_BIT_SHIFT, /**< 32 Kilobytes */
606 CY_PROT_SIZE_64KB = PROT_SIZE_64KB_BIT_SHIFT, /**< 64 Kilobytes */
607 CY_PROT_SIZE_128KB = PROT_SIZE_128KB_BIT_SHIFT, /**< 128 Kilobytes */
608 CY_PROT_SIZE_256KB = PROT_SIZE_256KB_BIT_SHIFT, /**< 256 Kilobytes */
609 CY_PROT_SIZE_512KB = PROT_SIZE_512KB_BIT_SHIFT, /**< 512 Kilobytes */
610 CY_PROT_SIZE_1MB = PROT_SIZE_1MB_BIT_SHIFT, /**< 1 Megabyte */
611 CY_PROT_SIZE_2MB = PROT_SIZE_2MB_BIT_SHIFT, /**< 2 Megabytes */
612 CY_PROT_SIZE_4MB = PROT_SIZE_4MB_BIT_SHIFT, /**< 4 Megabytes */
613 CY_PROT_SIZE_8MB = PROT_SIZE_8MB_BIT_SHIFT, /**< 8 Megabytes */
614 CY_PROT_SIZE_16MB = PROT_SIZE_16MB_BIT_SHIFT, /**< 16 Megabytes */
615 CY_PROT_SIZE_32MB = PROT_SIZE_32MB_BIT_SHIFT, /**< 32 Megabytes */
616 CY_PROT_SIZE_64MB = PROT_SIZE_64MB_BIT_SHIFT, /**< 64 Megabytes */
617 CY_PROT_SIZE_128MB = PROT_SIZE_128MB_BIT_SHIFT, /**< 128 Megabytes */
618 CY_PROT_SIZE_256MB = PROT_SIZE_256MB_BIT_SHIFT, /**< 256 Megabytes */
619 CY_PROT_SIZE_512MB = PROT_SIZE_512MB_BIT_SHIFT, /**< 512 Megabytes */
620 CY_PROT_SIZE_1GB = PROT_SIZE_1GB_BIT_SHIFT, /**< 1 Gigabyte */
621 CY_PROT_SIZE_2GB = PROT_SIZE_2GB_BIT_SHIFT, /**< 2 Gigabytes */
622 CY_PROT_SIZE_4GB = PROT_SIZE_4GB_BIT_SHIFT /**< 4 Gigabytes */
623 }cy_en_prot_size_t;
624
625 /**
626 * Protection Context (PC)
627 */
628 enum cy_en_prot_pc_t
629 {
630 CY_PROT_PC1 = 1U, /**< PC = 1 */
631 CY_PROT_PC2 = 2U, /**< PC = 2 */
632 CY_PROT_PC3 = 3U, /**< PC = 3 */
633 CY_PROT_PC4 = 4U, /**< PC = 4 */
634 CY_PROT_PC5 = 5U, /**< PC = 5 */
635 CY_PROT_PC6 = 6U, /**< PC = 6 */
636 CY_PROT_PC7 = 7U, /**< PC = 7 */
637 CY_PROT_PC8 = 8U, /**< PC = 8 */
638 CY_PROT_PC9 = 9U, /**< PC = 9 */
639 CY_PROT_PC10 = 10U, /**< PC = 10 */
640 CY_PROT_PC11 = 11U, /**< PC = 11 */
641 CY_PROT_PC12 = 12U, /**< PC = 12 */
642 CY_PROT_PC13 = 13U, /**< PC = 13 */
643 CY_PROT_PC14 = 14U, /**< PC = 14 */
644 CY_PROT_PC15 = 15U /**< PC = 15 */
645 };
646
647 /**
648 * Subregion disable (0-7)
649 */
650 enum cy_en_prot_subreg_t
651 {
652 CY_PROT_SUBREGION_DIS0 = 0x01U, /**< Disable subregion 0 */
653 CY_PROT_SUBREGION_DIS1 = 0x02U, /**< Disable subregion 1 */
654 CY_PROT_SUBREGION_DIS2 = 0x04U, /**< Disable subregion 2 */
655 CY_PROT_SUBREGION_DIS3 = 0x08U, /**< Disable subregion 3 */
656 CY_PROT_SUBREGION_DIS4 = 0x10U, /**< Disable subregion 4 */
657 CY_PROT_SUBREGION_DIS5 = 0x20U, /**< Disable subregion 5 */
658 CY_PROT_SUBREGION_DIS6 = 0x40U, /**< Disable subregion 6 */
659 CY_PROT_SUBREGION_DIS7 = 0x80U /**< Disable subregion 7 */
660 };
661
662 /**
663 * Protection context mask (PC_MASK)
664 */
665 enum cy_en_prot_pcmask_t
666 {
667 CY_PROT_PCMASK1 = 0x0001U, /**< Mask to allow PC = 1 */
668 CY_PROT_PCMASK2 = 0x0002U, /**< Mask to allow PC = 2 */
669 CY_PROT_PCMASK3 = 0x0004U, /**< Mask to allow PC = 3 */
670 CY_PROT_PCMASK4 = 0x0008U, /**< Mask to allow PC = 4 */
671 CY_PROT_PCMASK5 = 0x0010U, /**< Mask to allow PC = 5 */
672 CY_PROT_PCMASK6 = 0x0020U, /**< Mask to allow PC = 6 */
673 CY_PROT_PCMASK7 = 0x0040U, /**< Mask to allow PC = 7 */
674 CY_PROT_PCMASK8 = 0x0080U, /**< Mask to allow PC = 8 */
675 CY_PROT_PCMASK9 = 0x0100U, /**< Mask to allow PC = 9 */
676 CY_PROT_PCMASK10 = 0x0200U, /**< Mask to allow PC = 10 */
677 CY_PROT_PCMASK11 = 0x0400U, /**< Mask to allow PC = 11 */
678 CY_PROT_PCMASK12 = 0x0800U, /**< Mask to allow PC = 12 */
679 CY_PROT_PCMASK13 = 0x1000U, /**< Mask to allow PC = 13 */
680 CY_PROT_PCMASK14 = 0x2000U, /**< Mask to allow PC = 14 */
681 CY_PROT_PCMASK15 = 0x4000U /**< Mask to allow PC = 15 */
682 };
683
684 /**
685 * Request mode to get the SMPU or programmed PU structure
686 */
687 typedef enum
688 {
689 CY_PROT_REQMODE_HIGHPRIOR = 0U, /**< Request mode to return PU structure with highest priority */
690 CY_PROT_REQMODE_LOWPRIOR = 1U, /**< Request mode to return PU structure with lowest priority */
691 CY_PROT_REQMODE_INDEX = 2U /**< Request mode to return PU structure with specific index */
692 }cy_en_prot_req_mode_t;
693
694 /** \} group_prot_enums */
695
696
697 /***************************************
698 * Constants
699 ***************************************/
700
701 /** \cond INTERNAL */
702
703 /* Number of SMPU structures with highest priority */
704 #define PROT_SMPU_STRUCT_WTH_HIGHEST_PR (15)
705
706 /* Number of Programmable PPU structures with lowest priority */
707 #define PROT_PPU_PROG_STRUCT_WTH_LOWEST_PR (15)
708
709 /* Define to check maximum value of active PC */
710 #define PROT_PC_MAX (16U)
711
712 /* Define to check maximum mask of PC */
713 #define PROT_PC_MASK_MAX (0x7FFFUL)
714
715 #if defined (CY_IP_MXPERI_VERSION) && (CY_IP_MXPERI_VERSION == 1U)
716 typedef PERI_MS_PPU_PR_V2_Type PERI_MS_PPU_PR_Type;
717 typedef PERI_MS_PPU_FX_V2_Type PERI_MS_PPU_FX_Type;
718 #endif /* defined (CY_IP_MXPERI_VERSION) && (CY_IP_MXPERI_VERSION == 1U) */
719
720 #if defined (CY_IP_MXPERI_VERSION) && (CY_IP_MXPERI_VERSION > 1U)
721 typedef PERI_PPU_PR_V1_Type PERI_PPU_PR_Type;
722 typedef PERI_PPU_GR_V1_Type PERI_PPU_GR_Type;
723 typedef PERI_GR_PPU_SL_V1_Type PERI_GR_PPU_SL_Type;
724 typedef PERI_GR_PPU_RG_V1_Type PERI_GR_PPU_RG_Type;
725 #endif /* defined (CY_IP_MXPERI_VERSION) && (CY_IP_MXPERI_VERSION > 1U) */
726
727
728 /* General Masks and shifts */
729 #define CY_PROT_MSX_CTL_SHIFT (0x02UL) /**< Shift for MSx_CTL register */
730 #define CY_PROT_STRUCT_ENABLE (0x01UL) /**< Enable protection unit struct */
731 #define CY_PROT_STRUCT_DISABLE (0x00UL) /**< Disable protection unit struct */
732 #define CY_PROT_ADDR_SHIFT (8UL) /**< Address shift for MPU, SMPU and PROG PPU structs */
733 #define CY_PROT_PCMASK_CHECK (0x01UL) /**< Shift and mask for pcMask check */
734 #define CY_PROT_PCMASK_VALID ((0xFFFFUL) & (~(0xFFFFUL << PERI_PC_NR))) /**< Bitmask to mask pcMask for unavailable protection contexts */
735
736 /* Permission masks and shifts */
737 #define CY_PROT_ATT_PERMISSION_MASK (0x07UL) /**< Protection Unit attribute permission mask */
738 #define CY_PROT_ATT_PRIV_PERMISSION_SHIFT (0x03UL) /**< Protection Unit privileged attribute permission shift */
739
740 #define CY_PROT_ATT_PERI_USER_PERM_Pos (0UL) /**< PERI v2 privileged attribute permission shift */
741 #define CY_PROT_ATT_PERI_USER_PERM_Msk (0x03UL) /**< PERI v2 attribute permission mask */
742 #define CY_PROT_ATT_PERI_PRIV_PERM_Pos (2UL) /**< PERI v2 privileged attribute permission shift */
743 #define CY_PROT_ATT_PERI_PRIV_PERM_Msk ((uint32_t)(0x03UL << CY_PROT_ATT_PERI_PRIV_PERM_Pos)) /**< PERI v2 attribute permission mask */
744
745 #define CY_PROT_ATT_REGS_MAX (4U) /**< Maximum number of ATT registers */
746 #define CY_PROT_ATT_PC_MAX (4U) /**< Maximum PC value per ATT reg */
747
748 /* BWC macros */
749 #define CY_PROT_ATT_PERI_PERM_MASK (0x03UL)
750 #define CY_PROT_ATT_PERI_PRIV_PERM_SHIFT (0x02UL)
751 /* End of BWC macros */
752
753 #define CY_PROT_SMPU_PC_LIMIT_MASK ((uint32_t) 0xFFFFFFFFUL << (CY_PROT_PC_MAX - 1UL))
754 #define CY_PROT_PPU_PROG_PC_LIMIT_MASK ((uint32_t) 0xFFFFFFFFUL << (CY_PROT_PC_MAX - 1UL))
755 #define CY_PROT_PPU_FIXED_PC_LIMIT_MASK ((uint32_t) 0xFFFFFFFFUL << (CY_PROT_PC_MAX - 1UL))
756
757 #define CY_PROT_SMPU_ATT0_MASK ((uint32_t)~(PROT_SMPU_SMPU_STRUCT_ATT0_PC_MASK_0_Msk))
758 #define CY_PROT_SMPU_ATT1_MASK ((uint32_t)~(PROT_SMPU_SMPU_STRUCT_ATT1_UX_Msk \
759 | PROT_SMPU_SMPU_STRUCT_ATT1_PX_Msk \
760 | PROT_SMPU_SMPU_STRUCT_ATT1_PC_MASK_0_Msk \
761 | PROT_SMPU_SMPU_STRUCT_ATT1_REGION_SIZE_Msk \
762 ))
763
764 #define CY_PROT_PPU_PROG_ATT0_MASK ((uint32_t)~(PERI_PPU_PR_ATT0_UX_Msk \
765 | PERI_PPU_PR_ATT0_PX_Msk \
766 | PERI_PPU_PR_ATT0_PC_MASK_0_Msk \
767 ))
768 #define CY_PROT_PPU_PROG_ATT1_MASK ((uint32_t)~(PERI_PPU_PR_ATT1_UX_Msk \
769 | PERI_PPU_PR_ATT1_PX_Msk \
770 | PERI_PPU_PR_ATT1_PC_MASK_0_Msk \
771 | PERI_PPU_PR_ATT1_REGION_SIZE_Msk \
772 ))
773 #define CY_PROT_PPU_GR_ATT0_MASK ((uint32_t)~(PERI_PPU_GR_ATT0_UX_Msk \
774 | PERI_PPU_GR_ATT0_PX_Msk \
775 | PERI_PPU_GR_ATT0_PC_MASK_0_Msk \
776 | PERI_PPU_GR_ATT0_REGION_SIZE_Msk \
777 ))
778 #define CY_PROT_PPU_GR_ATT1_MASK ((uint32_t)~(PERI_PPU_GR_ATT1_UX_Msk \
779 | PERI_PPU_GR_ATT1_PX_Msk \
780 | PERI_PPU_GR_ATT1_PC_MASK_0_Msk \
781 | PERI_PPU_GR_ATT1_REGION_SIZE_Msk \
782 ))
783 #define CY_PROT_PPU_SL_ATT0_MASK ((uint32_t)~(PERI_PPU_GR_ATT0_UX_Msk \
784 | PERI_PPU_GR_ATT0_PX_Msk \
785 | PERI_PPU_GR_ATT0_PC_MASK_0_Msk \
786 | PERI_PPU_GR_ATT0_REGION_SIZE_Msk \
787 ))
788 #define CY_PROT_PPU_SL_ATT1_MASK ((uint32_t)~(PERI_PPU_GR_ATT1_UX_Msk \
789 | PERI_PPU_GR_ATT1_PX_Msk \
790 | PERI_PPU_GR_ATT1_PC_MASK_0_Msk \
791 | PERI_PPU_GR_ATT1_REGION_SIZE_Msk \
792 ))
793 #define CY_PROT_PPU_RG_ATT0_MASK ((uint32_t)~(PERI_PPU_GR_ATT0_UX_Msk \
794 | PERI_PPU_GR_ATT0_PX_Msk \
795 | PERI_PPU_GR_ATT0_PC_MASK_0_Msk \
796 | PERI_PPU_GR_ATT0_REGION_SIZE_Msk \
797 ))
798 #define CY_PROT_PPU_RG_ATT1_MASK ((uint32_t)~(PERI_PPU_GR_ATT1_UX_Msk \
799 | PERI_PPU_GR_ATT1_PX_Msk \
800 | PERI_PPU_GR_ATT1_PC_MASK_0_Msk \
801 | PERI_PPU_GR_ATT1_REGION_SIZE_Msk \
802 ))
803
804 /* Parameter check macros */
805 #define CY_PROT_IS_BUS_MASTER_VALID(busMaster) ((CY_PROT_BUS_MASTER_MASK & (1UL << (uint32_t)(busMaster))) != 0UL)
806
807 #define CY_PROT_IS_MPU_PERM_VALID(permission) (((permission) == CY_PROT_PERM_DISABLED) || \
808 ((permission) == CY_PROT_PERM_R) || \
809 ((permission) == CY_PROT_PERM_W) || \
810 ((permission) == CY_PROT_PERM_RW) || \
811 ((permission) == CY_PROT_PERM_X) || \
812 ((permission) == CY_PROT_PERM_RX) || \
813 ((permission) == CY_PROT_PERM_WX) || \
814 ((permission) == CY_PROT_PERM_RWX))
815
816 #define CY_PROT_IS_SMPU_MS_PERM_VALID(permission) (((permission) == CY_PROT_PERM_R) || \
817 ((permission) == CY_PROT_PERM_RW))
818
819 #define CY_PROT_IS_SMPU_SL_PERM_VALID(permission) (((permission) == CY_PROT_PERM_DISABLED) || \
820 ((permission) == CY_PROT_PERM_R) || \
821 ((permission) == CY_PROT_PERM_W) || \
822 ((permission) == CY_PROT_PERM_RW) || \
823 ((permission) == CY_PROT_PERM_X) || \
824 ((permission) == CY_PROT_PERM_RX) || \
825 ((permission) == CY_PROT_PERM_WX) || \
826 ((permission) == CY_PROT_PERM_RWX))
827
828 #define CY_PROT_IS_PROG_MS_PERM_VALID(permission) (((permission) == CY_PROT_PERM_R) || \
829 ((permission) == CY_PROT_PERM_RW))
830
831 #define CY_PROT_IS_PROG_SL_PERM_VALID(permission) (((permission) == CY_PROT_PERM_DISABLED) || \
832 ((permission) == CY_PROT_PERM_R) || \
833 ((permission) == CY_PROT_PERM_W) || \
834 ((permission) == CY_PROT_PERM_RW))
835
836 #define CY_PROT_IS_FIXED_MS_PERM_VALID(permission) (((permission) == CY_PROT_PERM_DISABLED) || \
837 ((permission) == CY_PROT_PERM_R) || \
838 ((permission) == CY_PROT_PERM_W) || \
839 ((permission) == CY_PROT_PERM_RW))
840
841 #define CY_PROT_IS_FIXED_MS_MS_PERM_VALID(permission) (((permission) == CY_PROT_PERM_R) || \
842 ((permission) == CY_PROT_PERM_RW))
843
844
845 #define CY_PROT_IS_FIXED_SL_PERM_VALID(permission) (((permission) == CY_PROT_PERM_DISABLED) || \
846 ((permission) == CY_PROT_PERM_R) || \
847 ((permission) == CY_PROT_PERM_W) || \
848 ((permission) == CY_PROT_PERM_RW))
849
850 #define CY_PROT_IS_REGION_SIZE_VALID(regionSize) (((regionSize) == CY_PROT_SIZE_256B) || \
851 ((regionSize) == CY_PROT_SIZE_512B) || \
852 ((regionSize) == CY_PROT_SIZE_1KB) || \
853 ((regionSize) == CY_PROT_SIZE_2KB) || \
854 ((regionSize) == CY_PROT_SIZE_4KB) || \
855 ((regionSize) == CY_PROT_SIZE_8KB) || \
856 ((regionSize) == CY_PROT_SIZE_16KB) || \
857 ((regionSize) == CY_PROT_SIZE_32KB) || \
858 ((regionSize) == CY_PROT_SIZE_64KB) || \
859 ((regionSize) == CY_PROT_SIZE_128KB) || \
860 ((regionSize) == CY_PROT_SIZE_256KB) || \
861 ((regionSize) == CY_PROT_SIZE_512KB) || \
862 ((regionSize) == CY_PROT_SIZE_1MB) || \
863 ((regionSize) == CY_PROT_SIZE_2MB) || \
864 ((regionSize) == CY_PROT_SIZE_4MB) || \
865 ((regionSize) == CY_PROT_SIZE_8MB) || \
866 ((regionSize) == CY_PROT_SIZE_16MB) || \
867 ((regionSize) == CY_PROT_SIZE_32MB) || \
868 ((regionSize) == CY_PROT_SIZE_64MB) || \
869 ((regionSize) == CY_PROT_SIZE_128MB) || \
870 ((regionSize) == CY_PROT_SIZE_256MB) || \
871 ((regionSize) == CY_PROT_SIZE_512MB) || \
872 ((regionSize) == CY_PROT_SIZE_1GB) || \
873 ((regionSize) == CY_PROT_SIZE_2GB) || \
874 ((regionSize) == CY_PROT_SIZE_4GB))
875
876 #define CY_PROT_IS_PPU_V2_SIZE_VALID(regionSize) (((regionSize) == CY_PROT_SIZE_4B) || \
877 ((regionSize) == CY_PROT_SIZE_8B) || \
878 ((regionSize) == CY_PROT_SIZE_16B) || \
879 ((regionSize) == CY_PROT_SIZE_32B) || \
880 ((regionSize) == CY_PROT_SIZE_64B) || \
881 ((regionSize) == CY_PROT_SIZE_128B) || \
882 ((regionSize) == CY_PROT_SIZE_256B) || \
883 ((regionSize) == CY_PROT_SIZE_512B) || \
884 ((regionSize) == CY_PROT_SIZE_1KB) || \
885 ((regionSize) == CY_PROT_SIZE_2KB) || \
886 ((regionSize) == CY_PROT_SIZE_4KB) || \
887 ((regionSize) == CY_PROT_SIZE_8KB) || \
888 ((regionSize) == CY_PROT_SIZE_16KB) || \
889 ((regionSize) == CY_PROT_SIZE_32KB) || \
890 ((regionSize) == CY_PROT_SIZE_64KB) || \
891 ((regionSize) == CY_PROT_SIZE_128KB) || \
892 ((regionSize) == CY_PROT_SIZE_256KB) || \
893 ((regionSize) == CY_PROT_SIZE_512KB) || \
894 ((regionSize) == CY_PROT_SIZE_1MB) || \
895 ((regionSize) == CY_PROT_SIZE_2MB) || \
896 ((regionSize) == CY_PROT_SIZE_4MB) || \
897 ((regionSize) == CY_PROT_SIZE_8MB) || \
898 ((regionSize) == CY_PROT_SIZE_16MB) || \
899 ((regionSize) == CY_PROT_SIZE_32MB) || \
900 ((regionSize) == CY_PROT_SIZE_64MB) || \
901 ((regionSize) == CY_PROT_SIZE_128MB) || \
902 ((regionSize) == CY_PROT_SIZE_256MB) || \
903 ((regionSize) == CY_PROT_SIZE_512MB) || \
904 ((regionSize) == CY_PROT_SIZE_1GB) || \
905 ((regionSize) == CY_PROT_SIZE_2GB) || \
906 ((regionSize) == CY_PROT_SIZE_4GB))
907
908 #define CY_PROT_IS_SMPU_REQ_MODE_VALID(reqMode) (((reqMode) == CY_PROT_REQMODE_HIGHPRIOR) || \
909 ((reqMode) == CY_PROT_REQMODE_LOWPRIOR) || \
910 ((reqMode) == CY_PROT_REQMODE_INDEX))
911
912 #define CY_PROT_IS_PPU_PROG_REQ_MODE_VALID(reqMode) (((reqMode) == CY_PROT_REQMODE_HIGHPRIOR) || \
913 ((reqMode) == CY_PROT_REQMODE_LOWPRIOR) || \
914 ((reqMode) == CY_PROT_REQMODE_INDEX))
915
916 #define CY_PROT_IS_SMPU_IDX_VALID(smpuIndex) ((smpuIndex) <= (uint32_t)PROT_SMPU_STRUCT_WTH_HIGHEST_PR)
917
918 #define CY_PROT_IS_PPU_PROG_IDX_VALID(ppuIndex) ((ppuIndex) <= (uint32_t)PROT_PPU_PROG_STRUCT_WTH_LOWEST_PR)
919
920 #define CY_PROT_IS_PC_VALID(pc) ((pc) < PROT_PC_MAX)
921 #define CY_PROT_IS_PC_MASK_VALID(pcMask) (((pcMask) & ((uint32_t)~PROT_PC_MASK_MAX)) == 0UL)
922
923 /** \endcond */
924
925
926 /***************************************
927 * Configuration Structures
928 ***************************************/
929
930 /**
931 * \addtogroup group_prot_data_structures
932 * \{
933 */
934
935 /** Configuration structure for MPU Struct initialization */
936 typedef struct
937 {
938 uint32_t* address; /**< Base address of the memory region */
939 cy_en_prot_size_t regionSize; /**< Size of the memory region */
940 uint8_t subregions; /**< Mask of the 8 subregions to disable */
941 cy_en_prot_perm_t userPermission; /**< User permissions for the region */
942 cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
943 bool secure; /**< Non Secure = 0, Secure = 1 */
944 } cy_stc_mpu_cfg_t;
945
946 /** Configuration structure for SMPU struct initialization */
947 typedef struct
948 {
949 uint32_t* address; /**< Base address of the memory region (Only applicable to slave) */
950 cy_en_prot_size_t regionSize; /**< Size of the memory region (Only applicable to slave) */
951 uint8_t subregions; /**< Mask of the 8 subregions to disable (Only applicable to slave) */
952 cy_en_prot_perm_t userPermission; /**< User permissions for the region */
953 cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
954 bool secure; /**< Non Secure = 0, Secure = 1 */
955 bool pcMatch; /**< Access evaluation = 0, Matching = 1 */
956 uint16_t pcMask; /**< Mask of allowed protection context(s) */
957 } cy_stc_smpu_cfg_t;
958
959 /** Configuration structure for Programmable (PROG) PPU (PPU_PR) struct initialization */
960 typedef struct
961 {
962 uint32_t* address; /**< Base address of the memory region (Only applicable to slave) */
963 cy_en_prot_size_t regionSize; /**< Size of the memory region (Only applicable to slave) */
964 uint8_t subregions; /**< Mask of the 8 subregions to disable (Only applicable to slave) */
965 cy_en_prot_perm_t userPermission; /**< User permissions for the region */
966 cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
967 bool secure; /**< Non Secure = 0, Secure = 1 */
968 bool pcMatch; /**< Access evaluation = 0, Matching = 1 */
969 uint16_t pcMask; /**< Mask of allowed protection context(s) */
970 } cy_stc_ppu_prog_cfg_t;
971
972 /** Configuration structure for Fixed Group (GR) PPU (PPU_GR) struct initialization */
973 typedef struct
974 {
975 cy_en_prot_perm_t userPermission; /**< User permissions for the region */
976 cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
977 bool secure; /**< Non Secure = 0, Secure = 1 */
978 bool pcMatch; /**< Access evaluation = 0, Matching = 1 */
979 uint16_t pcMask; /**< Mask of allowed protection context(s) */
980 } cy_stc_ppu_gr_cfg_t;
981
982 /** Configuration structure for Fixed Slave (SL) PPU (PPU_SL) struct initialization */
983 typedef struct
984 {
985 cy_en_prot_perm_t userPermission; /**< User permissions for the region */
986 cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
987 bool secure; /**< Non Secure = 0, Secure = 1 */
988 bool pcMatch; /**< Access evaluation = 0, Matching = 1 */
989 uint16_t pcMask; /**< Mask of allowed protection context(s) */
990 } cy_stc_ppu_sl_cfg_t;
991
992 /** Configuration structure for Fixed Region (RG) PPU (PPU_RG) struct initialization */
993 typedef struct
994 {
995 cy_en_prot_perm_t userPermission; /**< User permissions for the region */
996 cy_en_prot_perm_t privPermission; /**< Privileged permissions for the region */
997 bool secure; /**< Non Secure = 0, Secure = 1 */
998 bool pcMatch; /**< Access evaluation = 0, Matching = 1 */
999 uint16_t pcMask; /**< Mask of allowed protection context(s) */
1000 } cy_stc_ppu_rg_cfg_t;
1001
1002 /** \} group_prot_data_structures */
1003
1004
1005 /***************************************
1006 * Function Prototypes
1007 ***************************************/
1008
1009 /**
1010 * \addtogroup group_prot_functions
1011 * \{
1012 */
1013
1014 /**
1015 * \addtogroup group_prot_functions_busmaster
1016 * \{
1017 */
1018 cy_en_prot_status_t Cy_Prot_ConfigBusMaster(en_prot_master_t busMaster, bool privileged, bool secure, uint32_t pcMask);
1019 cy_en_prot_status_t Cy_Prot_SetActivePC(en_prot_master_t busMaster, uint32_t pc);
1020 uint32_t Cy_Prot_GetActivePC(en_prot_master_t busMaster);
1021 /** \} group_prot_functions_busmaster */
1022
1023 /**
1024 * \addtogroup group_prot_functions_mpu
1025 * \{
1026 */
1027 cy_en_prot_status_t Cy_Prot_ConfigMpuStruct(PROT_MPU_MPU_STRUCT_Type* base, const cy_stc_mpu_cfg_t* config);
1028 cy_en_prot_status_t Cy_Prot_EnableMpuStruct(PROT_MPU_MPU_STRUCT_Type* base);
1029 cy_en_prot_status_t Cy_Prot_DisableMpuStruct(PROT_MPU_MPU_STRUCT_Type* base);
1030 /** \} group_prot_functions_mpu */
1031
1032 /**
1033 * \addtogroup group_prot_functions_smpu
1034 * \{
1035 */
1036 __STATIC_INLINE cy_en_prot_status_t Cy_Prot_DisableSmpuStruct(PROT_SMPU_SMPU_STRUCT_Type* base);
1037 cy_en_prot_status_t Cy_Prot_GetSmpuStruct(PROT_SMPU_SMPU_STRUCT_Type** base, cy_en_prot_req_mode_t reqMode, uint32_t smpuIndex);
1038
1039 cy_en_prot_status_t Cy_Prot_ConfigSmpuMasterStruct(PROT_SMPU_SMPU_STRUCT_Type* base, const cy_stc_smpu_cfg_t* config);
1040 cy_en_prot_status_t Cy_Prot_ConfigSmpuSlaveStruct(PROT_SMPU_SMPU_STRUCT_Type* base, const cy_stc_smpu_cfg_t* config);
1041 cy_en_prot_status_t Cy_Prot_EnableSmpuMasterStruct(PROT_SMPU_SMPU_STRUCT_Type* base);
1042 cy_en_prot_status_t Cy_Prot_DisableSmpuMasterStruct(PROT_SMPU_SMPU_STRUCT_Type* base);
1043 cy_en_prot_status_t Cy_Prot_EnableSmpuSlaveStruct(PROT_SMPU_SMPU_STRUCT_Type* base);
1044 cy_en_prot_status_t Cy_Prot_DisableSmpuSlaveStruct(PROT_SMPU_SMPU_STRUCT_Type* base);
1045
1046 /** \} group_prot_functions_smpu */
1047
1048
1049
1050 /**
1051 * \addtogroup group_prot_functions_ppu_prog_v2
1052 * \{
1053 */
1054 cy_en_prot_status_t Cy_Prot_ConfigPpuProgMasterAtt(PERI_MS_PPU_PR_Type* base, uint16_t pcMask, cy_en_prot_perm_t userPermission, cy_en_prot_perm_t privPermission, bool secure);
1055 cy_en_prot_status_t Cy_Prot_ConfigPpuProgSlaveAddr(PERI_MS_PPU_PR_Type* base, uint32_t address, cy_en_prot_size_t regionSize);
1056 cy_en_prot_status_t Cy_Prot_ConfigPpuProgSlaveAtt(PERI_MS_PPU_PR_Type* base, uint16_t pcMask, cy_en_prot_perm_t userPermission, cy_en_prot_perm_t privPermission, bool secure);
1057 cy_en_prot_status_t Cy_Prot_EnablePpuProgSlaveRegion(PERI_MS_PPU_PR_Type* base);
1058 cy_en_prot_status_t Cy_Prot_DisablePpuProgSlaveRegion(PERI_MS_PPU_PR_Type* base);
1059
1060 /** \} group_prot_functions_ppu_prog_v2 */
1061
1062 /**
1063 * \addtogroup group_prot_functions_ppu_fixed_v2
1064 * \{
1065 */
1066 cy_en_prot_status_t Cy_Prot_ConfigPpuFixedMasterAtt(PERI_MS_PPU_FX_Type* base, uint16_t pcMask, cy_en_prot_perm_t userPermission, cy_en_prot_perm_t privPermission, bool secure);
1067 cy_en_prot_status_t Cy_Prot_ConfigPpuFixedSlaveAtt(PERI_MS_PPU_FX_Type* base, uint16_t pcMask, cy_en_prot_perm_t userPermission, cy_en_prot_perm_t privPermission, bool secure);
1068 /** \} group_prot_functions_ppu_fixed_v2 */
1069
1070
1071 /**
1072 * \addtogroup group_prot_functions_ppu_prog
1073 * \{
1074 */
1075 __STATIC_INLINE cy_en_prot_status_t Cy_Prot_DisablePpuProgStruct(PERI_PPU_PR_Type* base);
1076
1077 cy_en_prot_status_t Cy_Prot_ConfigPpuProgMasterStruct(PERI_PPU_PR_Type* base, const cy_stc_ppu_prog_cfg_t* config);
1078 cy_en_prot_status_t Cy_Prot_ConfigPpuProgSlaveStruct(PERI_PPU_PR_Type* base, const cy_stc_ppu_prog_cfg_t* config);
1079 cy_en_prot_status_t Cy_Prot_EnablePpuProgMasterStruct(PERI_PPU_PR_Type* base);
1080 cy_en_prot_status_t Cy_Prot_DisablePpuProgMasterStruct(PERI_PPU_PR_Type* base);
1081 cy_en_prot_status_t Cy_Prot_EnablePpuProgSlaveStruct(PERI_PPU_PR_Type* base);
1082 cy_en_prot_status_t Cy_Prot_DisablePpuProgSlaveStruct(PERI_PPU_PR_Type* base);
1083
1084 cy_en_prot_status_t Cy_Prot_GetPpuProgStruct(PERI_PPU_PR_Type** base, cy_en_prot_req_mode_t reqMode, uint32_t ppuProgIndex);
1085
1086 /** \} group_prot_functions_ppu_prog */
1087
1088 /**
1089 * \addtogroup group_prot_functions_ppu_gr
1090 * \{
1091 */
1092 cy_en_prot_status_t Cy_Prot_ConfigPpuFixedGrMasterStruct(PERI_PPU_GR_Type* base, const cy_stc_ppu_gr_cfg_t* config);
1093 cy_en_prot_status_t Cy_Prot_ConfigPpuFixedGrSlaveStruct(PERI_PPU_GR_Type* base, const cy_stc_ppu_gr_cfg_t* config);
1094 cy_en_prot_status_t Cy_Prot_EnablePpuFixedGrMasterStruct(PERI_PPU_GR_Type* base);
1095 cy_en_prot_status_t Cy_Prot_DisablePpuFixedGrMasterStruct(PERI_PPU_GR_Type* base);
1096 cy_en_prot_status_t Cy_Prot_EnablePpuFixedGrSlaveStruct(PERI_PPU_GR_Type* base);
1097 cy_en_prot_status_t Cy_Prot_DisablePpuFixedGrSlaveStruct(PERI_PPU_GR_Type* base);
1098 /** \} group_prot_functions_ppu_gr */
1099
1100 /**
1101 * \addtogroup group_prot_functions_ppu_sl
1102 * \{
1103 */
1104 cy_en_prot_status_t Cy_Prot_ConfigPpuFixedSlMasterStruct(PERI_GR_PPU_SL_Type* base, const cy_stc_ppu_sl_cfg_t* config);
1105 cy_en_prot_status_t Cy_Prot_ConfigPpuFixedSlSlaveStruct(PERI_GR_PPU_SL_Type* base, const cy_stc_ppu_sl_cfg_t* config);
1106 cy_en_prot_status_t Cy_Prot_EnablePpuFixedSlMasterStruct(PERI_GR_PPU_SL_Type* base);
1107 cy_en_prot_status_t Cy_Prot_DisablePpuFixedSlMasterStruct(PERI_GR_PPU_SL_Type* base);
1108 cy_en_prot_status_t Cy_Prot_EnablePpuFixedSlSlaveStruct(PERI_GR_PPU_SL_Type* base);
1109 cy_en_prot_status_t Cy_Prot_DisablePpuFixedSlSlaveStruct(PERI_GR_PPU_SL_Type* base);
1110 /** \} group_prot_functions_ppu_sl */
1111
1112 /**
1113 * \addtogroup group_prot_functions_ppu_rg
1114 * \{
1115 */
1116 cy_en_prot_status_t Cy_Prot_ConfigPpuFixedRgMasterStruct(PERI_GR_PPU_RG_Type* base, const cy_stc_ppu_rg_cfg_t* config);
1117 cy_en_prot_status_t Cy_Prot_ConfigPpuFixedRgSlaveStruct(PERI_GR_PPU_RG_Type* base, const cy_stc_ppu_rg_cfg_t* config);
1118 cy_en_prot_status_t Cy_Prot_EnablePpuFixedRgMasterStruct(PERI_GR_PPU_RG_Type* base);
1119 cy_en_prot_status_t Cy_Prot_DisablePpuFixedRgMasterStruct(PERI_GR_PPU_RG_Type* base);
1120 cy_en_prot_status_t Cy_Prot_EnablePpuFixedRgSlaveStruct(PERI_GR_PPU_RG_Type* base);
1121 cy_en_prot_status_t Cy_Prot_DisablePpuFixedRgSlaveStruct(PERI_GR_PPU_RG_Type* base);
1122 /** \} group_prot_functions_ppu_rg */
1123
1124 /** \} group_prot_functions */
1125
1126
1127
1128 /**
1129 * \addtogroup group_prot_functions
1130 * \{
1131 */
1132
1133 /**
1134 * \addtogroup group_prot_functions_smpu
1135 * \{
1136 */
1137
1138 /*******************************************************************************
1139 * Function Name: Cy_Prot_DisableSmpuStruct
1140 ****************************************************************************//**
1141 *
1142 * This function disables both the master and slave parts of a protection unit.
1143 *
1144 * \param base
1145 * The base address for the SMPU structure to be disabled.
1146 *
1147 * \return
1148 * Status of the function call.
1149 *
1150 * Status | Description
1151 * ---------------------| -----------
1152 * CY_PROT_SUCCESS | The Master and Slave SMPU struct was disabled
1153 * CY_PROT_FAILURE | The Master and/or slave SMPU struct was not disabled
1154 * CY_PROT_INVALID_STATE | Function was called on the unsupported PERI IP version
1155 *
1156 * \funcusage
1157 * \snippet prot/snippet/main.c snippet_Cy_Prot_DisableSmpuStruct
1158 *
1159 *******************************************************************************/
Cy_Prot_DisableSmpuStruct(PROT_SMPU_SMPU_STRUCT_Type * base)1160 __STATIC_INLINE cy_en_prot_status_t Cy_Prot_DisableSmpuStruct(PROT_SMPU_SMPU_STRUCT_Type* base)
1161 {
1162 cy_en_prot_status_t status = Cy_Prot_DisableSmpuMasterStruct(base);
1163
1164 if (CY_PROT_SUCCESS == status)
1165 {
1166 status = Cy_Prot_DisableSmpuSlaveStruct(base);
1167 }
1168
1169 return status;
1170 }
1171 /** \} group_prot_functions_smpu */
1172
1173
1174 /**
1175 * \addtogroup group_prot_functions_ppu_prog
1176 * \{
1177 */
1178 /*******************************************************************************
1179 * Function Name: Cy_Prot_DisablePpuProgStruct
1180 ****************************************************************************//**
1181 *
1182 * This function disables both the master and slave parts of a protection unit.
1183 *
1184 * \note
1185 * This functions has an effect only on devices with PERI IP version 1. Refer
1186 * to the device datasheet for information about PERI HW IP version.
1187 *
1188 * \param base
1189 * The base address for the Programmable PU structure to be disabled.
1190 *
1191 * \return
1192 * Status of the function call.
1193 *
1194 * Status | Description
1195 * ---------------------| -----------
1196 * CY_PROT_SUCCESS | The Master and Slave Programmable PU struct was disabled
1197 * CY_PROT_FAILURE | The Master and/or slave Programmable PU struct was not disabled
1198 * CY_PROT_INVALID_STATE | Function was called on the unsupported PERI IP version
1199 *
1200 * \funcusage
1201 * \snippet prot/snippet/main.c snippet_Cy_Prot_DisablePpuProgStruct
1202 *
1203 *******************************************************************************/
Cy_Prot_DisablePpuProgStruct(PERI_PPU_PR_Type * base)1204 __STATIC_INLINE cy_en_prot_status_t Cy_Prot_DisablePpuProgStruct(PERI_PPU_PR_Type* base)
1205 {
1206 cy_en_prot_status_t status = CY_PROT_INVALID_STATE;
1207
1208 if (CY_PERI_V1)
1209 {
1210 status = Cy_Prot_DisablePpuProgMasterStruct(base);
1211
1212 if (CY_PROT_SUCCESS == status)
1213 {
1214 status = Cy_Prot_DisablePpuProgSlaveStruct(base);
1215 }
1216 }
1217
1218 return status;
1219 }
1220 /** \} group_prot_functions_ppu_prog */
1221 /** \} group_prot_functions */
1222 /** \} group_prot */
1223
1224 #if defined(__cplusplus)
1225 }
1226 #endif
1227
1228 #endif /* CY_IP_M4CPUSS */
1229
1230 #endif /* CY_PROT_H */
1231