openocd: fix SPDX tag format for files .c
[fw/openocd] / src / target / arm11.c
index bb7b9c6be010d5f5e605c840acc34b037e3a330f..e48bcf30b06c72d8ee3f1d32e42f1a7fe6c23ac6 100644 (file)
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
 /***************************************************************************
  *   Copyright (C) 2008 digenius technology GmbH.                          *
  *   Michael Bruck                                                         *
@@ -7,21 +9,6 @@
  *   Copyright (C) 2008 Georg Acher <acher@in.tum.de>                      *
  *                                                                         *
  *   Copyright (C) 2009 David Brownell                                     *
- *                                                                         *
- *   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 2 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, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -44,7 +31,7 @@
 
 
 static int arm11_step(struct target *target, int current,
-               uint32_t address, int handle_breakpoints);
+               target_addr_t address, int handle_breakpoints);
 
 
 /** Check and if necessary take control of the system
@@ -53,14 +40,14 @@ static int arm11_step(struct target *target, int current,
  */
 static int arm11_check_init(struct arm11_common *arm11)
 {
-       CHECK_RETVAL(arm11_read_DSCR(arm11));
+       CHECK_RETVAL(arm11_read_dscr(arm11));
 
        if (!(arm11->dscr & DSCR_HALT_DBG_MODE)) {
                LOG_DEBUG("DSCR %08x", (unsigned) arm11->dscr);
                LOG_DEBUG("Bringing target into debug mode");
 
                arm11->dscr |= DSCR_HALT_DBG_MODE;
-               CHECK_RETVAL(arm11_write_DSCR(arm11, arm11->dscr));
+               CHECK_RETVAL(arm11_write_dscr(arm11, arm11->dscr));
 
                /* add further reset initialization here */
 
@@ -106,9 +93,9 @@ static int arm11_debug_entry(struct arm11_common *arm11)
        /* maybe save wDTR (pending DCC write to debug SW, e.g. libdcc) */
        arm11->is_wdtr_saved = !!(arm11->dscr & DSCR_DTR_TX_FULL);
        if (arm11->is_wdtr_saved) {
-               arm11_add_debug_SCAN_N(arm11, 0x05, ARM11_TAP_DEFAULT);
+               arm11_add_debug_scan_n(arm11, 0x05, ARM11_TAP_DEFAULT);
 
-               arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);
+               arm11_add_ir(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);
 
                struct scan_field chain5_fields[3];
 
@@ -128,7 +115,7 @@ static int arm11_debug_entry(struct arm11_common *arm11)
         * but not to issue ITRs(?).  The ARMv7 arch spec says it's required
         * for executing instructions via ITR.
         */
-       CHECK_RETVAL(arm11_write_DSCR(arm11, DSCR_ITR_EN | arm11->dscr));
+       CHECK_RETVAL(arm11_write_dscr(arm11, DSCR_ITR_EN | arm11->dscr));
 
 
        /* From the spec:
@@ -145,14 +132,14 @@ static int arm11_debug_entry(struct arm11_common *arm11)
                /* mcr     15, 0, r0, cr7, cr10, {4} */
                arm11_run_instr_no_data1(arm11, 0xee070f9a);
 
-               uint32_t dscr = arm11_read_DSCR(arm11);
+               uint32_t dscr = arm11_read_dscr(arm11);
 
                LOG_DEBUG("DRAIN, DSCR %08x", dscr);
 
                if (dscr & ARM11_DSCR_STICKY_IMPRECISE_DATA_ABORT) {
                        arm11_run_instr_no_data1(arm11, 0xe320f000);
 
-                       dscr = arm11_read_DSCR(arm11);
+                       dscr = arm11_read_dscr(arm11);
 
                        LOG_DEBUG("DRAIN, DSCR %08x (DONE)", dscr);
 
@@ -244,7 +231,7 @@ static int arm11_leave_debug_state(struct arm11_common *arm11, bool bpwp)
        /* spec says clear wDTR and rDTR; we assume they are clear as
           otherwise our programming would be sloppy */
        {
-               CHECK_RETVAL(arm11_read_DSCR(arm11));
+               CHECK_RETVAL(arm11_read_dscr(arm11));
 
                if (arm11->dscr & (DSCR_DTR_RX_FULL | DSCR_DTR_TX_FULL)) {
                        /*
@@ -287,23 +274,23 @@ static int arm11_leave_debug_state(struct arm11_common *arm11, bool bpwp)
        register_cache_invalidate(arm11->arm.core_cache);
 
        /* restore DSCR */
-       CHECK_RETVAL(arm11_write_DSCR(arm11, arm11->dscr));
+       CHECK_RETVAL(arm11_write_dscr(arm11, arm11->dscr));
 
        /* maybe restore rDTR */
        if (arm11->is_rdtr_saved) {
-               arm11_add_debug_SCAN_N(arm11, 0x05, ARM11_TAP_DEFAULT);
+               arm11_add_debug_scan_n(arm11, 0x05, ARM11_TAP_DEFAULT);
 
-               arm11_add_IR(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);
+               arm11_add_ir(arm11, ARM11_EXTEST, ARM11_TAP_DEFAULT);
 
                struct scan_field chain5_fields[3];
 
-               uint8_t Ready           = 0;                    /* ignored */
-               uint8_t Valid           = 0;                    /* ignored */
+               uint8_t ready           = 0;                    /* ignored */
+               uint8_t valid           = 0;                    /* ignored */
 
                arm11_setup_field(arm11, 32, &arm11->saved_rdtr,
                        NULL, chain5_fields + 0);
-               arm11_setup_field(arm11,  1, &Ready,    NULL, chain5_fields + 1);
-               arm11_setup_field(arm11,  1, &Valid,    NULL, chain5_fields + 2);
+               arm11_setup_field(arm11,  1, &ready,    NULL, chain5_fields + 1);
+               arm11_setup_field(arm11,  1, &valid,    NULL, chain5_fields + 2);
 
                arm11_add_dr_scan_vc(arm11->arm.target->tap, ARRAY_SIZE(
                                chain5_fields), chain5_fields, TAP_DRPAUSE);
@@ -357,21 +344,11 @@ static int arm11_arch_state(struct target *target)
        /* REVISIT also display ARM11-specific MMU and cache status ... */
 
        if (target->debug_reason == DBG_REASON_WATCHPOINT)
-               LOG_USER("Watchpoint triggered at PC %#08x",
-                       (unsigned) arm11->dpm.wp_pc);
+               LOG_USER("Watchpoint triggered at PC " TARGET_ADDR_FMT, arm11->dpm.wp_addr);
 
        return retval;
 }
 
-/* target request support */
-static int arm11_target_request_data(struct target *target,
-       uint32_t size, uint8_t *buffer)
-{
-       LOG_WARNING("Not implemented: %s", __func__);
-
-       return ERROR_FAIL;
-}
-
 /* target execution control */
 static int arm11_halt(struct target *target)
 {
@@ -388,20 +365,20 @@ static int arm11_halt(struct target *target)
                return ERROR_OK;
        }
 
-       arm11_add_IR(arm11, ARM11_HALT, TAP_IDLE);
+       arm11_add_ir(arm11, ARM11_HALT, TAP_IDLE);
 
        CHECK_RETVAL(jtag_execute_queue());
 
        int i = 0;
 
        while (1) {
-               CHECK_RETVAL(arm11_read_DSCR(arm11));
+               CHECK_RETVAL(arm11_read_dscr(arm11));
 
                if (arm11->dscr & DSCR_CORE_HALTED)
                        break;
 
 
-               long long then = 0;
+               int64_t then = 0;
                if (i == 1000)
                        then = timeval_ms();
                if (i >= 1000) {
@@ -429,16 +406,38 @@ static uint32_t arm11_nextpc(struct arm11_common *arm11, int current, uint32_t a
 {
        void *value = arm11->arm.pc->value;
 
-       if (!current)
-               buf_set_u32(value, 0, 32, address);
-       else
+       /* use the current program counter */
+       if (current)
                address = buf_get_u32(value, 0, 32);
 
+       /* Make sure that the gdb thumb fixup does not
+        * kill the return address
+        */
+       switch (arm11->arm.core_state) {
+               case ARM_STATE_ARM:
+                       address &= 0xFFFFFFFC;
+                       break;
+               case ARM_STATE_THUMB:
+                       /* When the return address is loaded into PC
+                        * bit 0 must be 1 to stay in Thumb state
+                        */
+                       address |= 0x1;
+                       break;
+
+               /* catch-all for JAZELLE and THUMB_EE */
+               default:
+                       break;
+       }
+
+       buf_set_u32(value, 0, 32, address);
+       arm11->arm.pc->dirty = true;
+       arm11->arm.pc->valid = true;
+
        return address;
 }
 
 static int arm11_resume(struct target *target, int current,
-       uint32_t address, int handle_breakpoints, int debug_execution)
+       target_addr_t address, int handle_breakpoints, int debug_execution)
 {
        /*        LOG_DEBUG("current %d  address %08x  handle_breakpoints %d  debug_execution %d", */
        /*      current, address, handle_breakpoints, debug_execution); */
@@ -456,7 +455,7 @@ static int arm11_resume(struct target *target, int current,
 
        address = arm11_nextpc(arm11, current, address);
 
-       LOG_DEBUG("RESUME PC %08" PRIx32 "%s", address, !current ? "!" : "");
+       LOG_DEBUG("RESUME PC %08" TARGET_PRIxADDR "%s", address, !current ? "!" : "");
 
        /* clear breakpoints/watchpoints and VCR*/
        CHECK_RETVAL(arm11_sc7_clear_vbw(arm11));
@@ -470,7 +469,7 @@ static int arm11_resume(struct target *target, int current,
 
                for (bp = target->breakpoints; bp; bp = bp->next) {
                        if (bp->address == address) {
-                               LOG_DEBUG("must step over %08" PRIx32 "", bp->address);
+                               LOG_DEBUG("must step over %08" TARGET_PRIxADDR "", bp->address);
                                arm11_step(target, 1, 0, 0);
                                break;
                        }
@@ -496,7 +495,7 @@ static int arm11_resume(struct target *target, int current,
 
                        CHECK_RETVAL(arm11_sc7_run(arm11, brp, ARRAY_SIZE(brp)));
 
-                       LOG_DEBUG("Add BP %d at %08" PRIx32, brp_num,
+                       LOG_DEBUG("Add BP %d at %08" TARGET_PRIxADDR, brp_num,
                                bp->address);
 
                        brp_num++;
@@ -509,13 +508,13 @@ static int arm11_resume(struct target *target, int current,
        /* activate all watchpoints and breakpoints */
        CHECK_RETVAL(arm11_leave_debug_state(arm11, true));
 
-       arm11_add_IR(arm11, ARM11_RESTART, TAP_IDLE);
+       arm11_add_ir(arm11, ARM11_RESTART, TAP_IDLE);
 
        CHECK_RETVAL(jtag_execute_queue());
 
        int i = 0;
        while (1) {
-               CHECK_RETVAL(arm11_read_DSCR(arm11));
+               CHECK_RETVAL(arm11_read_dscr(arm11));
 
                LOG_DEBUG("DSCR %08x", (unsigned) arm11->dscr);
 
@@ -523,7 +522,7 @@ static int arm11_resume(struct target *target, int current,
                        break;
 
 
-               long long then = 0;
+               int64_t then = 0;
                if (i == 1000)
                        then = timeval_ms();
                if (i >= 1000) {
@@ -546,7 +545,7 @@ static int arm11_resume(struct target *target, int current,
 }
 
 static int arm11_step(struct target *target, int current,
-       uint32_t address, int handle_breakpoints)
+       target_addr_t address, int handle_breakpoints)
 {
        LOG_DEBUG("target->state: %s",
                target_state_name(target));
@@ -560,7 +559,7 @@ static int arm11_step(struct target *target, int current,
 
        address = arm11_nextpc(arm11, current, address);
 
-       LOG_DEBUG("STEP PC %08" PRIx32 "%s", address, !current ? "!" : "");
+       LOG_DEBUG("STEP PC %08" TARGET_PRIxADDR "%s", address, !current ? "!" : "");
 
 
        /** \todo TODO: Thumb not supported here */
@@ -572,13 +571,13 @@ static int arm11_step(struct target *target, int current,
        /* skip over BKPT */
        if ((next_instruction & 0xFFF00070) == 0xe1200070) {
                address = arm11_nextpc(arm11, 0, address + 4);
-               LOG_DEBUG("Skipping BKPT %08" PRIx32, address);
+               LOG_DEBUG("Skipping BKPT %08" TARGET_PRIxADDR, address);
        }
        /* skip over Wait for interrupt / Standby
         * mcr  15, 0, r?, cr7, cr0, {4} */
        else if ((next_instruction & 0xFFFF0FFF) == 0xee070f90) {
                address = arm11_nextpc(arm11, 0, address + 4);
-               LOG_DEBUG("Skipping WFI %08" PRIx32, address);
+               LOG_DEBUG("Skipping WFI %08" TARGET_PRIxADDR, address);
        }
        /* ignore B to self */
        else if ((next_instruction & 0xFEFFFFFF) == 0xeafffffe)
@@ -651,7 +650,7 @@ static int arm11_step(struct target *target, int current,
 
                CHECK_RETVAL(arm11_leave_debug_state(arm11, handle_breakpoints));
 
-               arm11_add_IR(arm11, ARM11_RESTART, TAP_IDLE);
+               arm11_add_ir(arm11, ARM11_RESTART, TAP_IDLE);
 
                CHECK_RETVAL(jtag_execute_queue());
 
@@ -662,7 +661,7 @@ static int arm11_step(struct target *target, int current,
                        const uint32_t mask = DSCR_CORE_RESTARTED
                                | DSCR_CORE_HALTED;
 
-                       CHECK_RETVAL(arm11_read_DSCR(arm11));
+                       CHECK_RETVAL(arm11_read_dscr(arm11));
                        LOG_DEBUG("DSCR %08x e", (unsigned) arm11->dscr);
 
                        if ((arm11->dscr & mask) == mask)
@@ -703,21 +702,32 @@ static int arm11_assert_reset(struct target *target)
 {
        struct arm11_common *arm11 = target_to_arm11(target);
 
-       /* optionally catch reset vector */
-       if (target->reset_halt && !(arm11->vcr & 1))
-               CHECK_RETVAL(arm11_sc7_set_vcr(arm11, arm11->vcr | 1));
-
-       /* Issue some kind of warm reset. */
-       if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT))
-               target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
-       else if (jtag_get_reset_config() & RESET_HAS_SRST) {
-               /* REVISIT handle "pulls" cases, if there's
-                * hardware that needs them to work.
-                */
-               jtag_add_reset(0, 1);
+       if (!(target_was_examined(target))) {
+               if (jtag_get_reset_config() & RESET_HAS_SRST)
+                       jtag_add_reset(0, 1);
+               else {
+                       LOG_WARNING("Reset is not asserted because the target is not examined.");
+                       LOG_WARNING("Use a reset button or power cycle the target.");
+                       return ERROR_TARGET_NOT_EXAMINED;
+               }
        } else {
-               LOG_ERROR("%s: how to reset?", target_name(target));
-               return ERROR_FAIL;
+
+               /* optionally catch reset vector */
+               if (target->reset_halt && !(arm11->vcr & 1))
+                       CHECK_RETVAL(arm11_sc7_set_vcr(arm11, arm11->vcr | 1));
+
+               /* Issue some kind of warm reset. */
+               if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT))
+                       target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
+               else if (jtag_get_reset_config() & RESET_HAS_SRST) {
+                       /* REVISIT handle "pulls" cases, if there's
+                        * hardware that needs them to work.
+                        */
+                       jtag_add_reset(0, 1);
+               } else {
+                       LOG_ERROR("%s: how to reset?", target_name(target));
+                       return ERROR_FAIL;
+               }
        }
 
        /* registers are now invalid */
@@ -771,13 +781,6 @@ static int arm11_deassert_reset(struct target *target)
        return ERROR_OK;
 }
 
-static int arm11_soft_reset_halt(struct target *target)
-{
-       LOG_WARNING("Not implemented: %s", __func__);
-
-       return ERROR_FAIL;
-}
-
 /* target memory access
  * size: 1 = byte (8bit), 2 = half-word (16bit), 4 = word (32bit)
  * count: number of items of <size>
@@ -872,7 +875,7 @@ static int arm11_read_memory_inner(struct target *target,
 }
 
 static int arm11_read_memory(struct target *target,
-       uint32_t address,
+       target_addr_t address,
        uint32_t size,
        uint32_t count,
        uint8_t *buffer)
@@ -1028,7 +1031,7 @@ static int arm11_write_memory_inner(struct target *target,
 }
 
 static int arm11_write_memory(struct target *target,
-       uint32_t address, uint32_t size,
+       target_addr_t address, uint32_t size,
        uint32_t count, const uint8_t *buffer)
 {
        /* pointer increment matters only for multi-unit writes ...
@@ -1038,18 +1041,6 @@ static int arm11_write_memory(struct target *target,
                count, buffer, count == 1);
 }
 
-/* write target memory in multiples of 4 byte, optimized for writing large quantities of data */
-static int arm11_bulk_write_memory(struct target *target,
-       uint32_t address, uint32_t count, const uint8_t *buffer)
-{
-       if (target->state != TARGET_HALTED) {
-               LOG_WARNING("target was not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
-       return arm11_write_memory(target, address, 4, count, buffer);
-}
-
 /* target break-/watchpoint control
 * rw: 0 = write, 1 = read, 2 = access
 */
@@ -1094,7 +1085,7 @@ static int arm11_target_create(struct target *target, Jim_Interp *interp)
 {
        struct arm11_common *arm11;
 
-       if (target->tap == NULL)
+       if (!target->tap)
                return ERROR_FAIL;
 
        if (target->tap->ir_length != 5) {
@@ -1102,10 +1093,11 @@ static int arm11_target_create(struct target *target, Jim_Interp *interp)
                return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
-       arm11 = calloc(1, sizeof *arm11);
+       arm11 = calloc(1, sizeof(*arm11));
        if (!arm11)
                return ERROR_FAIL;
 
+       arm11->arm.core_type = ARM_CORE_TYPE_STD;
        arm_init_arch_info(target, &arm11->arm);
 
        arm11->jtag_info.tap = target->tap;
@@ -1127,6 +1119,14 @@ static int arm11_init_target(struct command_context *cmd_ctx,
        return ERROR_OK;
 }
 
+static void arm11_deinit_target(struct target *target)
+{
+       struct arm11_common *arm11 = target_to_arm11(target);
+
+       arm11_dpm_deinit(arm11);
+       free(arm11);
+}
+
 /* talk to the target and set things up */
 static int arm11_examine(struct target *target)
 {
@@ -1140,7 +1140,7 @@ static int arm11_examine(struct target *target)
 
        /* check IDCODE */
 
-       arm11_add_IR(arm11, ARM11_IDCODE, ARM11_TAP_DEFAULT);
+       arm11_add_ir(arm11, ARM11_IDCODE, ARM11_TAP_DEFAULT);
 
        struct scan_field idcode_field;
 
@@ -1150,9 +1150,9 @@ static int arm11_examine(struct target *target)
 
        /* check DIDR */
 
-       arm11_add_debug_SCAN_N(arm11, 0x00, ARM11_TAP_DEFAULT);
+       arm11_add_debug_scan_n(arm11, 0x00, ARM11_TAP_DEFAULT);
 
-       arm11_add_IR(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);
+       arm11_add_ir(arm11, ARM11_INTEST, ARM11_TAP_DEFAULT);
 
        struct scan_field chain0_fields[2];
 
@@ -1176,7 +1176,7 @@ static int arm11_examine(struct target *target)
                        type = "ARM1156";
                        break;
                case 0x7B76:
-                       arm11->arm.core_type = ARM_MODE_MON;
+                       arm11->arm.core_type = ARM_CORE_TYPE_SEC_EXT;
                        /* NOTE: could default arm11->hardware_step to true */
                        type = "ARM1176";
                        break;
@@ -1204,6 +1204,12 @@ static int arm11_examine(struct target *target)
        LOG_DEBUG("IDCODE %08" PRIx32 " IMPLEMENTOR %02x DIDR %08" PRIx32,
                device_id, implementor, didr);
 
+       /* Build register cache "late", after target_init(), since we
+        * want to know if this core supports Secure Monitor mode.
+        */
+       if (!target_was_examined(target))
+               CHECK_RETVAL(arm11_dpm_init(arm11, didr));
+
        /* as a side-effect this reads DSCR and thus
         * clears the ARM11_DSCR_STICKY_PRECISE_DATA_ABORT / Sticky Precise Data Abort Flag
         * as suggested by the spec.
@@ -1213,12 +1219,6 @@ static int arm11_examine(struct target *target)
        if (retval != ERROR_OK)
                return retval;
 
-       /* Build register cache "late", after target_init(), since we
-        * want to know if this core supports Secure Monitor mode.
-        */
-       if (!target_was_examined(target))
-               CHECK_RETVAL(arm11_dpm_init(arm11, didr));
-
        /* ETM on ARM11 still uses original scanchain 6 access mode */
        if (arm11->arm.etm && !target_was_examined(target)) {
                *register_get_last_cache_p(&target->reg_cache) =
@@ -1351,23 +1351,19 @@ struct target_type arm11_target = {
        .poll = arm11_poll,
        .arch_state = arm11_arch_state,
 
-       .target_request_data = arm11_target_request_data,
-
        .halt = arm11_halt,
        .resume = arm11_resume,
        .step = arm11_step,
 
        .assert_reset = arm11_assert_reset,
        .deassert_reset = arm11_deassert_reset,
-       .soft_reset_halt = arm11_soft_reset_halt,
 
+       .get_gdb_arch = arm_get_gdb_arch,
        .get_gdb_reg_list = arm_get_gdb_reg_list,
 
        .read_memory = arm11_read_memory,
        .write_memory = arm11_write_memory,
 
-       .bulk_write_memory = arm11_bulk_write_memory,
-
        .checksum_memory = arm_checksum_memory,
        .blank_check_memory = arm_blank_check_memory,
 
@@ -1379,5 +1375,6 @@ struct target_type arm11_target = {
        .commands = arm11_command_handlers,
        .target_create = arm11_target_create,
        .init_target = arm11_init_target,
+       .deinit_target = arm11_deinit_target,
        .examine = arm11_examine,
 };