You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by je...@apache.org on 2022/04/21 09:58:10 UTC

[mynewt-core] 01/04: mcu/nrf5340: Add memory protection with MPU

This is an automated email from the ASF dual-hosted git repository.

jerzy pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit 6c79dae60d57af6fe86bb3133a5dfb9e2f97d67d
Author: Jerzy Kasenberg <je...@codecoup.pl>
AuthorDate: Wed Apr 20 13:17:44 2022 +0200

    mcu/nrf5340: Add memory protection with MPU
    
    This change allows enabling MPU with configuration
    that will protect against:
    - code execution from RAM
    - modification of bootloader and image in slot 0
    - bootloader code read (this can also help with NULL pointer access)
    - execution code from non-slot0 area
    
    Signed-off-by: Jerzy Kasenberg <je...@codecoup.pl>
---
 hw/mcu/nordic/nrf5340/mpu/pkg.yml    | 29 ++++++++++++
 hw/mcu/nordic/nrf5340/mpu/src/mpu.c  | 89 ++++++++++++++++++++++++++++++++++++
 hw/mcu/nordic/nrf5340/mpu/syscfg.yml | 19 ++++++++
 hw/mcu/nordic/nrf5340/pkg.yml        |  3 ++
 hw/mcu/nordic/nrf5340/syscfg.yml     |  5 ++
 5 files changed, 145 insertions(+)

