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/09/14 16:10:53 UTC

[mynewt-core] branch master updated (1ca0314ec -> adb22c486)

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

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


    from 1ca0314ec bsp/pic32mz2048_wi-fire: use pic32mz common MCU
     new 1df46ed06 pic32: Relax flash write restrictions
     new adb22c486 pic32: Use uncached access when read from flash

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 hw/mcu/microchip/pic32mz/src/hal_flash.c | 48 +++++++++++++++++++++++++-------
 1 file changed, 38 insertions(+), 10 deletions(-)


[mynewt-core] 01/02: pic32: Relax flash write restrictions

Posted by je...@apache.org.
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 1df46ed06d239de6f8777d07832796719868b0ac
Author: Jerzy Kasenberg <je...@codecoup.pl>
AuthorDate: Tue Sep 13 00:03:16 2022 +0200

    pic32: Relax flash write restrictions
    
    Function pic32mz_flash_write() required source data to be 4 bytes
    aligned. This alignment is not followed in fcb that can request writes
    from odd addresses and that result in crash when *data is used with
    odd address.
    Now for unaligned source pointer function copies fragments of source
    buffer to correctly aligned buffer on stack.
    
    If num_bytes was not multiply of 4 function also did not write anything.
    Calls from FCB can write single byte of CRC and this should be allowed
    here.
---
 hw/mcu/microchip/pic32mz/src/hal_flash.c | 45 +++++++++++++++++++++++++-------
 1 file changed, 36 insertions(+), 9 deletions(-)

diff --git a/hw/mcu/microchip/pic32mz/src/hal_flash.c b/hw/mcu/microchip/pic32mz/src/hal_flash.c
index de15f5a96..507947734 100644
--- a/hw/mcu/microchip/pic32mz/src/hal_flash.c
+++ b/hw/mcu/microchip/pic32mz/src/hal_flash.c
@@ -104,23 +104,47 @@ pic32mz_flash_read(const struct hal_flash *dev, uint32_t address,
     return 0;
 }
 
