Skip to content
This repository was archived by the owner on Mar 7, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
2a385e7
avr: Added stub support for the AVR JTAG-PDI scan
dragonmux Dec 10, 2021
1df92b8
hosted: Fixed an error + warning the platform AVR support introduced
dragonmux Dec 10, 2021
67d3a58
jtag_scan: Added some brackets that were missing
dragonmux Dec 10, 2021
acb1425
adi: Fixed a couple of UB bitwise operations
dragonmux Dec 10, 2021
4928aad
avr: Begun implementing the PDI-specific JTAG IO routines
dragonmux Dec 10, 2021
52b6112
atxmega: Created a probing routine for the ATXMega series linup to co…
dragonmux Dec 11, 2021
38889a1
avr_pdi: Enabled the creation of a valid target to attach to in the J…
dragonmux Dec 11, 2021
f2c6384
jtag-pdi: Fixed an issue the way the JTAG handlers are called with th…
dragonmux Dec 11, 2021
39964b6
avr_pdi: Done some reorganisation to make the layout of the AVR targe…
dragonmux Dec 11, 2021
d6f6ba5
avr: Moved some code around and begun implementing the attach and det…
dragonmux Dec 11, 2021
c98ed53
avr: Added support for target_halt_poll
dragonmux Dec 18, 2021
18971f5
avr: Added support for target_reset
dragonmux Dec 18, 2021
211ead1
avr: Added support for target_halt_request
dragonmux Dec 18, 2021
a248d44
avr: Added support for enabling/disabling the debug and programming s…
dragonmux Dec 18, 2021
0a4832b
avr: Begun fleshing out attach/detach
dragonmux Dec 18, 2021
dcf006c
avr: Fixed the avr_attach error handling
dragonmux Dec 19, 2021
d3a8156
avr: Added debug logging to avr_jtag_shift_dr
dragonmux Dec 19, 2021
6357a9d
avr: Added the register size descriptor
dragonmux Dec 19, 2021
7fe0dc6
atxmega: Added register definitions for the xmega6 lineup
dragonmux Dec 19, 2021
c01f725
avr: Corrected the target register count field for the actual length …
dragonmux Dec 19, 2021
6ef59e9
avr: Created a first-pass at routines for reading/writing the AVR add…
dragonmux Dec 19, 2021
06767bf
avr: Implemented arbitrary processor-space memory block reading
dragonmux Dec 19, 2021
5197716
avr_pdi: Done a first pass at reading the AVR registers
dragonmux Dec 19, 2021
8f5a51a
avr: Rewrote the processor space load/store routines
dragonmux Dec 19, 2021
f7e8e19
avr: Static-correctness and added avr_regs_read to the target functio…
dragonmux Dec 19, 2021
f47da90
avr: Fixed the warning that was being generated by our target descrip…
dragonmux Dec 21, 2021
85878c0
avr: Removed the needless refcounting and added a target private free…
dragonmux Jan 18, 2022
e2b9f99
avr: Implemented handling for DELAY packets as we run so fast the PDI…
dragonmux Jan 21, 2022
42b6d2a
avr: Turns out a 16-bit read of an 8-bit register address does not re…
dragonmux Jan 21, 2022
cff5fdd
avr: Cleanup in avr_pdi_read_ind()
dragonmux Jan 21, 2022
350ad30
avr: Cleanup in avr_enable()
dragonmux Jan 21, 2022
b6ae147
avr: Made sure to enable NVM access during attach and disable it duri…
dragonmux Jan 21, 2022
470186f
avr: Improved the reset code so the status register not being the exp…
dragonmux Jan 21, 2022
58d5430
avr: Added preliminary read memory support (only supports Flash addre…
dragonmux Jan 21, 2022
2410423
avr: Unified the case of all the top of file constantsin avr_pdi.c
dragonmux Jan 21, 2022
d2ccf86
target: Made target_flash_for_addr() available as a target internal
dragonmux Feb 17, 2022
532da48
avr: Implemented PDI error tracking
dragonmux Feb 17, 2022
b0a59d1
atxmega: Fixed the memory map for the RAM
dragonmux Feb 17, 2022
7325d71
avr: Implemented read-out of RAM regions
dragonmux Feb 17, 2022
fd00957
avr: Fixed the naming of the JTAG PDI functions and types, dropping t…
dragonmux Feb 17, 2022
c50575a
avr: Refactored out avr_pdi_write_ptr() and avr_pdi_repeat() from avr…
dragonmux Feb 17, 2022
ed84ae4
avr: Implemented avr_pdi_write_ind()
dragonmux Feb 17, 2022
e4e3c45
avr: Implemented Flash erase and write routines
dragonmux Feb 17, 2022
a75d1ca
avr: Added a guard to stop the processor getting spuriously extra reset
dragonmux Feb 17, 2022
486a4a1
avr: Implemented an erase command to clean out Flash
dragonmux Feb 20, 2022
e6a27a9
hosted: Fixed an error introduced by the avr_pdi_t refactor
dragonmux Feb 20, 2022
2de8dab
avr: Added support in avr_pdi_s for breakpoints and storing the progr…
dragonmux Feb 20, 2022
d20d8f6
avr_pdi: Cleaned up the debug print in avr_jtag_shift_dr() to always …
dragonmux Feb 20, 2022
ddafc2c
avr: Added some additional r3 (debug status) checks to attach and reg…
dragonmux Feb 20, 2022
3779f89
atxmega: Added configuration to set the max breakpoints on each target
dragonmux Feb 20, 2022
d5747e2
avr: Implemented support for setting and clearing breakpoints
dragonmux Feb 20, 2022
50df05e
avr: Implemented the code required to write the current breakpoint co…
dragonmux Feb 20, 2022
91aa86b
avr: Implemented halt_resume and proper detection for running vs brea…
dragonmux Feb 20, 2022
0e2b322
avr: const and static correctness improvements
dragonmux Feb 20, 2022
dd94119
avr_jtagdp: Fixed the signature of avr_jtag_pdi_handler to match with…
dragonmux Mar 15, 2022
ee3e2b0
avr: Cleaned up the breakpoint configuration code, making it more robust
dragonmux Mar 19, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ SRC = \
adiv5.c \
adiv5_jtagdp.c \
adiv5_swdp.c \
atxmega.c \
avr_jtagdp.c \
avr_pdi.c \
command.c \
cortexa.c \
cortexm.c \
Expand Down
7 changes: 7 additions & 0 deletions src/platforms/hosted/platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "target.h"
#include "target_internal.h"
#include "adiv5.h"
#include "avr.h"
#include "timing.h"
#include "cl_utils.h"
#include "gdb_if.h"
Expand Down Expand Up @@ -252,6 +253,12 @@ int platform_jtag_dp_init(ADIv5_DP_t *dp)
return 0;
}

