X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Fxtensa%2Fxtensa_debug_module.h;h=b4bb88682371b76faddb9ecf4c57099222ce0992;hb=de99836cf639b63dc357a34c13825669af841f17;hp=88f9eb2a7bc280983fc9f17aa6a498f5c7cf5047;hpb=057e566097b41f9bfeee50e97ba6ef624189ae6a;p=openocd.git diff --git a/src/target/xtensa/xtensa_debug_module.h b/src/target/xtensa/xtensa_debug_module.h index 88f9eb2a7b..b4bb886823 100644 --- a/src/target/xtensa/xtensa_debug_module.h +++ b/src/target/xtensa/xtensa_debug_module.h @@ -1,13 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ /*************************************************************************** - * Xtensa debug module API * + * Xtensa Debug Module (XDM) Support for OpenOCD * + * Copyright (C) 2020-2022 Cadence Design Systems, Inc. * * Copyright (C) 2019 Espressif Systems Ltd. * - * * - * * * Derived from original ESP8266 target. * - * Copyright (C) 2015 by Angus Gratton * - * gus@projectgus.com * + * Author: Angus Gratton gus@projectgus.com * ***************************************************************************/ #ifndef OPENOCD_TARGET_XTENSA_DEBUG_MODULE_H @@ -18,8 +16,23 @@ #include /* Virtual IDs for using with xtensa_power_ops API */ -#define DMREG_PWRCTL 0x00 -#define DMREG_PWRSTAT 0x01 +enum xtensa_dm_pwr_reg { + XDMREG_PWRCTL = 0x00, + XDMREG_PWRSTAT, + XDMREG_PWRNUM +}; + +/* Debug Module Power Register offsets within APB */ +struct xtensa_dm_pwr_reg_offsets { + uint16_t apb; +}; + +/* Debug Module Power Register offset structure; must include XDMREG_PWRNUM entries */ +#define XTENSA_DM_PWR_REG_OFFSETS { \ + /* Power/Reset Registers */ \ + { .apb = 0x3020 }, /* XDMREG_PWRCTL */ \ + { .apb = 0x3024 }, /* XDMREG_PWRSTAT */ \ +} /* From the manual: @@ -45,68 +58,187 @@ #define PWRSTAT_DEBUGDOMAINON BIT(2) #define PWRSTAT_MEMDOMAINON BIT(1) #define PWRSTAT_COREDOMAINON BIT(0) +/* Virtual IDs for using with xtensa_debug_ops API */ +enum xtensa_dm_reg { + /* TRAX Registers */ + XDMREG_TRAXID = 0x00, + XDMREG_TRAXCTRL, + XDMREG_TRAXSTAT, + XDMREG_TRAXDATA, + XDMREG_TRAXADDR, + XDMREG_TRIGGERPC, + XDMREG_PCMATCHCTRL, + XDMREG_DELAYCNT, + XDMREG_MEMADDRSTART, + XDMREG_MEMADDREND, + + /* Performance Monitor Registers */ + XDMREG_PMG, + XDMREG_INTPC, + XDMREG_PM0, + XDMREG_PM1, + XDMREG_PM2, + XDMREG_PM3, + XDMREG_PM4, + XDMREG_PM5, + XDMREG_PM6, + XDMREG_PM7, + XDMREG_PMCTRL0, + XDMREG_PMCTRL1, + XDMREG_PMCTRL2, + XDMREG_PMCTRL3, + XDMREG_PMCTRL4, + XDMREG_PMCTRL5, + XDMREG_PMCTRL6, + XDMREG_PMCTRL7, + XDMREG_PMSTAT0, + XDMREG_PMSTAT1, + XDMREG_PMSTAT2, + XDMREG_PMSTAT3, + XDMREG_PMSTAT4, + XDMREG_PMSTAT5, + XDMREG_PMSTAT6, + XDMREG_PMSTAT7, + + /* OCD Registers */ + XDMREG_OCDID, + XDMREG_DCRCLR, + XDMREG_DCRSET, + XDMREG_DSR, + XDMREG_DDR, + XDMREG_DDREXEC, + XDMREG_DIR0EXEC, + XDMREG_DIR0, + XDMREG_DIR1, + XDMREG_DIR2, + XDMREG_DIR3, + XDMREG_DIR4, + XDMREG_DIR5, + XDMREG_DIR6, + XDMREG_DIR7, + + /* Misc Registers */ + XDMREG_ERISTAT, + + /* CoreSight Registers */ + XDMREG_ITCTRL, + XDMREG_CLAIMSET, + XDMREG_CLAIMCLR, + XDMREG_LOCKACCESS, + XDMREG_LOCKSTATUS, + XDMREG_AUTHSTATUS, + XDMREG_DEVID, + XDMREG_DEVTYPE, + XDMREG_PERID4, + XDMREG_PERID5, + XDMREG_PERID6, + XDMREG_PERID7, + XDMREG_PERID0, + XDMREG_PERID1, + XDMREG_PERID2, + XDMREG_PERID3, + XDMREG_COMPID0, + XDMREG_COMPID1, + XDMREG_COMPID2, + XDMREG_COMPID3, + + XDMREG_NUM +}; -/* *** NAR addresses (also used as IDs for debug registers in xtensa_debug_ops API) *** - *TRAX registers */ -#define NARADR_TRAXID 0x00 -#define NARADR_TRAXCTRL 0x01 -#define NARADR_TRAXSTAT 0x02 -#define NARADR_TRAXDATA 0x03 -#define NARADR_TRAXADDR 0x04 -#define NARADR_TRIGGERPC 0x05 -#define NARADR_PCMATCHCTRL 0x06 -#define NARADR_DELAYCNT 0x07 -#define NARADR_MEMADDRSTART 0x08 -#define NARADR_MEMADDREND 0x09 -/*Performance monitor registers */ -#define NARADR_PMG 0x20 -#define NARADR_INTPC 0x24 -#define NARADR_PM0 0x28 -/*... */ -#define NARADR_PM7 0x2F -#define NARADR_PMCTRL0 0x30 -/*... */ -#define NARADR_PMCTRL7 0x37 -#define NARADR_PMSTAT0 0x38 -/*... */ -#define NARADR_PMSTAT7 0x3F -/*OCD registers */ -#define NARADR_OCDID 0x40 -#define NARADR_DCRCLR 0x42 -#define NARADR_DCRSET 0x43 -#define NARADR_DSR 0x44 -#define NARADR_DDR 0x45 -#define NARADR_DDREXEC 0x46 -#define NARADR_DIR0EXEC 0x47 -#define NARADR_DIR0 0x48 -#define NARADR_DIR1 0x49 -/*... */ -#define NARADR_DIR7 0x4F -/*Misc registers */ -#define NARADR_PWRCTL 0x58 -#define NARADR_PWRSTAT 0x59 -#define NARADR_ERISTAT 0x5A -/*CoreSight registers */ -#define NARADR_ITCTRL 0x60 -#define NARADR_CLAIMSET 0x68 -#define NARADR_CLAIMCLR 0x69 -#define NARADR_LOCKACCESS 0x6c -#define NARADR_LOCKSTATUS 0x6d -#define NARADR_AUTHSTATUS 0x6e -#define NARADR_DEVID 0x72 -#define NARADR_DEVTYPE 0x73 -#define NARADR_PERID4 0x74 -/*... */ -#define NARADR_PERID7 0x77 -#define NARADR_PERID0 0x78 -/*... */ -#define NARADR_PERID3 0x7b -#define NARADR_COMPID0 0x7c -/*... */ -#define NARADR_COMPID3 0x7f -#define NARADR_MAX NARADR_COMPID3 - -/*OCD registers, bit definitions */ +/* Debug Module Register offsets within Nexus (NAR) or APB */ +struct xtensa_dm_reg_offsets { + uint8_t nar; + uint16_t apb; +}; + +/* Debug Module Register offset structure; must include XDMREG_NUM entries */ +#define XTENSA_DM_REG_OFFSETS { \ + /* TRAX Registers */ \ + { .nar = 0x00, .apb = 0x0000 }, /* XDMREG_TRAXID */ \ + { .nar = 0x01, .apb = 0x0004 }, /* XDMREG_TRAXCTRL */ \ + { .nar = 0x02, .apb = 0x0008 }, /* XDMREG_TRAXSTAT */ \ + { .nar = 0x03, .apb = 0x000c }, /* XDMREG_TRAXDATA */ \ + { .nar = 0x04, .apb = 0x0010 }, /* XDMREG_TRAXADDR */ \ + { .nar = 0x05, .apb = 0x0014 }, /* XDMREG_TRIGGERPC */ \ + { .nar = 0x06, .apb = 0x0018 }, /* XDMREG_PCMATCHCTRL */ \ + { .nar = 0x07, .apb = 0x001c }, /* XDMREG_DELAYCNT */ \ + { .nar = 0x08, .apb = 0x0020 }, /* XDMREG_MEMADDRSTART */ \ + { .nar = 0x09, .apb = 0x0024 }, /* XDMREG_MEMADDREND */ \ + \ + /* Performance Monitor Registers */ \ + { .nar = 0x20, .apb = 0x1000 }, /* XDMREG_PMG */ \ + { .nar = 0x24, .apb = 0x1010 }, /* XDMREG_INTPC */ \ + { .nar = 0x28, .apb = 0x1080 }, /* XDMREG_PM0 */ \ + { .nar = 0x29, .apb = 0x1084 }, /* XDMREG_PM1 */ \ + { .nar = 0x2a, .apb = 0x1088 }, /* XDMREG_PM2 */ \ + { .nar = 0x2b, .apb = 0x108c }, /* XDMREG_PM3 */ \ + { .nar = 0x2c, .apb = 0x1090 }, /* XDMREG_PM4 */ \ + { .nar = 0x2d, .apb = 0x1094 }, /* XDMREG_PM5 */ \ + { .nar = 0x2e, .apb = 0x1098 }, /* XDMREG_PM6 */ \ + { .nar = 0x2f, .apb = 0x109c }, /* XDMREG_PM7 */ \ + { .nar = 0x30, .apb = 0x1100 }, /* XDMREG_PMCTRL0 */ \ + { .nar = 0x31, .apb = 0x1104 }, /* XDMREG_PMCTRL1 */ \ + { .nar = 0x32, .apb = 0x1108 }, /* XDMREG_PMCTRL2 */ \ + { .nar = 0x33, .apb = 0x110c }, /* XDMREG_PMCTRL3 */ \ + { .nar = 0x34, .apb = 0x1110 }, /* XDMREG_PMCTRL4 */ \ + { .nar = 0x35, .apb = 0x1114 }, /* XDMREG_PMCTRL5 */ \ + { .nar = 0x36, .apb = 0x1118 }, /* XDMREG_PMCTRL6 */ \ + { .nar = 0x37, .apb = 0x111c }, /* XDMREG_PMCTRL7 */ \ + { .nar = 0x38, .apb = 0x1180 }, /* XDMREG_PMSTAT0 */ \ + { .nar = 0x39, .apb = 0x1184 }, /* XDMREG_PMSTAT1 */ \ + { .nar = 0x3a, .apb = 0x1188 }, /* XDMREG_PMSTAT2 */ \ + { .nar = 0x3b, .apb = 0x118c }, /* XDMREG_PMSTAT3 */ \ + { .nar = 0x3c, .apb = 0x1190 }, /* XDMREG_PMSTAT4 */ \ + { .nar = 0x3d, .apb = 0x1194 }, /* XDMREG_PMSTAT5 */ \ + { .nar = 0x3e, .apb = 0x1198 }, /* XDMREG_PMSTAT6 */ \ + { .nar = 0x3f, .apb = 0x119c }, /* XDMREG_PMSTAT7 */ \ + \ + /* OCD Registers */ \ + { .nar = 0x40, .apb = 0x2000 }, /* XDMREG_OCDID */ \ + { .nar = 0x42, .apb = 0x2008 }, /* XDMREG_DCRCLR */ \ + { .nar = 0x43, .apb = 0x200c }, /* XDMREG_DCRSET */ \ + { .nar = 0x44, .apb = 0x2010 }, /* XDMREG_DSR */ \ + { .nar = 0x45, .apb = 0x2014 }, /* XDMREG_DDR */ \ + { .nar = 0x46, .apb = 0x2018 }, /* XDMREG_DDREXEC */ \ + { .nar = 0x47, .apb = 0x201c }, /* XDMREG_DIR0EXEC */ \ + { .nar = 0x48, .apb = 0x2020 }, /* XDMREG_DIR0 */ \ + { .nar = 0x49, .apb = 0x2024 }, /* XDMREG_DIR1 */ \ + { .nar = 0x4a, .apb = 0x2028 }, /* XDMREG_DIR2 */ \ + { .nar = 0x4b, .apb = 0x202c }, /* XDMREG_DIR3 */ \ + { .nar = 0x4c, .apb = 0x2030 }, /* XDMREG_DIR4 */ \ + { .nar = 0x4d, .apb = 0x2034 }, /* XDMREG_DIR5 */ \ + { .nar = 0x4e, .apb = 0x2038 }, /* XDMREG_DIR6 */ \ + { .nar = 0x4f, .apb = 0x203c }, /* XDMREG_DIR7 */ \ + \ + /* Misc Registers */ \ + { .nar = 0x5a, .apb = 0x3028 }, /* XDMREG_ERISTAT */ \ + \ + /* CoreSight Registers */ \ + { .nar = 0x60, .apb = 0x3f00 }, /* XDMREG_ITCTRL */ \ + { .nar = 0x68, .apb = 0x3fa0 }, /* XDMREG_CLAIMSET */ \ + { .nar = 0x69, .apb = 0x3fa4 }, /* XDMREG_CLAIMCLR */ \ + { .nar = 0x6c, .apb = 0x3fb0 }, /* XDMREG_LOCKACCESS */ \ + { .nar = 0x6d, .apb = 0x3fb4 }, /* XDMREG_LOCKSTATUS */ \ + { .nar = 0x6e, .apb = 0x3fb8 }, /* XDMREG_AUTHSTATUS */ \ + { .nar = 0x72, .apb = 0x3fc8 }, /* XDMREG_DEVID */ \ + { .nar = 0x73, .apb = 0x3fcc }, /* XDMREG_DEVTYPE */ \ + { .nar = 0x74, .apb = 0x3fd0 }, /* XDMREG_PERID4 */ \ + { .nar = 0x75, .apb = 0x3fd4 }, /* XDMREG_PERID5 */ \ + { .nar = 0x76, .apb = 0x3fd8 }, /* XDMREG_PERID6 */ \ + { .nar = 0x77, .apb = 0x3fdc }, /* XDMREG_PERID7 */ \ + { .nar = 0x78, .apb = 0x3fe0 }, /* XDMREG_PERID0 */ \ + { .nar = 0x79, .apb = 0x3fe4 }, /* XDMREG_PERID1 */ \ + { .nar = 0x7a, .apb = 0x3fe8 }, /* XDMREG_PERID2 */ \ + { .nar = 0x7b, .apb = 0x3fec }, /* XDMREG_PERID3 */ \ + { .nar = 0x7c, .apb = 0x3ff0 }, /* XDMREG_COMPID0 */ \ + { .nar = 0x7d, .apb = 0x3ff4 }, /* XDMREG_COMPID1 */ \ + { .nar = 0x7e, .apb = 0x3ff8 }, /* XDMREG_COMPID2 */ \ + { .nar = 0x7f, .apb = 0x3ffc }, /* XDMREG_COMPID3 */ \ +} + +#define XTENSA_DM_APB_MASK (0x3fff) + +/* OCD registers, bit definitions */ #define OCDDCR_ENABLEOCD BIT(0) #define OCDDCR_DEBUGINTERRUPT BIT(1) #define OCDDCR_INTERRUPTALLCONDS BIT(2) @@ -153,7 +285,7 @@ #define TRAXCTRL_CTIEN BIT(5) /* Cross-trigger enable */ #define TRAXCTRL_TMEN BIT(7) /* Tracemem Enable. Always set. */ #define TRAXCTRL_CNTU BIT(9) /* Post-stop-trigger countdown units; selects when DelayCount-- happens. - *0 - every 32-bit word written to tracemem, 1 - every cpu instruction */ + * 0 - every 32-bit word written to tracemem, 1 - every cpu instruction */ #define TRAXCTRL_TSEN BIT(11) /* Undocumented/deprecated? */ #define TRAXCTRL_SMPER_SHIFT 12 /* Send sync every 2^(9-smper) messages. 7=reserved, 0=no sync msg */ #define TRAXCTRL_SMPER_MASK 0x07 /* Synchronization message period */ @@ -191,7 +323,7 @@ #define PCMATCHCTRL_PCML_SHIFT 0 /* Amount of lower bits to ignore in pc trigger register */ #define PCMATCHCTRL_PCML_MASK 0x1F #define PCMATCHCTRL_PCMS BIT(31) /* PC Match Sense, 0-match when procs PC is in-range, 1-match when - *out-of-range */ + * out-of-range */ #define XTENSA_MAX_PERF_COUNTERS 2 #define XTENSA_MAX_PERF_SELECT 32 @@ -205,20 +337,24 @@ struct xtensa_debug_ops { /** enable operation */ int (*queue_enable)(struct xtensa_debug_module *dm); /** register read. */ - int (*queue_reg_read)(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data); + int (*queue_reg_read)(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint8_t *data); /** register write. */ - int (*queue_reg_write)(struct xtensa_debug_module *dm, unsigned int reg, uint32_t data); + int (*queue_reg_write)(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint32_t data); }; +/* Xtensa power registers are 8 bits wide on JTAG interfaces but 32 bits wide + * when accessed via APB/DAP. In order to use DAP queuing APIs (for optimal + * performance), the XDM power register APIs take 32-bit register params. + */ struct xtensa_power_ops { /** register read. */ - int (*queue_reg_read)(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data, - uint8_t clear); + int (*queue_reg_read)(struct xtensa_debug_module *dm, enum xtensa_dm_pwr_reg reg, uint8_t *data, + uint32_t clear); /** register write. */ - int (*queue_reg_write)(struct xtensa_debug_module *dm, unsigned int reg, uint8_t data); + int (*queue_reg_write)(struct xtensa_debug_module *dm, enum xtensa_dm_pwr_reg reg, uint32_t data); }; -typedef uint8_t xtensa_pwrstat_t; +typedef uint32_t xtensa_pwrstat_t; typedef uint32_t xtensa_ocdid_t; typedef uint32_t xtensa_dsr_t; typedef uint32_t xtensa_traxstat_t; @@ -291,10 +427,20 @@ struct xtensa_debug_module { int xtensa_dm_init(struct xtensa_debug_module *dm, const struct xtensa_debug_module_config *cfg); int xtensa_dm_queue_enable(struct xtensa_debug_module *dm); -int xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *value); -int xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, unsigned int reg, uint32_t value); -int xtensa_dm_queue_pwr_reg_read(struct xtensa_debug_module *dm, unsigned int reg, uint8_t *data, uint8_t clear); -int xtensa_dm_queue_pwr_reg_write(struct xtensa_debug_module *dm, unsigned int reg, uint8_t data); +int xtensa_dm_queue_reg_read(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint8_t *value); +int xtensa_dm_queue_reg_write(struct xtensa_debug_module *dm, enum xtensa_dm_reg reg, uint32_t value); +int xtensa_dm_queue_pwr_reg_read(struct xtensa_debug_module *dm, + enum xtensa_dm_pwr_reg reg, + uint8_t *data, + uint32_t clear); +int xtensa_dm_queue_pwr_reg_write(struct xtensa_debug_module *dm, + enum xtensa_dm_pwr_reg reg, + uint32_t data); + +static inline int xtensa_dm_queue_execute(struct xtensa_debug_module *dm) +{ + return jtag_execute_queue(); +} static inline void xtensa_dm_queue_tdi_idle(struct xtensa_debug_module *dm) { @@ -341,7 +487,7 @@ static inline bool xtensa_dm_is_online(struct xtensa_debug_module *dm) int res = xtensa_dm_device_id_read(dm); if (res != ERROR_OK) return false; - return (dm->device_id != 0xffffffff && dm->device_id != 0); + return dm->device_id != 0xffffffff && dm->device_id != 0; } static inline bool xtensa_dm_tap_was_reset(struct xtensa_debug_module *dm)