aboutsummaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/include')
-rw-r--r--src/include/adiv5.h68
-rw-r--r--src/include/arm7tdmi.h1
-rw-r--r--src/include/command.h1
-rw-r--r--src/include/cortexm.h153
-rw-r--r--src/include/crc32.h4
-rw-r--r--src/include/exception.h74
-rw-r--r--src/include/gdb_packet.h8
-rw-r--r--src/include/general.h15
-rw-r--r--src/include/hex_utils.h5
-rw-r--r--src/include/jtag_scan.h2
-rw-r--r--src/include/jtagtap.h10
-rw-r--r--src/include/morse.h (renamed from src/include/traceswo.h)14
-rw-r--r--src/include/platform_support.h (renamed from src/include/usbuart.h)33
-rw-r--r--src/include/stm32lx-nvm.h190
-rw-r--r--src/include/swdptap.h2
-rw-r--r--src/include/target.h153
16 files changed, 593 insertions, 140 deletions
diff --git a/src/include/adiv5.h b/src/include/adiv5.h
index d2d4be0..12d3bf4 100644
--- a/src/include/adiv5.h
+++ b/src/include/adiv5.h
@@ -21,16 +21,19 @@
#ifndef __ADIV5_H
#define __ADIV5_H
-#include "general.h"
#include "jtag_scan.h"
#include "target.h"
+#define ADIV5_APnDP 0x100
+#define ADIV5_DP_REG(x) (x)
+#define ADIV5_AP_REG(x) (ADIV5_APnDP | (x))
+
/* ADIv5 DP Register addresses */
-#define ADIV5_DP_IDCODE 0x0
-#define ADIV5_DP_ABORT 0x0
-#define ADIV5_DP_CTRLSTAT 0x4
-#define ADIV5_DP_SELECT 0x8
-#define ADIV5_DP_RDBUFF 0xC
+#define ADIV5_DP_IDCODE ADIV5_DP_REG(0x0)
+#define ADIV5_DP_ABORT ADIV5_DP_REG(0x0)
+#define ADIV5_DP_CTRLSTAT ADIV5_DP_REG(0x4)
+#define ADIV5_DP_SELECT ADIV5_DP_REG(0x8)
+#define ADIV5_DP_RDBUFF ADIV5_DP_REG(0xC)
/* AP Abort Register (ABORT) */
/* Bits 31:5 - Reserved */
@@ -64,15 +67,15 @@
/* ADIv5 MEM-AP Registers */
-#define ADIV5_AP_CSW 0x00
-#define ADIV5_AP_TAR 0x04
+#define ADIV5_AP_CSW ADIV5_AP_REG(0x00)
+#define ADIV5_AP_TAR ADIV5_AP_REG(0x04)
/* 0x08 - Reserved */
-#define ADIV5_AP_DRW 0x0C
-#define ADIV5_AP_DB(x) (0x10 + (4*(x)))
+#define ADIV5_AP_DRW ADIV5_AP_REG(0x0C)
+#define ADIV5_AP_DB(x) ADIV5_AP_REG(0x10 + (4*(x)))
/* 0x20:0xF0 - Reserved */
-#define ADIV5_AP_CFG 0xF4
-#define ADIV5_AP_BASE 0xF8
-#define ADIV5_AP_IDR 0xFC
+#define ADIV5_AP_CFG ADIV5_AP_REG(0xF4)
+#define ADIV5_AP_BASE ADIV5_AP_REG(0xF8)
+#define ADIV5_AP_IDR ADIV5_AP_REG(0xFC)
/* AP Control and Status Word (CSW) */
#define ADIV5_AP_CSW_DBGSWENABLE (1u << 31)
@@ -94,11 +97,9 @@
#define ADIV5_AP_CSW_SIZE_WORD (2u << 0)
#define ADIV5_AP_CSW_SIZE_MASK (7u << 0)
-/* Constants to make RnW and APnDP parameters more clear in code */
+/* Constants to make RnW parameters more clear in code */
#define ADIV5_LOW_WRITE 0
#define ADIV5_LOW_READ 1
-#define ADIV5_LOW_DP 0
-#define ADIV5_LOW_AP 1
/* Try to keep this somewhat absract for later adding SW-DP */
typedef struct ADIv5_DP_s {
@@ -106,13 +107,10 @@ typedef struct ADIv5_DP_s {
uint32_t idcode;
- void (*dp_write)(struct ADIv5_DP_s *dp, uint8_t addr, uint32_t value);
- uint32_t (*dp_read)(struct ADIv5_DP_s *dp, uint8_t addr);
-
+ uint32_t (*dp_read)(struct ADIv5_DP_s *dp, uint16_t addr);
uint32_t (*error)(struct ADIv5_DP_s *dp);
-
- uint32_t (*low_access)(struct ADIv5_DP_s *dp, uint8_t APnDP, uint8_t RnW,
- uint8_t addr, uint32_t value);
+ uint32_t (*low_access)(struct ADIv5_DP_s *dp, uint8_t RnW,
+ uint16_t addr, uint32_t value);
union {
jtag_dev_t *dev;
@@ -120,12 +118,7 @@ typedef struct ADIv5_DP_s {
};
} ADIv5_DP_t;
-static inline void adiv5_dp_write(ADIv5_DP_t *dp, uint8_t addr, uint32_t value)
-{
- dp->dp_write(dp, addr, value);
-}
-
-static inline uint32_t adiv5_dp_read(ADIv5_DP_t *dp, uint8_t addr)
+static inline uint32_t adiv5_dp_read(ADIv5_DP_t *dp, uint16_t addr)
{
return dp->dp_read(dp, addr);
}
@@ -135,10 +128,10 @@ static inline uint32_t adiv5_dp_error(ADIv5_DP_t *dp)
return dp->error(dp);
}
-static inline uint32_t adiv5_dp_low_access(struct ADIv5_DP_s *dp, uint8_t APnDP,
- uint8_t RnW, uint8_t addr, uint32_t value)
+static inline uint32_t adiv5_dp_low_access(struct ADIv5_DP_s *dp, uint8_t RnW,
+ uint16_t addr, uint32_t value)
{
- return dp->low_access(dp, APnDP, RnW, addr, value);
+ return dp->low_access(dp, RnW, addr, value);
}
typedef struct ADIv5_AP_s {
@@ -157,22 +150,15 @@ typedef struct ADIv5_AP_s {
} ADIv5_AP_t;
void adiv5_dp_init(ADIv5_DP_t *dp);
+void adiv5_dp_write(ADIv5_DP_t *dp, uint16_t addr, uint32_t value);
void adiv5_dp_ref(ADIv5_DP_t *dp);
void adiv5_ap_ref(ADIv5_AP_t *ap);
void adiv5_dp_unref(ADIv5_DP_t *dp);
void adiv5_ap_unref(ADIv5_AP_t *ap);
-void adiv5_dp_write_ap(ADIv5_DP_t *dp, uint8_t addr, uint32_t value);
-uint32_t adiv5_dp_read_ap(ADIv5_DP_t *dp, uint8_t addr);
-
-uint32_t adiv5_ap_mem_read(ADIv5_AP_t *ap, uint32_t addr);
-void adiv5_ap_mem_write(ADIv5_AP_t *ap, uint32_t addr, uint32_t value);
-uint16_t adiv5_ap_mem_read_halfword(ADIv5_AP_t *ap, uint32_t addr);
-void adiv5_ap_mem_write_halfword(ADIv5_AP_t *ap, uint32_t addr, uint16_t value);
-
-void adiv5_ap_write(ADIv5_AP_t *ap, uint8_t addr, uint32_t value);
-uint32_t adiv5_ap_read(ADIv5_AP_t *ap, uint8_t addr);
+void adiv5_ap_write(ADIv5_AP_t *ap, uint16_t addr, uint32_t value);
+uint32_t adiv5_ap_read(ADIv5_AP_t *ap, uint16_t addr);
void adiv5_jtag_dp_handler(jtag_dev_t *dev);
int adiv5_swdp_scan(void);
diff --git a/src/include/arm7tdmi.h b/src/include/arm7tdmi.h
index ffcd6e9..fa7d586 100644
--- a/src/include/arm7tdmi.h
+++ b/src/include/arm7tdmi.h
@@ -21,7 +21,6 @@
#ifndef __ARM7TDMI_H
#define __ARM7TDMI_H
-#include "general.h"
#include "jtag_scan.h"
void arm7tdmi_jtag_handler(jtag_dev_t *dev);
diff --git a/src/include/command.h b/src/include/command.h
index 32b0d7b..3910bbb 100644
--- a/src/include/command.h
+++ b/src/include/command.h
@@ -21,7 +21,6 @@
#ifndef __COMMAND_H
#define __COMMAND_H
-#include "general.h"
#include "target.h"
int command_process(target *t, char *cmd);
diff --git a/src/include/cortexm.h b/src/include/cortexm.h
new file mode 100644
index 0000000..f7396bf
--- /dev/null
+++ b/src/include/cortexm.h
@@ -0,0 +1,153 @@
+/*
+ * This file is part of the Black Magic Debug project.
+ *
+ * Copyright (C) 2015 Gareth McMullin <gareth@blacksphere.co.nz>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef __CORTEXM_H
+#define __CORTEXM_H
+
+#include "target.h"
+
+/* Private peripheral bus base address */
+#define CORTEXM_PPB_BASE 0xE0000000
+
+#define CORTEXM_SCS_BASE (CORTEXM_PPB_BASE + 0xE000)
+
+#define CORTEXM_AIRCR (CORTEXM_SCS_BASE + 0xD0C)
+#define CORTEXM_CFSR (CORTEXM_SCS_BASE + 0xD28)
+#define CORTEXM_HFSR (CORTEXM_SCS_BASE + 0xD2C)
+#define CORTEXM_DFSR (CORTEXM_SCS_BASE + 0xD30)
+#define CORTEXM_CPACR (CORTEXM_SCS_BASE + 0xD88)
+#define CORTEXM_DHCSR (CORTEXM_SCS_BASE + 0xDF0)
+#define CORTEXM_DCRSR (CORTEXM_SCS_BASE + 0xDF4)
+#define CORTEXM_DCRDR (CORTEXM_SCS_BASE + 0xDF8)
+#define CORTEXM_DEMCR (CORTEXM_SCS_BASE + 0xDFC)
+
+#define CORTEXM_FPB_BASE (CORTEXM_PPB_BASE + 0x2000)
+
+/* ARM Literature uses FP_*, we use CORTEXM_FPB_* consistently */
+#define CORTEXM_FPB_CTRL (CORTEXM_FPB_BASE + 0x000)
+#define CORTEXM_FPB_REMAP (CORTEXM_FPB_BASE + 0x004)
+#define CORTEXM_FPB_COMP(i) (CORTEXM_FPB_BASE + 0x008 + (4*(i)))
+
+#define CORTEXM_DWT_BASE (CORTEXM_PPB_BASE + 0x1000)
+
+#define CORTEXM_DWT_CTRL (CORTEXM_DWT_BASE + 0x000)
+#define CORTEXM_DWT_COMP(i) (CORTEXM_DWT_BASE + 0x020 + (0x10*(i)))
+#define CORTEXM_DWT_MASK(i) (CORTEXM_DWT_BASE + 0x024 + (0x10*(i)))
+#define CORTEXM_DWT_FUNC(i) (CORTEXM_DWT_BASE + 0x028 + (0x10*(i)))
+
+/* Application Interrupt and Reset Control Register (AIRCR) */
+#define CORTEXM_AIRCR_VECTKEY (0x05FA << 16)
+/* Bits 31:16 - Read as VECTKETSTAT, 0xFA05 */
+#define CORTEXM_AIRCR_ENDIANESS (1 << 15)
+/* Bits 15:11 - Unused, reserved */
+#define CORTEXM_AIRCR_PRIGROUP (7 << 8)
+/* Bits 7:3 - Unused, reserved */
+#define CORTEXM_AIRCR_SYSRESETREQ (1 << 2)
+#define CORTEXM_AIRCR_VECTCLRACTIVE (1 << 1)
+#define CORTEXM_AIRCR_VECTRESET (1 << 0)
+
+/* HardFault Status Register (HFSR) */
+#define CORTEXM_HFSR_DEBUGEVT (1 << 31)
+#define CORTEXM_HFSR_FORCED (1 << 30)
+/* Bits 29:2 - Not specified */
+#define CORTEXM_HFSR_VECTTBL (1 << 1)
+/* Bits 0 - Reserved */
+
+/* Debug Fault Status Register (DFSR) */
+/* Bits 31:5 - Reserved */
+#define CORTEXM_DFSR_RESETALL 0x1F
+#define CORTEXM_DFSR_EXTERNAL (1 << 4)
+#define CORTEXM_DFSR_VCATCH (1 << 3)
+#define CORTEXM_DFSR_DWTTRAP (1 << 2)
+#define CORTEXM_DFSR_BKPT (1 << 1)
+#define CORTEXM_DFSR_HALTED (1 << 0)
+
+/* Debug Halting Control and Status Register (DHCSR) */
+/* This key must be written to bits 31:16 for write to take effect */
+#define CORTEXM_DHCSR_DBGKEY 0xA05F0000
+/* Bits 31:26 - Reserved */
+#define CORTEXM_DHCSR_S_RESET_ST (1 << 25)
+#define CORTEXM_DHCSR_S_RETIRE_ST (1 << 24)
+/* Bits 23:20 - Reserved */
+#define CORTEXM_DHCSR_S_LOCKUP (1 << 19)
+#define CORTEXM_DHCSR_S_SLEEP (1 << 18)
+#define CORTEXM_DHCSR_S_HALT (1 << 17)
+#define CORTEXM_DHCSR_S_REGRDY (1 << 16)
+/* Bits 15:6 - Reserved */
+#define CORTEXM_DHCSR_C_SNAPSTALL (1 << 5) /* v7m only */
+/* Bit 4 - Reserved */
+#define CORTEXM_DHCSR_C_MASKINTS (1 << 3)
+#define CORTEXM_DHCSR_C_STEP (1 << 2)
+#define CORTEXM_DHCSR_C_HALT (1 << 1)
+#define CORTEXM_DHCSR_C_DEBUGEN (1 << 0)
+
+/* Debug Core Register Selector Register (DCRSR) */
+#define CORTEXM_DCRSR_REGWnR 0x00010000
+#define CORTEXM_DCRSR_REGSEL_MASK 0x0000001F
+#define CORTEXM_DCRSR_REGSEL_XPSR 0x00000010
+#define CORTEXM_DCRSR_REGSEL_MSP 0x00000011
+#define CORTEXM_DCRSR_REGSEL_PSP 0x00000012
+
+/* Debug Exception and Monitor Control Register (DEMCR) */
+/* Bits 31:25 - Reserved */
+#define CORTEXM_DEMCR_TRCENA (1 << 24)
+/* Bits 23:20 - Reserved */
+#define CORTEXM_DEMCR_MON_REQ (1 << 19) /* v7m only */
+#define CORTEXM_DEMCR_MON_STEP (1 << 18) /* v7m only */
+#define CORTEXM_DEMCR_VC_MON_PEND (1 << 17) /* v7m only */
+#define CORTEXM_DEMCR_VC_MON_EN (1 << 16) /* v7m only */
+/* Bits 15:11 - Reserved */
+#define CORTEXM_DEMCR_VC_HARDERR (1 << 10)
+#define CORTEXM_DEMCR_VC_INTERR (1 << 9) /* v7m only */
+#define CORTEXM_DEMCR_VC_BUSERR (1 << 8) /* v7m only */
+#define CORTEXM_DEMCR_VC_STATERR (1 << 7) /* v7m only */
+#define CORTEXM_DEMCR_VC_CHKERR (1 << 6) /* v7m only */
+#define CORTEXM_DEMCR_VC_NOCPERR (1 << 5) /* v7m only */
+#define CORTEXM_DEMCR_VC_MMERR (1 << 4) /* v7m only */
+/* Bits 3:1 - Reserved */
+#define CORTEXM_DEMCR_VC_CORERESET (1 << 0)
+
+/* Flash Patch and Breakpoint Control Register (FP_CTRL) */
+/* Bits 32:15 - Reserved */
+/* Bits 14:12 - NUM_CODE2 */ /* v7m only */
+/* Bits 11:8 - NUM_LIT */ /* v7m only */
+/* Bits 7:4 - NUM_CODE1 */
+/* Bits 3:2 - Unspecified */
+#define CORTEXM_FPB_CTRL_KEY (1 << 1)
+#define CORTEXM_FPB_CTRL_ENABLE (1 << 0)
+
+/* Data Watchpoint and Trace Mask Register (DWT_MASKx) */
+#define CORTEXM_DWT_MASK_BYTE (0 << 0)
+#define CORTEXM_DWT_MASK_HALFWORD (1 << 0)
+#define CORTEXM_DWT_MASK_WORD (3 << 0)
+
+/* Data Watchpoint and Trace Function Register (DWT_FUNCTIONx) */
+#define CORTEXM_DWT_FUNC_MATCHED (1 << 24)
+#define CORTEXM_DWT_FUNC_DATAVSIZE_WORD (2 << 10) /* v7m only */
+#define CORTEXM_DWT_FUNC_FUNC_READ (5 << 0)
+#define CORTEXM_DWT_FUNC_FUNC_WRITE (6 << 0)
+#define CORTEXM_DWT_FUNC_FUNC_ACCESS (7 << 0)
+
+bool cortexm_attach(target *t);
+void cortexm_detach(target *t);
+void cortexm_halt_resume(target *t, bool step);
+int cortexm_run_stub(target *t, uint32_t loadaddr,
+ uint32_t r0, uint32_t r1, uint32_t r2, uint32_t r3);
+
+#endif
+
diff --git a/src/include/crc32.h b/src/include/crc32.h
index 6cc00ea..bd8d5c4 100644
--- a/src/include/crc32.h
+++ b/src/include/crc32.h
@@ -21,9 +21,7 @@
#ifndef __CRC32_H
#define __CRC32_H
-#include "platform.h"
-
uint32_t crc32_calc(uint32_t crc, uint8_t data);
-uint32_t generic_crc32(struct target_s *target, uint32_t base, int len);
+uint32_t generic_crc32(target *t, uint32_t base, int len);
#endif
diff --git a/src/include/exception.h b/src/include/exception.h
new file mode 100644
index 0000000..180398d
--- /dev/null
+++ b/src/include/exception.h
@@ -0,0 +1,74 @@
+/*
+ * This file is part of the Black Magic Debug project.
+ *
+ * Copyright (C) 2015 Black Sphere Technologies Ltd.
+ * Written by Gareth McMullin <gareth@blacksphere.co.nz>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Exception handling to escape deep nesting.
+ * Used for the case of communicaiton failure and timeouts.
+ */
+
+/* Example usage:
+ *
+ * volatile struct exception e;
+ * TRY_CATCH (e, EXCEPTION_TIMEOUT) {
+ * ...
+ * raise_exception(EXCEPTION_TIMEOUT, "Timeout occurred");
+ * ...
+ * }
+ * if (e.type == EXCEPTION_TIMEOUT) {
+ * printf("timeout: %s\n", e.msg);
+ * }
+ */
+
+/* Limitations:
+ * Can't use break, return, goto, etc from inside the TRY_CATCH block.
+ */
+
+#ifndef __EXCEPTION_H
+#define __EXCEPTION_H
+
+#include <setjmp.h>
+#include <stdint.h>
+
+#define EXCEPTION_ERROR 0x01
+#define EXCEPTION_TIMEOUT 0x02
+#define EXCEPTION_ALL -1
+
+struct exception {
+ uint32_t type;
+ const char *msg;
+ /* private */
+ uint32_t mask;
+ jmp_buf jmpbuf;
+ struct exception *outer;
+};
+
+extern struct exception *innermost_exception;
+
+#define TRY_CATCH(e, type_mask) \
+ (e).type = 0; \
+ (e).mask = (type_mask); \
+ (e).outer = innermost_exception; \
+ innermost_exception = (void*)&(e); \
+ if (setjmp(innermost_exception->jmpbuf) == 0) \
+ for (;innermost_exception == &(e); innermost_exception = (e).outer)
+
+void raise_exception(uint32_t type, const char *msg);
+
+#endif
+
diff --git a/src/include/gdb_packet.h b/src/include/gdb_packet.h
index 9f5430f..aa1a654 100644
--- a/src/include/gdb_packet.h
+++ b/src/include/gdb_packet.h
@@ -21,12 +21,10 @@
#ifndef __GDB_PACKET_H
#define __GDB_PACKET_H
-#include <string.h>
-
-int gdb_getpacket(unsigned char *packet, int size);
-void gdb_putpacket(unsigned char *packet, int size);
+int gdb_getpacket(char *packet, int size);
+void gdb_putpacket(const char *packet, int size);
#define gdb_putpacketz(packet) gdb_putpacket((packet), strlen(packet))
-void gdb_putpacket_f(const unsigned char *packet, ...);
+void gdb_putpacket_f(const char *packet, ...);
void gdb_out(const char *buf);
void gdb_outf(const char *fmt, ...);
diff --git a/src/include/general.h b/src/include/general.h
index b0721ac..c82c750 100644
--- a/src/include/general.h
+++ b/src/include/general.h
@@ -21,15 +21,26 @@
#ifndef __GENERAL_H
#define __GENERAL_H
+#define _GNU_SOURCE
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <inttypes.h>
+
#include "platform.h"
+#include "platform_support.h"
#ifndef DEBUG
#include <stdio.h>
#define DEBUG printf
#endif
-#include <stdint.h>
-#include <stdbool.h>
+#define ALIGN(x, n) (((x) + (n) - 1) & ~((n) - 1))
+#undef MIN
+#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#endif
diff --git a/src/include/hex_utils.h b/src/include/hex_utils.h
index 3aa210b..8a0d092 100644
--- a/src/include/hex_utils.h
+++ b/src/include/hex_utils.h
@@ -21,9 +21,8 @@
#ifndef __HEX_UTILS_H
#define __HEX_UTILS_H
-char * hexify(char *hex, const unsigned char *buf, int size);
-
-char * unhexify(unsigned char *buf, const char *hex, int size);
+char * hexify(char *hex, const void *buf, size_t size);
+char * unhexify(void *buf, const char *hex, size_t size);
#endif
diff --git a/src/include/jtag_scan.h b/src/include/jtag_scan.h
index b425b95..aa006e7 100644
--- a/src/include/jtag_scan.h
+++ b/src/include/jtag_scan.h
@@ -21,8 +21,6 @@
#ifndef __JTAG_SCAN_H
#define __JTAG_SCAN_H
-#include "general.h"
-
#define JTAG_MAX_DEVS 5
#define JTAG_MAX_IR_LEN 16
diff --git a/src/include/jtagtap.h b/src/include/jtagtap.h
index 9fe3e0d..0072594 100644
--- a/src/include/jtagtap.h
+++ b/src/include/jtagtap.h
@@ -21,15 +21,13 @@
#ifndef __JTAGTAP_H
#define __JTAGTAP_H
-#include "general.h"
-
/* Note: Signal names are as for the device under test. */
int jtagtap_init(void);
void jtagtap_reset(void);
-void jtagtap_srst(void);
+void jtagtap_srst(bool assert);
uint8_t jtagtap_next(const uint8_t TMS, const uint8_t TDI);
/* tap_next executes one state transision in the JTAG TAP state machine:
@@ -44,9 +42,9 @@ void jtagtap_tms_seq(uint32_t MS, int ticks);
void jtagtap_tdi_tdo_seq(uint8_t *DO, const uint8_t final_tms, const uint8_t *DI, int ticks);
void jtagtap_tdi_seq(const uint8_t final_tms, const uint8_t *DI, int ticks);
/* Shift out a sequence on MS and DI, capture data to DO.
- * - This is not endian safe: First byte will always be first shifted out.
- * - DO may be NULL to ignore captured data.
- * - DO may be point to the same address as DI.
+ * - This is not endian safe: First byte will always be first shifted out.
+ * - DO may be NULL to ignore captured data.
+ * - DO may be point to the same address as DI.
*/
/* generic soft reset: 1, 1, 1, 1, 1, 0 */
diff --git a/src/include/traceswo.h b/src/include/morse.h
index 5566f94..5ba39b1 100644
--- a/src/include/traceswo.h
+++ b/src/include/morse.h
@@ -1,7 +1,7 @@
/*
* This file is part of the Black Magic Debug project.
*
- * Copyright (C) 2012 Black Sphere Technologies Ltd.
+ * Copyright (C) 2015 Black Sphere Technologies Ltd.
* Written by Gareth McMullin <gareth@blacksphere.co.nz>
*
* This program is free software: you can redistribute it and/or modify
@@ -17,12 +17,14 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef __TRACESWO_H
-#define __TRACESWO_H
-#include <libopencm3/usb/usbd.h>
+#ifndef __MORSE_H
+#define __MORSE_H
-void traceswo_init(void);
-void trace_buf_drain(usbd_device *dev, uint8_t ep);
+extern const char *morse_msg;
+
+void morse(const char *msg, char repeat);
+bool morse_update(void);
#endif
+
diff --git a/src/include/usbuart.h b/src/include/platform_support.h
index 39f7dcd..1d853be 100644
--- a/src/include/usbuart.h
+++ b/src/include/platform_support.h
@@ -1,8 +1,7 @@
/*
* This file is part of the Black Magic Debug project.
*
- * Copyright (C) 2012 Black Sphere Technologies Ltd.
- * Written by Gareth McMullin <gareth@blacksphere.co.nz>
+ * Copyright (C) 2015 Gareth McMullin <gareth@blacksphere.co.nz>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,17 +16,29 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#ifndef __USBUART_H
-#define __USBUART_H
-#include <libopencm3/usb/usbd.h>
-#include <libopencm3/usb/cdc.h>
-#include "general.h"
+#ifndef __PLATFORM_SUPPORT_H
+#define __PLATFORM_SUPPORT_H
-void usbuart_init(void);
+#ifndef __GENERAL_H
+# error "Include 'general.h' instead"
+#endif
+
+#if defined(HOST)
+void platform_init(int argc, char **argv);
+#else
+void platform_init(void);
+#endif
-void usbuart_set_line_coding(struct usb_cdc_line_coding *coding);
-void usbuart_usb_out_cb(usbd_device *dev, uint8_t ep);
-void usbuart_usb_in_cb(usbd_device *dev, uint8_t ep);
+const char *platform_target_voltage(void);
+int platform_hwversion(void);
+void platform_timeout_set(uint32_t ms);
+bool platform_timeout_is_expired(void);
+void platform_delay(uint32_t delay);
+void platform_srst_set_val(bool assert);
+bool platform_target_get_power(void);
+void platform_target_set_power(bool power);
+void platform_request_boot(void);
#endif
+
diff --git a/src/include/stm32lx-nvm.h b/src/include/stm32lx-nvm.h
new file mode 100644
index 0000000..2e9d8c5
--- /dev/null
+++ b/src/include/stm32lx-nvm.h
@@ -0,0 +1,190 @@
+/* @file stm32lx-nvm.h
+ *
+ * This file is part of the Black Magic Debug project.
+ *
+ * Copyright (C) 2014 Woollysoft
+ * Written by Marc Singer <elf@woollysoft.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#if !defined (STM32Lx_NVM_H_INCLUDED)
+# define STM32Lx_NVM_H_INCLUDED
+
+/* ----- Includes */
+
+#include <stdint.h>
+
+/* ----- Macros */
+
+/* ----- Types */
+
+enum {
+ STM32Lx_STUB_PHYS = 0x20000000ul,
+ STM32Lx_STUB_INFO_PHYS = 0x20000004ul,
+ STM32Lx_STUB_DATA_PHYS = (0x20000000ul + 1024),
+ STM32Lx_STUB_DATA_MAX = 2048,
+
+ STM32Lx_NVM_OPT_PHYS = 0x1ff80000ul,
+ STM32Lx_NVM_EEPROM_PHYS = 0x08080000ul,
+
+ STM32L0_NVM_PHYS = 0x40022000ul,
+ STM32L0_NVM_PROG_PAGE_SIZE = 128,
+ STM32L0_NVM_DATA_PAGE_SIZE = 4,
+ STM32L0_NVM_OPT_SIZE = 12,
+ STM32L0_NVM_EEPROM_SIZE = 2*1024,
+
+ STM32L1_NVM_PHYS = 0x40023c00ul,
+ STM32L1_NVM_PROG_PAGE_SIZE = 256,
+ STM32L1_NVM_DATA_PAGE_SIZE = 4,
+ STM32L1_NVM_OPT_SIZE = 32,
+ STM32L1_NVM_EEPROM_SIZE = 16*1024,
+
+ STM32Lx_NVM_PEKEY1 = 0x89abcdeful,
+ STM32Lx_NVM_PEKEY2 = 0x02030405ul,
+ STM32Lx_NVM_PRGKEY1 = 0x8c9daebful,
+ STM32Lx_NVM_PRGKEY2 = 0x13141516ul,
+ STM32Lx_NVM_OPTKEY1 = 0xfbead9c8ul,
+ STM32Lx_NVM_OPTKEY2 = 0x24252627ul,
+
+ STM32Lx_NVM_PECR_OBL_LAUNCH = (1<<18),
+ STM32Lx_NVM_PECR_ERRIE = (1<<17),
+ STM32Lx_NVM_PECR_EOPIE = (1<<16),
+ STM32Lx_NVM_PECR_FPRG = (1<<10),
+ STM32Lx_NVM_PECR_ERASE = (1<< 9),
+ STM32Lx_NVM_PECR_FIX = (1<< 8), /* FTDW */
+ STM32Lx_NVM_PECR_DATA = (1<< 4),
+ STM32Lx_NVM_PECR_PROG = (1<< 3),
+ STM32Lx_NVM_PECR_OPTLOCK = (1<< 2),
+ STM32Lx_NVM_PECR_PRGLOCK = (1<< 1),
+ STM32Lx_NVM_PECR_PELOCK = (1<< 0),
+
+ STM32Lx_NVM_SR_FWWERR = (1<<17),
+ STM32Lx_NVM_SR_NOTZEROERR = (1<<16),
+ STM32Lx_NVM_SR_RDERR = (1<<13),
+ STM32Lx_NVM_SR_OPTVER = (1<<11),
+ STM32Lx_NVM_SR_SIZERR = (1<<10),
+ STM32Lx_NVM_SR_PGAERR = (1<<9),
+ STM32Lx_NVM_SR_WRPERR = (1<<8),
+ STM32Lx_NVM_SR_READY = (1<<3),
+ STM32Lx_NVM_SR_HWOFF = (1<<2),
+ STM32Lx_NVM_SR_EOP = (1<<1),
+ STM32Lx_NVM_SR_BSY = (1<<0),
+ STM32Lx_NVM_SR_ERR_M = ( STM32Lx_NVM_SR_WRPERR
+ | STM32Lx_NVM_SR_PGAERR
+ | STM32Lx_NVM_SR_SIZERR
+ | STM32Lx_NVM_SR_NOTZEROERR),
+
+ STM32L0_NVM_OPTR_BOOT1 = (1<<31),
+ STM32L0_NVM_OPTR_WDG_SW = (1<<20),
+ STM32L0_NVM_OPTR_WPRMOD = (1<<8),
+ STM32L0_NVM_OPTR_RDPROT_S = (0),
+ STM32L0_NVM_OPTR_RDPROT_M = (0xff),
+ STM32L0_NVM_OPTR_RDPROT_0 = (0xaa),
+ STM32L0_NVM_OPTR_RDPROT_2 = (0xcc),
+
+ STM32L1_NVM_OPTR_nBFB2 = (1<<23),
+ STM32L1_NVM_OPTR_nRST_STDBY = (1<<22),
+ STM32L1_NVM_OPTR_nRST_STOP = (1<<21),
+ STM32L1_NVM_OPTR_WDG_SW = (1<<20),
+ STM32L1_NVM_OPTR_BOR_LEV_S = (16),
+ STM32L1_NVM_OPTR_BOR_LEV_M = (0xf),
+ STM32L1_NVM_OPTR_SPRMOD = (1<<8),
+ STM32L1_NVM_OPTR_RDPROT_S = (0),
+ STM32L1_NVM_OPTR_RDPROT_M = (0xff),
+ STM32L1_NVM_OPTR_RDPROT_0 = (0xaa),
+ STM32L1_NVM_OPTR_RDPROT_2 = (0xcc),
+
+};
+
+#if defined (__cplusplus)
+
+namespace STM32 {
+ struct NVM {
+ volatile uint32_t acr;
+ volatile uint32_t pecr;
+ volatile uint32_t pdkeyr;
+ volatile uint32_t pkeyr;
+ volatile uint32_t prgkeyr;
+ volatile uint32_t optkeyr;
+ volatile uint32_t sr;
+ volatile uint32_t optr;
+ volatile uint32_t wrprot;
+
+ static constexpr uint32_t PKEY1 = 0x89abcdef;
+ static constexpr uint32_t PKEY2 = 0x02030405;
+ static constexpr uint32_t PRGKEY1 = 0x8c9daebf;
+ static constexpr uint32_t PRGKEY2 = 0x13141516;
+ static constexpr uint32_t OPTKEY1 = 0xfbead9c8;
+ static constexpr uint32_t OPTKEY2 = 0x24252627;
+ static constexpr uint32_t PDKEY1 = 0x04152637;
+ static constexpr uint32_t PDKEY2 = 0xfafbfcfd;
+ };
+
+ static_assert(sizeof (NVM) == 9*4, "NVM size error");
+}
+using stm32lx_stub_pointer_t = uint32_t*;
+
+#define Nvm(nvm) (*reinterpret_cast<STM32::NVM*>(nvm))
+#define Info (*reinterpret_cast<stm32lx_nvm_stub_info*>(STM32Lx_STUB_INFO_PHYS))
+
+namespace {
+ inline __attribute((always_inline)) bool unlock (STM32::NVM& nvm) {
+ // Lock guarantees unlock
+ nvm.pecr = STM32Lx_NVM_PECR_PELOCK;
+
+ nvm.pkeyr = STM32::NVM::PKEY1;
+ nvm.pkeyr = STM32::NVM::PKEY2;
+ nvm.prgkeyr = STM32::NVM::PRGKEY1;
+ nvm.prgkeyr = STM32::NVM::PRGKEY2;
+ return !(nvm.pecr & STM32Lx_NVM_PECR_PRGLOCK);
+ }
+ inline __attribute((always_inline)) void lock (STM32::NVM& nvm) {
+ nvm.pecr = STM32Lx_NVM_PECR_PELOCK; }
+
+}
+
+#else
+
+typedef uint32_t stm32lx_stub_pointer_t;
+
+#define STM32Lx_NVM_PECR(p) ((p) + 0x04)
+#define STM32Lx_NVM_PEKEYR(p) ((p) + 0x0C)
+#define STM32Lx_NVM_PRGKEYR(p) ((p) + 0x10)
+#define STM32Lx_NVM_OPTKEYR(p) ((p) + 0x14)
+#define STM32Lx_NVM_SR(p) ((p) + 0x18)
+#define STM32Lx_NVM_OPTR(p) ((p) + 0x1C)
+
+#endif
+
+enum {
+ OPT_STM32L1 = 1<<1,
+};
+
+struct stm32lx_nvm_stub_info {
+ stm32lx_stub_pointer_t destination;
+ int32_t size;
+ stm32lx_stub_pointer_t source;
+ uint32_t nvm;
+ uint16_t page_size;
+ uint16_t options;
+} __attribute__((packed));
+
+/* ----- Globals */
+
+/* ----- Prototypes */
+
+
+
+#endif /* STM32Lx_NVM_H_INCLUDED */
diff --git a/src/include/swdptap.h b/src/include/swdptap.h
index 5bb0545..3263a1d 100644
--- a/src/include/swdptap.h
+++ b/src/include/swdptap.h
@@ -21,8 +21,6 @@
#ifndef __SWDPTAP_H
#define __SWDPTAP_H
-#include "general.h"
-
int swdptap_init(void);
void swdptap_reset(void);
diff --git a/src/include/target.h b/src/include/target.h
index 31501f6..940a360 100644
--- a/src/include/target.h
+++ b/src/include/target.h
@@ -25,8 +25,6 @@
#ifndef __TARGET_H
#define __TARGET_H
-#include "general.h"
-
typedef struct target_s target;
/* The destroy callback function will be called by target_list_free() just
@@ -34,7 +32,7 @@ typedef struct target_s target;
* targets, or because of a communication failure. The target data may
* be assumed to be intact, but the communication medium may not be available,
* so access methods shouldn't be called.
- *
+ *
* The callback is installed by target_attach() and only removed by attaching
* with a different callback. It remains intact after target_detach().
*/
@@ -50,18 +48,11 @@ target *target_attach(target *t, target_destroy_callback destroy_cb);
(target)->check_error(target)
/* Memory access functions */
-#define target_mem_read_words(target, dest, src, len) \
- (target)->mem_read_words((target), (dest), (src), (len))
-
-#define target_mem_write_words(target, dest, src, len) \
- (target)->mem_write_words((target), (dest), (src), (len))
-
-#define target_mem_read_bytes(target, dest, src, len) \
- (target)->mem_read_bytes((target), (dest), (src), (len))
-
-#define target_mem_write_bytes(target, dest, src, len) \
- (target)->mem_write_bytes((target), (dest), (src), (len))
+#define target_mem_read(target, dest, src, len) \
+ (target)->mem_read((target), (dest), (src), (len))
+#define target_mem_write(target, dest, src, len) \
+ (target)->mem_write((target), (dest), (src), (len))
/* Register access functions */
#define target_regs_read(target, data) \
@@ -70,12 +61,6 @@ target *target_attach(target *t, target_destroy_callback destroy_cb);
#define target_regs_write(target, data) \
(target)->regs_write((target), (data))
-#define target_pc_read(target) \
- (target)->pc_read((target))
-
-#define target_pc_write(target, val) \
- (target)->pc_write((target), (val))
-
/* Halt/resume functions */
#define target_reset(target) \
@@ -116,50 +101,58 @@ target *target_attach(target *t, target_destroy_callback destroy_cb);
#define target_flash_write(target, dest, src, len) \
(target)->flash_write((target), (dest), (src), (len))
+#define target_flash_done(target) \
+ ((target)->flash_done ? (target)->flash_done(target) : 0)
+
+/* Host I/O */
+#define target_hostio_reply(target, recode, errcode) \
+ (target)->hostio_reply((target), (retcode), (errcode))
+
+/* Accessor functions */
+#define target_regs_size(target) \
+ ((target)->regs_size)
+
+#define target_mem_map(target) \
+ ((target)->xml_mem_map ? (target)->xml_mem_map : "")
+
+#define target_tdesc(target) \
+ ((target)->tdesc ? (target)->tdesc : "")
struct target_s {
/* Notify controlling debugger if target is lost */
target_destroy_callback destroy_callback;
/* Attach/Detach funcitons */
- bool (*attach)(struct target_s *target);
- void (*detach)(struct target_s *target);
- int (*check_error)(struct target_s *target);
+ bool (*attach)(target *t);
+ void (*detach)(target *t);
+ bool (*check_error)(target *t);
/* Memory access functions */
- int (*mem_read_words)(struct target_s *target, uint32_t *dest, uint32_t src,
- int len);
- int (*mem_write_words)(struct target_s *target, uint32_t dest,
- const uint32_t *src, int len);
-
- int (*mem_read_bytes)(struct target_s *target, uint8_t *dest, uint32_t src,
- int len);
- int (*mem_write_bytes)(struct target_s *target, uint32_t dest,
- const uint8_t *src, int len);
+ void (*mem_read)(target *t, void *dest, uint32_t src,
+ size_t len);
+ void (*mem_write)(target *t, uint32_t dest,
+ const void *src, size_t len);
/* Register access functions */
int regs_size;
const char *tdesc;
- int (*regs_read)(struct target_s *target, void *data);
- int (*regs_write)(struct target_s *target, const void *data);
-
- uint32_t (*pc_read)(struct target_s *target);
- int (*pc_write)(struct target_s *target, const uint32_t val);
+ void (*regs_read)(target *t, void *data);
+ void (*regs_write)(target *t, const void *data);
/* Halt/resume functions */
- void (*reset)(struct target_s *target);
- void (*halt_request)(struct target_s *target);
- int (*halt_wait)(struct target_s *target);
- void (*halt_resume)(struct target_s *target, bool step);
+ void (*reset)(target *t);
+ void (*halt_request)(target *t);
+ int (*halt_wait)(target *t);
+ void (*halt_resume)(target *t, bool step);
/* Break-/watchpoint functions */
- int (*set_hw_bp)(struct target_s *target, uint32_t addr);
- int (*clear_hw_bp)(struct target_s *target, uint32_t addr);
+ int (*set_hw_bp)(target *t, uint32_t addr);
+ int (*clear_hw_bp)(target *t, uint32_t addr);
- int (*set_hw_wp)(struct target_s *target, uint8_t type, uint32_t addr, uint8_t len);
- int (*clear_hw_wp)(struct target_s *target, uint8_t type, uint32_t addr, uint8_t len);
+ int (*set_hw_wp)(target *t, uint8_t type, uint32_t addr, uint8_t len);
+ int (*clear_hw_wp)(target *t, uint8_t type, uint32_t addr, uint8_t len);
- int (*check_hw_wp)(struct target_s *target, uint32_t *addr);
+ int (*check_hw_wp)(target *t, uint32_t *addr);
/* target-defined options */
unsigned target_options;
@@ -167,9 +160,13 @@ struct target_s {
/* Flash memory access functions */
const char *xml_mem_map;
- int (*flash_erase)(struct target_s *target, uint32_t addr, int len);
- int (*flash_write)(struct target_s *target, uint32_t dest,
- const uint8_t *src, int len);
+ int (*flash_erase)(target *t, uint32_t addr, size_t len);
+ int (*flash_write)(target *t, uint32_t dest,
+ const uint8_t *src, size_t len);
+ int (*flash_done)(target *t);
+
+ /* Host I/O support */
+ void (*hostio_reply)(target *t, int32_t retcode, uint32_t errcode);
const char *driver;
struct target_command_s *commands;
@@ -188,22 +185,64 @@ struct target_command_s {
};
extern target *target_list;
+extern bool connect_assert_srst;
target *target_new(unsigned size);
void target_list_free(void);
void target_add_commands(target *t, const struct command_s *cmds, const char *name);
+static inline uint32_t target_mem_read32(target *t, uint32_t addr)
+{
+ uint32_t ret;
+ target_mem_read(t, &ret, addr, sizeof(ret));
+ return ret;
+}
+
+static inline void target_mem_write32(target *t, uint32_t addr, uint32_t value)
+{
+ target_mem_write(t, addr, &value, sizeof(value));
+}
+
+static inline uint16_t target_mem_read16(target *t, uint32_t addr)
+{
+ uint16_t ret;
+ target_mem_read(t, &ret, addr, sizeof(ret));
+ return ret;
+}
+
+static inline void target_mem_write16(target *t, uint32_t addr, uint16_t value)
+{
+ target_mem_write(t, addr, &value, sizeof(value));
+}
+
+static inline uint8_t target_mem_read8(target *t, uint32_t addr)
+{
+ uint8_t ret;
+ target_mem_read(t, &ret, addr, sizeof(ret));
+ return ret;
+}
+
+static inline void target_mem_write8(target *t, uint32_t addr, uint8_t value)
+{
+ target_mem_write(t, addr, &value, sizeof(value));
+}
+
+
/* Probe for various targets.
* Actual functions implemented in their respective drivers.
*/
-bool cortexm_probe(struct target_s *target);
-bool stm32f1_probe(struct target_s *target);
-bool stm32f4_probe(struct target_s *target);
-bool stm32l1_probe(struct target_s *target);
-bool lmi_probe(struct target_s *target);
-bool lpc11xx_probe(struct target_s *target);
-bool lpc43xx_probe(struct target_s *target);
-bool sam3x_probe(struct target_s *target);
+bool cortexm_probe(target *t);
+bool stm32f1_probe(target *t);
+bool stm32f4_probe(target *t);
+bool stm32l0_probe(target *t);
+bool stm32l1_probe(target *t);
+bool lmi_probe(target *t);
+bool lpc11xx_probe(target *t);
+bool lpc43xx_probe(target *t);
+bool sam3x_probe(target *t);
+bool nrf51_probe(target *t);
+bool samd_probe(target *t);
+bool kinetis_probe(target *t);
#endif