+/**
+ * Function returns address to 4 byte aligned data
+ * @param src      pointer to source data
+ * @param aligned_buffer address of aligned buffer to use in case src in unaligned
+ * @param aligned_buffer_size size of aligned buffer in bytes
+ * @param num_bytes number of bytes to provide.
+ * @return src if it is 4 byte aligned otherwise aligned_buffer
+ */
+const uint32_t *
+aligned_ptr(const void *src, uint32_t *aligned_buffer, uint32_t aligned_buffer_size, uint32_t num_bytes)
+{
+    if (((uint32_t)src & 3) == 0) {
+        /* Source is aligned, there is no need to copy data */
+        return (const uint32_t *)src;
+    }
+    if (num_bytes > aligned_buffer_size) {
+        num_bytes = aligned_buffer_size;
+    }
+    memcpy(aligned_buffer, src, num_bytes);
+    return aligned_buffer;
+}
+
 static int
 pic32mz_flash_write(const struct hal_flash *dev, uint32_t address,
                     const void *src, uint32_t num_bytes)
 {
     (void)dev;
-    const uint32_t *data = (const uint32_t*)src;
-    uint32_t word;
+    const uint32_t *data;
+    uint32_t aligned_data[4];
 
-    if (num_bytes & (WORD_SIZE - 1) || (address & 3)) {
+    if ((address & 3)) {
         return -1;
     }
 
     /* Write flash by word until the next quadword boundary is reached */
     while (address & (QUADWORD_SIZE -1) && num_bytes >= WORD_SIZE) {
+        data = aligned_ptr(src, aligned_data, sizeof(aligned_data), num_bytes);
         NVMADDR = address;
         address += WORD_SIZE;
-        NVMDATA0 = *data++;
+        src += WORD_SIZE;
+        NVMDATA0 = *data;
 
         if (flash_do_op(WORD_PROGRAM)) {
             return -1;
@@ -129,14 +153,15 @@ pic32mz_flash_write(const struct hal_flash *dev, uint32_t address,
     }
 
     while (num_bytes >= QUADWORD_SIZE) {
+        data = aligned_ptr(src, aligned_data, sizeof(aligned_data), num_bytes);
         NVMADDR = address;
         address += QUADWORD_SIZE;
+        src += QUADWORD_SIZE;
 
         NVMDATA0 = data[0];
         NVMDATA1 = data[1];
         NVMDATA2 = data[2];
         NVMDATA3 = data[3];
-        data += 4;
 
         if (flash_do_op(QUADWORD_PROGRAM)) {
             return -1;
@@ -145,9 +170,11 @@ pic32mz_flash_write(const struct hal_flash *dev, uint32_t address,
     }
 
     while (num_bytes >= WORD_SIZE) {
+        data = aligned_ptr(src, aligned_data, sizeof(aligned_data), num_bytes);
         NVMADDR = address;
         address += WORD_SIZE;
-        NVMDATA0 = *data++;
+        src += WORD_SIZE;
+        NVMDATA0 = *data;
 
         if (flash_do_op(WORD_PROGRAM)) {
             return -1;
@@ -155,11 +182,11 @@ pic32mz_flash_write(const struct hal_flash *dev, uint32_t address,
         num_bytes -= WORD_SIZE;
     }
     if (num_bytes > 0) {
-        memcpy(&word, data, num_bytes);
-        pic32mz_flash_read(dev, address + num_bytes, ((uint8_t *)&word) + num_bytes, WORD_SIZE - num_bytes);
+        aligned_data[0] = 0xFFFFFFFF;
+        memcpy(aligned_data, src, num_bytes);
 
         NVMADDR = address;
-        NVMDATA0 = word;
+        NVMDATA0 = aligned_data[0];
 
         if (flash_do_op(WORD_PROGRAM)) {
             return -1;


[mynewt-core] 02/02: pic32: Use uncached access when read from flash

Posted by je...@apache.org.
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 adb22c4865e5a1cfa7005a3be1078a9f47dec454
Author: Jerzy Kasenberg <je...@codecoup.pl>
AuthorDate: Tue Sep 13 00:08:23 2022 +0200

    pic32: Use uncached access when read from flash
    
    During FCB write CRC that is calculated by reading flash.
    Writes to flash happen if such way that icache data can
    still have data that was cached before flash was written
    and this cached data may happen to be used during
    CRC calculation resulting in corrupted entries.
    
    To fix this problem flash read uses uncached access from KSEG1
    instead of cached KSEG0.
---
 hw/mcu/microchip/pic32mz/src/hal_flash.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/hw/mcu/microchip/pic32mz/src/hal_flash.c b/hw/mcu/microchip/pic32mz/src/hal_flash.c
index 507947734..c827b23cd 100644
--- a/hw/mcu/microchip/pic32mz/src/hal_flash.c
+++ b/hw/mcu/microchip/pic32mz/src/hal_flash.c
@@ -22,6 +22,7 @@
 #include <hal/hal_flash_int.h>
 #include <mcu/mips_hal.h>
 #include <string.h>
+#include <sys/kmem.h>
 
 #define VIRT_TO_PHY(ADDRESS)   (unsigned int)((int)(ADDRESS) & 0x1FFFFFFF)
 #define PHY_TO_VIRT(ADDRESS)   (unsigned int)((int)(ADDRESS) | 0x80000000)
@@ -100,7 +101,7 @@ pic32mz_flash_read(const struct hal_flash *dev, uint32_t address,
                    void *dst, uint32_t num_bytes)
 {
     (void)dev;
-    memcpy(dst, (void *)PHY_TO_VIRT(address), num_bytes);
+    memcpy(dst, (void *)PA_TO_KVA1(address), num_bytes);
     return 0;
 }