int platform_avr_jtag_pdi_init(avr_pdi_t *pdi)
{
(void)pdi;
return 0;
}

char *platform_ident(void)
{
switch (info.bmp_type) {
Expand Down
5 changes: 2 additions & 3 deletions src/target/adiv5.c
Original file line number Diff line number Diff line change
Expand Up @@ -683,9 +683,8 @@ void adiv5_dp_init(ADIv5_DP_t *dp)
return;
}
DEBUG_INFO("DPIDR 0x%08" PRIx32 " (v%d %srev%d)\n", dp->idcode,
(uint8_t)((dp->idcode >> 12) & 0xf),
(dp->idcode & ADIV5_MINDP) ? "MINDP " : "",
(uint16_t)(dp->idcode >> 28));
(uint8_t)((dp->idcode >> 12U) & 0xfU),
(dp->idcode & ADIV5_MINDP) ? "MINDP " : "", (uint16_t)(dp->idcode >> 28U));
volatile uint32_t ctrlstat = 0;
#if PC_HOSTED == 1
platform_adiv5_dp_defaults(dp);
Expand Down
74 changes: 74 additions & 0 deletions src/target/atxmega.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include "general.h"
#include "target.h"
#include "target_internal.h"
#include "avr.h"

#define IDCODE_XMEGA256A3U 0x9842U

static const char tdesc_xmega6[] =
"<?xml version=\"1.0\"?>"
"<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
"<target>"
" <architecture>avr:106</architecture>"
/* As it turns out, GDB doesn't acctually support this (despite asking for it!) yet */
#if 0
" <feature name=\"org.gnu.gdb.avr.cpu\">"
" <reg name=\"r0\" bitsize=\"8\" regnum=\"0\"/>"
" <reg name=\"r1\" bitsize=\"8\"/>"
" <reg name=\"r2\" bitsize=\"8\"/>"
" <reg name=\"r3\" bitsize=\"8\"/>"
" <reg name=\"r4\" bitsize=\"8\"/>"
" <reg name=\"r5\" bitsize=\"8\"/>"
" <reg name=\"r6\" bitsize=\"8\"/>"
" <reg name=\"r7\" bitsize=\"8\"/>"
" <reg name=\"r8\" bitsize=\"8\"/>"
" <reg name=\"r9\" bitsize=\"8\"/>"
" <reg name=\"r10\" bitsize=\"8\"/>"
" <reg name=\"r11\" bitsize=\"8\"/>"
" <reg name=\"r12\" bitsize=\"8\"/>"
" <reg name=\"r13\" bitsize=\"8\"/>"
" <reg name=\"r14\" bitsize=\"8\"/>"
" <reg name=\"r15\" bitsize=\"8\"/>"
" <reg name=\"r16\" bitsize=\"8\"/>"
" <reg name=\"r17\" bitsize=\"8\"/>"
" <reg name=\"r18\" bitsize=\"8\"/>"
" <reg name=\"r19\" bitsize=\"8\"/>"
" <reg name=\"r20\" bitsize=\"8\"/>"
" <reg name=\"r21\" bitsize=\"8\"/>"
" <reg name=\"r22\" bitsize=\"8\"/>"
" <reg name=\"r23\" bitsize=\"8\"/>"
" <reg name=\"r24\" bitsize=\"8\"/>"
" <reg name=\"r25\" bitsize=\"8\"/>"
" <reg name=\"r26\" bitsize=\"8\"/>"
" <reg name=\"r27\" bitsize=\"8\"/>"
" <reg name=\"r28\" bitsize=\"8\"/>"
" <reg name=\"r29\" bitsize=\"8\"/>"
" <reg name=\"r30\" bitsize=\"8\"/>"
" <reg name=\"r31\" bitsize=\"8\"/>"
" <reg name=\"sreg\" bitsize=\"8\"/>"
" <reg name=\"sp\" bitsize=\"16\" type=\"data_ptr\"/>"
" <reg name=\"pc\" bitsize=\"32\" type=\"code_ptr\"/>"
" </feature>"
#endif
"</target>";

