|
14 | 14 | #include <kernel_arch_data.h>
|
15 | 15 | #include <zephyr/mem_mgmt/mem_attr.h>
|
16 | 16 | #include <zephyr/dt-bindings/memory-attr/memory-attr-arm.h>
|
| 17 | +#include <zephyr/arch/arm/mpu/arm_mpu.h> |
17 | 18 |
|
18 | 19 | #define LOG_LEVEL CONFIG_MPU_LOG_LEVEL
|
19 | 20 | #include <zephyr/logging/log.h>
|
20 | 21 | LOG_MODULE_DECLARE(mpu);
|
21 | 22 |
|
| 23 | +#if Z_ARM_CPU_HAS_PMSAV8_MPU |
| 24 | +#define ATTRIBUTE_AND_SIZE_REG_NAME RLAR |
| 25 | +#else |
| 26 | +#define ATTRIBUTE_AND_SIZE_REG_NAME RASR |
| 27 | +#endif |
| 28 | + |
22 | 29 | #if defined(CONFIG_ARMV8_M_BASELINE) || defined(CONFIG_ARMV8_M_MAINLINE)
|
23 | 30 | /* The order here is on purpose since ARMv8-M SoCs may define
|
24 | 31 | * CONFIG_ARMV6_M_ARMV8_M_BASELINE or CONFIG_ARMV7_M_ARMV8_M_MAINLINE
|
@@ -407,6 +414,72 @@ void arm_core_mpu_configure_dynamic_mpu_regions(const struct z_arm_mpu_partition
|
407 | 414 | }
|
408 | 415 | }
|
409 | 416 |
|
| 417 | +#if defined(CONFIG_CPU_CORTEX_M) |
| 418 | +/** |
| 419 | + * @brief Save the current MPU configuration into the provided context struct. |
| 420 | + */ |
| 421 | +void z_arm_save_mpu_context(struct z_mpu_context_retained *ctx) |
| 422 | +{ |
| 423 | + uint32_t regions = get_num_regions(); |
| 424 | + |
| 425 | + __ASSERT_NO_MSG(ctx != NULL); |
| 426 | + |
| 427 | + if (regions == 0 || regions > Z_ARM_MPU_MAX_REGIONS) { |
| 428 | + LOG_DBG("Invalid MPU region count: %u", regions); |
| 429 | + ctx->num_valid_regions = 0; |
| 430 | + return; |
| 431 | + } |
| 432 | + |
| 433 | + ctx->num_valid_regions = regions; |
| 434 | + |
| 435 | + for (uint32_t i = 0; i < regions; i++) { |
| 436 | + MPU->RNR = i; |
| 437 | + __DSB(); /* Ensure MPU->RNR write completes before reading registers */ |
| 438 | + __ISB(); |
| 439 | + ctx->rbar[i] = MPU->RBAR; |
| 440 | + ctx->rasr_rlar[i] = MPU->ATTRIBUTE_AND_SIZE_REG_NAME; |
| 441 | + } |
| 442 | +#if Z_ARM_CPU_HAS_PMSAV8_MPU |
| 443 | + ctx->mair[0] = MPU->MAIR0; |
| 444 | + ctx->mair[1] = MPU->MAIR1; |
| 445 | +#endif |
| 446 | + ctx->ctrl = MPU->CTRL; |
| 447 | +} |
| 448 | + |
| 449 | +/** |
| 450 | + * @brief Restore the MPU configuration from the provided context struct. |
| 451 | + */ |
| 452 | +void z_arm_restore_mpu_context(const struct z_mpu_context_retained *ctx) |
| 453 | +{ |
| 454 | + __ASSERT_NO_MSG(ctx != NULL); |
| 455 | + |
| 456 | + if (ctx->num_valid_regions == 0 || ctx->num_valid_regions > Z_ARM_MPU_MAX_REGIONS) { |
| 457 | + LOG_DBG("Invalid MPU context num_valid_regions: %u", ctx->num_valid_regions); |
| 458 | + return; |
| 459 | + } |
| 460 | + |
| 461 | + /* Disable MPU before reprogramming */ |
| 462 | + arm_core_mpu_disable(); |
| 463 | + |
| 464 | + for (uint32_t i = 0; i < ctx->num_valid_regions; i++) { |
| 465 | + MPU->RNR = i; |
| 466 | + MPU->RBAR = ctx->rbar[i]; |
| 467 | + MPU->ATTRIBUTE_AND_SIZE_REG_NAME = ctx->rasr_rlar[i]; |
| 468 | + } |
| 469 | + |
| 470 | +#if Z_ARM_CPU_HAS_PMSAV8_MPU |
| 471 | + MPU->MAIR0 = ctx->mair[0]; |
| 472 | + MPU->MAIR1 = ctx->mair[1]; |
| 473 | +#endif |
| 474 | + /* Restore MPU control register (including enable bit if set) */ |
| 475 | + MPU->CTRL = ctx->ctrl; |
| 476 | + |
| 477 | + /* Ensure MPU settings take effect before continuing */ |
| 478 | + __DSB(); |
| 479 | + __ISB(); |
| 480 | +} |
| 481 | +#endif /* CONFIG_CPU_CORTEX_M */ |
| 482 | + |
410 | 483 | /* ARM MPU Driver Initial Setup */
|
411 | 484 |
|
412 | 485 | /*
|
|
0 commit comments