target: use 'ULL' suffix for long constants
[openocd.git] / src / target / aarch64.c
index d8a9664d72bf9bd4fee86b2e70b098f237fd9a9a..c6ebfb01136aafff0f4bd2dbd27bd28a10a7f673 100644 (file)
@@ -1,20 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
 /***************************************************************************
  *   Copyright (C) 2015 by David Ung                                       *
  *                                                                         *
- *   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.,                                       *
- *                                                                         *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -600,7 +588,7 @@ static int aarch64_restore_one(struct target *target, int current,
                        resume_pc &= 0xFFFFFFFC;
                        break;
                case ARM_STATE_AARCH64:
-                       resume_pc &= 0xFFFFFFFFFFFFFFFC;
+                       resume_pc &= 0xFFFFFFFFFFFFFFFCULL;
                        break;
                case ARM_STATE_THUMB:
                case ARM_STATE_THUMB_EE:
@@ -1078,9 +1066,12 @@ static int aarch64_post_debug_entry(struct target *target)
                armv8_identify_cache(armv8);
                armv8_read_mpidr(armv8);
        }
-
-       armv8->armv8_mmu.mmu_enabled =
+       if (armv8->is_armv8r) {
+               armv8->armv8_mmu.mmu_enabled = 0;
+       } else {
+               armv8->armv8_mmu.mmu_enabled =
                        (aarch64->system_control_reg & 0x1U) ? 1 : 0;
+       }
        armv8->armv8_mmu.armv8_cache.d_u_cache_enabled =
                (aarch64->system_control_reg & 0x4U) ? 1 : 0;
        armv8->armv8_mmu.armv8_cache.i_cache_enabled =
@@ -1257,7 +1248,7 @@ static int aarch64_set_breakpoint(struct target *target,
                        | (byte_addr_select << 5)
                        | (3 << 1) | 1;
                brp_list[brp_i].used = 1;
-               brp_list[brp_i].value = breakpoint->address & 0xFFFFFFFFFFFFFFFC;
+               brp_list[brp_i].value = breakpoint->address & 0xFFFFFFFFFFFFFFFCULL;
                brp_list[brp_i].control = control;
                bpt_value = brp_list[brp_i].value;
 
@@ -1309,28 +1300,28 @@ static int aarch64_set_breakpoint(struct target *target,
                buf_set_u32(code, 0, 32, opcode);
 
                retval = target_read_memory(target,
-                               breakpoint->address & 0xFFFFFFFFFFFFFFFE,
+                               breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
                                breakpoint->length, 1,
                                breakpoint->orig_instr);
                if (retval != ERROR_OK)
                        return retval;
 
                armv8_cache_d_inner_flush_virt(armv8,
-                               breakpoint->address & 0xFFFFFFFFFFFFFFFE,
+                               breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
                                breakpoint->length);
 
                retval = target_write_memory(target,
-                               breakpoint->address & 0xFFFFFFFFFFFFFFFE,
+                               breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
                                breakpoint->length, 1, code);
                if (retval != ERROR_OK)
                        return retval;
 
                armv8_cache_d_inner_flush_virt(armv8,
-                               breakpoint->address & 0xFFFFFFFFFFFFFFFE,
+                               breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
                                breakpoint->length);
 
                armv8_cache_i_inner_inval_virt(armv8,
-                               breakpoint->address & 0xFFFFFFFFFFFFFFFE,
+                               breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
                                breakpoint->length);
 
                breakpoint->is_set = true;
@@ -1462,7 +1453,7 @@ static int aarch64_set_hybrid_breakpoint(struct target *target, struct breakpoin
                | (iva_byte_addr_select << 5)
                | (3 << 1) | 1;
        brp_list[brp_2].used = 1;
-       brp_list[brp_2].value = breakpoint->address & 0xFFFFFFFFFFFFFFFC;
+       brp_list[brp_2].value = breakpoint->address & 0xFFFFFFFFFFFFFFFCULL;
        brp_list[brp_2].control = control_iva;
        retval = aarch64_dap_write_memap_register_u32(target, armv8->debug_base
                        + CPUV8_DBG_BVR_BASE + 16 * brp_list[brp_2].brpn,
@@ -1586,29 +1577,29 @@ static int aarch64_unset_breakpoint(struct target *target, struct breakpoint *br
                /* restore original instruction (kept in target endianness) */
 
                armv8_cache_d_inner_flush_virt(armv8,
-                               breakpoint->address & 0xFFFFFFFFFFFFFFFE,
+                               breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
                                breakpoint->length);
 
                if (breakpoint->length == 4) {
                        retval = target_write_memory(target,
-                                       breakpoint->address & 0xFFFFFFFFFFFFFFFE,
+                                       breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
                                        4, 1, breakpoint->orig_instr);
                        if (retval != ERROR_OK)
                                return retval;
                } else {
                        retval = target_write_memory(target,
-                                       breakpoint->address & 0xFFFFFFFFFFFFFFFE,
+                                       breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
                                        2, 1, breakpoint->orig_instr);
                        if (retval != ERROR_OK)
                                return retval;
                }
 
                armv8_cache_d_inner_flush_virt(armv8,
-                               breakpoint->address & 0xFFFFFFFFFFFFFFFE,
+                               breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
                                breakpoint->length);
 
                armv8_cache_i_inner_inval_virt(armv8,
-                               breakpoint->address & 0xFFFFFFFFFFFFFFFE,
+                               breakpoint->address & 0xFFFFFFFFFFFFFFFEULL,
                                breakpoint->length);
        }
        breakpoint->is_set = false;