diff --git a/hw/mcu/nordic/nrf5340/mpu/pkg.yml b/hw/mcu/nordic/nrf5340/mpu/pkg.yml
new file mode 100644
index 000000000..161a81c91
--- /dev/null
+++ b/hw/mcu/nordic/nrf5340/mpu/pkg.yml
@@ -0,0 +1,29 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+
+pkg.name: hw/mcu/nordic/nrf5340/mpu
+pkg.description: MPU configuration package
+pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+    - nrf5340
+    - MPU
+
+pkg.init:
+    mpu_pkg_init: $after:flash_map_init
diff --git a/hw/mcu/nordic/nrf5340/mpu/src/mpu.c b/hw/mcu/nordic/nrf5340/mpu/src/mpu.c
new file mode 100644
index 000000000..23de061d8
--- /dev/null
+++ b/hw/mcu/nordic/nrf5340/mpu/src/mpu.c
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <os/mynewt.h>
+#include <hal/hal_spi.h>
+#include <nrf.h>
+#include <bsp/bsp.h>
+
+void
+mpu_pkg_init(void)
+{
+    const struct flash_area *fa;
+    ARM_MPU_Region_t regions[5];
+    uint32_t bootloader_end = 0;
+    int region_index;
+    /*
+     * Protect settings:
+     *              read        write      execute
+     *              ------------------------------
+     * RAM            +           +          -
+     * Flash:
+     * - Bootloader   -           -          -
+     * - Slot0        +           -          +
+     * - Rest         +           +          -
+     * Peripherals:   +           +          -
+     */
+
+    ARM_MPU_Disable();
+    /* Set Attr 0 */
+    ARM_MPU_SetMemAttr(0UL, ARM_MPU_ATTR(           /* Normal memory */
+        ARM_MPU_ATTR_MEMORY_(0UL, 1UL, 1UL, 1UL),   /* Outer Write-Back transient with read and write allocate */
+        ARM_MPU_ATTR_MEMORY_(0UL, 0UL, 1UL, 1UL))); /* Inner Write-Through transient with read and write allocate */
+
+    /* RAM */
+    regions[0].RBAR = ARM_MPU_RBAR((uint32_t)&_ram_start, ARM_MPU_SH_OUTER, 0UL, 1UL, 1UL);
+    regions[0].RLAR = ARM_MPU_RLAR(((uint32_t)&_ram_start + RAM_SIZE - 1), 0UL);
+    region_index = 1;
+
+    if (flash_area_open(FLASH_AREA_BOOTLOADER, &fa) == 0) {
+        bootloader_end = fa->fa_size;
+    }
+#if MYNEWT_VAL(BOOT_LOADER)
+    if (bootloader_end) {
+        /* Bootloader read/exec */
+        regions[region_index].RBAR = ARM_MPU_RBAR(0, ARM_MPU_SH_NON, 1UL, 1UL, 0UL);
+        regions[region_index].RLAR = ARM_MPU_RLAR((bootloader_end - 1), 0UL);
+        region_index++;
+    }
+#endif
+    if (flash_area_open(FLASH_AREA_IMAGE_0, &fa) == 0) {
+        /* Flash between bootloader and SLOT0 marked as read/write */
+        if (fa->fa_off > bootloader_end) {
+            regions[region_index].RBAR = ARM_MPU_RBAR(bootloader_end, ARM_MPU_SH_NON, 0UL, 1UL, 1UL);
+            regions[region_index].RLAR = ARM_MPU_RLAR((fa->fa_off - 1), 0UL);
+            region_index++;
+        }
+        /* SLOT0 read/exec */
+        regions[region_index].RBAR = ARM_MPU_RBAR(fa->fa_off, ARM_MPU_SH_NON, 1UL, 1UL, 0UL);
+        regions[region_index].RLAR = ARM_MPU_RLAR((fa->fa_off + fa->fa_size - 0x1000 - 1), 0UL);
+        region_index++;
+        /* Rest of flash read/write */
+        regions[region_index].RBAR = ARM_MPU_RBAR((fa->fa_off + fa->fa_size - 0x1000), ARM_MPU_SH_NON, 0UL, 1UL, 1UL);
+        regions[region_index].RLAR = ARM_MPU_RLAR((0x100000 - 1), 0UL);
+        region_index++;
+        /* Peripherals read/write */
+        regions[region_index].RBAR = ARM_MPU_RBAR(0x40000000, ARM_MPU_SH_OUTER, 0UL, 1UL, 1UL);
+        regions[region_index].RLAR = ARM_MPU_RLAR((0xF0000000 - 1), 0UL);
+        region_index++;
+        ARM_MPU_Load(0, regions, region_index);
+        /* Enable MPU with no default map, only explicit regions are allowed */
+        ARM_MPU_Enable(0);
+    }
+}
diff --git a/hw/mcu/nordic/nrf5340/mpu/syscfg.yml b/hw/mcu/nordic/nrf5340/mpu/syscfg.yml
new file mode 100644
index 000000000..2cdd57468
--- /dev/null
+++ b/hw/mcu/nordic/nrf5340/mpu/syscfg.yml
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you 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.
+#
+
+syscfg.defs:
diff --git a/hw/mcu/nordic/nrf5340/pkg.yml b/hw/mcu/nordic/nrf5340/pkg.yml
index b1dd4c9b5..9d3406039 100644
--- a/hw/mcu/nordic/nrf5340/pkg.yml
+++ b/hw/mcu/nordic/nrf5340/pkg.yml
@@ -109,3 +109,6 @@ pkg.deps.NRF5340_EMBED_NET_CORE:
 
 pkg.cflags.MCU_NRF5340_EN_APPROTECT_USERHANDLING:
     - "-DENABLE_APPROTECT_USER_HANDLING"
+
+pkg.deps.MCU_MPU_ENABLE:
+    - "@apache-mynewt-core/hw/mcu/nordic/nrf5340/mpu"
diff --git a/hw/mcu/nordic/nrf5340/syscfg.yml b/hw/mcu/nordic/nrf5340/syscfg.yml
index 0a7142543..e0b0115e7 100644
--- a/hw/mcu/nordic/nrf5340/syscfg.yml
+++ b/hw/mcu/nordic/nrf5340/syscfg.yml
@@ -560,6 +560,11 @@ syscfg.defs:
         description: Embed net core image in application image for single image build.
         value: 0
 
+    MCU_MPU_ENABLE:
+        description: >
+            Adds default MPU configuration package
+        value: 0
+
 syscfg.vals:
     OS_TICKS_PER_SEC: 128