openocd: src: fix incorrect SPDX tags
[fw/openocd] / src / target / arc_mem.c
index e80bfb4e41561b791a40d01b1971e2f77607ad5b..0dc3f6870e707716ae0d77edadd003fbcf368572 100644 (file)
@@ -1,11 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
 /***************************************************************************
  *   Copyright (C) 2013-2014,2019-2020 Synopsys, Inc.                      *
  *   Frank Dols <frank.dols@synopsys.com>                                  *
  *   Mischa Jonker <mischa.jonker@synopsys.com>                            *
  *   Anton Kolesov <anton.kolesov@synopsys.com>                            *
  *   Evgeniy Didin <didin@synopsys.com>                                    *
- *                                                                         *
- *   SPDX-License-Identifier: GPL-2.0-or-later                             *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -41,10 +41,18 @@ static int arc_mem_write_block32(struct target *target, uint32_t addr,
        /* Check arguments */
        assert(!(addr & 3));
 
+       /* We need to flush the cache since it might contain dirty
+        * lines, so the cache invalidation may cause data inconsistency. */
+       CHECK_RETVAL(arc_cache_flush(target));
+
+
        /* No need to flush cache, because we don't read values from memory. */
        CHECK_RETVAL(arc_jtag_write_memory(&arc->jtag_info, addr, count,
                                (uint32_t *)buf));
 
+       /* Invalidate caches. */
+       CHECK_RETVAL(arc_cache_invalidate(target));
+
        return ERROR_OK;
 }
 
@@ -64,8 +72,11 @@ static int arc_mem_write_block16(struct target *target, uint32_t addr,
        /* Check arguments */
        assert(!(addr & 1));
 
-       /* non-word writes are less common, than 4-byte writes, so I suppose we can
-        * allowe ourselves to write this in a cycle, instead of calling arc_jtag
+       /* We will read data from memory, so we need to flush the cache. */
+       CHECK_RETVAL(arc_cache_flush(target));
+
+       /* non-word writes are less common than 4-byte writes, so I suppose we can
+        * allow ourselves to write this in a cycle, instead of calling arc_jtag
         * with count > 1. */
        for (i = 0; i < count; i++) {
                /* We can read only word at word-aligned address. Also *jtag_read_memory
@@ -97,6 +108,9 @@ static int arc_mem_write_block16(struct target *target, uint32_t addr,
                        (addr + i * sizeof(uint16_t)) & ~3u, 1, &buffer_he));
        }
 
+       /* Invalidate caches. */
+       CHECK_RETVAL(arc_cache_invalidate(target));
+
        return ERROR_OK;
 }
 
@@ -113,8 +127,11 @@ static int arc_mem_write_block8(struct target *target, uint32_t addr,
        LOG_DEBUG("Write 1-byte memory block: addr=0x%08" PRIx32 ", count=%" PRIu32,
                        addr, count);
 
-       /* non-word writes are less common, than 4-byte writes, so I suppose we can
-        * allowe ourselves to write this in a cycle, instead of calling arc_jtag
+       /* We will read data from memory, so we need to flush the cache. */
+       CHECK_RETVAL(arc_cache_flush(target));
+
+       /* non-word writes are less common than 4-byte writes, so I suppose we can
+        * allow ourselves to write this in a cycle, instead of calling arc_jtag
         * with count > 1. */
        for (i = 0; i < count; i++) {
                /* See comment in arc_mem_write_block16 for details. Since it is a byte
@@ -128,6 +145,9 @@ static int arc_mem_write_block8(struct target *target, uint32_t addr,
                CHECK_RETVAL(arc_jtag_write_memory(&arc->jtag_info, (addr + i) & ~3, 1, &buffer_he));
        }
 
+       /* Invalidate caches. */
+       CHECK_RETVAL(arc_cache_invalidate(target));
+
        return ERROR_OK;
 }
 
@@ -153,7 +173,7 @@ int arc_mem_write(struct target *target, target_addr_t address, uint32_t size,
        if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
                return ERROR_TARGET_UNALIGNED_ACCESS;
 
-       /* correct endianess if we have word or hword access */
+       /* correct endianness if we have word or hword access */
        if (size > 1) {
                /*
                 * arc_..._write_mem with size 4/2 requires uint32_t/uint16_t
@@ -205,6 +225,9 @@ static int arc_mem_read_block(struct target *target, target_addr_t addr,
        assert(!(addr & 3));
        assert(size == 4);
 
+       /* Flush cache before memory access */
+       CHECK_RETVAL(arc_cache_flush(target));
+
        CHECK_RETVAL(arc_jtag_read_memory(&arc->jtag_info, addr, count, buf,
                    arc_mem_is_slow_memory(arc, addr, size, count)));
 
@@ -258,7 +281,7 @@ int arc_mem_read(struct target *target, target_addr_t address, uint32_t size,
        /* arc_..._read_mem with size 4/2 returns uint32_t/uint16_t in host */
        /* endianness, but byte array should represent target endianness      */
 
-       if (ERROR_OK == retval) {
+       if (retval == ERROR_OK) {
                switch (size) {
                case 4:
                        target_buffer_set_u32_array(target, buffer, count,