diff --git a/src/Makefile b/src/Makefile index ea5a857..7080875 100644 --- a/src/Makefile +++ b/src/Makefile @@ -13,6 +13,7 @@ OPT_FLAGS ?= -O2 CFLAGS += -Wall -Wextra -Werror -Wno-char-subscripts\ $(OPT_FLAGS) -std=gnu99 -g3 -MD \ -I. -Iinclude -Iplatforms/common -I$(PLATFORM_DIR) +LDFLAGS += $(OPT_FLAGS) ifeq ($(ENABLE_DEBUG), 1) CFLAGS += -DENABLE_DEBUG diff --git a/src/gdb_main.c b/src/gdb_main.c index 77d2ce0..124fbd2 100644 --- a/src/gdb_main.c +++ b/src/gdb_main.c @@ -365,14 +365,7 @@ handle_v_packet(char *packet, int plen) if (sscanf(packet, "vAttach;%08lx", &addr) == 1) { /* Attach to remote target processor */ - target *t; - uint32_t i; - for(t = target_list, i = 1; t; t = t->next, i++) - if(i == addr) { - cur_target = target_attach(t, - gdb_target_destroy_callback); - break; - } + cur_target = target_attach_n(addr, gdb_target_destroy_callback); if(cur_target) gdb_putpacketz("T05"); else diff --git a/src/include/target.h b/src/include/target.h index e0839a2..867035a 100644 --- a/src/include/target.h +++ b/src/include/target.h @@ -1,7 +1,7 @@ /* * This file is part of the Black Magic Debug project. * - * Copyright (C) 2011 Black Sphere Technologies Ltd. + * Copyright (C) 2016 Black Sphere Technologies Ltd. * Written by Gareth McMullin * * This program is free software: you can redistribute it and/or modify @@ -40,59 +40,39 @@ typedef void (*target_destroy_callback)(target *t); /* Halt/resume functions */ target *target_attach(target *t, target_destroy_callback destroy_cb); - -#define target_detach(target) \ - (target)->detach(target) - -#define target_check_error(target) \ - (target)->check_error(target) +target *target_attach_n(int n, target_destroy_callback destroy_cb); +void target_detach(target *t); +bool target_check_error(target *t); /* Memory access functions */ -#define target_mem_read(target, dest, src, len) \ - (target)->mem_read((target), (dest), (src), (len)) +void target_mem_read(target *t, void *dest, uint32_t src, size_t len); +void target_mem_write(target *t, uint32_t dest, const void *src, size_t len); -#define target_mem_write(target, dest, src, len) \ - (target)->mem_write((target), (dest), (src), (len)) +uint32_t target_mem_read32(target *t, uint32_t addr); +uint16_t target_mem_read16(target *t, uint32_t addr); +uint8_t target_mem_read8(target *t, uint32_t addr); +void target_mem_write32(target *t, uint32_t addr, uint32_t value); +void target_mem_write16(target *t, uint32_t addr, uint16_t value); +void target_mem_write8(target *t, uint32_t addr, uint8_t value); /* Register access functions */ -#define target_regs_read(target, data) \ - (target)->regs_read((target), (data)) - -#define target_regs_write(target, data) \ - (target)->regs_write((target), (data)) - +void target_regs_read(target *t, void *data); +void target_regs_write(target *t, const void *data); /* Halt/resume functions */ -#define target_reset(target) \ - (target)->reset(target) - -#define target_halt_request(target) \ - (target)->halt_request(target) - -#define target_halt_wait(target) \ - (target)->halt_wait(target) - -#define target_halt_resume(target, step) \ - (target)->halt_resume((target), (step)) +void target_reset(target *t); +void target_halt_request(target *t); +int target_halt_wait(target *t); +void target_halt_resume(target *t, bool step); /* Break-/watchpoint functions */ -#define target_set_hw_bp(target, addr, len) \ - (target)->set_hw_bp((target), (addr), (len)) +int target_set_hw_bp(target *t, uint32_t addr, uint8_t len); +int target_clear_hw_bp(target *t, uint32_t addr, uint8_t len); -#define target_clear_hw_bp(target, addr, len) \ - (target)->clear_hw_bp((target), (addr), (len)) - - -#define target_set_hw_wp(target, type, addr, len) \ - (target)->set_hw_wp((target), (type), (addr), (len)) - -#define target_clear_hw_wp(target, type, addr, len) \ - (target)->clear_hw_wp((target), (type), (addr), (len)) - - -#define target_check_hw_wp(target, addr) \ - ((target)->check_hw_wp?(target)->check_hw_wp((target), (addr)):0) +int target_set_hw_wp(target *t, uint8_t type, uint32_t addr, uint8_t len); +int target_clear_hw_wp(target *t, uint8_t type, uint32_t addr, uint8_t len); +int target_check_hw_wp(target *t, uint32_t *addr); /* Flash memory access functions */ int target_flash_erase(target *t, uint32_t addr, size_t len); @@ -101,103 +81,12 @@ int target_flash_write(target *t, int target_flash_done(target *t); /* Host I/O */ -#define target_hostio_reply(target, recode, errcode) \ - (target)->hostio_reply((target), (retcode), (errcode)) +void target_hostio_reply(target *t, int32_t retcode, uint32_t errcode); /* Accessor functions */ -#define target_regs_size(target) \ - ((target)->regs_size) - -#define target_tdesc(target) \ - ((target)->tdesc ? (target)->tdesc : "") - -struct target_ram { - uint32_t start; - uint32_t length; - struct target_ram *next; -}; - -struct target_flash; -typedef int (*flash_erase_func)(struct target_flash *f, uint32_t addr, size_t len); -typedef int (*flash_write_func)(struct target_flash *f, uint32_t dest, - const void *src, size_t len); -typedef int (*flash_done_func)(struct target_flash *f); -struct target_flash { - uint32_t start; - uint32_t length; - uint32_t blocksize; - flash_erase_func erase; - flash_write_func write; - flash_done_func done; - target *t; - struct target_flash *next; - int align; - uint8_t erased; - - /* For buffered flash */ - size_t buf_size; - flash_write_func write_buf; - uint32_t buf_addr; - void *buf; -}; - -struct target_s { - /* Notify controlling debugger if target is lost */ - target_destroy_callback destroy_callback; - - /* Attach/Detach funcitons */ - bool (*attach)(target *t); - void (*detach)(target *t); - bool (*check_error)(target *t); - - /* Memory access functions */ - 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; - void (*regs_read)(target *t, void *data); - void (*regs_write)(target *t, const void *data); - - /* Halt/resume functions */ - 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)(target *t, uint32_t addr, uint8_t len); - int (*clear_hw_bp)(target *t, 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)(target *t, uint32_t *addr); - - /* target-defined options */ - unsigned target_options; - uint32_t idcode; - - /* Target memory map */ - char *dyn_mem_map; - struct target_ram *ram; - struct target_flash *flash; - - /* Host I/O support */ - void (*hostio_reply)(target *t, int32_t retcode, uint32_t errcode); - - const char *driver; - struct target_command_s *commands; - - int size; - struct target_s *next; - - void *priv; - void (*priv_free)(void *); -}; +int target_regs_size(target *t); +const char *target_tdesc(target *t); +const char *target_mem_map(target *t); struct target_command_s { const char *specific_name; @@ -209,68 +98,8 @@ extern target *target_list; target *target_new(unsigned size); void target_list_free(void); -void target_add_commands(target *t, const struct command_s *cmds, const char *name); -void target_add_ram(target *t, uint32_t start, uint32_t len); -void target_add_flash(target *t, struct target_flash *f); -const char *target_mem_map(target *t); -int target_flash_write_buffered(struct target_flash *f, - uint32_t dest, const void *src, size_t len); -int target_flash_done_buffered(struct target_flash *f); -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 stm32f1_probe(target *t); -bool stm32f4_probe(target *t); -bool stm32l0_probe(target *t); -bool stm32l1_probe(target *t); -bool stm32l4_probe(target *t); -bool lmi_probe(target *t); -bool lpc11xx_probe(target *t); -bool lpc15xx_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); -bool efm32_probe(target *t); +#include "target_internal.h" #endif diff --git a/src/target.c b/src/target.c index 5e44c48..94a24cf 100644 --- a/src/target.c +++ b/src/target.c @@ -1,7 +1,7 @@ /* * This file is part of the Black Magic Debug project. * - * Copyright (C) 2012 Black Sphere Technologies Ltd. + * Copyright (C) 2016 Black Sphere Technologies Ltd. * Written by Gareth McMullin * * This program is free software: you can redistribute it and/or modify @@ -80,6 +80,16 @@ void target_add_commands(target *t, const struct command_s *cmds, const char *na tc->next = NULL; } +target *target_attach_n(int n, target_destroy_callback destroy_cb) +{ + target *t; + int i; + for(t = target_list, i = 1; t; t = t->next, i++) + if(i == n) + return target_attach(t, destroy_cb); + return NULL; +} + target *target_attach(target *t, target_destroy_callback destroy_cb) { if (t->destroy_callback) @@ -254,4 +264,107 @@ int target_flash_done_buffered(struct target_flash *f) return ret; } +/* Wrapper functions */ +void target_detach(target *t) { t->detach(t); } +bool target_check_error(target *t) { return t->check_error(t); } + +/* Memory access functions */ +void target_mem_read(target *t, void *dest, uint32_t src, size_t len) +{ + t->mem_read(t, dest, src, len); +} + +void target_mem_write(target *t, uint32_t dest, const void *src, size_t len) +{ + t->mem_write(t, dest, src, len); +} + +/* Register access functions */ +void target_regs_read(target *t, void *data) { t->regs_read(t, data); } +void target_regs_write(target *t, const void *data) { t->regs_write(t, data); } + +/* Halt/resume functions */ +void target_reset(target *t) { t->reset(t); } +void target_halt_request(target *t) { t->halt_request(t); } +int target_halt_wait(target *t) { return t->halt_wait(t); } +void target_halt_resume(target *t, bool step) { t->halt_resume(t, step); } + +/* Break-/watchpoint functions */ +int target_set_hw_bp(target *t, uint32_t addr, uint8_t len) +{ + return t->set_hw_bp(t, addr, len); +} + +int target_clear_hw_bp(target *t, uint32_t addr, uint8_t len) +{ + return t->clear_hw_bp(t, addr, len); +} + +int target_set_hw_wp(target *t, uint8_t type, uint32_t addr, uint8_t len) +{ + return t->set_hw_wp(t, type, addr, len); +} + +int target_clear_hw_wp(target *t, uint8_t type, uint32_t addr, uint8_t len) +{ + return t->clear_hw_wp(t, type, addr, len); +} + +int target_check_hw_wp(target *t, uint32_t *addr) +{ + return t->check_hw_wp(t, addr); +} + +/* Host I/O */ +void target_hostio_reply(target *t, int32_t retcode, uint32_t errcode) +{ + t->hostio_reply(t, retcode, errcode); +} + +/* Accessor functions */ +int target_regs_size(target *t) +{ + return t->regs_size; +} + +const char *target_tdesc(target *t) +{ + return t->tdesc ? t->tdesc : ""; +} + +uint32_t target_mem_read32(target *t, uint32_t addr) +{ + uint32_t ret; + target_mem_read(t, &ret, addr, sizeof(ret)); + return ret; +} + +void target_mem_write32(target *t, uint32_t addr, uint32_t value) +{ + target_mem_write(t, addr, &value, sizeof(value)); +} + +uint16_t target_mem_read16(target *t, uint32_t addr) +{ + uint16_t ret; + target_mem_read(t, &ret, addr, sizeof(ret)); + return ret; +} + +void target_mem_write16(target *t, uint32_t addr, uint16_t value) +{ + target_mem_write(t, addr, &value, sizeof(value)); +} + +uint8_t target_mem_read8(target *t, uint32_t addr) +{ + uint8_t ret; + target_mem_read(t, &ret, addr, sizeof(ret)); + return ret; +} + +void target_mem_write8(target *t, uint32_t addr, uint8_t value) +{ + target_mem_write(t, addr, &value, sizeof(value)); +} diff --git a/src/target_internal.h b/src/target_internal.h new file mode 100644 index 0000000..6eb8fcf --- /dev/null +++ b/src/target_internal.h @@ -0,0 +1,137 @@ +/* + * This file is part of the Black Magic Debug project. + * + * Copyright (C) 2011 Black Sphere Technologies Ltd. + * Written by Gareth McMullin + * + * 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 . + */ + +#ifndef __TARGET_INTERNAL_H +#define __TARGET_INTERNAL_H + +struct target_ram { + uint32_t start; + uint32_t length; + struct target_ram *next; +}; + +struct target_flash; +typedef int (*flash_erase_func)(struct target_flash *f, uint32_t addr, size_t len); +typedef int (*flash_write_func)(struct target_flash *f, uint32_t dest, + const void *src, size_t len); +typedef int (*flash_done_func)(struct target_flash *f); +struct target_flash { + uint32_t start; + uint32_t length; + uint32_t blocksize; + flash_erase_func erase; + flash_write_func write; + flash_done_func done; + target *t; + struct target_flash *next; + int align; + uint8_t erased; + + /* For buffered flash */ + size_t buf_size; + flash_write_func write_buf; + uint32_t buf_addr; + void *buf; +}; + +struct target_s { + /* Notify controlling debugger if target is lost */ + target_destroy_callback destroy_callback; + + /* Attach/Detach funcitons */ + bool (*attach)(target *t); + void (*detach)(target *t); + bool (*check_error)(target *t); + + /* Memory access functions */ + 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; + void (*regs_read)(target *t, void *data); + void (*regs_write)(target *t, const void *data); + + /* Halt/resume functions */ + 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)(target *t, uint32_t addr, uint8_t len); + int (*clear_hw_bp)(target *t, 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)(target *t, uint32_t *addr); + + /* target-defined options */ + unsigned target_options; + uint32_t idcode; + + /* Target memory map */ + char *dyn_mem_map; + struct target_ram *ram; + struct target_flash *flash; + + /* Host I/O support */ + void (*hostio_reply)(target *t, int32_t retcode, uint32_t errcode); + + const char *driver; + struct target_command_s *commands; + + struct target_s *next; + + void *priv; + void (*priv_free)(void *); +}; + +void target_add_commands(target *t, const struct command_s *cmds, const char *name); +void target_add_ram(target *t, uint32_t start, uint32_t len); +void target_add_flash(target *t, struct target_flash *f); +int target_flash_write_buffered(struct target_flash *f, + uint32_t dest, const void *src, size_t len); +int target_flash_done_buffered(struct target_flash *f); + +/* Probe for various targets. + * Actual functions implemented in their respective drivers. + */ +bool stm32f1_probe(target *t); +bool stm32f4_probe(target *t); +bool stm32l0_probe(target *t); +bool stm32l1_probe(target *t); +bool stm32l4_probe(target *t); +bool lmi_probe(target *t); +bool lpc11xx_probe(target *t); +bool lpc15xx_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); +bool efm32_probe(target *t); + +#endif +