aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/openocd.texi4
-rw-r--r--src/target/arm_adi_v5.c34
-rw-r--r--src/target/arm_adi_v5.h4
3 files changed, 42 insertions, 0 deletions
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 03bb508..1d63b20 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -4836,6 +4836,10 @@ Set/get quirks mode for TI TMS450/TMS570 processors
Disabled by default
@end deffn
+@deffn {Config Command} {$dap_name nu_npcx_quirks} [@option{enable}]
+Set/get quirks mode for Nuvoton NPCX/NPCD MCU families
+Disabled by default
+@end deffn
@node CPU Configuration
@chapter CPU Configuration
diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c
index ff0d9b5..cc5f077 100644
--- a/src/target/arm_adi_v5.c
+++ b/src/target/arm_adi_v5.c
@@ -409,6 +409,26 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t siz
outvalue |= (uint32_t)*buffer++ << 8 * (0 ^ (drw_byte_idx & 3) ^ addr_xor);
break;
}
+ } else if (dap->nu_npcx_quirks) {
+ switch (this_size) {
+ case 4:
+ outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3);
+ outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3);
+ outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3);
+ outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx & 3);
+ break;
+ case 2:
+ outvalue |= (uint32_t)*buffer << 8 * (drw_byte_idx++ & 3);
+ outvalue |= (uint32_t)*(buffer+1) << 8 * (drw_byte_idx++ & 3);
+ outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx++ & 3);
+ outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx & 3);
+ break;
+ case 1:
+ outvalue |= (uint32_t)*buffer << 8 * (drw_byte_idx++ & 3);
+ outvalue |= (uint32_t)*buffer << 8 * (drw_byte_idx++ & 3);
+ outvalue |= (uint32_t)*buffer << 8 * (drw_byte_idx++ & 3);
+ outvalue |= (uint32_t)*buffer++ << 8 * (drw_byte_idx & 3);
+ }
} else {
switch (this_size) {
case 4:
@@ -2755,6 +2775,13 @@ COMMAND_HANDLER(dap_ti_be_32_quirks_command)
"TI BE-32 quirks mode");
}
+COMMAND_HANDLER(dap_nu_npcx_quirks_command)
+{
+ struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
+ return CALL_COMMAND_HANDLER(handle_command_parse_bool, &dap->nu_npcx_quirks,
+ "Nuvoton NPCX quirks mode");
+}
+
const struct command_registration dap_instance_commands[] = {
{
.name = "info",
@@ -2827,5 +2854,12 @@ const struct command_registration dap_instance_commands[] = {
.help = "set/get quirks mode for TI TMS450/TMS570 processors",
.usage = "[enable]",
},
+ {
+ .name = "nu_npcx_quirks",
+ .handler = dap_nu_npcx_quirks_command,
+ .mode = COMMAND_CONFIG,
+ .help = "set/get quirks mode for Nuvoton NPCX controllers",
+ .usage = "[enable]",
+ },
COMMAND_REGISTRATION_DONE
};
diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h
index 7ee6591..3eddbc0 100644
--- a/src/target/arm_adi_v5.h
+++ b/src/target/arm_adi_v5.h
@@ -359,6 +359,10 @@ struct adiv5_dap {
* swizzle appropriately. */
bool ti_be_32_quirks;
+ /* The Nuvoton NPCX M4 has an issue with writing to non-4-byte-aligned mmios.
+ * The work around is to repeat the data in all 4 bytes of DRW */
+ bool nu_npcx_quirks;
+
/**
* STLINK adapter need to know if last AP operation was read or write, and
* in case of write has to flush it with a dummy read from DP_RDBUFF