aboutsummaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/include')
-rw-r--r--src/include/adiv5.h71
-rw-r--r--src/include/cortexm.h8
-rw-r--r--src/include/crc32.h2
-rw-r--r--src/include/exception.h74
-rw-r--r--src/include/general.h4
-rw-r--r--src/include/target.h154
6 files changed, 197 insertions, 116 deletions
diff --git a/src/include/adiv5.h b/src/include/adiv5.h
index e0ce9cf..12d3bf4 100644
--- a/src/include/adiv5.h
+++ b/src/include/adiv5.h
@@ -24,12 +24,16 @@
#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 */
@@ -63,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)
@@ -93,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 {
@@ -105,15 +107,10 @@ typedef struct ADIv5_DP_s {
uint32_t idcode;
- bool allow_timeout;
-
- 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;
@@ -121,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);
}
@@ -136,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 {
@@ -158,24 +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);
-uint8_t adiv5_ap_mem_read_byte(ADIv5_AP_t *ap, uint32_t addr);
-void adiv5_ap_mem_write_byte(ADIv5_AP_t *ap, uint32_t addr, uint8_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/cortexm.h b/src/include/cortexm.h
index 1fd77e6..f7396bf 100644
--- a/src/include/cortexm.h
+++ b/src/include/cortexm.h
@@ -143,9 +143,11 @@
#define CORTEXM_DWT_FUNC_FUNC_WRITE (6 << 0)
#define CORTEXM_DWT_FUNC_FUNC_ACCESS (7 << 0)
-bool cortexm_attach(struct target_s *target);
-void cortexm_detach(struct target_s *target);
-void cortexm_halt_resume(struct target_s *target, bool step);
+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 9966d8d..bd8d5c4 100644
--- a/src/include/crc32.h
+++ b/src/include/crc32.h
@@ -22,6 +22,6 @@
#define __CRC32_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/general.h b/src/include/general.h
index 2cb4bd9..c82c750 100644
--- a/src/include/general.h
+++ b/src/include/general.h
@@ -38,5 +38,9 @@
#define DEBUG printf
#endif
+#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/target.h b/src/include/target.h
index 5db79a7..940a360 100644
--- a/src/include/target.h
+++ b/src/include/target.h
@@ -48,24 +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_halfwords(target, dest, src, len) \
- (target)->mem_read_halfwords((target), (dest), (src), (len))
-
-#define target_mem_write_halfwords(target, dest, src, len) \
- (target)->mem_write_halfwords((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) \
@@ -74,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) \
@@ -120,59 +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_halfwords)(struct target_s *target, uint16_t *dest, uint32_t src,
- int len);
- int (*mem_write_halfwords)(struct target_s *target, uint32_t dest,
- const uint16_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;
@@ -180,9 +160,10 @@ struct target_s {
/* Flash memory access functions */
const char *xml_mem_map;
- int (*flash_erase)(struct target_s *target, uint32_t addr, size_t len);
- int (*flash_write)(struct target_s *target, uint32_t dest,
+ 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);
@@ -210,21 +191,58 @@ 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 stm32l0_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 nrf51_probe(struct target_s *target);
-bool samd_probe(struct target_s *target);
-bool kinetis_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