@@ -1849,7 +1840,7 @@ static int aarch64_remove_watchpoint(struct target *target,
  * find out which watchpoint hits
  * get exception address and compare the address to watchpoints
  */
-int aarch64_hit_watchpoint(struct target *target,
+static int aarch64_hit_watchpoint(struct target *target,
        struct watchpoint **hit_watchpoint)
 {
        if (target->debug_reason != DBG_REASON_WATCHPOINT)
@@ -1942,7 +1933,7 @@ static int aarch64_assert_reset(struct target *target)
        else if (reset_config & RESET_HAS_SRST) {
                bool srst_asserted = false;
 
-               if (target->reset_halt) {
+               if (target->reset_halt && !(reset_config & RESET_SRST_PULLS_TRST)) {
                        if (target_was_examined(target)) {
 
                                if (reset_config & RESET_SRST_NO_GATING) {
@@ -1952,12 +1943,12 @@ static int aarch64_assert_reset(struct target *target)
                                         */
                                        adapter_assert_reset();
                                        srst_asserted = true;
-
-                                       /* make sure to clear all sticky errors */
-                                       mem_ap_write_atomic_u32(armv8->debug_ap,
-                                                       armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);
                                }
 
+                               /* make sure to clear all sticky errors */
+                               mem_ap_write_atomic_u32(armv8->debug_ap,
+                                               armv8->debug_base + CPUV8_DBG_DRCR, DRCR_CSE);
+
                                /* set up Reset Catch debug event to halt the CPU after reset */
                                retval = aarch64_enable_reset_catch(target, true);
                                if (retval != ERROR_OK)
@@ -2026,9 +2017,13 @@ static int aarch64_deassert_reset(struct target *target)
                if (target->state != TARGET_HALTED) {
                        LOG_WARNING("%s: ran after reset and before halt ...",
                                target_name(target));
-                       retval = target_halt(target);
-                       if (retval != ERROR_OK)
-                               return retval;
+                       if (target_was_examined(target)) {
+                               retval = aarch64_halt_one(target, HALT_LAZY);
+                               if (retval != ERROR_OK)
+                                       return retval;
+                       } else {
+                               target->state = TARGET_UNKNOWN;
+                       }
                }
        }
 
@@ -2554,15 +2549,21 @@ static int aarch64_examine_first(struct target *target)
        if (!pc)
                return ERROR_FAIL;
 
-       if (pc->adiv5_config.ap_num == DP_APSEL_INVALID) {
-               /* Search for the APB-AB */
-               retval = dap_find_ap(swjdp, AP_TYPE_APB_AP, &armv8->debug_ap);
-               if (retval != ERROR_OK) {
-                       LOG_ERROR("Could not find APB-AP for debug access");
-                       return retval;
+       if (!armv8->debug_ap) {
+               if (pc->adiv5_config.ap_num == DP_APSEL_INVALID) {
+                       /* Search for the APB-AB */
+                       retval = dap_find_get_ap(swjdp, AP_TYPE_APB_AP, &armv8->debug_ap);
+                       if (retval != ERROR_OK) {
+                               LOG_ERROR("Could not find APB-AP for debug access");
+                               return retval;
+                       }
+               } else {
+                       armv8->debug_ap = dap_get_ap(swjdp, pc->adiv5_config.ap_num);
+                       if (!armv8->debug_ap) {
+                               LOG_ERROR("Cannot get AP");
+                               return ERROR_FAIL;
+                       }
                }
-       } else {
-               armv8->debug_ap = dap_ap(swjdp, pc->adiv5_config.ap_num);
        }
 
        retval = mem_ap_init(armv8->debug_ap);
@@ -2728,6 +2729,25 @@ static int aarch64_init_arch_info(struct target *target,
        return ERROR_OK;
 }
 
+static int armv8r_target_create(struct target *target, Jim_Interp *interp)
+{
+       struct aarch64_private_config *pc = target->private_config;
+       struct aarch64_common *aarch64;
+
+       if (adiv5_verify_config(&pc->adiv5_config) != ERROR_OK)
+               return ERROR_FAIL;
+
+       aarch64 = calloc(1, sizeof(struct aarch64_common));
+       if (!aarch64) {
+               LOG_ERROR("Out of memory");
+               return ERROR_FAIL;
+       }
+
+       aarch64->armv8_common.is_armv8r = true;
+
+       return aarch64_init_arch_info(target, aarch64, pc->adiv5_config.dap);
+}
+
 static int aarch64_target_create(struct target *target, Jim_Interp *interp)
 {
        struct aarch64_private_config *pc = target->private_config;
@@ -2742,6 +2762,8 @@ static int aarch64_target_create(struct target *target, Jim_Interp *interp)
                return ERROR_FAIL;
        }
 
+       aarch64->armv8_common.is_armv8r = false;
+
        return aarch64_init_arch_info(target, aarch64, pc->adiv5_config.dap);
 }
 
@@ -2751,6 +2773,9 @@ static void aarch64_deinit_target(struct target *target)
        struct armv8_common *armv8 = &aarch64->armv8_common;
        struct arm_dpm *dpm = &armv8->dpm;
 
+       if (armv8->debug_ap)
+               dap_put_ap(armv8->debug_ap);
+
        armv8_free_reg_cache(target);
        free(aarch64->brp_list);
        free(dpm->dbp);
@@ -2761,12 +2786,16 @@ static void aarch64_deinit_target(struct target *target)
 
 static int aarch64_mmu(struct target *target, int *enabled)
 {
+       struct aarch64_common *aarch64 = target_to_aarch64(target);
+       struct armv8_common *armv8 = &aarch64->armv8_common;
        if (target->state != TARGET_HALTED) {
                LOG_ERROR("%s: target %s not halted", __func__, target_name(target));
                return ERROR_TARGET_INVALID;
        }
-
-       *enabled = target_to_aarch64(target)->armv8_common.armv8_mmu.mmu_enabled;
+       if (armv8->is_armv8r)
+               *enabled = 0;
+       else
+               *enabled = target_to_aarch64(target)->armv8_common.armv8_mmu.mmu_enabled;
        return ERROR_OK;
 }
 
@@ -2951,53 +2980,41 @@ COMMAND_HANDLER(aarch64_mask_interrupts_command)
        return ERROR_OK;
 }
 
-static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
+COMMAND_HANDLER(aarch64_mcrmrc_command)
 {
-       struct command *c = jim_to_command(interp);
-       struct command_context *context;
-       struct target *target;
-       struct arm *arm;
-       int retval;
        bool is_mcr = false;
-       int arg_cnt = 0;
+       unsigned int arg_cnt = 5;
 
-       if (!strcmp(c->name, "mcr")) {
+       if (!strcmp(CMD_NAME, "mcr")) {
                is_mcr = true;
-               arg_cnt = 7;
-       } else {
                arg_cnt = 6;
        }
 
-       context = current_command_context(interp);
-       assert(context);
+       if (arg_cnt != CMD_ARGC)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
-       target = get_current_target(context);
+       struct target *target = get_current_target(CMD_CTX);
        if (!target) {
-               LOG_ERROR("%s: no current target", __func__);
-               return JIM_ERR;
+               command_print(CMD, "no current target");
+               return ERROR_FAIL;
        }
        if (!target_was_examined(target)) {
-               LOG_ERROR("%s: not yet examined", target_name(target));
-               return JIM_ERR;
+               command_print(CMD, "%s: not yet examined", target_name(target));
+               return ERROR_TARGET_NOT_EXAMINED;
        }
 
-       arm = target_to_arm(target);
+       struct arm *arm = target_to_arm(target);
        if (!is_arm(arm)) {
-               LOG_ERROR("%s: not an ARM", target_name(target));
-               return JIM_ERR;
+               command_print(CMD, "%s: not an ARM", target_name(target));
+               return ERROR_FAIL;
        }
 
        if (target->state != TARGET_HALTED)
                return ERROR_TARGET_NOT_HALTED;
 
        if (arm->core_state == ARM_STATE_AARCH64) {
-               LOG_ERROR("%s: not 32-bit arm target", target_name(target));
-               return JIM_ERR;
-       }
-
-       if (argc != arg_cnt) {
-               LOG_ERROR("%s: wrong number of arguments", __func__);
-               return JIM_ERR;
+               command_print(CMD, "%s: not 32-bit arm target", target_name(target));
+               return ERROR_FAIL;
        }
 
        int cpnum;
@@ -3006,87 +3023,62 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
        uint32_t crn;
        uint32_t crm;
        uint32_t value;
-       long l;
 
        /* NOTE:  parameter sequence matches ARM instruction set usage:
         *      MCR     pNUM, op1, rX, CRn, CRm, op2    ; write CP from rX
         *      MRC     pNUM, op1, rX, CRn, CRm, op2    ; read CP into rX
         * The "rX" is necessarily omitted; it uses Tcl mechanisms.
         */
-       retval = Jim_GetLong(interp, argv[1], &l);
-       if (retval != JIM_OK)
-               return retval;
-       if (l & ~0xf) {
-               LOG_ERROR("%s: %s %d out of range", __func__,
-                       "coprocessor", (int) l);
-               return JIM_ERR;
+       COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], cpnum);
+       if (cpnum & ~0xf) {
+               command_print(CMD, "coprocessor %d out of range", cpnum);
+               return ERROR_COMMAND_ARGUMENT_INVALID;
        }
-       cpnum = l;
 
-       retval = Jim_GetLong(interp, argv[2], &l);
-       if (retval != JIM_OK)
-               return retval;
-       if (l & ~0x7) {
-               LOG_ERROR("%s: %s %d out of range", __func__,
-                       "op1", (int) l);
-               return JIM_ERR;
+       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], op1);
+       if (op1 & ~0x7) {
+               command_print(CMD, "op1 %d out of range", op1);
+               return ERROR_COMMAND_ARGUMENT_INVALID;
        }
-       op1 = l;
 
-       retval = Jim_GetLong(interp, argv[3], &l);
-       if (retval != JIM_OK)
-               return retval;
-       if (l & ~0xf) {
-               LOG_ERROR("%s: %s %d out of range", __func__,
-                       "CRn", (int) l);
-               return JIM_ERR;
+       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], crn);
+       if (crn & ~0xf) {
+               command_print(CMD, "CRn %d out of range", crn);
+               return ERROR_COMMAND_ARGUMENT_INVALID;
        }
-       crn = l;
 
-       retval = Jim_GetLong(interp, argv[4], &l);
-       if (retval != JIM_OK)
-               return retval;
-       if (l & ~0xf) {
-               LOG_ERROR("%s: %s %d out of range", __func__,
-                       "CRm", (int) l);
-               return JIM_ERR;
+       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], crm);
+       if (crm & ~0xf) {
+               command_print(CMD, "CRm %d out of range", crm);
+               return ERROR_COMMAND_ARGUMENT_INVALID;
        }
-       crm = l;
 
-       retval = Jim_GetLong(interp, argv[5], &l);
-       if (retval != JIM_OK)
-               return retval;
-       if (l & ~0x7) {
-               LOG_ERROR("%s: %s %d out of range", __func__,
-                       "op2", (int) l);
-               return JIM_ERR;
+       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[4], op2);
+       if (op2 & ~0x7) {
+               command_print(CMD, "op2 %d out of range", op2);
+               return ERROR_COMMAND_ARGUMENT_INVALID;
        }
-       op2 = l;
-
-       value = 0;
 
-       if (is_mcr == true) {
-               retval = Jim_GetLong(interp, argv[6], &l);
-               if (retval != JIM_OK)
-                       return retval;
-               value = l;
+       if (is_mcr) {
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[5], value);
 
                /* NOTE: parameters reordered! */
                /* ARMV4_5_MCR(cpnum, op1, 0, crn, crm, op2) */
-               retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value);
+               int retval = arm->mcr(target, cpnum, op1, op2, crn, crm, value);
                if (retval != ERROR_OK)
-                       return JIM_ERR;
+                       return retval;
        } else {
+               value = 0;
                /* NOTE: parameters reordered! */
                /* ARMV4_5_MRC(cpnum, op1, 0, crn, crm, op2) */
-               retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value);
+               int retval = arm->mrc(target, cpnum, op1, op2, crn, crm, &value);
                if (retval != ERROR_OK)
-                       return JIM_ERR;
+                       return retval;
 
-               Jim_SetResult(interp, Jim_NewIntObj(interp, value));
+               command_print(CMD, "0x%" PRIx32, value);
        }
 
-       return JIM_OK;
+       return ERROR_OK;
 }
 
 static const struct command_registration aarch64_exec_command_handlers[] = {
@@ -3121,14 +3113,14 @@ static const struct command_registration aarch64_exec_command_handlers[] = {
        {
                .name = "mcr",
                .mode = COMMAND_EXEC,
-               .jim_handler = jim_mcrmrc,
+               .handler = aarch64_mcrmrc_command,
                .help = "write coprocessor register",
                .usage = "cpnum op1 CRn CRm op2 value",
        },
        {
                .name = "mrc",
                .mode = COMMAND_EXEC,
-               .jim_handler = jim_mcrmrc,
+               .handler = aarch64_mcrmrc_command,
                .help = "read coprocessor register",
                .usage = "cpnum op1 CRn CRm op2",
        },
@@ -3140,8 +3132,6 @@ static const struct command_registration aarch64_exec_command_handlers[] = {
        COMMAND_REGISTRATION_DONE
 };
 
-extern const struct command_registration semihosting_common_handlers[];
-
 static const struct command_registration aarch64_command_handlers[] = {
        {
                .name = "arm",
@@ -3203,3 +3193,39 @@ struct target_type aarch64_target = {
        .mmu = aarch64_mmu,
        .virt2phys = aarch64_virt2phys,
 };
+
+struct target_type armv8r_target = {
+       .name = "armv8r",
+
+       .poll = aarch64_poll,
+       .arch_state = armv8_arch_state,
+
+       .halt = aarch64_halt,
+       .resume = aarch64_resume,
+       .step = aarch64_step,
+
+       .assert_reset = aarch64_assert_reset,
+       .deassert_reset = aarch64_deassert_reset,
+
+       /* REVISIT allow exporting VFP3 registers ... */
+       .get_gdb_arch = armv8_get_gdb_arch,
+       .get_gdb_reg_list = armv8_get_gdb_reg_list,
+
+       .read_memory = aarch64_read_phys_memory,
+       .write_memory = aarch64_write_phys_memory,
+
+       .add_breakpoint = aarch64_add_breakpoint,
+       .add_context_breakpoint = aarch64_add_context_breakpoint,
+       .add_hybrid_breakpoint = aarch64_add_hybrid_breakpoint,
+       .remove_breakpoint = aarch64_remove_breakpoint,
+       .add_watchpoint = aarch64_add_watchpoint,
+       .remove_watchpoint = aarch64_remove_watchpoint,
+       .hit_watchpoint = aarch64_hit_watchpoint,
+
+       .commands = aarch64_command_handlers,
+       .target_create = armv8r_target_create,
+       .target_jim_configure = aarch64_jim_configure,
+       .init_target = aarch64_init_target,
+       .deinit_target = aarch64_deinit_target,
+       .examine = aarch64_examine,
+};

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)