diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c
index ff9779209834ad98d91973eb0b181e82830061ed..1afa29ffeda54b96eb7e6391b43aae5b66091a86 100644
--- a/src/target/cortex_m3.c
+++ b/src/target/cortex_m3.c
@@ -52,6 +52,12 @@ extern uint8_t armv7m_gdb_dummy_cpsr_value[];
 extern reg_t armv7m_gdb_dummy_cpsr_reg;
 #endif
 
+static int cortex_m3_has_mmu(struct target_s *target, bool *has_mmu)
+{
+	*has_mmu = false;
+	return ERROR_OK;
+}
+
 static int cortexm3_dap_read_coreregister_u32(swjdp_common_t *swjdp,
 		uint32_t *value, int regnum)
 {
@@ -1837,6 +1843,7 @@ target_type_t cortexm3_target =
 	.register_commands = cortex_m3_register_commands,
 	.target_create = cortex_m3_target_create,
 	.init_target = cortex_m3_init_target,
+	.has_mmu = cortex_m3_has_mmu,
 	.examine = cortex_m3_examine,
 };
 
diff --git a/src/target/target.c b/src/target/target.c
index 5cf70118d043f06f3870ccdf4a487d06c46700b9..2a66fcf107a8c3b6e831bcbaf2302614833b1a67 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -496,7 +496,13 @@ static int default_virt2phys(struct target_s *target, uint32_t virtual, uint32_t
 
 static int default_mmu(struct target_s *target, int *enabled)
 {
-	*enabled = 0;
+	LOG_ERROR("Not implemented.");
+	return ERROR_FAIL;
+}
+
+static int default_has_mmu(struct target_s *target, bool *has_mmu)
+{
+	*has_mmu = true;
 	return ERROR_OK;
 }
 
@@ -743,14 +749,32 @@ int target_mcr(struct target_s *target, int cpnum, uint32_t op1, uint32_t op2, u
 
 static int default_read_phys_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
 {
-	LOG_ERROR("Not implemented");
-	return ERROR_FAIL;
+	int retval;
+	bool mmu;
+	retval = target->type->has_mmu(target, &mmu);
+	if (retval != ERROR_OK)
+		return retval;
+	if (mmu)
+	{
+		LOG_ERROR("Not implemented");
+		return ERROR_FAIL;
+	}
+	return target_read_memory(target, address, size, count, buffer);
 }
 
 static int default_write_phys_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
 {
-	LOG_ERROR("Not implemented");
-	return ERROR_FAIL;
+	int retval;
+	bool mmu;
+	retval = target->type->has_mmu(target, &mmu);
+	if (retval != ERROR_OK)
+		return retval;
+	if (mmu)
+	{
+		LOG_ERROR("Not implemented");
+		return ERROR_FAIL;
+	}
+	return target_write_memory(target, address, size, count, buffer);
 }
 
 
@@ -816,6 +840,10 @@ int target_init(struct command_context_s *cmd_ctx)
 		{
 			target->type->mmu = default_mmu;
 		}
+		if (target->type->has_mmu == NULL)
+		{
+			target->type->has_mmu = default_has_mmu;
+		}
 		target = target->next;
 	}
 
diff --git a/src/target/target_type.h b/src/target/target_type.h
index dd469db10788af5764500c829bba7cd07f930ed3..23ed40e04e494fa0787ddd675bf43cf37687cb49 100644
--- a/src/target/target_type.h
+++ b/src/target/target_type.h
@@ -199,8 +199,16 @@ struct target_type_s
 	 */
 	int (*write_phys_memory)(struct target_s *target, uint32_t phys_address, uint32_t size, uint32_t count, uint8_t *buffer);
 
+	/* returns true if the mmu is enabled. Default implementation returns error. */
 	int (*mmu)(struct target_s *target, int *enabled);
 
+	/* returns true if the target has an mmu. This can only be
+	determined after the target has been examined.
+	
+	Default implementation returns success and has_mmu==true.
+	*/
+	int (*has_mmu)(struct target_s *target, bool *has_mmu);
+
 	/* Read coprocessor - arm specific. Default implementation returns error. */
 	int (*mrc)(struct target_s *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value);