bool atxmega_probe(target *t)
{
avr_pdi_t *pdi = t->priv;

switch (t->idcode) {
case IDCODE_XMEGA256A3U:
t->core = "ATXMega256A3U";
// RAM is actually at 0x01002000, but this is done to keep things right for GDB
// - internally we add 0x00800000 to get to the PDI mapped address.
target_add_ram(t, 0x00802000, 0x800);
// These are mapped here to make things make sense to GDB
// - internally we add 0x00800000 to get to the PDI mapped address.
avr_add_flash(t, 0x00000000, 0x40000);
avr_add_flash(t, 0x00040000, 0x2000);
t->tdesc = tdesc_xmega6;
pdi->hw_breakpoints_max = 2;
return true;
}
return false;
}
41 changes: 41 additions & 0 deletions src/target/avr.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#ifndef ATMEL___H
#define ATMEL___H

#include "jtag_scan.h"
#include "target.h"

enum avr_error_e
{
pdi_ok,
pdi_failure,
};

#define AVR_MAX_BREAKPOINTS 2

typedef struct avr_pdi_s {
uint32_t idcode;

uint8_t dp_jd_index;
enum target_halt_reason halt_reason;
enum avr_error_e error_state;
target_addr programCounter;

target_addr hw_breakpoint[AVR_MAX_BREAKPOINTS];
uint32_t hw_breakpoints_enabled;
uint32_t hw_breakpoints_max;
} avr_pdi_t;

bool avr_pdi_init(avr_pdi_t *pdi);

void avr_jtag_pdi_handler(uint8_t jd_index);
int platform_avr_jtag_pdi_init(avr_pdi_t *pdi);

bool avr_jtag_shift_dr(jtag_proc_t *jp, uint8_t jd_index, uint8_t *dout, const uint8_t din);
bool avr_pdi_reg_write(avr_pdi_t *pdi, uint8_t reg, uint8_t value);
uint8_t avr_pdi_reg_read(avr_pdi_t *pdi, uint8_t reg);

bool avr_attach(target *t);
void avr_detach(target *t);
void avr_add_flash(target *t, uint32_t start, size_t length);

#endif /*ATMEL___H*/
55 changes: 55 additions & 0 deletions src/target/avr_jtagdp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include "general.h"
#include "exception.h"
#include "avr.h"
#include "jtag_scan.h"
#include "jtagtap.h"

#define PDI_DELAY 0xDBU

void avr_jtag_pdi_handler(uint8_t jd_index)
{
avr_pdi_t *pdi = calloc(1, sizeof(*pdi));
if (!pdi) { /* calloc failed: heap exhaustion */
DEBUG_WARN("calloc: failed in %s\n", __func__);
return;
}
pdi->dp_jd_index = jd_index;
pdi->idcode = jtag_devs[jd_index].jd_idcode;
pdi->error_state = pdi_ok;
pdi->hw_breakpoints_enabled = 0;
if ((PC_HOSTED == 0) || (!platform_avr_jtag_pdi_init(pdi))) {
//
}
avr_pdi_init(pdi);
}

bool avr_jtag_shift_dr(jtag_proc_t *jp, uint8_t jd_index, uint8_t *dout, const uint8_t din)
{
jtag_dev_t *d = &jtag_devs[jd_index];
uint8_t result = 0;
uint16_t request = 0, response = 0;
uint8_t *data;
if (!dout)
return false;
do
{
data = (uint8_t *)&request;
jtagtap_shift_dr();
jp->jtagtap_tdi_seq(0, ones, d->dr_prescan);
data[0] = din;
// Calculate the parity bit
for (uint8_t i = 0; i < 8; ++i)
data[1] ^= (din >> i) & 1U;
jp->jtagtap_tdi_tdo_seq((uint8_t *)&response, 1, (uint8_t *)&request, 9);
jp->jtagtap_tdi_seq(1, ones, d->dr_postscan);
jtagtap_return_idle();
data = (uint8_t *)&response;
}
while (data[0] == PDI_DELAY && data[1] == 1);
// Calculate the parity bit
for (uint8_t i = 0; i < 8; ++i)
result ^= (data[0] >> i) & 1U;
*dout = data[0];
DEBUG_INFO("Sent 0x%02x to target, response was 0x%02x (0x%x)\n", din, data[0], data[1]);
return result == data[1];
}
Loading