You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2018/11/08 07:41:26 UTC

[GitHub] kasjer closed pull request #1490: Hal flash write protection

kasjer closed pull request #1490: Hal flash write protection
URL: https://github.com/apache/mynewt-core/pull/1490
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/hw/drivers/flash/enc_flash/test/src/testcases/enc_flash_hal.c b/hw/drivers/flash/enc_flash/test/src/testcases/enc_flash_hal.c
index fce211afe8..c478da15be 100644
--- a/hw/drivers/flash/enc_flash/test/src/testcases/enc_flash_hal.c
+++ b/hw/drivers/flash/enc_flash/test/src/testcases/enc_flash_hal.c
@@ -17,6 +17,7 @@
  * under the License.
  */
 
+#include <defs/error.h>
 #include <hal/hal_flash.h>
 #include <flash_map/flash_map.h>
 
@@ -65,4 +66,45 @@ TEST_CASE(enc_flash_test_hal)
     rc = hal_flash_isempty(fa->fa_id, fa->fa_off, readdata, sizeof(readdata));
     TEST_ASSERT(rc == 0);
     TEST_ASSERT(!memcmp(writedata, readdata, sizeof(writedata)));
+
+    /* Wrong id */
+    rc = hal_flash_write_protect(2, 1);
+    TEST_ASSERT(rc == SYS_EINVAL);
+
+    rc = hal_flash_write_protect(fa->fa_id, 1);
+    TEST_ASSERT(rc == 0);
+
+    /* hal_flash_erase should fail */
+    rc = hal_flash_erase(fa->fa_id, fa->fa_off, fa->fa_size);
+    TEST_ASSERT(rc == SYS_EACCES);
+    (void)memset(readdata, 0xAB, sizeof(readdata));
+    rc = hal_flash_read(fa->fa_id, fa->fa_off, readdata, sizeof(readdata));
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(0 == memcmp(writedata, readdata, sizeof(readdata)));
+
+    /* hal_flash_sector_erase should fail */
+    rc = hal_flash_erase_sector(fa->fa_id, 0);
+    TEST_ASSERT(rc == SYS_EACCES);
+    (void)memset(readdata, 0xAB, sizeof(readdata));
+    rc = hal_flash_read(fa->fa_id, fa->fa_off, readdata, sizeof(readdata));
+    TEST_ASSERT(rc == 0);
+    TEST_ASSERT(0 == memcmp(writedata, readdata, sizeof(readdata)));
+
+    /* Un-protect and erase */
+    rc = hal_flash_write_protect(fa->fa_id, 0);
+    TEST_ASSERT(rc == 0);
+    rc = hal_flash_erase(fa->fa_id, fa->fa_off, fa->fa_size);
+    TEST_ASSERT(rc == 0);
+
+    /* Protect again */
+    rc = hal_flash_write_protect(fa->fa_id, 1);
+    TEST_ASSERT(rc == 0);
+    /* Verify that area is erased */
+    rc = hal_flash_isempty_no_buf(fa->fa_id, fa->fa_off, 30);
+    TEST_ASSERT(rc == 1);
+    /* Try to write that should fail */
+    rc = hal_flash_write(fa->fa_id, fa->fa_off, writedata, sizeof(writedata));
+    TEST_ASSERT(rc == SYS_EACCES);
+    /* Verify that area is still erased */
+    rc = hal_flash_isempty_no_buf(fa->fa_id, fa->fa_off, 30);
 }
diff --git a/hw/hal/include/hal/hal_flash.h b/hw/hal/include/hal/hal_flash.h
index 429837e437..de2f9919a6 100644
--- a/hw/hal/include/hal/hal_flash.h
+++ b/hw/hal/include/hal/hal_flash.h
@@ -64,6 +64,21 @@ uint8_t hal_flash_align(uint8_t flash_id);
 uint8_t hal_flash_erased_val(uint8_t flash_id);
 int hal_flash_init(void);
 
+/**
+ * @brief Set or clears write protection
+ *
+ * This function allows to disable write to the device if for some reason
+ * (i.e. low power state) writes could result in data corruption.
+ *
+ * @param id          The ID of the flash
+ * @param protect     1 - disable writes
+ *                    0 - enable writes
+ *
+ * @return           SYS_EINVAL - if flash id is not valid
+ *                   SYS_OK - on success
+ */
+int hal_flash_write_protect(uint8_t id, uint8_t protect);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/hw/hal/src/hal_flash.c b/hw/hal/src/hal_flash.c
index ac26a05fb9..2d78f38e76 100644
--- a/hw/hal/src/hal_flash.c
+++ b/hw/hal/src/hal_flash.c
@@ -26,6 +26,8 @@
 #include "hal/hal_flash.h"
 #include "hal/hal_flash_int.h"
 
+static uint8_t protected_flash[1];
+
 int
 hal_flash_init(void)
 {
@@ -165,6 +167,10 @@ hal_flash_write(uint8_t id, uint32_t address, const void *src,
         return -1;
     }
 
+    if (protected_flash[id / 8] & (1 << (id & 7))) {
+        return SYS_EACCES;
+    }
+
     rc = hf->hf_itf->hff_write(hf, address, src, num_bytes);
     if (rc != 0) {
         return rc;
@@ -198,6 +204,10 @@ hal_flash_erase_sector(uint8_t id, uint32_t sector_address)
         return -1;
     }
 
+    if (protected_flash[id / 8] & (1 << (id & 7))) {
+        return SYS_EACCES;
+    }
+
     rc = hf->hf_itf->hff_erase_sector(hf, sector_address);
     if (rc != 0) {
         return rc;
@@ -238,6 +248,10 @@ hal_flash_erase(uint8_t id, uint32_t address, uint32_t num_bytes)
         return -1;
     }
 
+    if (protected_flash[id / 8] & (1 << (id & 7))) {
+        return SYS_EACCES;
+    }
+
     end = address + num_bytes;
     if (end <= address) {
         /*
@@ -338,3 +352,22 @@ hal_flash_ioctl(uint8_t id, uint32_t cmd, void *args)
 {
     return 0;
 }
+
+int
+hal_flash_write_protect(uint8_t id, uint8_t protect)
+{
+    if (NULL == hal_bsp_flash_dev(id)) {
+        return SYS_EINVAL;
+    }
+    if (id / 8 >= sizeof(protected_flash) / sizeof(protected_flash[0])) {
+        return SYS_EINVAL;
+    }
+
+    if (protect) {
+        protected_flash[id / 8] |= (1 << (id & 7));
+    } else {
+        protected_flash[id / 8] &= ~(1 << (id & 7));
+    }
+
+    return SYS_EOK;
+}


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services