Hi all,
I have noticed that accessing (more precise: writing) memory
byte-by-byte on MIPS32 targets is currently borken.

Temporary array allocated for endianess swap replaces the contenst of
the buffer. However, this temporary array is set-up only for hword and
word accesses.

This, in the case of byte access, it just (unnecessarily) overwrites
buffer with random (uninitialized) value.

As a fix, I propose patch attached.

I will wait for comments and send PULL request from my github MIPS
maintained branch, as I usually do.

BR,
Drasko
From b61cc1ec5d5420436fc933146d9fd4a91f79db15 Mon Sep 17 00:00:00 2001
From: Drasko DRASKOVIC <[email protected]>
Date: Mon, 25 Jul 2011 14:23:35 +0200
Subject: [PATCH] mips32 : Fixed memory byte access

Function mips_m4k_write_memory() does endianess byte swap,
but this procedure break one byte access (temporary array
overwrites content in buffer).
As a fix, this endianess swap and buffer affecting
is preformed only on hword and word accesses (not on byte access).
---
 src/target/mips_m4k.c |   51 ++++++++++++++++++++++++++----------------------
 1 files changed, 28 insertions(+), 23 deletions(-)

diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c
index 350ed51..e4ab044 100644
--- a/src/target/mips_m4k.c
+++ b/src/target/mips_m4k.c
@@ -923,33 +923,38 @@ static int mips_m4k_write_memory(struct target *target, uint32_t address,
 	if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
 		return ERROR_TARGET_UNALIGNED_ACCESS;
 
-	/* mips32_..._write_mem with size 4/2 requires uint32_t/uint16_t in host */
-	/* endianness, but byte array represents target endianness               */
-	uint8_t * t = NULL;
-	t = malloc(count * sizeof(uint32_t));
-	if (t == NULL)
+	/** correct endianess if we have word or hword access */
+	uint8_t *t = NULL;
+	if (size > 1)
 	{
-		LOG_ERROR("Out of memory");
-		return ERROR_FAIL;
-	}
+		/* mips32_..._write_mem with size 4/2 requires uint32_t/uint16_t in host */
+		/* endianness, but byte array represents target endianness               */
+		t = malloc(count * sizeof(uint32_t));
+		if (t == NULL)
+		{
+			LOG_ERROR("Out of memory");
+			return ERROR_FAIL;
+		}
 
- 	uint32_t i, t32;
-	uint16_t t16;
-	for(i = 0; i < (count*size); i += size)
-	{
-		switch(size)
+		uint32_t i, t32;
+		uint16_t t16;
+		for(i = 0; i < (count*size); i += size)
 		{
-		case 4:
-			t32 = target_buffer_get_u32(target,&buffer[i]);
-			h_u32_to_le(&t[i], t32);
-			break;
-		case 2:
-			t16 = target_buffer_get_u16(target,&buffer[i]);
-			h_u16_to_le(&t[i], t16);
-			break;
+			switch(size)
+			{
+			case 4:
+				t32 = target_buffer_get_u32(target,&buffer[i]);
+				h_u32_to_le(&t[i], t32);
+				break;
+			case 2:
+				t16 = target_buffer_get_u16(target,&buffer[i]);
+				h_u16_to_le(&t[i], t16);
+				break;
+			}
 		}
+
+		buffer = t;
 	}
-	buffer = t;
 
 	/* if noDMA off, use DMAACC mode for memory write */
 	int retval;
-- 
1.7.6

_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to