diff --git a/patches/0001-build-add-Dockerfile-and-Ampere-README-files-DO-NOT-.patch b/patches/0001-build-add-Dockerfile-and-Ampere-README-files-DO-NOT-.patch new file mode 100644 index 000000000..d244154bb --- /dev/null +++ b/patches/0001-build-add-Dockerfile-and-Ampere-README-files-DO-NOT-.patch @@ -0,0 +1,115 @@ +From 7d91c9de2bab296772d04e9d9de840af8ec5e9c3 Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Fri, 7 May 2021 15:27:35 -0400 +Subject: [PATCH 01/33] build: add Dockerfile and Ampere README files [DO NOT + UPSTREAM] + +Change-Id: Ia9ae4963bdb6fc50939461753c5133a152aa93e2 +Signed-off-by: Daniel Goehring +--- + Dockerfile | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++ + README.AMPERE | 26 +++++++++++++++++++++++ + 2 files changed, 85 insertions(+) + create mode 100644 Dockerfile + create mode 100644 README.AMPERE + +diff --git a/Dockerfile b/Dockerfile +new file mode 100644 +index 000000000..69adde4aa +--- /dev/null ++++ b/Dockerfile +@@ -0,0 +1,59 @@ ++# SPDX-License-Identifier: BSD-3-Clause ++# Copyright (c) 2021-2022, Ampere Computing LLC ++ ++FROM docker.io/ubuntu:18.04 ++ ++RUN apt-get update -q && \ ++ apt-get install -y --no-install-recommends sudo ++RUN adduser --disabled-password --gecos '' openocd && \ ++ adduser openocd sudo && \ ++ echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers ++USER openocd ++RUN sudo apt-get update -q && \ ++ sudo apt-get install -y --no-install-recommends \ ++ libftdi-dev \ ++ git \ ++ libtool \ ++ automake \ ++ texinfo \ ++ pkg-config \ ++ libusb-1.0.0-dev \ ++ vim \ ++ net-tools \ ++ usbutils \ ++ libpython3.8 \ ++ python3.8-minimal \ ++ gdb \ ++ ddd \ ++ telnet \ ++ libcapstone-dev \ ++ ca-certificates ++ ++COPY arm-gnu-toolchain*/bin/aarch64-none-elf-gdb /usr/bin/ ++COPY arm-gnu-toolchain*/bin/aarch64-none-elf-gdb-add-index /usr/bin/ ++ ++COPY arm-gnu-toolchain*/bin/aarch64-none-linux-gnu-gdb /usr/bin/ ++COPY arm-gnu-toolchain*/bin/aarch64-none-linux-gnu-gdb-add-index /usr/bin/ ++ ++COPY arm-gnu-toolchain*/bin/arm-none-eabi-gdb /usr/bin/ ++COPY arm-gnu-toolchain*/bin/arm-none-eabi-gdb-add-index /usr/bin/ ++ ++COPY arm-gnu-toolchain*/bin/arm-none-linux-gnueabihf-gdb /usr/bin/ ++COPY arm-gnu-toolchain*/bin/arm-none-linux-gnueabihf-gdb-add-index /usr/bin/ ++ ++COPY arm-gnu-toolchain*/include/gdb /usr/include/gdb/ ++COPY arm-gnu-toolchain*/share/doc/gdb /usr/share/doc/gdb/ ++COPY arm-gnu-toolchain*/share/gdb /usr/share/gdb/ ++COPY arm-gnu-toolchain*/share/info/gdb.info /usr/share/info/ ++ ++COPY --chown=openocd:openocd openocd /home/openocd/openocd ++WORKDIR /home/openocd/openocd ++RUN mv README.AMPERE .. 2>/dev/null || true ++RUN ./bootstrap ++RUN ./configure --enable-vdebug --enable-jtag_dpi --enable-ftdi --enable-ft2232_ftd2xx --with-capstone ++RUN make ++RUN sudo make install ++RUN rm -rf .git ++WORKDIR /home/openocd ++ ++EXPOSE 3333 3334 3335 3336 3337 3338 4444 4445 5555 5556 6666 +diff --git a/README.AMPERE b/README.AMPERE +new file mode 100644 +index 000000000..7db9ad8ae +--- /dev/null ++++ b/README.AMPERE +@@ -0,0 +1,26 @@ ++This Docker container was built by Ampere Computing using an internal and ++proprietary build process. This container was built using sources from open source ++as well as closed source projects. ++ ++The base layer of this container was built using the Ubuntu 18.04 image ++as hosted by DockerHub. ++ ++A number of packages were installed using the standard apt package manager. These ++can be discovered using the ```sudo apt list --installed``` command (or equivalent). ++ ++In addition to packages installed via the standard Ubuntu package repository, ++the following projects were directly added to this container: ++ ++ - OpenOCD With Ampere Patches ++ Placed at location: /home/openocd/openocd/, /home/openocd/openocd/patches/ ++ ++ - Ampere OpenOCD Dockerfile ++ Placed at location: /home/openocd/openocd/Dockerfile ++ This file is distributed under the BSD-3-Clause license. Full license text for the ++ BSD-3-Clause license can be found at /home/openocd/openocd/LICENSES/preferred/BSD-3-Clause ++ ++ - Arm GNU Toolchain ++ Placed at locations: /usr/bin, /usr/include/gdb, /usr/share/, /usr/share/gdb/, ++ /usr/share/doc/gdb/, /usr/share/info/ ++ This toolchain is included without modifications and as distributed by Arm at ++ this page: https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads/10-3-2021-07 +-- +2.25.1 + diff --git a/patches/0002-Cadence-vdebug-interface-updates-DO-NOT-UPSTREAM.patch b/patches/0002-Cadence-vdebug-interface-updates-DO-NOT-UPSTREAM.patch new file mode 100644 index 000000000..27eca9323 --- /dev/null +++ b/patches/0002-Cadence-vdebug-interface-updates-DO-NOT-UPSTREAM.patch @@ -0,0 +1,45 @@ +From f9a2cf11b6a3381443b4f5696917ba3af682c048 Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Mon, 23 May 2022 19:07:51 -0400 +Subject: [PATCH 02/33] Cadence vdebug interface updates [DO NOT UPSTREAM] + +Change-Id: I968c005e524b40b9642d03f27fb900304c639e28 +Signed-off-by: Daniel Goehring +--- + src/jtag/drivers/vdebug.c | 2 +- + tcl/interface/vdebug.cfg | 4 ++-- + 2 files changed, 3 insertions(+), 3 deletions(-) + +diff --git a/src/jtag/drivers/vdebug.c b/src/jtag/drivers/vdebug.c +index f1fc4535f..0811e7b46 100644 +--- a/src/jtag/drivers/vdebug.c ++++ b/src/jtag/drivers/vdebug.c +@@ -53,7 +53,7 @@ + #include "helper/log.h" + #include "helper/list.h" + +-#define VD_VERSION 48 ++#define VD_VERSION 42 + #define VD_BUFFER_LEN 4024 + #define VD_CHEADER_LEN 24 + #define VD_SHEADER_LEN 16 +diff --git a/tcl/interface/vdebug.cfg b/tcl/interface/vdebug.cfg +index 7350bb9a9..9faa5bd11 100644 +--- a/tcl/interface/vdebug.cfg ++++ b/tcl/interface/vdebug.cfg +@@ -21,10 +21,10 @@ vdebug server $_VDEBUGHOST:$_VDEBUGPORT + #log_output vd_ocd.log + + # example config listen on all interfaces, disable tcl/telnet server +-bindto 0.0.0.0 ++#bindto 0.0.0.0 + #gdb_port 3333 + #telnet_port disabled +-tcl_port disabled ++#tcl_port disabled + + # transaction batching: 0 - no batching, 1 - (default) wr, 2 - rw + vdebug batching 1 +-- +2.25.1 + diff --git a/patches/0003-gdb_server-remove-fake_thread-workaround-for-OS-thre.patch b/patches/0003-gdb_server-remove-fake_thread-workaround-for-OS-thre.patch new file mode 100644 index 000000000..e66664a35 --- /dev/null +++ b/patches/0003-gdb_server-remove-fake_thread-workaround-for-OS-thre.patch @@ -0,0 +1,81 @@ +From 4f14501eac4eab74b894713b749a9bcd5bb4cb91 Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Thu, 25 Apr 2019 11:38:04 -0400 +Subject: [PATCH 03/33] gdb_server: remove 'fake_thread' workaround for OS + threads. [DO NOT UPSTREAM] + +The 'fake_thread' workaround resolves an issue with respect to +GDB debugging multiple OS threads which is outside the scope +of OpenOCD. The workaround breaks HW CPU thread support. +Since OpenOCD only supports debugging from a CPU core +perspective and not OS Threads, it is unnecessary to include +this workaround. My recommendation is to remove the workaround +since it isn't needed and breaks HW CPU thread functionality. + +Tested on an Ampere eMAG8180 and Quicksilver silicon. + +Change-Id: I7b09d56727a860fb86652bb3ff1e9c2f8cf6fb7b +Signed-off-by: Daniel Goehring +--- + src/server/gdb_server.c | 31 ------------------------------- + 1 file changed, 31 deletions(-) + +diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c +index 5052bf43b..014f1ce37 100644 +--- a/src/server/gdb_server.c ++++ b/src/server/gdb_server.c +@@ -3033,7 +3033,6 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p + /* single-step or step-over-breakpoint */ + if (parse[0] == 's') { + gdb_running_type = 's'; +- bool fake_step = false; + + struct target *ct = target; + int current_pc = 1; +@@ -3055,13 +3054,6 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p + rtos_update_threads(target); + + target->rtos->gdb_target_for_threadid(connection, thread_id, &ct); +- +- /* +- * check if the thread to be stepped is the current rtos thread +- * if not, we must fake the step +- */ +- if (target->rtos->current_thread != thread_id) +- fake_step = true; + } + + if (parse[0] == ';') { +@@ -3098,29 +3090,6 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p + gdb_connection->output_flag = GDB_OUTPUT_ALL; + target_call_event_callbacks(ct, TARGET_EVENT_GDB_START); + +- /* +- * work around an annoying gdb behaviour: when the current thread +- * is changed in gdb, it assumes that the target can follow and also +- * make the thread current. This is an assumption that cannot hold +- * for a real target running a multi-threading OS. We just fake +- * the step to not trigger an internal error in gdb. See +- * https://sourceware.org/bugzilla/show_bug.cgi?id=22925 for details +- */ +- if (fake_step) { +- int sig_reply_len; +- char sig_reply[128]; +- +- LOG_DEBUG("fake step thread %"PRIx64, thread_id); +- +- sig_reply_len = snprintf(sig_reply, sizeof(sig_reply), +- "T05thread:%016"PRIx64";", thread_id); +- +- gdb_put_packet(connection, sig_reply, sig_reply_len); +- gdb_connection->output_flag = GDB_OUTPUT_NO; +- +- return true; +- } +- + /* support for gdb_sync command */ + if (gdb_connection->sync) { + gdb_connection->sync = false; +-- +2.25.1 + diff --git a/patches/0004-gdb_server-fix-CPU-status-reporting-for-step-command.patch b/patches/0004-gdb_server-fix-CPU-status-reporting-for-step-command.patch new file mode 100644 index 000000000..be44f5fe7 --- /dev/null +++ b/patches/0004-gdb_server-fix-CPU-status-reporting-for-step-command.patch @@ -0,0 +1,46 @@ +From f510faf994243a04ae9a3882dda2167219864bf4 Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Thu, 25 Apr 2019 11:38:04 -0400 +Subject: [PATCH 04/33] gdb_server: fix CPU status reporting for 'step' command + +The call to 'rtos_update_threads()' should be after the call +to 'target_step()' and not before. With the update, 'info threads' +reports the current hardware thread state. + +Tested on an Ampere eMAG8180 and Quicksilver silicon + +Change-Id: I2168d3f965a4d7cceac40bc3dcf198e413ee4fe6 +Signed-off-by: Daniel Goehring +--- + src/server/gdb_server.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c +index 014f1ce37..aecb470dc 100644 +--- a/src/server/gdb_server.c ++++ b/src/server/gdb_server.c +@@ -3050,9 +3050,6 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p + } + + if (target->rtos) { +- /* FIXME: why is this necessary? rtos state should be up-to-date here already! */ +- rtos_update_threads(target); +- + target->rtos->gdb_target_for_threadid(connection, thread_id, &ct); + } + +@@ -3107,6 +3104,11 @@ static bool gdb_handle_vcont_packet(struct connection *connection, const char *p + if (retval == ERROR_TARGET_NOT_HALTED) + LOG_INFO("target %s was not halted when step was requested", target_name(ct)); + ++ if (target->rtos) { ++ /* After executing the 'step' command, update the rtos threads */ ++ rtos_update_threads(target); ++ } ++ + /* if step was successful send a reply back to gdb */ + if (retval == ERROR_OK) { + retval = target_poll(ct); +-- +2.25.1 + diff --git a/patches/0005-target-aarch64-add-steponly-command-for-SMP.patch b/patches/0005-target-aarch64-add-steponly-command-for-SMP.patch new file mode 100644 index 000000000..aad66f9c0 --- /dev/null +++ b/patches/0005-target-aarch64-add-steponly-command-for-SMP.patch @@ -0,0 +1,205 @@ +From 0aca4bce218e4341aa0f618480c8168fd0cc1dc3 Mon Sep 17 00:00:00 2001 +From: Kevin Burke +Date: Fri, 3 Apr 2020 18:33:06 -0400 +Subject: [PATCH 05/33] target/aarch64: add 'steponly' command for SMP + +The OpenOCD 'step' command defaults to starting all other +targets in an SMP configuration prior to stepping the selected +target. Other industry standard debuggers provide a mechanism +to step only the selected target. + +The 'aarch64 steponly [on/off]' command can change this default +behavior to match the behavior seen on other industry +standard debuggers. + +- 'aarch64 steponly on' prevents the SMP targets from starting + ('resume') when issuing the step command. +- 'aarch64 steponly off' restores the default behavior. +- 'aarch64 steponly' shows the current state (on or off) + being used. + +Tested on an Ampere eMAG8180 and Quicksilver silicon. +Tested OpenOCD with GDB Client functionality. + +Change-Id: I6d93ecbc8d3b3a94bd34b14625fefbc23f9564c8 +Signed-off-by: Kevin Burke +Signed-off-by: Daniel Goehring +--- + src/target/aarch64.c | 82 ++++++++++++++++++++++++++++++++++++-------- + src/target/aarch64.h | 8 +++++ + 2 files changed, 75 insertions(+), 15 deletions(-) + +diff --git a/src/target/aarch64.c b/src/target/aarch64.c +index 6a70b2ddf..55f3d47f5 100644 +--- a/src/target/aarch64.c ++++ b/src/target/aarch64.c +@@ -2,6 +2,7 @@ + + /*************************************************************************** + * Copyright (C) 2015 by David Ung * ++ * Copyright (C) 2019-2023, Ampere Computing LLC * + * * + ***************************************************************************/ + +@@ -1093,6 +1094,7 @@ static int aarch64_step(struct target *target, int current, target_addr_t addres + { + struct armv8_common *armv8 = target_to_armv8(target); + struct aarch64_common *aarch64 = target_to_aarch64(target); ++ struct target_list *head; + int saved_retval = ERROR_OK; + int poll_retval; + int retval; +@@ -1122,23 +1124,33 @@ static int aarch64_step(struct target *target, int current, target_addr_t addres + if (retval != ERROR_OK) + return retval; + +- if (target->smp && (current == 1)) { +- /* +- * isolate current target so that it doesn't get resumed +- * together with the others +- */ +- retval = arm_cti_gate_channel(armv8->cti, 1); +- /* resume all other targets in the group */ +- if (retval == ERROR_OK) +- retval = aarch64_step_restart_smp(target); +- if (retval != ERROR_OK) { +- LOG_ERROR("Failed to restart non-stepping targets in SMP group"); +- return retval; ++ if (target->smp) { ++ if (current != 1 || aarch64->step_only_mode == AARCH64_STEPONLY_ON) { ++ struct target *curr = target; ++ ++ foreach_smp_target(head, target->smp_targets) { ++ curr = head->target; ++ if (curr != target && curr->debug_reason == DBG_REASON_SINGLESTEP) ++ curr->debug_reason = DBG_REASON_DBGRQ; ++ } ++ } else { ++ /* ++ * isolate current target so that it doesn't get resumed ++ * together with the others ++ */ ++ retval = arm_cti_gate_channel(armv8->cti, 1); ++ /* resume all other targets in the group */ ++ if (retval == ERROR_OK) ++ retval = aarch64_step_restart_smp(target); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Failed to restart non-stepping targets in SMP group"); ++ return retval; ++ } ++ LOG_DEBUG("Restarted all non-stepping targets in SMP group"); + } +- LOG_DEBUG("Restarted all non-stepping targets in SMP group"); + } + +- /* all other targets running, restore and restart the current target */ ++ /* all other targets running in SMP, restore and restart the current target */ + retval = aarch64_restore_one(target, current, &address, 0, 0); + if (retval == ERROR_OK) + retval = aarch64_restart_one(target, RESTART_LAZY); +@@ -2730,7 +2742,6 @@ static int aarch64_examine_first(struct target *target) + + target->state = TARGET_UNKNOWN; + target->debug_reason = DBG_REASON_NOTHALTED; +- aarch64->isrmasking_mode = AARCH64_ISRMASK_ON; + target_set_examined(target); + return ERROR_OK; + } +@@ -2772,6 +2783,8 @@ static int aarch64_init_arch_info(struct target *target, + + /* Setup struct aarch64_common */ + aarch64->common_magic = AARCH64_COMMON_MAGIC; ++ aarch64->isrmasking_mode = AARCH64_ISRMASK_ON; ++ aarch64->step_only_mode = AARCH64_STEPONLY_OFF; /* resume smp cpus while stepping single cpu */ + armv8->arm.dap = dap; + + /* register arch-specific functions */ +@@ -3033,6 +3046,38 @@ COMMAND_HANDLER(aarch64_mask_interrupts_command) + return ERROR_OK; + } + ++COMMAND_HANDLER(aarch64_step_only_command) ++{ ++ struct target *target = get_current_target(CMD_CTX); ++ struct target_list *head; ++ struct aarch64_common *aarch64 = target_to_aarch64(target); ++ ++ static const struct jim_nvp nvp_steponly_modes[] = { ++ { .name = "off", .value = AARCH64_STEPONLY_OFF }, ++ { .name = "on", .value = AARCH64_STEPONLY_ON }, ++ { .name = NULL, .value = -1 }, ++ }; ++ const struct jim_nvp *n; ++ ++ if (CMD_ARGC > 0) { ++ n = jim_nvp_name2value_simple(nvp_steponly_modes, CMD_ARGV[0]); ++ if (!n->name) { ++ LOG_ERROR("Unknown parameter: %s - should be off or on", CMD_ARGV[0]); ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ } ++ foreach_smp_target(head, target->smp_targets) { ++ aarch64 = target_to_aarch64(head->target); ++ aarch64->step_only_mode = n->value; ++ /* head->target->step_only_mode = n->value; */ ++ } ++ } ++ ++ n = jim_nvp_value2name_simple(nvp_steponly_modes, aarch64->step_only_mode); ++ command_print(CMD, "aarch64 step only mode %s", n->name); ++ ++ return ERROR_OK; ++} ++ + COMMAND_HANDLER(aarch64_mcrmrc_command) + { + bool is_mcr = false; +@@ -3165,6 +3210,13 @@ static const struct command_registration aarch64_exec_command_handlers[] = { + .help = "mask aarch64 interrupts during single-step", + .usage = "['on'|'off']", + }, ++ { ++ .name = "steponly", ++ .handler = aarch64_step_only_command, ++ .mode = COMMAND_ANY, ++ .help = "do not resume aarch64 smp cpus during single-step", ++ .usage = "['on'|'off']", ++ }, + { + .name = "mcr", + .mode = COMMAND_EXEC, +diff --git a/src/target/aarch64.h b/src/target/aarch64.h +index b265e8249..17e5f9cec 100644 +--- a/src/target/aarch64.h ++++ b/src/target/aarch64.h +@@ -2,6 +2,7 @@ + + /*************************************************************************** + * Copyright (C) 2015 by David Ung * ++ * Copyright (C) 2019, Ampere Computing LLC * + ***************************************************************************/ + + #ifndef OPENOCD_TARGET_AARCH64_H +@@ -29,6 +30,11 @@ enum aarch64_isrmasking_mode { + AARCH64_ISRMASK_ON, + }; + ++enum aarch64_steponly_mode { ++ AARCH64_STEPONLY_OFF, ++ AARCH64_STEPONLY_ON, ++}; ++ + struct aarch64_brp { + int used; + int type; +@@ -58,6 +64,8 @@ struct aarch64_common { + struct aarch64_brp *wp_list; + + enum aarch64_isrmasking_mode isrmasking_mode; ++ ++ enum aarch64_steponly_mode step_only_mode; + }; + + static inline struct aarch64_common * +-- +2.25.1 + diff --git a/patches/0006-target-aarch64-add-MSR-MRS-TCL-UI-support.patch b/patches/0006-target-aarch64-add-MSR-MRS-TCL-UI-support.patch new file mode 100644 index 000000000..ac871be2c --- /dev/null +++ b/patches/0006-target-aarch64-add-MSR-MRS-TCL-UI-support.patch @@ -0,0 +1,557 @@ +From 29d63ba22807fa054d7f9d67b39e54eb83816d5b Mon Sep 17 00:00:00 2001 +From: Kevin Burke +Date: Tue, 14 Apr 2020 14:52:27 -0400 +Subject: [PATCH 06/33] target/aarch64: add MSR/MRS TCL/UI support + +Aarch64 has a new class of system registers that are accessed +via the MRS/MSR assembly instructions. This update allows +the user to read or write these registers regardless of +exception level. + +Tested on an Ampere eMAG8180 and Quicksilver silicon + +Change-Id: I99cfc37ac756294fd9779c84e840037529ef304f +Signed-off-by: Kevin Burke +Signed-off-by: Daniel Goehring +--- + src/target/aarch64.c | 150 +++++++++++++++++++++++++ + src/target/arm.h | 14 +++ + src/target/armv8.h | 10 ++ + src/target/armv8_dpm.c | 219 +++++++++++++++++++++++++++++++++++++ + src/target/armv8_opcodes.h | 30 ++++- + 5 files changed, 420 insertions(+), 3 deletions(-) + +diff --git a/src/target/aarch64.c b/src/target/aarch64.c +index 55f3d47f5..56e50f975 100644 +--- a/src/target/aarch64.c ++++ b/src/target/aarch64.c +@@ -3181,6 +3181,142 @@ COMMAND_HANDLER(aarch64_mcrmrc_command) + return ERROR_OK; + } + ++COMMAND_HANDLER(aarch64_msr_mrs) ++{ ++ struct target *target = get_current_target(CMD_CTX); ++ struct armv8_common *armv8; ++ struct arm *arm; ++ int retval; ++ bool is_msr; ++ unsigned int arg_cnt; ++ uint32_t op0; ++ uint32_t op1; ++ uint32_t op2; ++ uint32_t crn; ++ uint32_t crm; ++ uint64_t value; ++ uint32_t ns_requested = MSRMRS_NOOPTION; ++ int index = 0; ++ ++ if (!strcmp(CMD_NAME, "mrs")) { ++ is_msr = false; ++ arg_cnt = 5; ++ } else { ++ is_msr = true; ++ arg_cnt = 6; ++ } ++ ++ /* check to see if user is specifying a security preference */ ++ if (CMD_ARGC > 0) { ++ if (!strcmp(CMD_ARGV[0], "sec")) { ++ ns_requested = MSRMRS_SECURE; ++ arg_cnt++; ++ index++; ++ } else if (!strcmp(CMD_ARGV[0], "nsec")) { ++ ns_requested = MSRMRS_NONSECURE; ++ arg_cnt++; ++ index++; ++ } else if (!strcmp(CMD_ARGV[0], "asis")) { ++ ns_requested = MSRMRS_ASIS; ++ arg_cnt++; ++ index++; ++ } ++ } ++ ++ if (arg_cnt != CMD_ARGC) { ++ LOG_ERROR("%s command failed: wrong number of arguments", CMD_NAME); ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ } ++ ++ if (!target) { ++ LOG_ERROR("%s: target not found", CMD_NAME); ++ return ERROR_FAIL; ++ } ++ ++ if (!target_was_examined(target)) { ++ LOG_ERROR("%s: not yet examined", target_name(target)); ++ return ERROR_FAIL; ++ } ++ ++ armv8 = target_to_armv8(target); ++ if (!is_armv8(armv8)) { ++ LOG_ERROR("%s: not an ARMv8", target_name(target)); ++ return ERROR_FAIL; ++ } ++ ++ if (target->state != TARGET_HALTED) { ++ LOG_ERROR("%s: not halted", target_name(target)); ++ return ERROR_TARGET_NOT_HALTED; ++ } ++ ++ arm = &armv8->arm; ++ if (arm->core_state != ARM_STATE_AARCH64) { ++ LOG_ERROR("%s: is not in AArch64 state", target_name(target)); ++ return ERROR_FAIL; ++ } ++ ++ /* NOTE: parameter sequence matches ARM instruction set usage: ++ * MSR op0, op1, rX, CRn, CRm, op2 ; write System Reg from rX ++ * MRS op0, op1, rX, CRn, CRm, op2 ; read System Reg into rX ++ * The "rX" is necessarily omitted; it uses Tcl mechanisms. ++ */ ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[index++], op0); ++ if (op0 & ~0x3) { ++ LOG_ERROR("%s: %s %d out of range", CMD_NAME, ++ "op0", (int)op0); ++ return ERROR_FAIL; ++ } ++ ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[index++], op1); ++ if (op1 & ~0x7) { ++ LOG_ERROR("%s: %s %d out of range", CMD_NAME, ++ "op1", (int)op1); ++ return ERROR_FAIL; ++ } ++ ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[index++], crn); ++ if (crn & ~0xf) { ++ LOG_ERROR("%s: %s %d out of range", CMD_NAME, ++ "CRn", (int)crn); ++ return ERROR_FAIL; ++ } ++ ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[index++], crm); ++ if (crm & ~0xf) { ++ LOG_ERROR("%s: %s %d out of range", CMD_NAME, ++ "CRm", (int)crm); ++ return ERROR_FAIL; ++ } ++ ++ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[index++], op2); ++ if (op2 & ~0x7) { ++ LOG_ERROR("%s: %s %d out of range", CMD_NAME, ++ "op2", (int)op2); ++ return ERROR_FAIL; ++ } ++ ++ value = 0; ++ ++ if (is_msr) { ++ COMMAND_PARSE_NUMBER(u64, CMD_ARGV[index], value); ++ /* NOTE: parameters reordered! */ ++ /* ARMV8_MSR(ns, op0, op1, 0, CRn, CRm, op2) */ ++ retval = arm->msr(target, ns_requested, op0, op1, op2, crn, crm, value); ++ if (retval != ERROR_OK) ++ LOG_ERROR("%s: error encountered writing the designated register", CMD_NAME); ++ } else { ++ /* NOTE: parameters reordered! */ ++ /* ARMV8_MRS(ns, op0, op1, 0, CRn, CRm, op2) */ ++ retval = arm->mrs(target, ns_requested, op0, op1, op2, crn, crm, &value); ++ if (retval == ERROR_OK) ++ command_print(CMD, "0x%16.16" PRIx64, value); ++ else ++ LOG_ERROR("%s: error encountered reading the designated register", CMD_NAME); ++ } ++ ++ return retval; ++} ++ + static const struct command_registration aarch64_exec_command_handlers[] = { + { + .name = "cache_info", +@@ -3231,6 +3367,20 @@ static const struct command_registration aarch64_exec_command_handlers[] = { + .help = "read coprocessor register", + .usage = "cpnum op1 CRn CRm op2", + }, ++ { ++ .name = "msr", ++ .mode = COMMAND_EXEC, ++ .handler = aarch64_msr_mrs, ++ .help = "write system register", ++ .usage = "['sec' | 'nsec' | ' ' | 'asis'] op0 op1 CRn CRm op2 value", ++ }, ++ { ++ .name = "mrs", ++ .mode = COMMAND_EXEC, ++ .handler = aarch64_msr_mrs, ++ .help = "read system register", ++ .usage = "['sec' | 'nsec' | ' ' | 'asis'] op0 op1 CRn CRm op2", ++ }, + { + .chain = smp_command_handlers, + }, +diff --git a/src/target/arm.h b/src/target/arm.h +index 486666b5c..5b86bd8e8 100644 +--- a/src/target/arm.h ++++ b/src/target/arm.h +@@ -12,6 +12,8 @@ + * + * Copyright (C) 2018 by Liviu Ionescu + * ++ * ++ * Copyright (C) 2019-2023, Ampere Computing LLC + */ + + #ifndef OPENOCD_TARGET_ARM_H +@@ -247,6 +249,18 @@ struct arm { + uint32_t op, uint32_t crm, + uint64_t value); + ++ /** Read system register. */ ++ int (*mrs)(struct target *target, uint32_t ns_requested, uint32_t op0, ++ uint32_t op1, uint32_t op2, ++ uint32_t crn, uint32_t crm, ++ uint64_t *value); ++ ++ /** Write system register. */ ++ int (*msr)(struct target *target, uint32_t ns_requested, uint32_t op0, ++ uint32_t op1, uint32_t op2, ++ uint32_t crn, uint32_t crm, ++ uint64_t value); ++ + void *arch_info; + + /** For targets conforming to ARM Debug Interface v5, +diff --git a/src/target/armv8.h b/src/target/armv8.h +index f5aa21109..5a52320b2 100644 +--- a/src/target/armv8.h ++++ b/src/target/armv8.h +@@ -2,6 +2,7 @@ + + /*************************************************************************** + * Copyright (C) 2015 by David Ung * ++ * Copyright (C) 2019-2020, Ampere Computing LLC * + ***************************************************************************/ + + #ifndef OPENOCD_TARGET_ARMV8_H +@@ -192,6 +193,8 @@ struct armv8_common { + target_addr_t debug_base; + struct adiv5_ap *debug_ap; + ++ enum arm_mode max_aarch64_el; ++ + const uint32_t *opcodes; + + /* mdir */ +@@ -243,9 +246,16 @@ static inline bool is_armv8(struct armv8_common *armv8) + return armv8->common_magic == ARMV8_COMMON_MAGIC; + } + ++/* msr/mrs command options */ ++#define MSRMRS_SECURE 0 ++#define MSRMRS_NONSECURE 1 ++#define MSRMRS_ASIS 2 ++#define MSRMRS_NOOPTION 3 ++ + /* register offsets from armv8.debug_base */ + #define CPUV8_DBG_MAINID0 0xD00 + #define CPUV8_DBG_CPUFEATURE0 0xD20 ++#define CPUV8_DBG_PFR 0xD20 + #define CPUV8_DBG_DBGFEATURE0 0xD28 + #define CPUV8_DBG_MEMFEATURE0 0xD38 + +diff --git a/src/target/armv8_dpm.c b/src/target/armv8_dpm.c +index 8bb24f225..898c8c1d0 100644 +--- a/src/target/armv8_dpm.c ++++ b/src/target/armv8_dpm.c +@@ -2,6 +2,7 @@ + + /* + * Copyright (C) 2009 by David Brownell ++ * Copyright (C) 2019-2023, Ampere Computing LLC + */ + + #ifdef HAVE_CONFIG_H +@@ -530,6 +531,220 @@ static int dpmv8_mcr(struct target *target, int cpnum, + return retval; + } + ++/* determine highest Exception Level for this target */ ++static int dpmv8_maximum_el(struct arm_dpm *dpm, enum arm_mode *highest_mode) ++{ ++ int retval; ++ uint32_t edpfr_lower; ++ ++ struct armv8_common *armv8 = (struct armv8_common *)dpm->arm->arch_info; ++ ++ if (armv8->max_aarch64_el == ARMV8_64_EL0T) { ++ /* read EDPFR register to see what ELs exist in AARCH64 state */ ++ retval = mem_ap_read_atomic_u32(armv8->debug_ap, ++ armv8->debug_base + CPUV8_DBG_PFR, ++ &edpfr_lower); ++ if (retval != ERROR_OK) ++ return retval; ++ if ((edpfr_lower >> 12) & 0xf) /* aarch64 EL3 present */ ++ *highest_mode = ARMV8_64_EL3H; ++ else if ((edpfr_lower >> 8) & 0xf) /* EL2 present bits */ ++ *highest_mode = ARMV8_64_EL2H; ++ else ++ *highest_mode = ARMV8_64_EL1H; ++ ++ armv8->max_aarch64_el = *highest_mode; ++ } else { ++ *highest_mode = armv8->max_aarch64_el; ++ } ++ ++ return ERROR_OK; ++} ++ ++/* ++ * System register support ++ */ ++ ++/* Read system register */ ++static int dpmv8_mrs(struct target *target, uint32_t ns_requested, uint32_t op0, ++ uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm, ++ uint64_t *value) ++{ ++ struct arm *arm = target_to_arm(target); ++ struct arm_dpm *dpm = arm->dpm; ++ int retval; ++ enum arm_mode highest_mode; ++ uint32_t target_el, highest_el; ++ uint64_t scr_value; ++ bool restore_scr; ++ ++ target_el = 0; ++ highest_el = target_el; /* set default to run with current exception level */ ++ restore_scr = false; /* indicate the scr does not need to be restored */ ++ ++ LOG_DEBUG("MRS %d, %d, x0, c%d, c%d, %d", (int)op0, ++ (int)op1, (int)crn, ++ (int)crm, (int)op2); ++ ++ retval = dpm->prepare(dpm); ++ if (retval != ERROR_OK) ++ return retval; ++ ++ if (ns_requested != MSRMRS_ASIS) { ++ /* user wants to execute the command at the highest exception level */ ++ retval = dpmv8_maximum_el(dpm, &highest_mode); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Unable to determine highest EL level to use on MSR operation"); ++ goto fail; ++ } ++ ++ target_el = ((buf_get_u32(dpm->arm->cpsr->value, 0, 32) >> 2) & 3); /* current el */ ++ highest_el = ((uint32_t)highest_mode) >> 2; ++ if (target_el < highest_el) { ++ retval = armv8_dpm_modeswitch(dpm, highest_mode); /* all accesses at highest EL */ ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Unable to switch to highest exception level on MSR operation"); ++ highest_el = target_el; /* no need to try to restore exception level */ ++ goto fail; ++ } ++ } ++ if (ns_requested != MSRMRS_NOOPTION) { /* user specified a specific security setting */ ++ if (ns_requested == MSRMRS_SECURE && highest_mode != ARMV8_64_EL3H) { ++ LOG_ERROR("MSR %d, %d, x0, c%d, c%d, %d secure does not exist", ++ (int)op0, (int)op1, (int)crn, ++ (int)crm, (int)op2); ++ goto fail; /* may need to restore target_el */ ++ } else if (highest_mode == ARMV8_64_EL3H) { ++ /* Need to see if EL3's NS bit is set correctly */ ++ /* by reading SCR_EL3 */ ++ retval = dpm->instr_read_data_r0_64(dpm, ++ ARMV8_MRS_INSTR(3, 6, 0, 1, 1, 0), ++ &scr_value); ++ if (retval != ERROR_OK) ++ goto fail; ++ if (ns_requested != (scr_value & 0x1)) { ++ retval = dpm->instr_write_data_r0_64(dpm, ++ ARMV8_MSR_INSTR(3, 6, 0, 1, 1, 0), ++ ((scr_value & 0xFFFFFFFFFFFFFFFE) | ns_requested)); ++ if (retval != ERROR_OK) ++ goto fail; ++ else ++ restore_scr = true; ++ } ++ } ++ } ++ } ++ ++ /* read system register into x0; return via DCC */ ++ retval = dpm->instr_read_data_r0_64(dpm, ++ ARMV8_MRS_INSTR(op0, op1, 0, crn, crm, op2), value); ++ ++fail: ++ if (restore_scr) { ++ /* need to restore scr_el3.ns before leaving */ ++ retval += dpm->instr_write_data_r0_64(dpm, ++ ARMV8_MSR_INSTR(3, 6, 0, 1, 1, 0), ++ scr_value); ++ } ++ if (target_el < highest_el) { ++ /* need to restore exception level */ ++ retval += armv8_dpm_modeswitch(dpm, ARM_MODE_ANY); /* return to previous access */ ++ } ++ ++ dpm->finish(dpm); ++ return retval; ++} ++ ++/* Write system register */ ++static int dpmv8_msr(struct target *target, uint32_t ns_requested, uint32_t op0, ++ uint32_t op1, uint32_t op2, uint32_t crn, uint32_t crm, ++ uint64_t value) ++{ ++ struct arm *arm = target_to_arm(target); ++ struct arm_dpm *dpm = arm->dpm; ++ int retval; ++ enum arm_mode highest_mode; ++ uint32_t target_el, highest_el; ++ uint64_t scr_value; ++ bool restore_scr; ++ ++ target_el = 0; ++ highest_el = target_el; /* set default not to restore exception level */ ++ restore_scr = false; /* indicate the scr does not need to be restored */ ++ ++ LOG_DEBUG("MSR %d, %d, x0, c%d, c%d, %d", (int)op0, ++ (int)op1, (int)crn, ++ (int)crm, (int)op2); ++ ++ retval = dpm->prepare(dpm); ++ if (retval != ERROR_OK) ++ return retval; ++ ++ if (ns_requested != MSRMRS_ASIS) { ++ /* user wants to execute the command at the highest exception level */ ++ retval = dpmv8_maximum_el(dpm, &highest_mode); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Unable to determine highest EL level to use on MSR operation"); ++ goto fail; ++ } ++ ++ target_el = ((buf_get_u32(dpm->arm->cpsr->value, 0, 32) >> 2) & 3); /* current el */ ++ highest_el = ((uint32_t)highest_mode) >> 2; ++ if (target_el < highest_el) { ++ retval = armv8_dpm_modeswitch(dpm, highest_mode); /* all accesses at highest EL */ ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Unable to switch to highest exception level on MSR operation"); ++ highest_el = target_el; /* no need to try to restore exception level */ ++ goto fail; ++ } ++ } ++ if (ns_requested != MSRMRS_NOOPTION) { /* user specified a specific security setting */ ++ if (ns_requested == MSRMRS_SECURE && highest_mode != ARMV8_64_EL3H) { ++ LOG_ERROR("MSR %d, %d, x0, c%d, c%d, %d secure does not exist", ++ (int)op0, (int)op1, (int)crn, ++ (int)crm, (int)op2); ++ goto fail; /* may need to restore target_el */ ++ } else if (highest_mode == ARMV8_64_EL3H) { ++ /* Need to see if EL3's NS bit is set correctly */ ++ /* by reading SCR_EL3 */ ++ retval = dpm->instr_read_data_r0_64(dpm, ++ ARMV8_MRS_INSTR(3, 6, 0, 1, 1, 0), ++ &scr_value); ++ if (retval != ERROR_OK) ++ goto fail; ++ if (ns_requested != (scr_value & 0x1)) { ++ retval = dpm->instr_write_data_r0_64(dpm, ++ ARMV8_MSR_INSTR(3, 6, 0, 1, 1, 0), ++ ((scr_value & 0xFFFFFFFFFFFFFFFE) | ns_requested)); ++ if (retval != ERROR_OK) ++ goto fail; ++ else ++ restore_scr = true; ++ } ++ } ++ } ++ } ++ ++ /* read DCC into x0; then write system register from R0 */ ++ retval = dpm->instr_write_data_r0_64(dpm, ++ ARMV8_MSR_INSTR(op0, op1, 0, crn, crm, op2), value); ++ ++fail: ++ if (restore_scr) { ++ /* need to restore scr_el3.ns before leaving */ ++ retval += dpm->instr_write_data_r0_64(dpm, ++ ARMV8_MSR_INSTR(3, 6, 0, 1, 1, 0), ++ scr_value); ++ } ++ if (target_el < highest_el) { ++ /* need to restore exception level */ ++ retval += armv8_dpm_modeswitch(dpm, ARM_MODE_ANY); /* return to previous access */ ++ } ++ ++ dpm->finish(dpm); ++ return retval; ++} ++ + /*----------------------------------------------------------------------*/ + + /* +@@ -1421,6 +1636,10 @@ int armv8_dpm_setup(struct arm_dpm *dpm) + arm->mrc = dpmv8_mrc; + arm->mcr = dpmv8_mcr; + ++ /* system register setup */ ++ arm->mrs = dpmv8_mrs; ++ arm->msr = dpmv8_msr; ++ + dpm->prepare = dpmv8_dpm_prepare; + dpm->finish = dpmv8_dpm_finish; + +diff --git a/src/target/armv8_opcodes.h b/src/target/armv8_opcodes.h +index 9200dac72..897689c99 100644 +--- a/src/target/armv8_opcodes.h ++++ b/src/target/armv8_opcodes.h +@@ -2,6 +2,7 @@ + + /* + * Copyright (C) 2015 by pierrr kuo ++ * Copyright (C) 2019-2020, 2024, Ampere Computing LLC + */ + + #ifndef OPENOCD_TARGET_ARMV8_OPCODES_H +@@ -129,10 +130,33 @@ + #define ARMV8_ISB 0xd5033fdf + #define ARMV8_ISB_SY_T1 0xf3bf8f6f + +-#define ARMV8_MRS(system, rt) (0xd5300000 | ((system) << 5) | (rt)) ++/* Move to ARM register from system register ++ * op0: first system register opcode ++ * op1: second system register opcode ++ * CRn: first system register operand ++ * CRm: second system register operand ++ * op2: third system register opcode ++ * Rd: destination register ++ */ ++#define ARMV8_MRS_INSTR(op0, op1, rd, crn, crm, op2) \ ++ (0xd5200000 | (rd) | ((op2) << 5) | ((crm) << 8) \ ++ | ((crn) << 12) | ((op1) << 16) | ((op0) << 19)) ++ ++/* Move to system register from ARM register ++ * op0: first system register opcode ++ * op1: second system register opcode ++ * CRn: first system register operand ++ * CRm: second system register operand ++ * op2: third system register opcode ++ * Rd: destination register ++ */ ++#define ARMV8_MSR_INSTR(op0, op1, rd, crn, crm, op2) \ ++ (0xd5000000 | (rd) | ((op2) << 5) | ((crm) << 8) \ ++ | ((crn) << 12) | ((op1) << 16) | ((op0) << 19)) ++ ++#define ARMV8_MRS(system, rt) ARMV8_MRS_INSTR(0, 0, rt, 0, 0, system) + /* ARM V8 Move to system register. */ +-#define ARMV8_MSR_GP(system, rt) \ +- (0xd5100000 | ((system) << 5) | (rt)) ++#define ARMV8_MSR_GP(system, rt) ARMV8_MSR_INSTR(0, 0, rt, 0, 0, system) + /* ARM V8 Move immediate to process state field. */ + #define ARMV8_MSR_IM(op1, crm, op2) \ + (0xd500401f | ((op1) << 16) | ((crm) << 8) | ((op2) << 5)) +-- +2.25.1 + diff --git a/patches/0007-target-armv8-fix-DSCR-polling.patch b/patches/0007-target-armv8-fix-DSCR-polling.patch new file mode 100644 index 000000000..e28fe46a0 --- /dev/null +++ b/patches/0007-target-armv8-fix-DSCR-polling.patch @@ -0,0 +1,142 @@ +From f9042da6e05d5bec55ee3053b2fbd7832a3388c0 Mon Sep 17 00:00:00 2001 +From: Kevin Burke +Date: Tue, 9 Feb 2021 18:08:44 -0500 +Subject: [PATCH 07/33] target/armv8: fix DSCR polling + +Make sure the DSCR register read value is checked prior +to the loop timeout. The original code performed a read +of the DSCR but could timeout prior to checking the last +register value. + +Tested on 4-core ARM ARES platform. + +Change-Id: I0387747178f4735fa20b71f7ea1dfe33c07fa2be +Signed-off-by: Kevin Burke +Signed-off-by: Daniel Goehring +--- + src/target/armv8_dpm.c | 63 ++++++++++++++++++++++-------------------- + 1 file changed, 33 insertions(+), 30 deletions(-) + +diff --git a/src/target/armv8_dpm.c b/src/target/armv8_dpm.c +index 898c8c1d0..432d790c7 100644 +--- a/src/target/armv8_dpm.c ++++ b/src/target/armv8_dpm.c +@@ -83,21 +83,21 @@ static int dpmv8_read_dcc(struct armv8_common *armv8, uint32_t *data, + + /* Wait for DTRRXfull */ + long long then = timeval_ms(); +- while ((dscr & DSCR_DTR_TX_FULL) == 0) { +- retval = mem_ap_read_atomic_u32(armv8->debug_ap, +- armv8->debug_base + CPUV8_DBG_DSCR, +- &dscr); +- if (retval != ERROR_OK) +- return retval; ++ while ((retval = mem_ap_read_atomic_u32(armv8->debug_ap, ++ armv8->debug_base + CPUV8_DBG_DSCR, &dscr)) == ERROR_OK) { ++ if ((dscr & DSCR_DTR_TX_FULL) != 0) ++ break; + if (timeval_ms() > then + 1000) { + LOG_ERROR("Timeout waiting for read dcc"); + return ERROR_FAIL; + } + } +- +- retval = mem_ap_read_atomic_u32(armv8->debug_ap, ++ if (retval == ERROR_OK) { ++ retval = mem_ap_read_atomic_u32(armv8->debug_ap, + armv8->debug_base + CPUV8_DBG_DTRTX, + data); ++ } ++ + if (retval != ERROR_OK) + return retval; + +@@ -119,21 +119,21 @@ static int dpmv8_read_dcc_64(struct armv8_common *armv8, uint64_t *data, + + /* Wait for DTRRXfull */ + long long then = timeval_ms(); +- while ((dscr & DSCR_DTR_TX_FULL) == 0) { +- retval = mem_ap_read_atomic_u32(armv8->debug_ap, +- armv8->debug_base + CPUV8_DBG_DSCR, +- &dscr); +- if (retval != ERROR_OK) +- return retval; ++ while ((retval = mem_ap_read_atomic_u32(armv8->debug_ap, ++ armv8->debug_base + CPUV8_DBG_DSCR, &dscr)) == ERROR_OK) { ++ if ((dscr & DSCR_DTR_TX_FULL) != 0) ++ break; + if (timeval_ms() > then + 1000) { + LOG_ERROR("Timeout waiting for DTR_TX_FULL, dscr = 0x%08" PRIx32, dscr); + return ERROR_FAIL; + } + } + +- retval = mem_ap_read_atomic_u32(armv8->debug_ap, ++ if (retval == ERROR_OK) { ++ retval = mem_ap_read_atomic_u32(armv8->debug_ap, + armv8->debug_base + CPUV8_DBG_DTRTX, + (uint32_t *)data); ++ } + if (retval != ERROR_OK) + return retval; + +@@ -207,19 +207,21 @@ static int dpmv8_exec_opcode(struct arm_dpm *dpm, + + /* Wait for InstrCompl bit to be set */ + long long then = timeval_ms(); +- while ((dscr & DSCR_ITE) == 0) { +- retval = mem_ap_read_atomic_u32(armv8->debug_ap, +- armv8->debug_base + CPUV8_DBG_DSCR, &dscr); +- if (retval != ERROR_OK) { +- LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32, opcode); +- return retval; +- } ++ while ((retval = mem_ap_read_atomic_u32(armv8->debug_ap, ++ armv8->debug_base + CPUV8_DBG_DSCR, &dscr)) == ERROR_OK) { ++ if ((dscr & DSCR_ITE) != 0) ++ break; + if (timeval_ms() > then + 1000) { + LOG_ERROR("Timeout waiting for aarch64_exec_opcode"); + return ERROR_FAIL; + } + } + ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Could not read DSCR register, opcode = 0x%08" PRIx32, opcode); ++ return retval; ++ } ++ + if (armv8_dpm_get_core_state(dpm) != ARM_STATE_AARCH64) + opcode = T32_FMTITR(opcode); + +@@ -229,18 +231,19 @@ static int dpmv8_exec_opcode(struct arm_dpm *dpm, + return retval; + + then = timeval_ms(); +- do { +- retval = mem_ap_read_atomic_u32(armv8->debug_ap, +- armv8->debug_base + CPUV8_DBG_DSCR, &dscr); +- if (retval != ERROR_OK) { +- LOG_ERROR("Could not read DSCR register"); +- return retval; +- } ++ while ((retval = mem_ap_read_atomic_u32(armv8->debug_ap, ++ armv8->debug_base + CPUV8_DBG_DSCR, &dscr)) == ERROR_OK) { ++ if ((dscr & DSCR_ITE) != 0) /* Wait for InstrCompl bit to be set */ ++ break; + if (timeval_ms() > then + 1000) { + LOG_ERROR("Timeout waiting for aarch64_exec_opcode"); + return ERROR_FAIL; + } +- } while ((dscr & DSCR_ITE) == 0); /* Wait for InstrCompl bit to be set */ ++ } ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Could not read DSCR register"); ++ return retval; ++ } + + /* update dscr and el after each command execution */ + dpm->dscr = dscr; +-- +2.25.1 + diff --git a/patches/0008-target-aarch64-preserve-memaccess-tck-setting.patch b/patches/0008-target-aarch64-preserve-memaccess-tck-setting.patch new file mode 100644 index 000000000..61a38bbce --- /dev/null +++ b/patches/0008-target-aarch64-preserve-memaccess-tck-setting.patch @@ -0,0 +1,47 @@ +From afde510b7fb7580aa0c4fbdcce8e17e54a0dde67 Mon Sep 17 00:00:00 2001 +From: Kevin Burke +Date: Tue, 9 Feb 2021 18:11:08 -0500 +Subject: [PATCH 08/33] target/aarch64: preserve memaccess tck setting + +The default non-zero memaccess tck cycle setting +is preserved during the first examination. The +dap memaccess command can be used to change the +default if a lower cycle count is desired. This +change provides use of a larger, conservative +initial tck cycle count which is useful in +support of certain emulation environments. + +Testing performed on ARM ARES 4-core platform. + +Change-Id: I89501f98186e1dcd5f6afa7da8a202c6474588b6 +Signed-off-by: Kevin Burke +Signed-off-by: Daniel Goehring +--- + src/target/aarch64.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +diff --git a/src/target/aarch64.c b/src/target/aarch64.c +index 56e50f975..02be09503 100644 +--- a/src/target/aarch64.c ++++ b/src/target/aarch64.c +@@ -2639,7 +2639,16 @@ static int aarch64_examine_first(struct target *target) + return retval; + } + +- armv8->debug_ap->memaccess_tck = 10; ++ /****************************************************/ ++ /* Force the tck cycle count to 10 only if the */ ++ /* current setting is zero. This allows the default */ ++ /* settings to be used which may be required in */ ++ /* emulation environments. Users can execute the dap*/ ++ /* memaccess command to change the current setting */ ++ /* for each access port. */ ++ /****************************************************/ ++ if (!armv8->debug_ap->memaccess_tck) ++ armv8->debug_ap->memaccess_tck = 10; + + if (!target->dbgbase_set) { + /* Lookup Processor DAP */ +-- +2.25.1 + diff --git a/patches/0009-target-armv8-fix-GDB-register-list-read.patch b/patches/0009-target-armv8-fix-GDB-register-list-read.patch new file mode 100644 index 000000000..f1a950880 --- /dev/null +++ b/patches/0009-target-armv8-fix-GDB-register-list-read.patch @@ -0,0 +1,172 @@ +From a36b653e6b0144e20e391f2b41635e831958d05f Mon Sep 17 00:00:00 2001 +From: Kevin Burke +Date: Fri, 3 Apr 2020 22:49:58 -0400 +Subject: [PATCH 09/33] target/armv8: fix GDB register list read + +This change provides GDB with current values of all general registers + +Tested on an Ampere eMAG8180 and Quicksilver silicon + +Change-Id: I8c91aa5727350f3967aab09c6a379061387c565f +Signed-off-by: Kevin Burke +Signed-off-by: Daniel Goehring +--- + src/target/aarch64.c | 1 + + src/target/arm.h | 3 ++ + src/target/armv8.c | 100 +++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 104 insertions(+) + +diff --git a/src/target/aarch64.c b/src/target/aarch64.c +index 02be09503..f2b6104c2 100644 +--- a/src/target/aarch64.c ++++ b/src/target/aarch64.c +@@ -3435,6 +3435,7 @@ struct target_type aarch64_target = { + /* REVISIT allow exporting VFP3 registers ... */ + .get_gdb_arch = armv8_get_gdb_arch, + .get_gdb_reg_list = armv8_get_gdb_reg_list, ++ .get_gdb_reg_list_noread = armv8_get_gdb_reg_list_noread, + + .read_memory = aarch64_read_memory, + .write_memory = aarch64_write_memory, +diff --git a/src/target/arm.h b/src/target/arm.h +index 5b86bd8e8..6310bc443 100644 +--- a/src/target/arm.h ++++ b/src/target/arm.h +@@ -315,6 +315,9 @@ const char *armv8_get_gdb_arch(const struct target *target); + int armv8_get_gdb_reg_list(struct target *target, + struct reg **reg_list[], int *reg_list_size, + enum target_register_class reg_class); ++int armv8_get_gdb_reg_list_noread(struct target *target, ++ struct reg **reg_list[], int *reg_list_size, ++ enum target_register_class reg_class); + + int arm_init_arch_info(struct target *target, struct arm *arm); + +diff --git a/src/target/armv8.c b/src/target/armv8.c +index bf582ff80..2b8ea6f32 100644 +--- a/src/target/armv8.c ++++ b/src/target/armv8.c +@@ -5,6 +5,8 @@ + * * + * Copyright (C) 2018 by Liviu Ionescu * + * * ++ * * ++ * Copyright (C) 2019-2023, Ampere Computing LLC * + ***************************************************************************/ + + #ifdef HAVE_CONFIG_H +@@ -1808,6 +1810,43 @@ struct reg *armv8_reg_current(struct arm *arm, unsigned regnum) + return r; + } + ++static struct reg *armv8_reg_current_read(struct arm *arm, unsigned int regnum) ++{ ++ struct reg *r; ++ int retval; ++ ++ ++ if (regnum > (ARMV8_LAST_REG - 1)) ++ return NULL; ++ ++ r = arm->core_cache->reg_list + regnum; ++ if (!r->valid) { ++ retval = r->type->get(r); ++ if (retval != ERROR_OK) ++ LOG_ERROR("Failure trying to read %s", r->name); ++ } ++ ++ return r; ++} ++ ++static struct reg *armv8_reg32_current_read(struct arm *arm, unsigned int regnum) ++{ ++ struct reg *r; ++ int retval; ++ ++ if (regnum > (arm->core_cache->next->num_regs - 1)) ++ return NULL; ++ ++ r = arm->core_cache->next->reg_list + regnum; ++ if (!r->valid) { ++ retval = r->type->get(r); ++ if (retval != ERROR_OK) ++ LOG_ERROR("Failure trying to read %s", r->name); ++ } ++ ++ return r; ++} ++ + static void armv8_free_cache(struct reg_cache *cache, bool regs32) + { + struct reg *reg; +@@ -1878,6 +1917,67 @@ int armv8_get_gdb_reg_list(struct target *target, + struct arm *arm = target_to_arm(target); + int i; + ++ if (arm->core_state == ARM_STATE_AARCH64) { ++ LOG_DEBUG("Creating Aarch64 register list for target %s", target_name(target)); ++ ++ switch (reg_class) { ++ case REG_CLASS_GENERAL: ++ *reg_list_size = ARMV8_V0; ++ *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size)); ++ ++ for (i = 0; i < *reg_list_size; i++) ++ (*reg_list)[i] = armv8_reg_current_read(arm, i); ++ return ERROR_OK; ++ ++ case REG_CLASS_ALL: ++ *reg_list_size = ARMV8_LAST_REG; ++ *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size)); ++ ++ for (i = 0; i < *reg_list_size; i++) ++ (*reg_list)[i] = armv8_reg_current_read(arm, i); ++ ++ return ERROR_OK; ++ ++ default: ++ LOG_ERROR("not a valid register class type in query."); ++ return ERROR_FAIL; ++ } ++ } else { ++ struct reg_cache *cache32 = arm->core_cache->next; ++ ++ LOG_DEBUG("Creating Aarch32 register list for target %s", target_name(target)); ++ ++ switch (reg_class) { ++ case REG_CLASS_GENERAL: ++ *reg_list_size = ARMV8_R14 + 3; ++ *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size)); ++ ++ for (i = 0; i < *reg_list_size; i++) ++ (*reg_list)[i] = armv8_reg32_current_read(arm, i); ++ ++ return ERROR_OK; ++ case REG_CLASS_ALL: ++ *reg_list_size = cache32->num_regs; ++ *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size)); ++ ++ for (i = 0; i < *reg_list_size; i++) ++ (*reg_list)[i] = armv8_reg32_current_read(arm, i); ++ ++ return ERROR_OK; ++ default: ++ LOG_ERROR("not a valid register class type in query."); ++ return ERROR_FAIL; ++ } ++ } ++} ++ ++int armv8_get_gdb_reg_list_noread(struct target *target, ++ struct reg **reg_list[], int *reg_list_size, ++ enum target_register_class reg_class) ++{ ++ struct arm *arm = target_to_arm(target); ++ int i; ++ + if (arm->core_state == ARM_STATE_AARCH64) { + + LOG_DEBUG("Creating Aarch64 register list for target %s", target_name(target)); +-- +2.25.1 + diff --git a/patches/0010-jtag-JTAG-driver-remote-debug-support.patch b/patches/0010-jtag-JTAG-driver-remote-debug-support.patch new file mode 100644 index 000000000..75b6e6392 --- /dev/null +++ b/patches/0010-jtag-JTAG-driver-remote-debug-support.patch @@ -0,0 +1,994 @@ +From b5ad3ef2b3b1c815a961908ac7b73bed27906271 Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Thu, 4 Mar 2021 12:30:00 -0500 +Subject: [PATCH 10/33] jtag: JTAG driver remote debug support + +Add remote debug support for the upstream community OS JTAG driver. + +Both software and hardware accelerated remote debug modes for the +upstream community OS JTAG driver are supported. + +Tested on an Ampere dual socket Mt. Jade system with an AST2500 BMC + +Change-Id: I4e3866fe3b3d5c09628e3c900ca36874504fe6c0 +Signed-off-by: Daniel Goehring +--- + configure.ac | 10 + + src/helper/uapi_linux_jtag.h | 211 +++++++++++ + src/jtag/drivers/Makefile.am | 3 + + src/jtag/drivers/jtag_driver.c | 641 +++++++++++++++++++++++++++++++++ + src/jtag/interface.h | 1 + + src/jtag/interfaces.c | 3 + + tcl/interface/jtag_driver.cfg | 19 + + 7 files changed, 888 insertions(+) + create mode 100644 src/helper/uapi_linux_jtag.h + create mode 100644 src/jtag/drivers/jtag_driver.c + create mode 100644 tcl/interface/jtag_driver.cfg + +diff --git a/configure.ac b/configure.ac +index becc531b0..4aa56b85c 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -295,6 +295,10 @@ AC_ARG_ENABLE([jtag_dpi], + AS_HELP_STRING([--enable-jtag_dpi], [Enable building support for JTAG DPI]), + [build_jtag_dpi=$enableval], [build_jtag_dpi=no]) + ++AC_ARG_ENABLE([jtag_driver], ++ AS_HELP_STRING([--enable-jtag_driver], [Enable building support for JTAG DRIVER]), ++ [build_jtag_driver=$enableval], [build_jtag_driver=yes]) ++ + AC_ARG_ENABLE([amtjtagaccel], + AS_HELP_STRING([--enable-amtjtagaccel], [Enable building the Amontec JTAG-Accelerator driver]), + [build_amtjtagaccel=$enableval], [build_amtjtagaccel=no]) +@@ -564,6 +568,11 @@ AS_IF([test "x$build_jtag_dpi" = "xyes"], [ + AC_DEFINE([BUILD_JTAG_DPI], [0], [0 if you don't want JTAG DPI.]) + ]) + ++AS_IF([test "x$build_jtag_driver" = "xyes"], [ ++ AC_DEFINE([BUILD_JTAG_DRIVER], [1], [1 if you want JTAG DRIVER.]) ++], [ ++ AC_DEFINE([BUILD_JTAG_DRIVER], [0], [0 if you don't want JTAG DRIVER.]) ++]) + + AS_IF([test "x$build_amtjtagaccel" = "xyes"], [ + AC_DEFINE([BUILD_AMTJTAGACCEL], [1], [1 if you want the Amontec JTAG-Accelerator driver.]) +@@ -759,6 +768,7 @@ AM_CONDITIONAL([BITBANG], [test "x$build_bitbang" = "xyes"]) + AM_CONDITIONAL([JTAG_VPI], [test "x$build_jtag_vpi" = "xyes"]) + AM_CONDITIONAL([VDEBUG], [test "x$build_vdebug" = "xyes"]) + AM_CONDITIONAL([JTAG_DPI], [test "x$build_jtag_dpi" = "xyes"]) ++AM_CONDITIONAL([JTAG_DRIVER], [test "x$build_jtag_driver" = "xyes"]) + AM_CONDITIONAL([USB_BLASTER_DRIVER], [test "x$enable_usb_blaster" != "xno" -o "x$enable_usb_blaster_2" != "xno"]) + AM_CONDITIONAL([AMTJTAGACCEL], [test "x$build_amtjtagaccel" = "xyes"]) + AM_CONDITIONAL([GW16012], [test "x$build_gw16012" = "xyes"]) +diff --git a/src/helper/uapi_linux_jtag.h b/src/helper/uapi_linux_jtag.h +new file mode 100644 +index 000000000..b23aac9e3 +--- /dev/null ++++ b/src/helper/uapi_linux_jtag.h +@@ -0,0 +1,211 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++ ++/*************************************************************************** ++ * include/uapi/linux/jtag.h - JTAG class driver uapi * ++ * * ++ * Copyright (c) 2018 Mellanox Technologies. All rights reserved. * ++ * Copyright (c) 2018 Oleksandr Shamray * ++ ***************************************************************************/ ++ ++typedef __signed__ char __s8; ++typedef unsigned char __u8; ++ ++typedef __signed__ short __s16; ++typedef unsigned short __u16; ++ ++typedef __signed__ int __s32; ++typedef unsigned int __u32; ++ ++typedef __signed__ long long __s64; ++typedef unsigned long long __u64; ++ ++#ifndef __UAPI_LINUX_JTAG_H ++#define __UAPI_LINUX_JTAG_H ++ ++#define JTAG_MAX_XFER_DATA_LEN 65535 ++ ++/* ++ * JTAG_XFER_MODE: JTAG transfer mode. Used to set JTAG controller transfer mode ++ * This is bitmask for feature param in jtag_mode for ioctl JTAG_SIOCMODE ++ */ ++#define JTAG_XFER_MODE 0 ++/* ++ * JTAG_CONTROL_MODE: JTAG controller mode. Used to set JTAG controller mode ++ * This is bitmask for feature param in jtag_mode for ioctl JTAG_SIOCMODE ++ */ ++#define JTAG_CONTROL_MODE 1 ++/* ++ * JTAG_SLAVE_MODE: JTAG slave mode. Used to set JTAG controller slave mode ++ * This is bitmask for mode param in jtag_mode for ioctl JTAG_SIOCMODE ++ */ ++#define JTAG_SLAVE_MODE 0 ++/* ++ * JTAG_MASTER_MODE: JTAG master mode. Used to set JTAG controller master mode ++ * This is bitmask for mode param in jtag_mode for ioctl JTAG_SIOCMODE ++ */ ++#define JTAG_MASTER_MODE 1 ++/* ++ * JTAG_XFER_HW_MODE: JTAG hardware mode. Used to set HW drived or bitbang ++ * mode. This is bitmask for mode param in jtag_mode for ioctl JTAG_SIOCMODE ++ */ ++#define JTAG_XFER_HW_MODE 1 ++/* ++ * JTAG_XFER_SW_MODE: JTAG software mode. Used to set SW drived or bitbang ++ * mode. This is bitmask for mode param in jtag_mode for ioctl JTAG_SIOCMODE ++ */ ++#define JTAG_XFER_SW_MODE 0 ++ ++/** ++ * enum jtag_endstate: ++ * ++ * @JTAG_STATE_TLRESET: JTAG state machine Test Logic Reset state ++ * @JTAG_STATE_IDLE: JTAG state machine IDLE state ++ * @JTAG_STATE_SELECTDR: JTAG state machine SELECT_DR state ++ * @JTAG_STATE_CAPTUREDR: JTAG state machine CAPTURE_DR state ++ * @JTAG_STATE_SHIFTDR: JTAG state machine SHIFT_DR state ++ * @JTAG_STATE_EXIT1DR: JTAG state machine EXIT-1 DR state ++ * @JTAG_STATE_PAUSEDR: JTAG state machine PAUSE_DR state ++ * @JTAG_STATE_EXIT2DR: JTAG state machine EXIT-2 DR state ++ * @JTAG_STATE_UPDATEDR: JTAG state machine UPDATE DR state ++ * @JTAG_STATE_SELECTIR: JTAG state machine SELECT_IR state ++ * @JTAG_STATE_CAPTUREIR: JTAG state machine CAPTURE_IR state ++ * @JTAG_STATE_SHIFTIR: JTAG state machine SHIFT_IR state ++ * @JTAG_STATE_EXIT1IR: JTAG state machine EXIT-1 IR state ++ * @JTAG_STATE_PAUSEIR: JTAG state machine PAUSE_IR state ++ * @JTAG_STATE_EXIT2IR: JTAG state machine EXIT-2 IR state ++ * @JTAG_STATE_UPDATEIR: JTAG state machine UPDATE IR state ++ */ ++enum jtag_endstate { ++ JTAG_STATE_TLRESET, ++ JTAG_STATE_IDLE, ++ JTAG_STATE_SELECTDR, ++ JTAG_STATE_CAPTUREDR, ++ JTAG_STATE_SHIFTDR, ++ JTAG_STATE_EXIT1DR, ++ JTAG_STATE_PAUSEDR, ++ JTAG_STATE_EXIT2DR, ++ JTAG_STATE_UPDATEDR, ++ JTAG_STATE_SELECTIR, ++ JTAG_STATE_CAPTUREIR, ++ JTAG_STATE_SHIFTIR, ++ JTAG_STATE_EXIT1IR, ++ JTAG_STATE_PAUSEIR, ++ JTAG_STATE_EXIT2IR, ++ JTAG_STATE_UPDATEIR ++}; ++ ++/** ++ * enum jtag_reset: ++ * ++ * @JTAG_NO_RESET: JTAG run TAP from current state ++ * @JTAG_FORCE_RESET: JTAG force TAP to reset state ++ */ ++enum jtag_reset { ++ JTAG_NO_RESET = 0, ++ JTAG_FORCE_RESET = 1, ++}; ++ ++/** ++ * enum jtag_xfer_type: ++ * ++ * @JTAG_SIR_XFER: SIR transfer ++ * @JTAG_SDR_XFER: SDR transfer ++ */ ++enum jtag_xfer_type { ++ JTAG_SIR_XFER = 0, ++ JTAG_SDR_XFER = 1, ++}; ++ ++/** ++ * enum jtag_xfer_direction: ++ * ++ * @JTAG_READ_XFER: read transfer ++ * @JTAG_WRITE_XFER: write transfer ++ * @JTAG_READ_WRITE_XFER: read & write transfer ++ */ ++enum jtag_xfer_direction { ++ JTAG_READ_XFER = 1, ++ JTAG_WRITE_XFER = 2, ++ JTAG_READ_WRITE_XFER = 3, ++}; ++ ++/** ++ * struct jtag_end_tap_state - forces JTAG state machine to go into a TAPC ++ * state ++ * ++ * @reset: 0 - run IDLE/PAUSE from current state ++ * 1 - go through TEST_LOGIC/RESET state before IDLE/PAUSE ++ * @end: completion flag ++ * @tck: clock counter ++ * ++ * Structure provide interface to JTAG device for JTAG set state execution. ++ */ ++struct jtag_end_tap_state { ++ __u8 reset; ++ __u8 endstate; ++ __u8 tck; ++}; ++ ++/** ++ * struct jtag_xfer - jtag xfer: ++ * ++ * @type: transfer type ++ * @direction: xfer direction ++ * @length: xfer bits len ++ * @tdio : xfer data array ++ * @endir: xfer end state ++ * ++ * Structure provide interface to JTAG device for JTAG SDR/SIR xfer execution. ++ */ ++struct jtag_xfer { ++ __u8 type; ++ __u8 direction; ++ __u8 endstate; ++ __u8 padding; ++ __u32 length; ++ __u64 tdio; ++}; ++ ++/** ++ * struct jtag_bitbang - jtag bitbang: ++ * ++ * @tms: JTAG TMS ++ * @tdi: JTAG TDI (input) ++ * @tdo: JTAG TDO (output) ++ * ++ * Structure provide interface to JTAG device for JTAG bitbang execution. ++ */ ++struct tck_bitbang { ++ __u8 tms; ++ __u8 tdi; ++ __u8 tdo; ++} __attribute__((__packed__)); ++ ++/** ++ * struct jtag_mode - jtag mode: ++ * ++ * @feature: 0 - JTAG feature setting selector for JTAG controller HW/SW ++ * 1 - JTAG feature setting selector for controller ++ * bus(master/slave) mode. ++ * @mode: (0 - SW / 1 - HW) for JTAG_XFER_MODE feature(0) ++ * (0 - Slave / 1 - Master) for JTAG_CONTROL_MODE feature(1) ++ * ++ * Structure provide configuration modes to JTAG device. ++ */ ++struct jtag_mode { ++ __u32 feature; ++ __u32 mode; ++}; ++ ++/* ioctl interface */ ++#define __JTAG_IOCTL_MAGIC 0xb2 ++ ++#define JTAG_SIOCSTATE _IOW(__JTAG_IOCTL_MAGIC, 0, struct jtag_end_tap_state) ++#define JTAG_SIOCFREQ _IOW(__JTAG_IOCTL_MAGIC, 1, unsigned int) ++#define JTAG_GIOCFREQ _IOR(__JTAG_IOCTL_MAGIC, 2, unsigned int) ++#define JTAG_IOCXFER _IOWR(__JTAG_IOCTL_MAGIC, 3, struct jtag_xfer) ++#define JTAG_GIOCSTATUS _IOWR(__JTAG_IOCTL_MAGIC, 4, enum jtag_endstate) ++#define JTAG_SIOCMODE _IOW(__JTAG_IOCTL_MAGIC, 5, unsigned int) ++#define JTAG_IOCBITBANG _IOW(__JTAG_IOCTL_MAGIC, 6, unsigned int) ++ ++#endif /* __UAPI_LINUX_JTAG_H */ +diff --git a/src/jtag/drivers/Makefile.am b/src/jtag/drivers/Makefile.am +index e404afe9f..e7226efe3 100644 +--- a/src/jtag/drivers/Makefile.am ++++ b/src/jtag/drivers/Makefile.am +@@ -85,6 +85,9 @@ endif + if JTAG_DPI + DRIVERFILES += %D%/jtag_dpi.c + endif ++if JTAG_DRIVER ++DRIVERFILES += %D%/jtag_driver.c ++endif + if USB_BLASTER_DRIVER + %C%_libocdjtagdrivers_la_LIBADD += %D%/usb_blaster/libocdusbblaster.la + include %D%/usb_blaster/Makefile.am +diff --git a/src/jtag/drivers/jtag_driver.c b/src/jtag/drivers/jtag_driver.c +new file mode 100644 +index 000000000..fb58813b4 +--- /dev/null ++++ b/src/jtag/drivers/jtag_driver.c +@@ -0,0 +1,641 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++ ++/* ++ * JTAG Driver ++ * ++ * Copyright (C) 2020, Ampere Computing LLC ++ * ++ * Based on: ++ * ftdi.c: (C) 2012 Andreas Fritiofson, ++ * jtag_dpi.c: (C) 2013 Franck Jullien, ++ * (C) 2019-2020 Ampere Computing LLC ++ */ ++ ++#include ++ ++#include ++ ++#ifdef HAVE_CONFIG_H ++#include "config.h" ++#endif ++ ++#include ++ ++#include ++ ++#define JTAG_INSTANCE 0 ++ ++/** ++ * Note: When calculating the 8-bit aligned address below for the maximum ++ * JTAG transfer data bit length, the JTAG_MAX_XFER_DATA_LEN define is ++ * adjusted by one bit to account for a code bug in the open-source Linux ++ * JTAG driver. Due to the driver bug, transfers of exact size ++ * JTAG_MAX_XFER_DATA_LEN bits will fail. ++ */ ++#define JTAG_MAX_XFER_DATA_LEN_BYTE_ALIGNED (((JTAG_MAX_XFER_DATA_LEN) - 1) & (~0x7)) ++#define JTAG_MAX_XFER_DATA_LEN_BYTE_ALIGNED_DIV8 ((JTAG_MAX_XFER_DATA_LEN_BYTE_ALIGNED) >> 3) ++ ++int jtag_instance = JTAG_INSTANCE; ++int jtag_hw_accel = 1; ++int jtag_fd; ++ ++/* Local Function Prototypes */ ++static enum jtag_endstate state_conversion(tap_state_t state); ++static int move_to_state(tap_state_t goal_state); ++static int jtag_driver_get_speed(int *speed); ++static int jtag_driver_set_speed(int speed); ++static int jtag_driver_speed_div(int speed, int *khz); ++static void jtag_driver_end_state(tap_state_t state); ++static int jtag_driver_execute_scan(struct scan_command *scan); ++static int jtag_driver_execute_runtest(int num_cycles, tap_state_t state); ++static int jtag_driver_execute_stableclocks(struct stableclocks_command *stableclocks); ++static int jtag_driver_reset(int trst, int srst); ++static int jtag_driver_execute_sleep(struct sleep_command *sleep); ++static int jtag_driver_execute_tms(struct tms_command *tms); ++static int jtag_driver_execute_queue(struct jtag_command *cmd_queue); ++static int jtag_driver_init(void); ++static int jtag_driver_quit(void); ++ ++static enum jtag_endstate state_conversion(tap_state_t state) ++{ ++ enum jtag_endstate endstate; ++ ++ switch (state) { ++ case TAP_DREXIT2: ++ endstate = JTAG_STATE_EXIT2DR; ++ break; ++ case TAP_DREXIT1: ++ endstate = JTAG_STATE_EXIT1DR; ++ break; ++ case TAP_DRSHIFT: ++ endstate = JTAG_STATE_SHIFTDR; ++ break; ++ case TAP_DRPAUSE: ++ endstate = JTAG_STATE_PAUSEDR; ++ break; ++ case TAP_IRSELECT: ++ endstate = JTAG_STATE_SELECTIR; ++ break; ++ case TAP_DRUPDATE: ++ endstate = JTAG_STATE_UPDATEDR; ++ break; ++ case TAP_DRCAPTURE: ++ endstate = JTAG_STATE_CAPTUREDR; ++ break; ++ case TAP_DRSELECT: ++ endstate = JTAG_STATE_SELECTDR; ++ break; ++ case TAP_IREXIT2: ++ endstate = JTAG_STATE_EXIT2IR; ++ break; ++ case TAP_IREXIT1: ++ endstate = JTAG_STATE_EXIT1IR; ++ break; ++ case TAP_IRSHIFT: ++ endstate = JTAG_STATE_SHIFTIR; ++ break; ++ case TAP_IRPAUSE: ++ endstate = JTAG_STATE_PAUSEIR; ++ break; ++ case TAP_IDLE: ++ endstate = JTAG_STATE_IDLE; ++ break; ++ case TAP_IRUPDATE: ++ endstate = JTAG_STATE_UPDATEIR; ++ break; ++ case TAP_IRCAPTURE: ++ endstate = JTAG_STATE_CAPTUREIR; ++ break; ++ case TAP_RESET: ++ endstate = JTAG_STATE_TLRESET; ++ break; ++ default: ++ LOG_ERROR("JTAG DRIVER ERROR: unknown JTAG state encountered %d", state); ++ endstate = JTAG_STATE_IDLE; ++ } ++ ++ return endstate; ++} ++ ++/** ++ * Function move_to_state ++ * moves the TAP controller from the current state to a ++ * goal_state through a path given by tap_get_tms_path(). ++ * State transition logging is performed by delegation to clock_tms(). ++ * ++ * @param goal_state is the destination state for the move. ++ */ ++static int move_to_state(tap_state_t goal_state) ++{ ++ struct jtag_end_tap_state end_state; ++ int ret = ERROR_OK; ++ int ret_errno; ++ ++ end_state.reset = JTAG_NO_RESET; ++ end_state.endstate = state_conversion(goal_state); ++ end_state.tck = 0; ++ ++ ret_errno = ioctl(jtag_fd, JTAG_SIOCSTATE, &end_state); ++ if (ret_errno < 0) { ++ LOG_ERROR("JTAG DRIVER ERROR: state transition failed"); ++ ret = ERROR_FAIL; ++ } else { ++ tap_set_state(goal_state); ++ } ++ ++ return ret; ++} ++ ++static int jtag_driver_get_speed(int *speed) ++{ ++ int ret = ERROR_OK; ++ int ret_errno; ++ int local_speed; ++ ++ ret_errno = ioctl(jtag_fd, JTAG_GIOCFREQ, &local_speed); ++ if (ret_errno < 0) { ++ LOG_ERROR("JTAG DRIVER ERROR: ioctl call fail for %s", __func__); ++ ret = ERROR_FAIL; ++ } else if (!speed) { ++ LOG_INFO("JTAG DRIVER INFO: Read JTAG TCK frequency of %u", local_speed); ++ } else { ++ *speed = local_speed; ++ } ++ ++ return ret; ++} ++ ++static int jtag_driver_set_speed(int expected_speed) ++{ ++ int ret = ERROR_OK; ++ int ret_errno; ++ int actual_speed; ++ ++ ret_errno = ioctl(jtag_fd, JTAG_SIOCFREQ, &expected_speed); ++ if (ret_errno < 0) { ++ LOG_ERROR("JTAG DRIVER ERROR: unable to program JTAG TCK frequency"); ++ ret = ERROR_FAIL; ++ } else { ++ ret = jtag_driver_get_speed(&actual_speed); ++ if (ret != ERROR_OK) ++ LOG_ERROR("JTAG DRIVER ERROR: Set requested JTAG TCK frequency " ++ "to %u, unable to verify set frequency", expected_speed); ++ else ++ LOG_INFO("JTAG DRIVER INFO: Requested JTAG TCK frequency " ++ "%u, actual frequency %u", expected_speed, actual_speed); ++ } ++ ++ return ret; ++} ++ ++static int jtag_driver_speed_div(int speed, int *khz) ++{ ++ *khz = speed / 1000; ++ return ERROR_OK; ++} ++ ++static int jtag_driver_khz(int khz, int *jtag_speed) ++{ ++ *jtag_speed = khz * 1000; ++ return ERROR_OK; ++} ++ ++static void jtag_driver_end_state(tap_state_t state) ++{ ++ if (tap_is_state_stable(state)) { ++ tap_set_end_state(state); ++ } else { ++ LOG_ERROR("JTAG DRIVER ERROR: %s is not a stable end state", tap_state_name(state)); ++ exit(-1); ++ } ++} ++ ++/** ++ * jtag_driver_execute_scan - launches a IR-scan or DR-scan ++ * @cmd: the command to launch ++ * ++ * Launch a JTAG IR-scan or DR-scan ++ * ++ * Returns ERROR_OK if OK, otherwise ERROR_XXX ++ */ ++static int jtag_driver_execute_scan(struct scan_command *scan) ++{ ++ tap_state_t end_state; ++ struct jtag_xfer xfer; ++ struct jtag_xfer xfer_copy; ++ enum scan_type type; ++ uint8_t *data_buf_start; ++ uint8_t *data_buf_chunk; ++ int num_bits; ++ int ret = ERROR_OK; ++ int ret_errno; ++ ++ type = jtag_scan_type(scan); ++ ++ LOG_DEBUG_IO("JTAG DRIVER DEBUG: %s type:%d", scan->ir_scan ? "IRSCAN" : "DRSCAN", ++ type); ++ ++ num_bits = jtag_build_buffer(scan, &data_buf_start); ++ data_buf_chunk = data_buf_start; ++ ++ if (scan->ir_scan) ++ xfer_copy.type = JTAG_SIR_XFER; ++ else ++ xfer_copy.type = JTAG_SDR_XFER; ++ ++ if (type == SCAN_IN) { ++ /* From target to host */ ++ xfer_copy.direction = JTAG_READ_XFER; ++ } else if (type == SCAN_OUT) { ++ /* From host to target */ ++ xfer_copy.direction = JTAG_WRITE_XFER; ++ } else { ++ /* Full-duplex scan */ ++ xfer_copy.direction = JTAG_READ_WRITE_XFER; ++ } ++ ++ while (num_bits > 0) { ++ xfer.type = xfer_copy.type; ++ xfer.direction = xfer_copy.direction; ++ xfer.tdio = (__u64)(uintptr_t)data_buf_chunk; ++ if (num_bits > JTAG_MAX_XFER_DATA_LEN_BYTE_ALIGNED) { ++ xfer.length = (__u32)JTAG_MAX_XFER_DATA_LEN_BYTE_ALIGNED; ++ if (scan->ir_scan) ++ xfer.endstate = state_conversion(TAP_IRPAUSE); ++ else ++ xfer.endstate = state_conversion(TAP_DRPAUSE); ++ } else { ++ xfer.length = (__u32)num_bits; ++ xfer.endstate = state_conversion(scan->end_state); ++ } ++ ++ ret_errno = ioctl(jtag_fd, JTAG_IOCXFER, &xfer); ++ if (ret_errno < 0) { ++ LOG_ERROR("JTAG DRIVER ERROR: unable to scan"); ++ ret = ERROR_FAIL; ++ } else { ++ if (num_bits > JTAG_MAX_XFER_DATA_LEN_BYTE_ALIGNED) { ++ if (scan->ir_scan) ++ end_state = TAP_IRPAUSE; ++ else ++ end_state = TAP_DRPAUSE; ++ } else { ++ end_state = scan->end_state; ++ } ++ tap_set_state(end_state); ++ ++ if (type != SCAN_OUT) ++ ret = jtag_read_buffer(data_buf_chunk, scan); ++ ++ LOG_DEBUG_IO("JTAG DRIVER DEBUG: %s scan, %i bits, end in %s", ++ (scan->ir_scan) ? "IR" : "DR", num_bits, ++ tap_state_name(end_state)); ++ } ++ ++ if (ret != ERROR_OK) ++ break; ++ ++ num_bits -= MIN(num_bits, JTAG_MAX_XFER_DATA_LEN_BYTE_ALIGNED); ++ data_buf_chunk += JTAG_MAX_XFER_DATA_LEN_BYTE_ALIGNED_DIV8; ++ } ++ ++ free(data_buf_start); ++ ++ return ret; ++} ++ ++static int jtag_driver_execute_runtest(int num_cycles, tap_state_t state) ++{ ++ struct tck_bitbang bitbang; ++ int i; ++ int ret = ERROR_OK; ++ int ret_errno; ++ ++ LOG_DEBUG_IO("JTAG DRIVER DEBUG: runtest %i cycles, end in %s", num_cycles, ++ tap_state_name(state)); ++ ++ if (tap_get_state() != TAP_IDLE) ++ move_to_state(TAP_IDLE); ++ ++ bitbang.tms = (__u8)0; ++ bitbang.tdi = (__u8)0; /* write: host to device */ ++ bitbang.tdo = (__u8)0; /* read: device to host */ ++ ++ for (i = 0; i < num_cycles && ret == ERROR_OK; i++) { ++ ret_errno = ioctl(jtag_fd, JTAG_IOCBITBANG, &bitbang); ++ if (ret_errno < 0) { ++ LOG_ERROR("JTAG DRIVER ERROR: couldn't execute runtest"); ++ ret = ERROR_FAIL; ++ } ++ } ++ ++ jtag_driver_end_state(state); ++ ++ if (tap_get_state() != tap_get_end_state()) ++ move_to_state(tap_get_end_state()); ++ ++ LOG_DEBUG_IO("JTAG DRIVER DEBUG: runtest: %i, end in %s", num_cycles, ++ tap_state_name(tap_get_end_state())); ++ ++ return ret; ++} ++ ++static int jtag_driver_execute_stableclocks(struct stableclocks_command *stableclocks) ++{ ++ int num_cycles = stableclocks->num_cycles; ++ int ret = ERROR_OK; ++ ++ ret = jtag_driver_execute_runtest(num_cycles, TAP_IDLE); ++ if (ret != ERROR_OK) ++ LOG_ERROR("JTAG DRIVER ERROR: Fail in %s", __func__); ++ else ++ LOG_DEBUG_IO("JTAG DRIVER DEBUG: clocks %i while in %s", num_cycles, ++ tap_state_name(tap_get_state())); ++ ++ return ret; ++} ++ ++static int jtag_driver_reset(int trst, int srst) ++{ ++ struct jtag_end_tap_state end_state; ++ struct tms_command tms; ++ struct jtag_xfer xfer; ++ uint32_t data_buf; ++ int ret = ERROR_OK; ++ int ret_errno; ++ uint8_t bits; ++ ++ LOG_DEBUG_IO("JTAG DRIVER DEBUG: reset trst: %i srst %i", trst, srst); ++ ++ if (trst == 1) { ++ if (jtag_hw_accel == 0) { ++ /* SW (bitbang) mode */ ++ /* Perform ioctl() JTAG_SIOCSTATE call to reset JTAG */ ++ /* controller state to Test-Logic-Reset (TLR) */ ++ end_state.reset = JTAG_FORCE_RESET; ++ end_state.endstate = JTAG_STATE_TLRESET; ++ end_state.tck = 0; ++ ret_errno = ioctl(jtag_fd, JTAG_SIOCSTATE, &end_state); ++ if (ret_errno < 0) { ++ LOG_ERROR("JTAG DRIVER ERROR: couldn't reset JTAG state machine"); ++ ret = ERROR_FAIL; ++ } else { ++ LOG_INFO("JTAG DRIVER INFO: SW - Successfully reset JTAG state machine"); ++ tap_set_state(TAP_RESET); ++ } ++ } else { ++ /* HW acceleration mode enabled */ ++ ++ /* There are two issues with initializing the controller for HW mode. */ ++ /* 1. Resetting the JTAG state machine to Test-Logic-Reset (TLR) */ ++ /* doesn't work with the ioctl() JTAG_SIOCSTATE call as it */ ++ /* does with (bitbang) mode. The workaround is to force */ ++ /* a reset by holding TMS high and pulsing TCK five times. */ ++ /* 2. After switching to HW mode and resetting the JTAG state */ ++ /* machine to TLR, for Coresight topology, the first */ ++ /* DP CTRL/STAT read returns incorrect data. The workaround */ ++ /* is after switching to HW mode and resetting to TLR state, */ ++ /* perform a dummy DR read (not write) and discard the result. */ ++ bits = 0x1F; ++ tms.num_bits = 5; ++ tms.bits = &bits; ++ ret = jtag_driver_execute_tms(&tms); ++ if (ret != ERROR_OK) { ++ LOG_ERROR("JTAG DRIVER ERROR: couldn't reset JTAG state machine"); ++ } else { ++ LOG_INFO("JTAG DRIVER INFO: HW - Successfully reset JTAG state machine"); ++ /* Bug Workaround - perform the dummy DR read */ ++ xfer.type = JTAG_SDR_XFER; /* Type is DR scan */ ++ xfer.direction = JTAG_READ_XFER; /* Only perform DR read, no write */ ++ xfer.length = (__u32)1; /* Only a single bit is needed */ ++ xfer.tdio = (__u64)(uintptr_t)(&data_buf); /* Location to store read result */ ++ xfer.endstate = JTAG_STATE_TLRESET; ++ ++ ret_errno = ioctl(jtag_fd, JTAG_IOCXFER, &xfer); ++ if (ret_errno < 0) { ++ LOG_ERROR("JTAG DRIVER ERROR: scan failed"); ++ ret = ERROR_FAIL; ++ } else { ++ tap_set_state(TAP_RESET); ++ } ++ } ++ } ++ } ++ ++ if (srst == 1) { ++ LOG_ERROR("JTAG DRIVER ERROR: Can't assert SRST: nSRST signal is not defined"); ++ ret = ERROR_FAIL; ++ } ++ ++ return ret; ++} ++ ++static int jtag_driver_execute_sleep(struct sleep_command *sleep) ++{ ++ LOG_DEBUG_IO("JTAG DRIVER DEBUG: sleep %" PRIi32, sleep->us); ++ ++ jtag_sleep(sleep->us); ++ ++ LOG_DEBUG_IO("JTAG DRIVER DEBUG: sleep %" PRIi32 " usec while in %s", ++ sleep->us, ++ tap_state_name(tap_get_state())); ++ ++ return ERROR_OK; ++} ++ ++static int jtag_driver_execute_tms(struct tms_command *tms) ++{ ++ struct tck_bitbang bitbang; ++ int ret = ERROR_OK; ++ int ret_errno; ++ unsigned int index, this_len, i, j; ++ unsigned int tms_num_bits = tms->num_bits; ++ uint8_t tms_bits = tms->bits[0]; ++ ++ LOG_DEBUG_IO("JTAG DRIVER DEBUG: TMS: %d bits", tms_num_bits); ++ ++ bitbang.tdi = (__u8)0; ++ bitbang.tdo = (__u8)0; ++ ++ index = 0; ++ j = 0; ++ ++ while ((j < tms_num_bits) && (ret == ERROR_OK)) { ++ this_len = tms_num_bits > 8 ? 8 : tms_num_bits; ++ for (i = 0; i < this_len && ret == ERROR_OK; i++) { ++ bitbang.tms = (__u8)((tms_bits >> i) & 0x1); ++ ret_errno = ioctl(jtag_fd, JTAG_IOCBITBANG, &bitbang); ++ if (ret_errno < 0) { ++ LOG_ERROR("JTAG DRIVER ERROR: execute_tms failed"); ++ ret = ERROR_FAIL; ++ } else { ++ tap_set_state(tap_state_transition(tap_get_state(), (tms_bits >> i) & 0x1)); ++ } ++ } ++ j += this_len; ++ if (j < tms_num_bits) { ++ index++; ++ tms_bits = tms->bits[index]; ++ } ++ } ++ ++ return ret; ++} ++ ++static int jtag_driver_execute_queue(struct jtag_command *cmd_queue) ++{ ++ struct jtag_command *cmd; ++ int ret = ERROR_OK; ++ ++ for (cmd = cmd_queue; ret == ERROR_OK && cmd; cmd = cmd->next) { ++ switch (cmd->type) { ++ case JTAG_SCAN: ++ ret = jtag_driver_execute_scan(cmd->cmd.scan); ++ break; ++ case JTAG_TLR_RESET: ++ ret = jtag_driver_reset(1, 0); ++ break; ++ case JTAG_RUNTEST: ++ ret = jtag_driver_execute_runtest(cmd->cmd.runtest->num_cycles, ++ cmd->cmd.runtest->end_state); ++ break; ++ case JTAG_RESET: ++ LOG_INFO("JTAG DRIVER INFO: Received deprecated JTAG_RESET command"); ++ break; ++ case JTAG_PATHMOVE: ++ break; ++ case JTAG_SLEEP: ++ ret = jtag_driver_execute_sleep(cmd->cmd.sleep); ++ break; ++ case JTAG_STABLECLOCKS: ++ ret = jtag_driver_execute_stableclocks(cmd->cmd.stableclocks); ++ break; ++ case JTAG_TMS: ++ ret = jtag_driver_execute_tms(cmd->cmd.tms); ++ break; ++ default: ++ LOG_ERROR("JTAG DRIVER ERROR: unknown JTAG command type encountered 0x%X", ++ cmd->type); ++ ret = ERROR_FAIL; ++ break; ++ } ++ } ++ ++ return ret; ++} ++ ++static int jtag_driver_init(void) ++{ ++ struct jtag_mode jmode; ++ int ret = ERROR_OK; ++ int ret_errno; ++ char buf[32]; ++ ++ snprintf(buf, sizeof(buf), "/dev/jtag%u", jtag_instance); ++ jtag_fd = open(buf, O_RDWR); ++ if (jtag_fd < 0) { ++ LOG_ERROR("JTAG DRIVER ERROR: Could not open JTAG device"); ++ LOG_ERROR("JTAG DRIVER ERROR: Connection to /dev/jtag%u failed", jtag_instance); ++ return ERROR_FAIL; ++ } ++ LOG_INFO("JTAG DRIVER INFO: Connection to /dev/jtag%u succeeded", jtag_instance); ++ ++ jmode.feature = JTAG_CONTROL_MODE; ++ jmode.mode = JTAG_MASTER_MODE; /* JTAG_MASTER_MODE or JTAG_SLAVE_MODE */ ++ ret_errno = ioctl(jtag_fd, JTAG_SIOCMODE, &jmode); ++ if (ret_errno < 0) { ++ LOG_ERROR("JTAG DRIVER ERROR: unable to set JTAG_CONTROL_MODE"); ++ ret = ERROR_FAIL; ++ } else { ++ jmode.feature = JTAG_XFER_MODE; ++ if (jtag_hw_accel == 0) ++ jmode.mode = JTAG_XFER_SW_MODE; ++ else ++ jmode.mode = JTAG_XFER_HW_MODE; ++ ++ ret_errno = ioctl(jtag_fd, JTAG_SIOCMODE, &jmode); ++ if (ret_errno < 0) { ++ LOG_ERROR("JTAG DRIVER ERROR: unable to set JTAG_XFER_MODE"); ++ ret = ERROR_FAIL; ++ } else if (jmode.mode == JTAG_XFER_HW_MODE) { ++ LOG_INFO("JTAG DRIVER INFO: Hardware Acceleration mode enabled"); ++ } else { ++ LOG_INFO("JTAG DRIVER INFO: Software mode enabled"); ++ } ++ } ++ ++ return ret; ++} ++ ++static int jtag_driver_quit(void) ++{ ++ int ret = ERROR_OK; ++ ++ close(jtag_fd); ++ ++ return ret; ++} ++ ++COMMAND_HANDLER(jtag_driver_set_instance) ++{ ++ if (CMD_ARGC > 1) ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ else if (CMD_ARGC == 1) ++ COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], jtag_instance); ++ ++ LOG_INFO("JTAG DRIVER INFO: Using /dev/jtag%u", jtag_instance); ++ ++ return ERROR_OK; ++} ++ ++COMMAND_HANDLER(jtag_driver_hw_accel) ++{ ++ if (CMD_ARGC > 1) ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ else if (CMD_ARGC == 1) ++ COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], jtag_hw_accel); ++ ++ if (jtag_hw_accel == 0) ++ LOG_INFO("JTAG DRIVER INFO: Using Software mode"); ++ else ++ LOG_INFO("JTAG DRIVER INFO: Using Hardware Acceleration mode"); ++ ++ return ERROR_OK; ++} ++ ++static const struct command_registration jtag_driver_command_handlers[] = { ++ { ++ .name = "jtag_driver_set_instance", ++ .handler = &jtag_driver_set_instance, ++ .mode = COMMAND_CONFIG, ++ .help = "set the instance of the JTAG device", ++ .usage = "description_string", ++ }, ++ { ++ .name = "jtag_driver_hw_accel", ++ .handler = &jtag_driver_hw_accel, ++ .mode = COMMAND_CONFIG, ++ .help = "enable or disable JTAG controller hardware acceleration", ++ .usage = "description_string", ++ }, ++ COMMAND_REGISTRATION_DONE ++}; ++ ++static struct jtag_interface jtag_driver_interface = { ++ .supported = DEBUG_CAP_TMS_SEQ, ++ .execute_queue = jtag_driver_execute_queue, ++}; ++ ++struct adapter_driver jtag_driver_adapter_driver = { ++ .name = "jtag_driver", ++ .transports = jtag_only, ++ .commands = jtag_driver_command_handlers, ++ ++ .init = jtag_driver_init, ++ .quit = jtag_driver_quit, ++ .reset = jtag_driver_reset, ++ .speed = jtag_driver_set_speed, ++ .khz = jtag_driver_khz, ++ .speed_div = jtag_driver_speed_div, ++ .jtag_ops = &jtag_driver_interface, ++}; +diff --git a/src/jtag/interface.h b/src/jtag/interface.h +index 28c1458cb..150ce9532 100644 +--- a/src/jtag/interface.h ++++ b/src/jtag/interface.h +@@ -383,6 +383,7 @@ extern struct adapter_driver hl_adapter_driver; + extern struct adapter_driver imx_gpio_adapter_driver; + extern struct adapter_driver jlink_adapter_driver; + extern struct adapter_driver jtag_dpi_adapter_driver; ++extern struct adapter_driver jtag_driver_adapter_driver; + extern struct adapter_driver jtag_vpi_adapter_driver; + extern struct adapter_driver kitprog_adapter_driver; + extern struct adapter_driver linuxgpiod_adapter_driver; +diff --git a/src/jtag/interfaces.c b/src/jtag/interfaces.c +index c24ead8cd..f1b086a55 100644 +--- a/src/jtag/interfaces.c ++++ b/src/jtag/interfaces.c +@@ -60,6 +60,9 @@ struct adapter_driver *adapter_drivers[] = { + #if BUILD_JTAG_DPI == 1 + &jtag_dpi_adapter_driver, + #endif ++#if BUILD_JTAG_DRIVER == 1 ++ &jtag_driver_adapter_driver, ++#endif + #if BUILD_FT232R == 1 + &ft232r_adapter_driver, + #endif +diff --git a/tcl/interface/jtag_driver.cfg b/tcl/interface/jtag_driver.cfg +new file mode 100644 +index 000000000..8238cb23c +--- /dev/null ++++ b/tcl/interface/jtag_driver.cfg +@@ -0,0 +1,19 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++ ++# ++# Provide support for the JTAG Driver ++# ++# Copyright (c) 2020, Ampere Computing LLC ++# ++ ++adapter driver jtag_driver ++ ++# Set the JTAG /dev/jtagX device instance for 'X' ++if { [info exists JTAG_INSTANCE] } { ++ set _JTAG_INSTANCE $JTAG_INSTANCE ++} else { ++ set _JTAG_INSTANCE 0 ++} ++ ++jtag_driver_set_instance $_JTAG_INSTANCE ++jtag_driver_hw_accel 1 +-- +2.25.1 + diff --git a/patches/0011-jtag-Remote-debug-remove-jtag-max-xfer-scan-len.patch b/patches/0011-jtag-Remote-debug-remove-jtag-max-xfer-scan-len.patch new file mode 100644 index 000000000..e22305082 --- /dev/null +++ b/patches/0011-jtag-Remote-debug-remove-jtag-max-xfer-scan-len.patch @@ -0,0 +1,95 @@ +From 768c13ba61508d2f7c2923b6712df856083c03bd Mon Sep 17 00:00:00 2001 +From: Brian Esquilona +Date: Wed, 22 Nov 2023 09:41:43 -0700 +Subject: [PATCH 11/33] jtag: Remote debug remove jtag max xfer scan len + +Not all systems support IRPAUSE and DRPAUSE JTAG states, but are +still capable of streaming large chains of JTAG data. By removing +the arbitrary maximum transfer length, this fixes a problem +transferring data that exceeds the length on systems that do not +support IRPAUSE and DRPAUSE. + +Change-Id: I3cec7a8b9dee3f1e9029294d7c60baae66027de7 +Signed-off-by: Brian Esquilona +Signed-off-by: Daniel Goehring +--- + src/jtag/drivers/jtag_driver.c | 40 +++++----------------------------- + 1 file changed, 5 insertions(+), 35 deletions(-) + +diff --git a/src/jtag/drivers/jtag_driver.c b/src/jtag/drivers/jtag_driver.c +index fb58813b4..d10a832f3 100644 +--- a/src/jtag/drivers/jtag_driver.c ++++ b/src/jtag/drivers/jtag_driver.c +@@ -25,16 +25,6 @@ + + #define JTAG_INSTANCE 0 + +-/** +- * Note: When calculating the 8-bit aligned address below for the maximum +- * JTAG transfer data bit length, the JTAG_MAX_XFER_DATA_LEN define is +- * adjusted by one bit to account for a code bug in the open-source Linux +- * JTAG driver. Due to the driver bug, transfers of exact size +- * JTAG_MAX_XFER_DATA_LEN bits will fail. +- */ +-#define JTAG_MAX_XFER_DATA_LEN_BYTE_ALIGNED (((JTAG_MAX_XFER_DATA_LEN) - 1) & (~0x7)) +-#define JTAG_MAX_XFER_DATA_LEN_BYTE_ALIGNED_DIV8 ((JTAG_MAX_XFER_DATA_LEN_BYTE_ALIGNED) >> 3) +- + int jtag_instance = JTAG_INSTANCE; + int jtag_hw_accel = 1; + int jtag_fd; +@@ -254,34 +244,20 @@ static int jtag_driver_execute_scan(struct scan_command *scan) + xfer_copy.direction = JTAG_READ_WRITE_XFER; + } + +- while (num_bits > 0) { ++ if (num_bits > 0) { + xfer.type = xfer_copy.type; + xfer.direction = xfer_copy.direction; + xfer.tdio = (__u64)(uintptr_t)data_buf_chunk; +- if (num_bits > JTAG_MAX_XFER_DATA_LEN_BYTE_ALIGNED) { +- xfer.length = (__u32)JTAG_MAX_XFER_DATA_LEN_BYTE_ALIGNED; +- if (scan->ir_scan) +- xfer.endstate = state_conversion(TAP_IRPAUSE); +- else +- xfer.endstate = state_conversion(TAP_DRPAUSE); +- } else { +- xfer.length = (__u32)num_bits; +- xfer.endstate = state_conversion(scan->end_state); +- } ++ ++ xfer.length = (__u32)num_bits; ++ xfer.endstate = state_conversion(scan->end_state); + + ret_errno = ioctl(jtag_fd, JTAG_IOCXFER, &xfer); + if (ret_errno < 0) { + LOG_ERROR("JTAG DRIVER ERROR: unable to scan"); + ret = ERROR_FAIL; + } else { +- if (num_bits > JTAG_MAX_XFER_DATA_LEN_BYTE_ALIGNED) { +- if (scan->ir_scan) +- end_state = TAP_IRPAUSE; +- else +- end_state = TAP_DRPAUSE; +- } else { +- end_state = scan->end_state; +- } ++ end_state = scan->end_state; + tap_set_state(end_state); + + if (type != SCAN_OUT) +@@ -291,12 +267,6 @@ static int jtag_driver_execute_scan(struct scan_command *scan) + (scan->ir_scan) ? "IR" : "DR", num_bits, + tap_state_name(end_state)); + } +- +- if (ret != ERROR_OK) +- break; +- +- num_bits -= MIN(num_bits, JTAG_MAX_XFER_DATA_LEN_BYTE_ALIGNED); +- data_buf_chunk += JTAG_MAX_XFER_DATA_LEN_BYTE_ALIGNED_DIV8; + } + + free(data_buf_start); +-- +2.25.1 + diff --git a/patches/0012-jtag-JTAG-Driver-remote-debug.patch b/patches/0012-jtag-JTAG-Driver-remote-debug.patch new file mode 100644 index 000000000..06fb39243 --- /dev/null +++ b/patches/0012-jtag-JTAG-Driver-remote-debug.patch @@ -0,0 +1,28 @@ +From 0405acd215d06c1490683460d41af73efaabb8b9 Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Sat, 19 Feb 2022 03:59:56 +0000 +Subject: [PATCH 12/33] jtag: JTAG Driver remote debug + +With the latest Linux JTAG driver, hardware accelerated mode isn't +working. There may be a bug in the Linux JTAG driver wrt hardware +accelerated mode. Until HW mode is fixed, make software mode the default. + +Change-Id: Ibfc4540538432f572e0a56122e0d4dbce71069dc +Signed-off-by: Daniel Goehring +--- + tcl/interface/jtag_driver.cfg | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/tcl/interface/jtag_driver.cfg b/tcl/interface/jtag_driver.cfg +index 8238cb23c..4b4068548 100644 +--- a/tcl/interface/jtag_driver.cfg ++++ b/tcl/interface/jtag_driver.cfg +@@ -16,4 +16,4 @@ if { [info exists JTAG_INSTANCE] } { + } + + jtag_driver_set_instance $_JTAG_INSTANCE +-jtag_driver_hw_accel 1 ++jtag_driver_hw_accel 0 +-- +2.25.1 + diff --git a/patches/0013-aarch64-add-system-register-helper-script-support.patch b/patches/0013-aarch64-add-system-register-helper-script-support.patch new file mode 100644 index 000000000..f631b8124 --- /dev/null +++ b/patches/0013-aarch64-add-system-register-helper-script-support.patch @@ -0,0 +1,208 @@ +From 4949480ad03913ee2117bf7b2721f0fad752719a Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Thu, 3 Sep 2020 21:49:54 -0400 +Subject: [PATCH 13/33] aarch64: add system register helper script support + +Add TCL helper script to wrap the OpenOCD MRS and MSR program commands +with a layer that maps the system register name as specified in the +ARM Architecture Reference Manual to the instruction encoding. + +Change-Id: I3a5e293ff3c8a09cf5d03cf7b5fad89c41ea9d3c +Signed-off-by: Daniel Goehring +--- + tcl/cpu/arm/armv8_sr.tcl | 183 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 183 insertions(+) + create mode 100644 tcl/cpu/arm/armv8_sr.tcl + +diff --git a/tcl/cpu/arm/armv8_sr.tcl b/tcl/cpu/arm/armv8_sr.tcl +new file mode 100644 +index 000000000..36de7c1a7 +--- /dev/null ++++ b/tcl/cpu/arm/armv8_sr.tcl +@@ -0,0 +1,183 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# ARMv8 Architected System Register support ++# ++# Copyright (c) 2020-2023, Ampere Computing LLC ++# ++ ++# Command Usage ++# ++# Execute TCL script to load the read_reg and write_reg routines ++# ++# read_reg target_id sys_reg_name ['sec' | 'nsec' | 'asis'] ++# target_id : OpenOCD ARMv8 core target ++# sys_reg_name : One of the reg names in the get_sr_encoding routine ++# 'sec' : perform system reg read at highest exception level and ns=0 ++# 'nsec' : perform system reg read at highest exception level and ns=1 ++# 'asis' : perform sys reg read at current exception level and ns setting ++# ++# write_reg target_id sys_reg_name write_value ['sec' | 'nsec' | 'asis'] ++# target_id : OpenOCD ARMv8 core target ++# sys_reg_name : One of the reg names in the get_sr_encoding routine ++# write_value : The numeric value in hexadecimal or decimal ++# 'sec' : perform system reg write at highest exception level and ns=0 ++# 'nsec' : perform system reg write at highest exception level and ns=1 ++# 'asis' : perform sys reg write at current exception level and ns setting ++ ++proc get_sr_encoding {sys_reg_name} { ++ set sr_encoding {} ++ ++ set sys_reg_name [string toupper $sys_reg_name] ++ ++ switch $sys_reg_name { ++ SCTLR_EL3 {set sr_encoding {3 6 1 0 0}} ++ SCR_EL3 {set sr_encoding {3 6 1 1 0}} ++ CPTR_EL3 {set sr_encoding {3 6 1 1 2}} ++ SP_EL2 {set sr_encoding {3 6 4 1 0}} ++ VBAR_EL3 {set sr_encoding {3 6 12 0 0}} ++ ICC_CTLR_EL3 {set sr_encoding {3 6 12 12 4}} ++ ICC_SRE_EL3 {set sr_encoding {3 6 12 12 5}} ++ ICC_IGRPEN1_EL3 {set sr_encoding {3 6 12 12 7}} ++ MPIDR_EL1 {set sr_encoding {3 0 0 0 5}} ++ SCTLR_EL1 {set sr_encoding {3 0 1 0 0}} ++ CPACR_EL1 {set sr_encoding {3 0 1 0 2}} ++ ELR_EL1 {set sr_encoding {3 0 4 0 1}} ++ SP_EL0 {set sr_encoding {3 0 4 1 0}} ++ SPSEL {set sr_encoding {3 0 4 2 0}} ++ CURRENTEL {set sr_encoding {3 0 4 2 2}} ++ ESR_EL1 {set sr_encoding {3 0 5 2 0}} ++ ERRIDR_EL1 {set sr_encoding {3 0 5 3 0}} ++ ERRSELR_EL1 {set sr_encoding {3 0 5 3 1}} ++ ERXFR_EL1 {set sr_encoding {3 0 5 4 0}} ++ ERXCTLR_EL1 {set sr_encoding {3 0 5 4 1}} ++ ERXSTATUS_EL1 {set sr_encoding {3 0 5 4 2}} ++ ERXADDR_EL1 {set sr_encoding {3 0 5 4 3}} ++ ERXMISC0_EL1 {set sr_encoding {3 0 5 5 0}} ++ ERXMISC1_EL1 {set sr_encoding {3 0 5 5 1}} ++ FAR_EL1 {set sr_encoding {3 0 6 0 0}} ++ PAR_EL1 {set sr_encoding {3 0 7 4 0}} ++ VBAR_EL1 {set sr_encoding {3 0 12 0 0}} ++ ICC_IAR0_EL1 {set sr_encoding {3 0 12 8 0}} ++ ICC_EOIR0_EL1 {set sr_encoding {3 0 12 8 1}} ++ ICC_HPPIR0_EL1 {set sr_encoding {3 0 12 8 2}} ++ ICC_DIR_EL1 {set sr_encoding {3 0 12 11 1}} ++ ICC_RPR_EL1 {set sr_encoding {3 0 12 11 3}} ++ ICC_HPPIR1_EL1 {set sr_encoding {3 0 12 12 2}} ++ ICC_CTLR_EL1 {set sr_encoding {3 0 12 12 4}} ++ ICC_SRE_EL1 {set sr_encoding {3 0 12 12 5}} ++ ICC_IGRPEN0_EL1 {set sr_encoding {3 0 12 12 6}} ++ ICC_IGRPEN1_EL1 {set sr_encoding {3 0 12 12 7}} ++ ICC_IAR1_EL1 {set sr_encoding {3 0 12 12 0}} ++ ERXPFGF_EL1 {set sr_encoding {3 0 5 4 4}} ++ ERXPFGCTL_EL1 {set sr_encoding {3 0 5 4 5}} ++ ERXPFGCDN_EL1 {set sr_encoding {3 0 5 4 6}} ++ CNTPCT_EL0 {set sr_encoding {3 3 14 0 1}} ++ CNTP_TVAL_EL0 {set sr_encoding {3 3 14 2 0}} ++ CNTP_CVAL_EL0 {set sr_encoding {3 3 14 2 2}} ++ SCTLR_EL2 {set sr_encoding {3 4 1 0 0}} ++ HCR_EL2 {set sr_encoding {3 4 1 1 0}} ++ CPTR_EL2 {set sr_encoding {3 4 1 1 2}} ++ SP_EL1 {set sr_encoding {3 4 4 1 0}} ++ CNTPS_TVAL_EL1 {set sr_encoding {3 7 14 2 0}} ++ CNTPS_CTL_EL1 {set sr_encoding {3 7 14 2 1}} ++ CNTPS_CVAL_EL1 {set sr_encoding {3 7 14 2 2}} ++ default {set sr_encoding {"Unsupported system register name"}} ++ } ++ ++ return $sr_encoding ++} ++ ++proc read_reg_usage {} { ++ echo {read_reg target_id sys_reg_name ['sec' | 'nsec' | 'asis']} ++ echo { target_id : OpenOCD ARMv8 core target identifier} ++ echo { sys_reg_name : a supported system register} ++ echo { 'sec' : read at highest exception level and ns=0} ++ echo { 'nsec' : read at highest exception level and ns=1} ++ echo { 'asis' : read at current exception level and ns setting} ++ echo {} ++} ++ ++proc read_reg {args} { ++ set num [llength $args] ++ if { $num == 2 } { ++ set target_id [lindex $args 0] ++ set sys_reg_name [lindex $args 1] ++ } elseif { $num == 3 } { ++ set target_id [lindex $args 0] ++ set sys_reg_name [lindex $args 1] ++ set option [string tolower [lindex $args 2]] ++ if { $option != {sec} && $option != {nsec} && $option != {asis} } { ++ read_reg_usage ++ return {Invalid read_reg parameters} ++ } ++ } else { ++ read_reg_usage ++ return {Invalid read_reg parameters} ++ } ++ ++ set sr_enc [get_sr_encoding $sys_reg_name] ++ ++ if {[llength $sr_enc] == 5 } { ++ if {$num == 2} { ++ set result [$target_id aarch64 mrs [lindex $sr_enc 0] [lindex $sr_enc 1] [lindex $sr_enc 2] [lindex $sr_enc 3] [lindex $sr_enc 4]] ++ } else { ++ set result [$target_id aarch64 mrs $option [lindex $sr_enc 0] [lindex $sr_enc 1] [lindex $sr_enc 2] [lindex $sr_enc 3] [lindex $sr_enc 4]] ++ } ++ } else { ++ set result "Unsupported system register name $sys_reg_name" ++ read_reg_usage ++ } ++ ++ return $result ++} ++ ++proc write_reg_usage {} { ++ echo {write_reg target_id sys_reg_name write_value ['sec' | 'nsec' | 'asis']} ++ echo { target_id : OpenOCD ARMv8 core target identifier} ++ echo { sys_reg_name : a supported system register} ++ echo { write_value : write value in hexadecimal or decimal} ++ echo { 'sec' : write at highest exception level and ns=0} ++ echo { 'nsec' : write at highest exception level and ns=1} ++ echo { 'asis' : write at current exception level and ns setting} ++ echo {} ++} ++ ++proc write_reg {args} { ++ set num [llength $args] ++ if { $num == 3 } { ++ set target_id [lindex $args 0] ++ set sys_reg_name [lindex $args 1] ++ set write_value [lindex $args 2] ++ } elseif { $num == 4 } { ++ set target_id [lindex $args 0] ++ set sys_reg_name [lindex $args 1] ++ set write_value [lindex $args 2] ++ set option [string tolower [lindex $args 3]] ++ if { $option != {sec} && $option != {nsec} && $option != {asis} } { ++ write_reg_usage ++ return {Invalid write_reg parameters} ++ } ++ } else { ++ write_reg_usage ++ return {Invalid write_reg parameters} ++ } ++ ++ set sr_enc [get_sr_encoding $sys_reg_name] ++ ++ if {[llength $sr_enc] == 5} { ++ if {$num == 3} { ++ set result [$target_id aarch64 msr [lindex $sr_enc 0] [lindex $sr_enc 1] [lindex $sr_enc 2] [lindex $sr_enc 3] [lindex $sr_enc 4] $write_value] ++ } else { ++ set result [$target_id aarch64 msr $option [lindex $sr_enc 0] [lindex $sr_enc 1] [lindex $sr_enc 2] [lindex $sr_enc 3] [lindex $sr_enc 4] $write_value] ++ } ++ } else { ++ set result "Unsupported system register name $sys_reg_name" ++ write_reg_usage ++ } ++ ++ return $result ++} ++ ++echo "Added Commands:" ++read_reg_usage ++write_reg_usage +-- +2.25.1 + diff --git a/patches/0014-aarch64-BRBE-register-names-added-for-MSR-MRS-access.patch b/patches/0014-aarch64-BRBE-register-names-added-for-MSR-MRS-access.patch new file mode 100644 index 000000000..0dc8a651a --- /dev/null +++ b/patches/0014-aarch64-BRBE-register-names-added-for-MSR-MRS-access.patch @@ -0,0 +1,137 @@ +From 3e3561239148431767bd6abf7cf5b8ae8aaa92fe Mon Sep 17 00:00:00 2001 +From: Kevin Burke +Date: Tue, 13 Jun 2023 11:35:02 -0600 +Subject: [PATCH 14/33] aarch64: BRBE register names added for MSR/MRS access + +Added BRB* named registers for Branch Record Buffer support. +Ordered register names alphabetically for easier read. + +Change-Id: I0d360f95e0f542a323eb070cfa1acaaea863362a +Signed-off-by: Kevin Burke +Signed-off-by: Daniel Goehring +--- + tcl/cpu/arm/armv8_sr.tcl | 86 +++++++++++++++++++++++----------------- + 1 file changed, 49 insertions(+), 37 deletions(-) + +diff --git a/tcl/cpu/arm/armv8_sr.tcl b/tcl/cpu/arm/armv8_sr.tcl +index 36de7c1a7..ec5239266 100644 +--- a/tcl/cpu/arm/armv8_sr.tcl ++++ b/tcl/cpu/arm/armv8_sr.tcl +@@ -2,7 +2,7 @@ + # + # ARMv8 Architected System Register support + # +-# Copyright (c) 2020-2023, Ampere Computing LLC ++# Copyright (c) 2020-2024, Ampere Computing LLC + # + + # Command Usage +@@ -30,57 +30,69 @@ proc get_sr_encoding {sys_reg_name} { + set sys_reg_name [string toupper $sys_reg_name] + + switch $sys_reg_name { +- SCTLR_EL3 {set sr_encoding {3 6 1 0 0}} +- SCR_EL3 {set sr_encoding {3 6 1 1 0}} +- CPTR_EL3 {set sr_encoding {3 6 1 1 2}} +- SP_EL2 {set sr_encoding {3 6 4 1 0}} +- VBAR_EL3 {set sr_encoding {3 6 12 0 0}} +- ICC_CTLR_EL3 {set sr_encoding {3 6 12 12 4}} +- ICC_SRE_EL3 {set sr_encoding {3 6 12 12 5}} +- ICC_IGRPEN1_EL3 {set sr_encoding {3 6 12 12 7}} +- MPIDR_EL1 {set sr_encoding {3 0 0 0 5}} +- SCTLR_EL1 {set sr_encoding {3 0 1 0 0}} ++ BRBCR_EL1 {set sr_encoding {2 1 9 0 0}} ++ BRBCR_EL2 {set sr_encoding {2 4 9 0 0}} ++ BRBFCR_EL1 {set sr_encoding {2 1 9 0 1}} ++ BRBIDR0_EL1 {set sr_encoding {2 1 9 2 0}} ++ BRBINFn_EL1 {set sr_encoding {8 1 8 0 0}} ++ BRBSRCn_EL1 {set sr_encoding {2 1 8 0 1}} ++ BRBTGTn_EL1 {set sr_encoding {2 1 8 0 2}} ++ BRBTS_EL1 {set sr_encoding {2 1 9 0 2}} ++ BRB_IALL {set sr_encoding {1 1 7 2 4}} ++ CNTPCT_EL0 {set sr_encoding {3 3 14 0 1}} ++ CNTPS_CTL_EL1 {set sr_encoding {3 7 14 2 1}} ++ CNTPS_CVAL_EL1 {set sr_encoding {3 7 14 2 2}} ++ CNTPS_TVAL_EL1 {set sr_encoding {3 7 14 2 0}} ++ CNTP_CVAL_EL0 {set sr_encoding {3 3 14 2 2}} ++ CNTP_TVAL_EL0 {set sr_encoding {3 3 14 2 0}} + CPACR_EL1 {set sr_encoding {3 0 1 0 2}} +- ELR_EL1 {set sr_encoding {3 0 4 0 1}} +- SP_EL0 {set sr_encoding {3 0 4 1 0}} +- SPSEL {set sr_encoding {3 0 4 2 0}} ++ CPTR_EL2 {set sr_encoding {3 4 1 1 2}} ++ CPTR_EL3 {set sr_encoding {3 6 1 1 2}} + CURRENTEL {set sr_encoding {3 0 4 2 2}} +- ESR_EL1 {set sr_encoding {3 0 5 2 0}} ++ ELR_EL1 {set sr_encoding {3 0 4 0 1}} + ERRIDR_EL1 {set sr_encoding {3 0 5 3 0}} + ERRSELR_EL1 {set sr_encoding {3 0 5 3 1}} +- ERXFR_EL1 {set sr_encoding {3 0 5 4 0}} +- ERXCTLR_EL1 {set sr_encoding {3 0 5 4 1}} +- ERXSTATUS_EL1 {set sr_encoding {3 0 5 4 2}} + ERXADDR_EL1 {set sr_encoding {3 0 5 4 3}} ++ ERXCTLR_EL1 {set sr_encoding {3 0 5 4 1}} ++ ERXFR_EL1 {set sr_encoding {3 0 5 4 0}} + ERXMISC0_EL1 {set sr_encoding {3 0 5 5 0}} + ERXMISC1_EL1 {set sr_encoding {3 0 5 5 1}} ++ ERXPFGCDN_EL1 {set sr_encoding {3 0 5 4 6}} ++ ERXPFGCTL_EL1 {set sr_encoding {3 0 5 4 5}} ++ ERXPFGF_EL1 {set sr_encoding {3 0 5 4 4}} ++ ERXSTATUS_EL1 {set sr_encoding {3 0 5 4 2}} ++ ESR_EL1 {set sr_encoding {3 0 5 2 0}} + FAR_EL1 {set sr_encoding {3 0 6 0 0}} +- PAR_EL1 {set sr_encoding {3 0 7 4 0}} +- VBAR_EL1 {set sr_encoding {3 0 12 0 0}} +- ICC_IAR0_EL1 {set sr_encoding {3 0 12 8 0}} ++ HCR_EL2 {set sr_encoding {3 4 1 1 0}} ++ ICC_CTLR_EL1 {set sr_encoding {3 0 12 12 4}} ++ ICC_CTLR_EL3 {set sr_encoding {3 6 12 12 4}} ++ ICC_DIR_EL1 {set sr_encoding {3 0 12 11 1}} + ICC_EOIR0_EL1 {set sr_encoding {3 0 12 8 1}} + ICC_HPPIR0_EL1 {set sr_encoding {3 0 12 8 2}} +- ICC_DIR_EL1 {set sr_encoding {3 0 12 11 1}} +- ICC_RPR_EL1 {set sr_encoding {3 0 12 11 3}} + ICC_HPPIR1_EL1 {set sr_encoding {3 0 12 12 2}} +- ICC_CTLR_EL1 {set sr_encoding {3 0 12 12 4}} +- ICC_SRE_EL1 {set sr_encoding {3 0 12 12 5}} ++ ICC_IAR0_EL1 {set sr_encoding {3 0 12 8 0}} ++ ICC_IAR1_EL1 {set sr_encoding {3 0 12 12 0}} + ICC_IGRPEN0_EL1 {set sr_encoding {3 0 12 12 6}} + ICC_IGRPEN1_EL1 {set sr_encoding {3 0 12 12 7}} +- ICC_IAR1_EL1 {set sr_encoding {3 0 12 12 0}} +- ERXPFGF_EL1 {set sr_encoding {3 0 5 4 4}} +- ERXPFGCTL_EL1 {set sr_encoding {3 0 5 4 5}} +- ERXPFGCDN_EL1 {set sr_encoding {3 0 5 4 6}} +- CNTPCT_EL0 {set sr_encoding {3 3 14 0 1}} +- CNTP_TVAL_EL0 {set sr_encoding {3 3 14 2 0}} +- CNTP_CVAL_EL0 {set sr_encoding {3 3 14 2 2}} ++ ICC_IGRPEN1_EL3 {set sr_encoding {3 6 12 12 7}} ++ ICC_RPR_EL1 {set sr_encoding {3 0 12 11 3}} ++ ICC_SRE_EL1 {set sr_encoding {3 0 12 12 5}} ++ ICC_SRE_EL3 {set sr_encoding {3 6 12 12 5}} ++ ID_AA64DFR0_EL1 {set sr_encoding {3 0 0 5 0}} ++ MDCR_EL3 {set sr_encoding {3 6 1 3 1}} ++ MPIDR_EL1 {set sr_encoding {3 0 0 0 5}} ++ PAR_EL1 {set sr_encoding {3 0 7 4 0}} ++ PMCR_EL0 {set sr_encoding {3 3 9 12 0}} ++ SCR_EL3 {set sr_encoding {3 6 1 1 0}} ++ SCTLR_EL1 {set sr_encoding {3 0 1 0 0}} + SCTLR_EL2 {set sr_encoding {3 4 1 0 0}} +- HCR_EL2 {set sr_encoding {3 4 1 1 0}} +- CPTR_EL2 {set sr_encoding {3 4 1 1 2}} ++ SCTLR_EL3 {set sr_encoding {3 6 1 0 0}} ++ SPSEL {set sr_encoding {3 0 4 2 0}} ++ SP_EL0 {set sr_encoding {3 0 4 1 0}} + SP_EL1 {set sr_encoding {3 4 4 1 0}} +- CNTPS_TVAL_EL1 {set sr_encoding {3 7 14 2 0}} +- CNTPS_CTL_EL1 {set sr_encoding {3 7 14 2 1}} +- CNTPS_CVAL_EL1 {set sr_encoding {3 7 14 2 2}} ++ SP_EL2 {set sr_encoding {3 6 4 1 0}} ++ VBAR_EL1 {set sr_encoding {3 0 12 0 0}} ++ VBAR_EL3 {set sr_encoding {3 6 12 0 0}} + default {set sr_encoding {"Unsupported system register name"}} + } + +-- +2.25.1 + diff --git a/patches/0015-target-aarch64-CTI-rework-of-run-halt-events.patch b/patches/0015-target-aarch64-CTI-rework-of-run-halt-events.patch new file mode 100644 index 000000000..c32b86bf8 --- /dev/null +++ b/patches/0015-target-aarch64-CTI-rework-of-run-halt-events.patch @@ -0,0 +1,421 @@ +From b1ea04e28d81cb6c5325a9af98edaaa37f20d4de Mon Sep 17 00:00:00 2001 +From: Steve Clevenger +Date: Mon, 29 Nov 2021 21:53:56 +0000 +Subject: [PATCH 15/33] target/aarch64: CTI rework of run/halt events + +CTI rework for tighter coupling of run/halt events. + +Leverage ARM's CTI to propagate resume and halt trigger events. +This approach provides tighter SMP coupling when resuming and +halting SMP cores. + +Change-Id: I3025316cfd4660bea0dd0e054d43653f8f49ac89 +Signed-off-by: Steve Clevenger +Signed-off-by: Daniel Goehring +--- + src/target/aarch64.c | 183 ++++++++++++++++++++++++++++++++++++------- + src/target/aarch64.h | 7 ++ + 2 files changed, 161 insertions(+), 29 deletions(-) + +diff --git a/src/target/aarch64.c b/src/target/aarch64.c +index f2b6104c2..a2b588c0a 100644 +--- a/src/target/aarch64.c ++++ b/src/target/aarch64.c +@@ -200,6 +200,7 @@ static int aarch64_mmu_modify(struct target *target, int enable) + static int aarch64_init_debug_access(struct target *target) + { + struct armv8_common *armv8 = target_to_armv8(target); ++ struct aarch64_common *aarch64 = target_to_aarch64(target); + int retval; + uint32_t dummy; + +@@ -221,7 +222,7 @@ static int aarch64_init_debug_access(struct target *target) + + /* + * Static CTI configuration: +- * Channel 0 -> trigger outputs HALT request to PE ++ * Channel 0 -> trigger outputs HALT request to PE (or all PEs) + * Channel 1 -> trigger outputs Resume request to PE + * Gate all channel trigger events from entering the CTM + */ +@@ -231,18 +232,27 @@ static int aarch64_init_debug_access(struct target *target) + /* By default, gate all channel events to and from the CTM */ + if (retval == ERROR_OK) + retval = arm_cti_write_reg(armv8->cti, CTI_GATE, 0); ++ /* For CTI extended mode, set up synchronous halt using channel 0. Each ++ * CTI propagates a channel 0 cross-halt trigger event in extended mode. ++ */ ++ if (aarch64->cti_mode == AARCH64_CTIMODE_EXTEND) { ++ /* each CTI generates a debug request trigger in response to channel event */ ++ if (retval == ERROR_OK) ++ retval = arm_cti_write_reg(armv8->cti, CTI_INEN0, CTI_CHNL(0)); ++ } else { ++ if (retval == ERROR_OK) ++ retval = arm_cti_write_reg(armv8->cti, CTI_INEN0, 0); ++ } + /* output halt requests to PE on channel 0 event */ + if (retval == ERROR_OK) + retval = arm_cti_write_reg(armv8->cti, CTI_OUTEN0, CTI_CHNL(0)); + /* output restart requests to PE on channel 1 event */ + if (retval == ERROR_OK) + retval = arm_cti_write_reg(armv8->cti, CTI_OUTEN1, CTI_CHNL(1)); +- if (retval != ERROR_OK) +- return retval; + + /* Resync breakpoint registers */ + +- return ERROR_OK; ++ return retval; + } + + /* Write to memory mapped registers directly with no cache or mmu handling */ +@@ -379,7 +389,7 @@ static int aarch64_halt_one(struct target *target, enum halt_mode mode) + if (retval != ERROR_OK) + return retval; + +- /* trigger an event on channel 0, this outputs a halt request to the PE */ ++ /* trigger an event on channel 0, this outputs a halt request */ + retval = arm_cti_pulse_channel(armv8->cti, 0); + if (retval != ERROR_OK) + return retval; +@@ -461,13 +471,16 @@ static int aarch64_halt_smp(struct target *target, bool exc_target) + + static int update_halt_gdb(struct target *target, enum target_debug_reason debug_reason) + { ++ struct aarch64_common *aarch64 = target_to_aarch64(target); + struct target *gdb_target = NULL; + struct target_list *head; + struct target *curr; + +- if (debug_reason == DBG_REASON_NOTHALTED) { +- LOG_DEBUG("Halting remaining targets in SMP group"); +- aarch64_halt_smp(target, true); ++ if (aarch64->cti_mode == AARCH64_CTIMODE_LEGACY) { ++ if (debug_reason == DBG_REASON_NOTHALTED) { ++ LOG_DEBUG("Halting remaining targets in SMP group"); ++ aarch64_halt_smp(target, true); ++ } + } + + /* poll all targets in the group, but skip the target that serves GDB */ +@@ -519,6 +532,7 @@ static int aarch64_poll(struct target *target) + if (halted) { + prev_target_state = target->state; + if (prev_target_state != TARGET_HALTED) { ++ struct aarch64_common *aarch64 = target_to_aarch64(target); + enum target_debug_reason debug_reason = target->debug_reason; + + /* We have a halting debug event */ +@@ -534,6 +548,17 @@ static int aarch64_poll(struct target *target) + if (arm_semihosting(target, &retval) != 0) + return retval; + ++ /* The verbose_halt_msg setting is tied to LOG_LVL here. OpenOCD ++ * attempts to suppress (what it considers) redundant messages ++ * related to GDB run/halt events. The unfortunate end result is ++ * misleading log messages. ++ */ ++ bool verbose_halt_msg = target->verbose_halt_msg; ++ ++ if (aarch64->cti_mode == AARCH64_CTIMODE_EXTEND && ++ debug_level >= LOG_LVL_INFO) ++ target->verbose_halt_msg = true; ++ + switch (prev_target_state) { + case TARGET_RUNNING: + case TARGET_UNKNOWN: +@@ -546,6 +571,9 @@ static int aarch64_poll(struct target *target) + default: + break; + } ++ if (aarch64->cti_mode == AARCH64_CTIMODE_EXTEND && ++ debug_level >= LOG_LVL_INFO) ++ target->verbose_halt_msg = verbose_halt_msg; + } + } else + target->state = TARGET_RUNNING; +@@ -626,6 +654,7 @@ static int aarch64_restore_one(struct target *target, int current, + */ + static int aarch64_prepare_restart_one(struct target *target) + { ++ struct aarch64_common *aarch64 = target_to_aarch64(target); + struct armv8_common *armv8 = target_to_armv8(target); + int retval; + uint32_t dscr; +@@ -652,8 +681,14 @@ static int aarch64_prepare_restart_one(struct target *target) + */ + if (retval == ERROR_OK) + retval = arm_cti_ungate_channel(armv8->cti, 1); +- if (retval == ERROR_OK) +- retval = arm_cti_gate_channel(armv8->cti, 0); ++ if (aarch64->cti_mode == AARCH64_CTIMODE_EXTEND) { ++ /* Open the CTI gate for channel 0 to propagate halt events to all PEs. */ ++ if (retval == ERROR_OK) ++ retval = arm_cti_ungate_channel(armv8->cti, 0); ++ } else { ++ if (retval == ERROR_OK) ++ retval = arm_cti_gate_channel(armv8->cti, 0); ++ } + + /* make sure that DSCR.HDE is set */ + if (retval == ERROR_OK) { +@@ -770,6 +805,7 @@ static int aarch64_prep_restart_smp(struct target *target, int handle_breakpoint + static int aarch64_step_restart_smp(struct target *target) + { + int retval = ERROR_OK; ++ struct aarch64_common *aarch64 = target_to_aarch64(target); + struct target_list *head; + struct target *first = NULL; + +@@ -778,12 +814,17 @@ static int aarch64_step_restart_smp(struct target *target) + retval = aarch64_prep_restart_smp(target, 0, &first); + if (retval != ERROR_OK) + return retval; +- +- if (first) +- retval = aarch64_do_restart_one(first, RESTART_LAZY); +- if (retval != ERROR_OK) { +- LOG_DEBUG("error restarting target %s", target_name(first)); +- return retval; ++ if (aarch64->cti_mode == AARCH64_CTIMODE_LEGACY) { ++ /* ++ * CTI legacy mode restarts SMP cores here, but it's faked ++ * in extended mode. ++ */ ++ if (first) ++ retval = aarch64_do_restart_one(first, RESTART_LAZY); ++ if (retval != ERROR_OK) { ++ LOG_DEBUG("error restarting target %s", target_name(first)); ++ return retval; ++ } + } + + int64_t then = timeval_ms(); +@@ -803,13 +844,16 @@ static int aarch64_step_restart_smp(struct target *target) + if (!target_was_examined(curr)) + continue; + +- retval = aarch64_check_state_one(curr, +- PRSR_SDR, PRSR_SDR, &resumed, &prsr); +- if (retval != ERROR_OK || (!resumed && (prsr & PRSR_HALT))) { +- all_resumed = false; +- break; ++ if (aarch64->cti_mode == AARCH64_CTIMODE_LEGACY) { ++ retval = aarch64_check_state_one(curr, ++ PRSR_SDR, PRSR_SDR, &resumed, &prsr); ++ if (retval != ERROR_OK || (!resumed && (prsr & PRSR_HALT))) { ++ all_resumed = false; ++ break; ++ } + } + ++ /* Only fake a restart for CTI extended mode */ + if (curr->state != TARGET_RUNNING) { + curr->state = TARGET_RUNNING; + curr->debug_reason = DBG_REASON_NOTHALTED; +@@ -832,10 +876,11 @@ static int aarch64_step_restart_smp(struct target *target) + * cluster explicitly. So if we find that a core has not halted + * yet, we trigger an explicit resume for the second cluster. + */ +- retval = aarch64_do_restart_one(curr, RESTART_LAZY); ++ if (aarch64->cti_mode == AARCH64_CTIMODE_LEGACY) ++ retval = aarch64_do_restart_one(curr, RESTART_LAZY); + if (retval != ERROR_OK) + break; +-} ++ } + + return retval; + } +@@ -846,6 +891,8 @@ static int aarch64_resume(struct target *target, int current, + int retval = 0; + uint64_t addr = address; + ++ LOG_DEBUG("%s", target_name(target)); ++ + struct armv8_common *armv8 = target_to_armv8(target); + armv8->last_run_control_op = ARMV8_RUNCONTROL_RESUME; + +@@ -959,6 +1006,11 @@ static int aarch64_debug_entry(struct target *target) + if (retval == ERROR_OK) + retval = mem_ap_read_atomic_u32(armv8->debug_ap, + armv8->debug_base + CPUV8_DBG_DSCR, &dscr); ++ ++ /* close the CTI gate for all events */ ++ if (retval == ERROR_OK) ++ retval = arm_cti_write_reg(armv8->cti, CTI_GATE, 0); ++ + if (retval == ERROR_OK) + retval = arm_cti_ack_events(armv8->cti, CTI_TRIG(HALT)); + +@@ -972,9 +1024,6 @@ static int aarch64_debug_entry(struct target *target) + armv8_select_opcodes(armv8, core_state == ARM_STATE_AARCH64); + armv8_select_reg_access(armv8, core_state == ARM_STATE_AARCH64); + +- /* close the CTI gate for all events */ +- if (retval == ERROR_OK) +- retval = arm_cti_write_reg(armv8->cti, CTI_GATE, 0); + /* discard async exceptions */ + if (retval == ERROR_OK) + retval = dpm->instr_cpsr_sync(dpm); +@@ -1100,6 +1149,8 @@ static int aarch64_step(struct target *target, int current, target_addr_t addres + int retval; + uint32_t edecr; + ++ LOG_DEBUG("%s", target_name(target)); ++ + armv8->last_run_control_op = ARMV8_RUNCONTROL_STEP; + + if (target->state != TARGET_HALTED) { +@@ -1135,11 +1186,26 @@ static int aarch64_step(struct target *target, int current, target_addr_t addres + } + } else { + /* +- * isolate current target so that it doesn't get resumed +- * together with the others ++ * Isolate current target so that it doesn't get resumed ++ * with the other SMP cores. + */ + retval = arm_cti_gate_channel(armv8->cti, 1); +- /* resume all other targets in the group */ ++ if (aarch64->cti_mode == AARCH64_CTIMODE_EXTEND) { ++ if (retval == ERROR_OK) ++ retval = arm_cti_gate_channel(armv8->cti, 0); ++ if (retval == ERROR_OK) ++ retval = arm_cti_ack_events(armv8->cti, CTI_TRIG(HALT)); ++ if (retval != ERROR_OK) { ++ LOG_ERROR("Failed to gate stepping target CTI"); ++ return retval; ++ } ++ } ++ /* For CTI legacy mode, aarch64_step_restart_smp restarts ++ * the other SMP cores prior to stepping the current core. ++ * CTI extended mode only fakes like this happened. To ++ * ensure tighter SMP coupling, the non-stepped SMP cores ++ * are CTI signaled to restart when the current core steps. ++ */ + if (retval == ERROR_OK) + retval = aarch64_step_restart_smp(target); + if (retval != ERROR_OK) { +@@ -1251,6 +1317,8 @@ static int aarch64_set_breakpoint(struct target *target, + struct armv8_common *armv8 = &aarch64->armv8_common; + struct aarch64_brp *brp_list = aarch64->brp_list; + ++ LOG_DEBUG("%s", target_name(target)); ++ + if (breakpoint->is_set) { + LOG_WARNING("breakpoint already set"); + return ERROR_OK; +@@ -1505,6 +1573,8 @@ static int aarch64_unset_breakpoint(struct target *target, struct breakpoint *br + struct armv8_common *armv8 = &aarch64->armv8_common; + struct aarch64_brp *brp_list = aarch64->brp_list; + ++ LOG_DEBUG("%s", target_name(target)); ++ + if (!breakpoint->is_set) { + LOG_WARNING("breakpoint not set"); + return ERROR_OK; +@@ -2792,6 +2862,7 @@ static int aarch64_init_arch_info(struct target *target, + + /* Setup struct aarch64_common */ + aarch64->common_magic = AARCH64_COMMON_MAGIC; ++ aarch64->cti_mode = AARCH64_CTIMODE_LEGACY; /* default to legacy */ + aarch64->isrmasking_mode = AARCH64_ISRMASK_ON; + aarch64->step_only_mode = AARCH64_STEPONLY_OFF; /* resume smp cpus while stepping single cpu */ + armv8->arm.dap = dap; +@@ -3087,6 +3158,53 @@ COMMAND_HANDLER(aarch64_step_only_command) + return ERROR_OK; + } + ++COMMAND_HANDLER(aarch64_cti_mode) ++{ ++ struct target *target = get_current_target(CMD_CTX); ++ struct target_list *head; ++ struct aarch64_common *aarch64 = target_to_aarch64(target); ++ struct armv8_common *armv8 = NULL; ++ ++ static const struct jim_nvp nvp_cti_mode[] = { ++ { .name = "legacy", .value = AARCH64_CTIMODE_LEGACY }, ++ { .name = "extend", .value = AARCH64_CTIMODE_EXTEND }, ++ { .name = NULL, .value = -1 }, ++ }; ++ const struct jim_nvp *n; ++ ++ if (CMD_ARGC > 0) { ++ int retval = ERROR_OK; ++ n = jim_nvp_name2value_simple(nvp_cti_mode, CMD_ARGV[0]); ++ if (!n->name) { ++ LOG_ERROR("Unknown parameter: %s - should be legacy or extend", CMD_ARGV[0]); ++ return ERROR_COMMAND_SYNTAX_ERROR; ++ } ++ foreach_smp_target(head, target->smp_targets) { ++ aarch64 = target_to_aarch64(head->target); ++ armv8 = target_to_armv8(head->target); ++ ++ aarch64->cti_mode = n->value; ++ retval = arm_cti_enable(armv8->cti, false); ++ ++ if (retval == ERROR_OK) ++ retval = aarch64_init_debug_access(head->target); ++ ++ if (retval == ERROR_OK) ++ retval = aarch64_poll(head->target); ++ ++ if (retval != ERROR_OK) { ++ LOG_ERROR("%s: debug access failure", __func__); ++ return retval; ++ } ++ } ++ } ++ ++ n = jim_nvp_value2name_simple(nvp_cti_mode, aarch64->cti_mode); ++ command_print(CMD, "aarch64 cti mode %s", n->name); ++ ++ return ERROR_OK; ++} ++ + COMMAND_HANDLER(aarch64_mcrmrc_command) + { + bool is_mcr = false; +@@ -3334,6 +3452,13 @@ static const struct command_registration aarch64_exec_command_handlers[] = { + .help = "display information about target caches", + .usage = "", + }, ++ { ++ .name = "cti", ++ .handler = aarch64_cti_mode, ++ .mode = COMMAND_ANY, ++ .help = "tighter coupling of smp core run/halt events", ++ .usage = "['legacy'|'extend']", ++ }, + { + .name = "dbginit", + .handler = aarch64_handle_dbginit_command, +diff --git a/src/target/aarch64.h b/src/target/aarch64.h +index 17e5f9cec..e34197e59 100644 +--- a/src/target/aarch64.h ++++ b/src/target/aarch64.h +@@ -35,6 +35,11 @@ enum aarch64_steponly_mode { + AARCH64_STEPONLY_ON, + }; + ++enum aarch64_cti_mode { ++ AARCH64_CTIMODE_LEGACY, ++ AARCH64_CTIMODE_EXTEND ++}; ++ + struct aarch64_brp { + int used; + int type; +@@ -66,6 +71,8 @@ struct aarch64_common { + enum aarch64_isrmasking_mode isrmasking_mode; + + enum aarch64_steponly_mode step_only_mode; ++ ++ enum aarch64_cti_mode cti_mode; + }; + + static inline struct aarch64_common * +-- +2.25.1 + diff --git a/patches/0016-target-armv8-enhanced-defer_examine-support.patch b/patches/0016-target-armv8-enhanced-defer_examine-support.patch new file mode 100644 index 000000000..0fe2b1ef8 --- /dev/null +++ b/patches/0016-target-armv8-enhanced-defer_examine-support.patch @@ -0,0 +1,47 @@ +From 6999de1b4bbf6da8e2503725be6d73a60aa6d980 Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Fri, 14 Jan 2022 11:45:15 -0500 +Subject: [PATCH 16/33] target/armv8: enhanced defer_examine support + +Allow user to put a target back into the defer-examine state +by executing the command " arp_examine allow-defer" +during a debug session. This can be useful if the user wants +to detach from the target when performing a custom reset sequence. + +Change-Id: I41d5a31d83f180a1e5665f66bce9cf145e21eedc +Signed-off-by: Daniel Goehring +--- + src/target/armv8_dpm.c | 4 ++++ + src/target/target.c | 1 + + 2 files changed, 5 insertions(+) + +diff --git a/src/target/armv8_dpm.c b/src/target/armv8_dpm.c +index 432d790c7..24b995181 100644 +--- a/src/target/armv8_dpm.c ++++ b/src/target/armv8_dpm.c +@@ -1633,6 +1633,10 @@ int armv8_dpm_setup(struct arm_dpm *dpm) + cache = armv8_build_reg_cache(target); + if (!cache) + return ERROR_FAIL; ++ } else { ++ /* If prior register cache exists, invalidate it */ ++ register_cache_invalidate(arm->core_cache); ++ register_cache_invalidate(arm->core_cache->next); + } + + /* coprocessor access setup */ +diff --git a/src/target/target.c b/src/target/target.c +index efc168903..f13f12cd6 100644 +--- a/src/target/target.c ++++ b/src/target/target.c +@@ -5272,6 +5272,7 @@ COMMAND_HANDLER(handle_target_examine) + } + + if (allow_defer && target->defer_examine) { ++ target_reset_examined(target); + LOG_INFO("Deferring arp_examine of %s", target_name(target)); + LOG_INFO("Use arp_examine command to examine it manually!"); + return ERROR_OK; +-- +2.25.1 + diff --git a/patches/0017-target-armv8-update-MPIDR-decoding.patch b/patches/0017-target-armv8-update-MPIDR-decoding.patch new file mode 100644 index 000000000..781adf2f1 --- /dev/null +++ b/patches/0017-target-armv8-update-MPIDR-decoding.patch @@ -0,0 +1,84 @@ +From 6301dce0c316857209b4685c780b9aa3c003b57b Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Tue, 18 Jan 2022 12:34:25 -0500 +Subject: [PATCH 17/33] target/armv8: update MPIDR decoding + +Update MPIDR decode to support the multithreading (MT) bit. +If detected, socket, cluster, core and multithread numbers +are displayed (affinity levels 0-3). + +Change-Id: I43569141fa0eef8ee8fc16c187a4af3c23e97db8 +Signed-off-by: Daniel Goehring +--- + src/target/armv8.c | 25 +++++++++++++++++-------- + src/target/armv8.h | 7 +++++-- + 2 files changed, 22 insertions(+), 10 deletions(-) + +diff --git a/src/target/armv8.c b/src/target/armv8.c +index 2b8ea6f32..142c40b6a 100644 +--- a/src/target/armv8.c ++++ b/src/target/armv8.c +@@ -801,7 +801,7 @@ int armv8_read_mpidr(struct armv8_common *armv8) + int retval = ERROR_FAIL; + struct arm *arm = &armv8->arm; + struct arm_dpm *dpm = armv8->arm.dpm; +- uint32_t mpidr; ++ uint64_t mpidr; + + retval = dpm->prepare(dpm); + if (retval != ERROR_OK) +@@ -814,17 +814,26 @@ int armv8_read_mpidr(struct armv8_common *armv8) + return retval; + } + +- retval = dpm->instr_read_data_r0(dpm, armv8_opcode(armv8, READ_REG_MPIDR), &mpidr); ++ retval = dpm->instr_read_data_r0_64(dpm, ARMV8_MRS(SYSTEM_MPIDR, 0), &mpidr); + if (retval != ERROR_OK) + goto done; + if (mpidr & 1U<<31) { + armv8->multi_processor_system = (mpidr >> 30) & 1; +- armv8->cluster_id = (mpidr >> 8) & 0xf; +- armv8->cpu_id = mpidr & 0x3; +- LOG_INFO("%s cluster %x core %x %s", target_name(armv8->arm.target), +- armv8->cluster_id, +- armv8->cpu_id, +- armv8->multi_processor_system == 0 ? "multi core" : "single core"); ++ armv8->aff3 = (mpidr >> 32) & 0xff; ++ armv8->aff2 = (mpidr >> 16) & 0xff; ++ armv8->aff1 = (mpidr >> 8) & 0xff; ++ armv8->aff0 = mpidr & 0xff; ++ armv8->mt = (mpidr >> 24) & 0x1; ++ if (armv8->mt) ++ LOG_INFO("%s socket 0x%02" PRIx32 " cluster 0x%02" PRIx32 " core 0x%02" PRIx32 ++ " thread 0x%02" PRIx32 " %s", target_name(armv8->arm.target), ++ armv8->aff3, armv8->aff2, armv8->aff1, armv8->aff0, ++ armv8->multi_processor_system == 0 ? "multi core" : "single core"); ++ else ++ LOG_INFO("%s cluster %x core %x %s", target_name(armv8->arm.target), ++ armv8->aff1, ++ armv8->aff0, ++ armv8->multi_processor_system == 0 ? "multi core" : "single core"); + } else + LOG_ERROR("mpidr not in multiprocessor format"); + +diff --git a/src/target/armv8.h b/src/target/armv8.h +index 5a52320b2..36ac9a46d 100644 +--- a/src/target/armv8.h ++++ b/src/target/armv8.h +@@ -199,8 +199,11 @@ struct armv8_common { + + /* mdir */ + uint8_t multi_processor_system; +- uint8_t cluster_id; +- uint8_t cpu_id; ++ uint8_t aff3; ++ uint8_t aff2; ++ uint8_t aff1; ++ uint8_t aff0; ++ uint8_t mt; + + /* armv8 aarch64 need below information for page translation */ + uint8_t va_size; +-- +2.25.1 + diff --git a/patches/0018-arm_adi_v5-add-ability-to-ignore-the-CDBGPWRUPACK-bi.patch b/patches/0018-arm_adi_v5-add-ability-to-ignore-the-CDBGPWRUPACK-bi.patch new file mode 100644 index 000000000..143d2998e --- /dev/null +++ b/patches/0018-arm_adi_v5-add-ability-to-ignore-the-CDBGPWRUPACK-bi.patch @@ -0,0 +1,106 @@ +From bb3cd4e4f9fa8b7c59ac8f8f4d2f039229fbaab8 Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Wed, 2 Feb 2022 17:45:13 -0800 +Subject: [PATCH 18/33] arm_adi_v5: add ability to ignore the CDBGPWRUPACK bit + +The CTRL/STAT register in the ARM DAP DP has a debug power up +ack bit and a system power up ack bit. To avoid having the +initial target examination fail due to a hardware bug +the user can now specify that this bit should be ignored. + +Change-Id: I1173b965e2c45c3f7025e8fb982c975b060698cf +Signed-off-by: Daniel Goehring +--- + src/target/adi_v5_jtag.c | 4 +++- + src/target/arm_adi_v5.c | 14 ++++++++------ + src/target/arm_adi_v5.h | 3 +++ + src/target/arm_dap.c | 5 +++++ + 4 files changed, 19 insertions(+), 7 deletions(-) + +diff --git a/src/target/adi_v5_jtag.c b/src/target/adi_v5_jtag.c +index 8d54a50fb..ae908a912 100644 +--- a/src/target/adi_v5_jtag.c ++++ b/src/target/adi_v5_jtag.c +@@ -670,7 +670,9 @@ static int jtagdp_transaction_endcheck(struct adiv5_dap *dap) + if (ctrlstat & SSTICKYERR) { + LOG_DEBUG("jtag-dp: CTRL/STAT 0x%" PRIx32, ctrlstat); + /* Check power to debug regions */ +- pwrmask = CDBGPWRUPREQ | CDBGPWRUPACK | CSYSPWRUPREQ; ++ pwrmask = CDBGPWRUPREQ | CSYSPWRUPREQ; ++ if (!dap->ignore_dbgpwrupack) ++ pwrmask |= CDBGPWRUPACK; + if (!dap->ignore_syspwrupack) + pwrmask |= CSYSPWRUPACK; + if ((ctrlstat & pwrmask) != pwrmask) { +diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c +index 9129acecf..40ebf585a 100644 +--- a/src/target/arm_adi_v5.c ++++ b/src/target/arm_adi_v5.c +@@ -812,12 +812,14 @@ int dap_dp_init(struct adiv5_dap *dap) + return retval; + + /* Check that we have debug power domains activated */ +- LOG_DEBUG("DAP: wait CDBGPWRUPACK"); +- retval = dap_dp_poll_register(dap, DP_CTRL_STAT, +- CDBGPWRUPACK, CDBGPWRUPACK, +- DAP_POWER_DOMAIN_TIMEOUT); +- if (retval != ERROR_OK) +- return retval; ++ if (!dap->ignore_dbgpwrupack) { ++ LOG_DEBUG("DAP: wait CDBGPWRUPACK"); ++ retval = dap_dp_poll_register(dap, DP_CTRL_STAT, ++ CDBGPWRUPACK, CDBGPWRUPACK, ++ DAP_POWER_DOMAIN_TIMEOUT); ++ if (retval != ERROR_OK) ++ return retval; ++ } + + if (!dap->ignore_syspwrupack) { + LOG_DEBUG("DAP: wait CSYSPWRUPACK"); +diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h +index 92c3dbc3a..44920cede 100644 +--- a/src/target/arm_adi_v5.h ++++ b/src/target/arm_adi_v5.h +@@ -413,6 +413,9 @@ struct adiv5_dap { + */ + bool do_reconnect; + ++ /** Flag saying whether to ignore the dbgpwrupack flag in DAP. */ ++ bool ignore_dbgpwrupack; ++ + /** Flag saying whether to ignore the syspwrupack flag in DAP. Some devices + * do not set this bit until later in the bringup sequence */ + bool ignore_syspwrupack; +diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c +index 9f4afae74..e73772eda 100644 +--- a/src/target/arm_dap.c ++++ b/src/target/arm_dap.c +@@ -180,6 +180,7 @@ int dap_cleanup_all(void) + + enum dap_cfg_param { + CFG_CHAIN_POSITION, ++ CFG_IGNORE_DBGPWRUPACK, + CFG_IGNORE_SYSPWRUPACK, + CFG_DP_ID, + CFG_INSTANCE_ID, +@@ -189,6 +190,7 @@ enum dap_cfg_param { + + static const struct jim_nvp nvp_config_opts[] = { + { .name = "-chain-position", .value = CFG_CHAIN_POSITION }, ++ { .name = "-ignore-dbgpwrupack", .value = CFG_IGNORE_DBGPWRUPACK }, + { .name = "-ignore-syspwrupack", .value = CFG_IGNORE_SYSPWRUPACK }, + { .name = "-dp-id", .value = CFG_DP_ID }, + { .name = "-instance-id", .value = CFG_INSTANCE_ID }, +@@ -228,6 +230,9 @@ static int dap_configure(struct jim_getopt_info *goi, struct arm_dap_object *dap + /* loop for more */ + break; + } ++ case CFG_IGNORE_DBGPWRUPACK: ++ dap->dap.ignore_dbgpwrupack = true; ++ break; + case CFG_IGNORE_SYSPWRUPACK: + dap->dap.ignore_syspwrupack = true; + break; +-- +2.25.1 + diff --git a/patches/0019-aarch64-BP-count-enable-feature-DO-NOT-UPSTREAM.patch b/patches/0019-aarch64-BP-count-enable-feature-DO-NOT-UPSTREAM.patch new file mode 100644 index 000000000..38b5ca2b2 --- /dev/null +++ b/patches/0019-aarch64-BP-count-enable-feature-DO-NOT-UPSTREAM.patch @@ -0,0 +1,164 @@ +From 9f022ea895ce8b7340cc81db6f71b6387f1c7964 Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Thu, 28 Jul 2022 19:06:19 -0600 +Subject: [PATCH 19/33] aarch64: BP count enable feature [DO NOT UPSTREAM] + +Add support for Ampere's implementation defined HW BP count enable +feature. + +Change-Id: I4ac2057802fcbb97a0a33e0fcda0a0601ce5e95a +Signed-off-by: Daniel Goehring +--- + src/openocd.c | 2 ++ + src/target/aarch64.c | 44 ++++++++++++++++++++++++++++++++++++++++---- + src/target/aarch64.h | 9 +++++++++ + 3 files changed, 51 insertions(+), 4 deletions(-) + +diff --git a/src/openocd.c b/src/openocd.c +index 54c5eb34f..088c881d7 100644 +--- a/src/openocd.c ++++ b/src/openocd.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -256,6 +257,7 @@ static struct command_context *setup_command_handler(Jim_Interp *interp) + &cti_register_commands, + &dap_register_commands, + &arm_tpiu_swo_register_commands, ++ &impdef_register_commands, + NULL + }; + for (unsigned i = 0; command_registrants[i]; i++) { +diff --git a/src/target/aarch64.c b/src/target/aarch64.c +index a2b588c0a..a608cb17a 100644 +--- a/src/target/aarch64.c ++++ b/src/target/aarch64.c +@@ -25,6 +25,8 @@ + #include + #include + ++static enum aarch64_bpcnt_mode bpcnt_mode = AARCH64_BPCNT_OFF; ++ + enum restart_mode { + RESTART_LAZY, + RESTART_SYNC, +@@ -2784,13 +2786,17 @@ static int aarch64_examine_first(struct target *target) + + armv8->cti = pc->cti; + +- retval = aarch64_dpm_setup(aarch64, debug); +- if (retval != ERROR_OK) +- return retval; +- + /* Setup Breakpoint Register Pairs */ + aarch64->brp_num = (uint32_t)((debug >> 12) & 0x0F) + 1; + aarch64->brp_num_context = (uint32_t)((debug >> 28) & 0x0F) + 1; ++ if (aarch64->bpcnt_mode == AARCH64_BPCNT_ON) { ++ /* Reserve upper two breakpoints for implementation defined feature */ ++ aarch64->brp_num -= 2; ++ if (aarch64->brp_num_context == 1) ++ aarch64->brp_num_context = 0; ++ else ++ aarch64->brp_num_context -= 2; ++ } + aarch64->brp_num_available = aarch64->brp_num; + aarch64->brp_list = calloc(aarch64->brp_num, sizeof(struct aarch64_brp)); + for (i = 0; i < aarch64->brp_num; i++) { +@@ -2816,6 +2822,12 @@ static int aarch64_examine_first(struct target *target) + aarch64->wp_list[i].brpn = i; + } + ++ debug = (debug & ~0x0000F000ULL) | ((aarch64->brp_num - 1) << 12); ++ debug = (debug & ~0x00F00000ULL) | ((aarch64->wp_num - 1) << 20); ++ retval = aarch64_dpm_setup(aarch64, debug); ++ if (retval != ERROR_OK) ++ return retval; ++ + LOG_DEBUG("Configured %i hw breakpoints, %i watchpoints", + aarch64->brp_num, aarch64->wp_num); + +@@ -2865,6 +2877,7 @@ static int aarch64_init_arch_info(struct target *target, + aarch64->cti_mode = AARCH64_CTIMODE_LEGACY; /* default to legacy */ + aarch64->isrmasking_mode = AARCH64_ISRMASK_ON; + aarch64->step_only_mode = AARCH64_STEPONLY_OFF; /* resume smp cpus while stepping single cpu */ ++ aarch64->bpcnt_mode = bpcnt_mode; + armv8->arm.dap = dap; + + /* register arch-specific functions */ +@@ -3205,6 +3218,13 @@ COMMAND_HANDLER(aarch64_cti_mode) + return ERROR_OK; + } + ++COMMAND_HANDLER(aarch64_bpcnt_command) ++{ ++ bpcnt_mode = AARCH64_BPCNT_ON; ++ ++ return ERROR_OK; ++} ++ + COMMAND_HANDLER(aarch64_mcrmrc_command) + { + bool is_mcr = false; +@@ -3544,6 +3564,22 @@ static const struct command_registration aarch64_command_handlers[] = { + COMMAND_REGISTRATION_DONE + }; + ++static const struct command_registration aarch64_bpcnt_handler[] = { ++ { ++ .name = "bkpt_cnt", ++ .mode = COMMAND_CONFIG, ++ .help = "Enable Ampere implementation defined feature", ++ .usage = "", ++ .handler = aarch64_bpcnt_command, ++ }, ++ COMMAND_REGISTRATION_DONE ++}; ++ ++int impdef_register_commands(struct command_context *cmd_ctx) ++{ ++ return register_commands(cmd_ctx, NULL, aarch64_bpcnt_handler); ++} ++ + struct target_type aarch64_target = { + .name = "aarch64", + +diff --git a/src/target/aarch64.h b/src/target/aarch64.h +index e34197e59..0f9814d00 100644 +--- a/src/target/aarch64.h ++++ b/src/target/aarch64.h +@@ -40,6 +40,11 @@ enum aarch64_cti_mode { + AARCH64_CTIMODE_EXTEND + }; + ++enum aarch64_bpcnt_mode { ++ AARCH64_BPCNT_OFF, ++ AARCH64_BPCNT_ON, ++}; ++ + struct aarch64_brp { + int used; + int type; +@@ -73,6 +78,8 @@ struct aarch64_common { + enum aarch64_steponly_mode step_only_mode; + + enum aarch64_cti_mode cti_mode; ++ ++ enum aarch64_bpcnt_mode bpcnt_mode; + }; + + static inline struct aarch64_common * +@@ -81,4 +88,6 @@ target_to_aarch64(struct target *target) + return container_of(target->arch_info, struct aarch64_common, armv8_common.arm); + } + ++int impdef_register_commands(struct command_context *cmd_ctx); ++ + #endif /* OPENOCD_TARGET_AARCH64_H */ +-- +2.25.1 + diff --git a/patches/0020-aarch64-WP-count-enable-feature-DO-NOT-UPSTREAM.patch b/patches/0020-aarch64-WP-count-enable-feature-DO-NOT-UPSTREAM.patch new file mode 100644 index 000000000..2d61f920d --- /dev/null +++ b/patches/0020-aarch64-WP-count-enable-feature-DO-NOT-UPSTREAM.patch @@ -0,0 +1,126 @@ +From e670f73d7c31b667d6b7bf3bd00a359ac39c362c Mon Sep 17 00:00:00 2001 +From: Madhuri Murthy +Date: Thu, 29 Jun 2023 16:36:48 -0600 +Subject: [PATCH 20/33] aarch64: WP count enable feature [DO NOT UPSTREAM] + +Add support for Ampere's implementation defined HW WP count enable +feature. + +Change-Id: Ib951d69e5b33525924b0269dbc153d3db1545740 +Signed-off-by: Madhuri Murthy +Signed-off-by: Daniel Goehring +--- + src/target/aarch64.c | 30 +++++++++++++++++++++++++++--- + src/target/aarch64.h | 7 +++++++ + 2 files changed, 34 insertions(+), 3 deletions(-) + +diff --git a/src/target/aarch64.c b/src/target/aarch64.c +index a608cb17a..afef001c8 100644 +--- a/src/target/aarch64.c ++++ b/src/target/aarch64.c +@@ -26,6 +26,7 @@ + #include + + static enum aarch64_bpcnt_mode bpcnt_mode = AARCH64_BPCNT_OFF; ++static enum aarch64_wpcnt_mode wpcnt_mode = AARCH64_WPCNT_OFF; + + enum restart_mode { + RESTART_LAZY, +@@ -2812,6 +2813,10 @@ static int aarch64_examine_first(struct target *target) + + /* Setup Watchpoint Register Pairs */ + aarch64->wp_num = (uint32_t)((debug >> 20) & 0x0F) + 1; ++ if (aarch64->wpcnt_mode == AARCH64_WPCNT_ON) { ++ /* Reserve upper two watchpoints for implementation defined feature */ ++ aarch64->wp_num -= 2; ++ } + aarch64->wp_num_available = aarch64->wp_num; + aarch64->wp_list = calloc(aarch64->wp_num, sizeof(struct aarch64_brp)); + for (i = 0; i < aarch64->wp_num; i++) { +@@ -2878,6 +2883,7 @@ static int aarch64_init_arch_info(struct target *target, + aarch64->isrmasking_mode = AARCH64_ISRMASK_ON; + aarch64->step_only_mode = AARCH64_STEPONLY_OFF; /* resume smp cpus while stepping single cpu */ + aarch64->bpcnt_mode = bpcnt_mode; ++ aarch64->wpcnt_mode = wpcnt_mode; + armv8->arm.dap = dap; + + /* register arch-specific functions */ +@@ -3225,6 +3231,13 @@ COMMAND_HANDLER(aarch64_bpcnt_command) + return ERROR_OK; + } + ++COMMAND_HANDLER(aarch64_wpcnt_command) ++{ ++ wpcnt_mode = AARCH64_WPCNT_ON; ++ ++ return ERROR_OK; ++} ++ + COMMAND_HANDLER(aarch64_mcrmrc_command) + { + bool is_mcr = false; +@@ -3564,22 +3577,33 @@ static const struct command_registration aarch64_command_handlers[] = { + COMMAND_REGISTRATION_DONE + }; + +-static const struct command_registration aarch64_bpcnt_handler[] = { ++static const struct command_registration aarch64_bpwpcnt_handler[] = { + { +- .name = "bkpt_cnt", ++ .name = "bp_cnt", + .mode = COMMAND_CONFIG, + .help = "Enable Ampere implementation defined feature", + .usage = "", + .handler = aarch64_bpcnt_command, + }, ++ ++ { ++ .name = "wp_cnt", ++ .mode = COMMAND_CONFIG, ++ .help = "Enable Ampere implementation defined feature", ++ .usage = "", ++ .handler = aarch64_wpcnt_command, ++ }, ++ + COMMAND_REGISTRATION_DONE + }; + + int impdef_register_commands(struct command_context *cmd_ctx) + { +- return register_commands(cmd_ctx, NULL, aarch64_bpcnt_handler); ++ return register_commands(cmd_ctx, NULL, aarch64_bpwpcnt_handler); + } + ++ ++ + struct target_type aarch64_target = { + .name = "aarch64", + +diff --git a/src/target/aarch64.h b/src/target/aarch64.h +index 0f9814d00..68920a35a 100644 +--- a/src/target/aarch64.h ++++ b/src/target/aarch64.h +@@ -45,6 +45,11 @@ enum aarch64_bpcnt_mode { + AARCH64_BPCNT_ON, + }; + ++enum aarch64_wpcnt_mode { ++ AARCH64_WPCNT_OFF, ++ AARCH64_WPCNT_ON, ++}; ++ + struct aarch64_brp { + int used; + int type; +@@ -80,6 +85,8 @@ struct aarch64_common { + enum aarch64_cti_mode cti_mode; + + enum aarch64_bpcnt_mode bpcnt_mode; ++ ++ enum aarch64_wpcnt_mode wpcnt_mode; + }; + + static inline struct aarch64_common * +-- +2.25.1 + diff --git a/patches/0021-N1SDP-Arm-N1SDP-configs.patch b/patches/0021-N1SDP-Arm-N1SDP-configs.patch new file mode 100644 index 000000000..4f4857be7 --- /dev/null +++ b/patches/0021-N1SDP-Arm-N1SDP-configs.patch @@ -0,0 +1,234 @@ +From cb7adf8b2fc4058b16543039fd7e9bf6f23a73e9 Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Wed, 1 Apr 2020 15:50:19 -0400 +Subject: [PATCH 21/33] N1SDP: Arm N1SDP configs + +Add board and target configuration files for +Arm Dawn N1SDP board and N1 processor. + +Tested on an Arm Dawn N1SDP development platform + +Change-Id: I060db53d465404c3dafadd4e0d1f284bb69f2301 +Signed-off-by: Daniel Goehring +--- + tcl/board/arm_n1sdp.cfg | 40 ++++++++++ + tcl/target/arm_n1.cfg | 160 ++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 200 insertions(+) + create mode 100644 tcl/board/arm_n1sdp.cfg + create mode 100644 tcl/target/arm_n1.cfg + +diff --git a/tcl/board/arm_n1sdp.cfg b/tcl/board/arm_n1sdp.cfg +new file mode 100644 +index 000000000..a5a730932 +--- /dev/null ++++ b/tcl/board/arm_n1sdp.cfg +@@ -0,0 +1,40 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# OpenOCD Board Configuration for Arm Neoverse N1 SDP ++# ++# Copyright (c) 2019-2020, Ampere Computing LLC ++# ++# 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; ++# ++# ++ ++# ++# Configure JTAG speed ++# ++ ++adapter speed 1000 ++ ++# ++# Configure Resets ++# ++ ++adapter srst delay 200 ++jtag_ntrst_delay 100 ++reset_config trst_and_srst separate srst_open_drain ++ ++# ++# Configure Targets ++# ++ ++source [find target/arm_n1.cfg] +diff --git a/tcl/target/arm_n1.cfg b/tcl/target/arm_n1.cfg +new file mode 100644 +index 000000000..b9d4e3976 +--- /dev/null ++++ b/tcl/target/arm_n1.cfg +@@ -0,0 +1,160 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# OpenOCD Target Configuration for ARM Neoverse N1 Processor ++# ++# Copyright (c) 2019-2020, Ampere Computing LLC ++# ++# 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; ++# ++# ++ ++# ++# Configure defaults for target ++# These settings can be overridden in the board configuration file ++# ++ ++if { [info exists CHIPNAME] } { ++ set _CHIPNAME ${CHIPNAME} ++} else { ++ set _CHIPNAME n1soc ++} ++ ++if { [info exists NUMCLUSTERS] } { ++ set _NUMCLUSTERS ${NUMCLUSTERS} ++} else { ++ set _NUMCLUSTERS 2 ++} ++ ++if { [info exists NUMCORESPERCLUSTER] } { ++ set _NUMCORESPERCLUSTER ${NUMCORESPERCLUSTER} ++} else { ++ set _NUMCORESPERCLUSTER 2 ++} ++ ++if { [info exists ENDIAN] } { ++ set _ENDIAN ${ENDIAN} ++} else { ++ set _ENDIAN little ++} ++ ++if { [info exists CPUTAPID ] } { ++ set _CPUTAPID ${CPUTAPID} ++} else { ++ set _CPUTAPID 0x6BA00477 ++} ++ ++# ++# Configure JTAG TAP ++# ++ ++jtag newtap ${_CHIPNAME} m7 -irlen 4 -ircapture 0x1 -irmask 0x3 -expected-id $_CPUTAPID ++set _TAPNAME0 ${_CHIPNAME}.m7 ++ ++jtag newtap ${_CHIPNAME} n1 -irlen 4 -ircapture 0x1 -irmask 0x3 -expected-id $_CPUTAPID ++set _TAPNAME1 ${_CHIPNAME}.n1 ++ ++set _DAPNAME0 ${_CHIPNAME}_m7.dap ++set _DAPNAME1 ${_CHIPNAME}_n1.dap ++ ++# M7 CPUs ++set _APNUM_M7_0 0 ++set _APNUM_M7_1 1 ++#dap create ${_DAPNAME0} -v6 -chain-position ${_TAPNAME0} ++dap create ${_DAPNAME0} -chain-position ${_TAPNAME0} ++ ++# N1 CPUs ++set _APNUM_ARES 0 ++#dap create ${_DAPNAME1} -v6 -chain-position ${_TAPNAME1} ++dap create ${_DAPNAME1} -chain-position ${_TAPNAME1} ++#${_DAPNAME1} apsel ${_APNUM_ARES} ++ ++# Create the DAP0 AP0 AHB-AP MEM-AP target for the first M7 instance ++target create AHB0 mem_ap -endian $_ENDIAN -dap ${_DAPNAME0} -ap-num 0 ++ ++# Create the DAP0 AP1 AHB-AP MEM-AP target for the second M7 instance ++target create AHB1 mem_ap -endian $_ENDIAN -dap ${_DAPNAME0} -ap-num 1 ++ ++# ARM M7 core setup ++# Configure which TAP to use ++ ++# Create the M7 SCP target ++set _SMP_STR "target smp" ++set _TARGETNAME ${_TAPNAME0}_0 ++eval [format "target create ${_TARGETNAME} cortex_m -endian $_ENDIAN -dap ${_DAPNAME0} -ap-num ${_APNUM_M7_0} -dbgbase 0x%08X -rtos hwthread -coreid 0" [expr 0xE000ED00]] ++puts [format "target create ${_TARGETNAME} cortex_m -endian $_ENDIAN -dap ${_DAPNAME0} -ap-num ${_APNUM_M7_0} -dbgbase 0x%08X -rtos hwthread -coreid 0" [expr 0xE000ED00]] ++set _SMP_STR "${_SMP_STR} ${_TARGETNAME}" ++ ++# Create the M7 MCP target ++set _TARGETNAME ${_TAPNAME0}_1 ++eval [format "target create ${_TARGETNAME} cortex_m -endian $_ENDIAN -dap ${_DAPNAME0} -ap-num ${_APNUM_M7_1} -dbgbase 0x%08X -rtos hwthread -coreid 1" [expr 0xE000ED00]] ++puts [format "target create ${_TARGETNAME} cortex_m -endian $_ENDIAN -dap ${_DAPNAME0} -ap-num ${_APNUM_M7_1} -dbgbase 0x%08X -rtos hwthread -coreid 1" [expr 0xE000ED00]] ++set _SMP_STR "${_SMP_STR} ${_TARGETNAME}" ++ ++eval ${_SMP_STR} ++ ++# Create the DAP1 AP0 APB-AP MEM-AP target for the N1 cores ++target create APB mem_ap -endian $_ENDIAN -dap ${_DAPNAME1} -ap-num 0 ++ ++# Create the DAP1 AP1 AXI-AP MEM-AP target for the N1 cores ++target create AXI mem_ap -endian $_ENDIAN -dap ${_DAPNAME1} -ap-num 1 ++ ++# ++# Configure target CPUs ++# ++ ++# Build string used to enable smp mode ++set _SMP_STR "target smp" ++ ++set _index 0 ++for {set _i 0} {$_i < $_NUMCLUSTERS} {incr _i} { ++ for {set _j 0} {$_j < $_NUMCORESPERCLUSTER} {incr _j} { ++ # Configure which TAP to use ++ eval [format "set _TARGETNAME ${_TAPNAME1}_%02d" $_index] ++ ++ # Create and configure Cross Trigger Interface (CTI) - required for halt and resume ++ set _CTINAME ${_TARGETNAME}.cti ++ eval [format "cti create ${_CTINAME} -dap ${_DAPNAME1} -ap-num ${_APNUM_ARES} -baseaddr 0x%08X" [expr 0x82020000 + ($_i << 24) + ($_j << 20)]] ++ puts [format "cti create ${_CTINAME} -dap ${_DAPNAME1} -ap-num ${_APNUM_ARES} -baseaddr 0x%08X" [expr 0x82020000 + ($_i << 24) + ($_j << 20)]] ++ ++ # Create the target ++ eval [format "target create ${_TARGETNAME} aarch64 -endian $_ENDIAN -dap ${_DAPNAME1} -ap-num ${_APNUM_ARES} -dbgbase 0x%08X -rtos hwthread -cti ${_CTINAME} -coreid %d" [expr 0x82010000 + ($_i << 24) + ($_j << 20)] $_index] ++ puts [format "target create ${_TARGETNAME} aarch64 -endian $_ENDIAN -dap ${_DAPNAME1} -ap-num ${_APNUM_ARES} -dbgbase 0x%08X -rtos hwthread -cti ${_CTINAME} -coreid %d" [expr 0x82010000 + ($_i << 24) + ($_j << 20)] $_index] ++ set _SMP_STR "${_SMP_STR} ${_TARGETNAME}" ++ ++ # Clear CTI output/input enables that are not configured by OpenOCD for aarch64 ++ ${_TARGETNAME} configure -event reset-init [subst { ++ ${_CTINAME} write INEN0 0x00000000 ++ ${_CTINAME} write INEN1 0x00000000 ++ ${_CTINAME} write INEN2 0x00000000 ++ ${_CTINAME} write INEN3 0x00000000 ++ ${_CTINAME} write INEN4 0x00000000 ++ ${_CTINAME} write INEN5 0x00000000 ++ ${_CTINAME} write INEN6 0x00000000 ++ ${_CTINAME} write INEN7 0x00000000 ++ ${_CTINAME} write INEN8 0x00000000 ++ ++ ${_CTINAME} write OUTEN2 0x00000000 ++ ${_CTINAME} write OUTEN3 0x00000000 ++ ${_CTINAME} write OUTEN4 0x00000000 ++ ${_CTINAME} write OUTEN5 0x00000000 ++ ${_CTINAME} write OUTEN6 0x00000000 ++ ${_CTINAME} write OUTEN7 0x00000000 ++ ${_CTINAME} write OUTEN8 0x00000000 ++ }] ++ ++ incr _index ++ } ++} ++ ++eval ${_SMP_STR} +-- +2.25.1 + diff --git a/patches/0022-N1SDP-Arm-N1SDP-user-configs-DO-NOT-UPSTREAM.patch b/patches/0022-N1SDP-Arm-N1SDP-user-configs-DO-NOT-UPSTREAM.patch new file mode 100644 index 000000000..524589d9d --- /dev/null +++ b/patches/0022-N1SDP-Arm-N1SDP-user-configs-DO-NOT-UPSTREAM.patch @@ -0,0 +1,49 @@ +From af68c26a8b244ef15b3a3e1a2b7a100a3580e59c Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Thu, 16 Apr 2020 15:29:30 -0400 +Subject: [PATCH 22/33] N1SDP: Arm N1SDP user configs [DO NOT UPSTREAM] + +Add user configuration file for ARM Neoverse N1. +Configured for the Olimex ARM-USB-OCD-H JTAG probe. + +https://www.olimex.com/Products/ARM/JTAG/ARM-USB-OCD-H/ + +Tested on ARM Neoverse N1 Development Platform + +Change-Id: I0a39727e5c3be6c0c5df6230dcc8d5b467da5f28 +Signed-off-by: Daniel Goehring +--- + tcl/openocd.n1sdp.cfg | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + create mode 100644 tcl/openocd.n1sdp.cfg + +diff --git a/tcl/openocd.n1sdp.cfg b/tcl/openocd.n1sdp.cfg +new file mode 100644 +index 000000000..15819d1da +--- /dev/null ++++ b/tcl/openocd.n1sdp.cfg +@@ -0,0 +1,21 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for ARM Neoverse N1 Development Platform ++# ++# Copyright (c) 2019-2023, Ampere Computing LLC ++# ++ ++bindto 0.0.0.0 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] ++ ++ ++# ++# Board (Platform) Configuration ++# ++ ++source [find board/arm_n1sdp.cfg] +-- +2.25.1 + diff --git a/patches/0023-eMAG-Ampere-eMAG-user-configs-DO-NOT-UPSTREAM.patch b/patches/0023-eMAG-Ampere-eMAG-user-configs-DO-NOT-UPSTREAM.patch new file mode 100644 index 000000000..8b420d785 --- /dev/null +++ b/patches/0023-eMAG-Ampere-eMAG-user-configs-DO-NOT-UPSTREAM.patch @@ -0,0 +1,49 @@ +From dca0eac2dc32f35189953476e5ca1d260e77b5de Mon Sep 17 00:00:00 2001 +From: Anthony Ferranti +Date: Thu, 16 Apr 2020 15:21:14 -0400 +Subject: [PATCH 23/33] eMAG: Ampere eMAG user configs [DO NOT UPSTREAM] + +Add user configuration file for Ampere eMAG8180. +Configured for the Olimex ARM-USB-OCD-H JTAG probe. + +https://www.olimex.com/Products/ARM/JTAG/ARM-USB-OCD-H/ + +Tested on Ampere eMAG8180 Development Platform + +Change-Id: I3a31abeee8b73d4704f43bd2d9e1441e369913af +Signed-off-by: Anthony Ferranti +Signed-off-by: Daniel Goehring +--- + tcl/openocd.emag8180.cfg | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + create mode 100644 tcl/openocd.emag8180.cfg + +diff --git a/tcl/openocd.emag8180.cfg b/tcl/openocd.emag8180.cfg +new file mode 100644 +index 000000000..c841d1c85 +--- /dev/null ++++ b/tcl/openocd.emag8180.cfg +@@ -0,0 +1,20 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for eMAG Development Platform ++# ++# Copyright (c) 2019-2023, Ampere Computing LLC ++# ++ ++bindto 0.0.0.0 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++source [find board/ampere_emag8180.cfg] +-- +2.25.1 + diff --git a/patches/0024-QS-MQ-target-board-Ampere-QS-MQ-boundary-scan-config.patch b/patches/0024-QS-MQ-target-board-Ampere-QS-MQ-boundary-scan-config.patch new file mode 100644 index 000000000..0a61d96a7 --- /dev/null +++ b/patches/0024-QS-MQ-target-board-Ampere-QS-MQ-boundary-scan-config.patch @@ -0,0 +1,183 @@ +From 1d25fc0c887a38165f8f4f15f2cd44d456bb4201 Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Fri, 3 Apr 2020 19:45:29 -0400 +Subject: [PATCH 24/33] QS|MQ: target/board: Ampere QS|MQ boundary-scan configs + [DO NOT UPSTREAM] + +Add Ampere Altra and Ampere Altra Max +target/board boundary-scan configuration files. + +The target configuration file supports silicon and emulation. +The board configuration files support 1 and 2 socket platforms. + +Tested on Ampere Altra and Ampere Altra Max silicon + +Change-Id: Ib1b841c8dcb1c529ebf343c64732dc41d805eb89 +Signed-off-by: Daniel Goehring +--- + tcl/board/ampere_qs_mq_1s_bs.cfg | 52 ++++++++++++++++++++++++++++++ + tcl/board/ampere_qs_mq_2s_bs.cfg | 55 ++++++++++++++++++++++++++++++++ + tcl/target/ampere_qs_mq_bs.cfg | 30 +++++++++++++++++ + 3 files changed, 137 insertions(+) + create mode 100644 tcl/board/ampere_qs_mq_1s_bs.cfg + create mode 100644 tcl/board/ampere_qs_mq_2s_bs.cfg + create mode 100644 tcl/target/ampere_qs_mq_bs.cfg + +diff --git a/tcl/board/ampere_qs_mq_1s_bs.cfg b/tcl/board/ampere_qs_mq_1s_bs.cfg +new file mode 100644 +index 000000000..6f2791475 +--- /dev/null ++++ b/tcl/board/ampere_qs_mq_1s_bs.cfg +@@ -0,0 +1,52 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# OpenOCD Board Configuration for Ampere Altra and ++# Ampere Altra Max processors ++# ++# Copyright (c) 2019-2023, Ampere Computing LLC ++# ++ ++# Argument Description ++# ++# JTAGFREQ ++# Set the JTAG clock frequency ++# Syntax: -c "set JTAGFREQ {freq_in_khz}" ++# ++# SYSNAME ++# Set the system name ++# If not specified, defaults to "qs" ++# Syntax: -c "set SYSNAME {qs}" ++ ++# ++# Configure JTAG speed ++# ++ ++if { [info exists JTAGFREQ] } { ++ adapter speed $JTAGFREQ ++} else { ++ adapter speed 100 ++} ++ ++# ++# Set the system name ++# ++ ++if { [info exists SYSNAME] } { ++ set _SYSNAME $SYSNAME ++} else { ++ set _SYSNAME qs ++} ++ ++# ++# Configure Resets ++# ++ ++jtag_ntrst_delay 100 ++reset_config trst_only ++ ++# ++# Configure Targets ++# ++ ++set CHIPNAME ${_SYSNAME}0 ++source [find target/ampere_qs_mq_bs.cfg] +diff --git a/tcl/board/ampere_qs_mq_2s_bs.cfg b/tcl/board/ampere_qs_mq_2s_bs.cfg +new file mode 100644 +index 000000000..518208977 +--- /dev/null ++++ b/tcl/board/ampere_qs_mq_2s_bs.cfg +@@ -0,0 +1,55 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# OpenOCD Board Configuration for Ampere Altra and ++# Ampere Altra Max processors ++# ++# Copyright (c) 2019-2023, Ampere Computing LLC ++# ++ ++# Argument Description ++# ++# JTAGFREQ ++# Set the JTAG clock frequency ++# Syntax: -c "set JTAGFREQ {freq_in_khz}" ++# ++# SYSNAME ++# Set the system name ++# If not specified, defaults to "qs" ++# Syntax: -c "set SYSNAME {qs}" ++ ++# ++# Configure JTAG speed ++# ++ ++if { [info exists JTAGFREQ] } { ++ adapter speed $JTAGFREQ ++} else { ++ adapter speed 100 ++} ++ ++# ++# Set the system name ++# ++ ++if { [info exists SYSNAME] } { ++ set _SYSNAME $SYSNAME ++} else { ++ set _SYSNAME qs ++} ++ ++# ++# Configure Resets ++# ++ ++jtag_ntrst_delay 100 ++reset_config trst_only ++ ++# ++# Configure Targets ++# ++ ++set CHIPNAME ${_SYSNAME}1 ++source [find target/ampere_qs_mq_bs.cfg] ++ ++set CHIPNAME ${_SYSNAME}0 ++source [find target/ampere_qs_mq_bs.cfg] +diff --git a/tcl/target/ampere_qs_mq_bs.cfg b/tcl/target/ampere_qs_mq_bs.cfg +new file mode 100644 +index 000000000..432fdc02e +--- /dev/null ++++ b/tcl/target/ampere_qs_mq_bs.cfg +@@ -0,0 +1,30 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# OpenOCD Target Configuration for Ampere Altra and ++# Ampere Altra Max processors ++# ++# Copyright (c) 2019-2023, Ampere Computing LLC ++# ++ ++# ++# Configure defaults for target ++# These settings can be overridden in the board configuration file ++# ++ ++if { [info exists CHIPNAME] } { ++ set _CHIPNAME $CHIPNAME ++} else { ++ set _CHIPNAME qs ++} ++ ++if { [info exists SOC_TAPID] } { ++ set _SOC_TAPID $SOC_TAPID ++} else { ++ set _SOC_TAPID 0x11080a2d ++} ++ ++# ++# Configure JTAG TAPs ++# ++ ++jtag newtap $_CHIPNAME soc.bs -irlen 8 -ircapture 0x1 -irmask 0x3 -expected-id $_SOC_TAPID +-- +2.25.1 + diff --git a/patches/0025-QS-MQ-silicon-user-configs-DO-NOT-UPSTREAM.patch b/patches/0025-QS-MQ-silicon-user-configs-DO-NOT-UPSTREAM.patch new file mode 100644 index 000000000..b8f1d297c --- /dev/null +++ b/patches/0025-QS-MQ-silicon-user-configs-DO-NOT-UPSTREAM.patch @@ -0,0 +1,371 @@ +From 2da28f649b2b83ffaee5d8e8bd3fda7a3354a1e5 Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Thu, 16 Apr 2020 15:51:53 -0400 +Subject: [PATCH 25/33] QS|MQ: silicon user configs [DO NOT UPSTREAM] + +Add user configuration files for Ampere Altra +and Ampere Altra Max silicon. + +Configured for the Olimex ARM-USB-OCD_H JTAG probe. +https://www.olimex.com/Products/ARM/JTAG/ARM-USB-OCD-H/ + +OpenOCD configured for the Ampere Altra and Ampere Altra Max options +1. One and two socket platforms + +Tested on the following system platforms +* Ampere Fansipan and Mt. Jade servers + +Change-Id: Iad136db2afc0dee985ffaa43809fb6ff756fead6 +Signed-off-by: Daniel Goehring +--- + tcl/openocd.mq_1s_sil.cfg | 75 +++++++++++++++++++++++++++++++++++ + tcl/openocd.mq_2s_sil.cfg | 83 +++++++++++++++++++++++++++++++++++++++ + tcl/openocd.qs_1s_sil.cfg | 74 ++++++++++++++++++++++++++++++++++ + tcl/openocd.qs_2s_sil.cfg | 82 ++++++++++++++++++++++++++++++++++++++ + 4 files changed, 314 insertions(+) + create mode 100644 tcl/openocd.mq_1s_sil.cfg + create mode 100644 tcl/openocd.mq_2s_sil.cfg + create mode 100644 tcl/openocd.qs_1s_sil.cfg + create mode 100644 tcl/openocd.qs_2s_sil.cfg + +diff --git a/tcl/openocd.mq_1s_sil.cfg b/tcl/openocd.mq_1s_sil.cfg +new file mode 100644 +index 000000000..8913b51ac +--- /dev/null ++++ b/tcl/openocd.mq_1s_sil.cfg +@@ -0,0 +1,75 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the Ampere Altra Max ++# Development Platform ++# ++# Copyright (c) 2020-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "5000" kHz ++# Syntax: -c "set JTAGFREQ {5000}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "mq" ++# Syntax: -c "set SYSNAME {mq}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0 ++# Specify available physical cores by number ++# Example syntax to connect to physical cores 16 and 17 for S0 ++# Syntax: -c "set CORELIST_S0 {16 17}" ++# ++# COREMASK_S0_LO ++# Specify available physical cores 0-63 by mask ++# Example syntax to connect to physical cores 16 and 17 for S0 ++# Syntax: -c "set COREMASK_S0_LO {0x0000000000030000}" ++# ++# COREMASK_S0_HI ++# Specify available physical cores 64 and above by mask ++# Example syntax to connect to physical cores 94 and 95 for S0 ++# Syntax: -c "set COREMASK_S0_HI {0x00000000C0000000}" ++# ++# PHYS_IDX ++# Enable OpenOCD ARMv8 core target physical indexing ++# If not specified, defaults to OpenOCD ARMv8 core target logical indexing ++# Syntax: -c "set PHYS_IDX {}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] ++ftdi tdo_sample_edge falling ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 5000 ++} ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME mq ++} ++ ++set MQ_ENABLE "" ++source [find board/ampere_qs_mq_1s.cfg] +diff --git a/tcl/openocd.mq_2s_sil.cfg b/tcl/openocd.mq_2s_sil.cfg +new file mode 100644 +index 000000000..f2e8afd3e +--- /dev/null ++++ b/tcl/openocd.mq_2s_sil.cfg +@@ -0,0 +1,83 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the Ampere Altra Max ++# Development Platform ++# ++# Copyright (c) 2020-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "5000" kHz ++# Syntax: -c "set JTAGFREQ {5000}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "mq" ++# Syntax: -c "set SYSNAME {mq}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0, CORELIST_S1 ++# Specify available physical cores by number ++# Example syntax to connect to physical cores 16 and 17 for S0 and S1 ++# Syntax: -c "set CORELIST_S0 {16 17}" ++# Syntax: -c "set CORELIST_S1 {16 17}" ++# ++# COREMASK_S0_LO, COREMASK_S1_LO ++# Specify available physical cores 0-63 by mask ++# Example syntax to connect to physical cores 16 and 17 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_LO {0x0000000000030000}" ++# Syntax: -c "set COREMASK_S1_LO {0x0000000000030000}" ++# ++# COREMASK_S0_HI, COREMASK_S1_HI ++# Specify available physical cores 64 and above by mask ++# Example syntax to connect to physical cores 94 and 95 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_HI {0x00000000C0000000}" ++# Syntax: -c "set COREMASK_S1_HI {0x00000000C0000000}" ++# ++# SPLITSMP ++# Group all ARMv8 cores per socket into individual SMP sessions ++# If not specified, group ARMv8 cores from both sockets into one SMP session ++# Syntax: -c "set SPLITSMP {}" ++# ++# PHYS_IDX ++# Enable OpenOCD ARMv8 core target physical indexing ++# If not specified, defaults to OpenOCD ARMv8 core target logical indexing ++# Syntax: -c "set PHYS_IDX {}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] ++ftdi tdo_sample_edge falling ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 5000 ++} ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME mq ++} ++ ++set MQ_ENABLE "" ++source [find board/ampere_qs_mq_2s.cfg] +diff --git a/tcl/openocd.qs_1s_sil.cfg b/tcl/openocd.qs_1s_sil.cfg +new file mode 100644 +index 000000000..0a30e163c +--- /dev/null ++++ b/tcl/openocd.qs_1s_sil.cfg +@@ -0,0 +1,74 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the Ampere Altra ++# Development Platform ++# ++# Copyright (c) 2019-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "5000" kHz ++# Syntax: -c "set JTAGFREQ {5000}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "qs" ++# Syntax: -c "set SYSNAME {qs}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0 ++# Specify available physical cores by number ++# Example syntax to connect to physical cores 16 and 17 for S0 ++# Syntax: -c "set CORELIST_S0 {16 17}" ++# ++# COREMASK_S0_LO ++# Specify available physical cores 0-63 by mask ++# Example syntax to connect to physical cores 16 and 17 for S0 ++# Syntax: -c "set COREMASK_S0_LO {0x0000000000030000}" ++# ++# COREMASK_S0_HI ++# Specify available physical cores 64 and above by mask ++# Example syntax to connect to physical cores 78 and 79 for S0 ++# Syntax: -c "set COREMASK_S0_HI {0x000000000000C000}" ++# ++# PHYS_IDX ++# Enable OpenOCD ARMv8 core target physical indexing ++# If not specified, defaults to OpenOCD ARMv8 core target logical indexing ++# Syntax: -c "set PHYS_IDX {}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] ++ftdi tdo_sample_edge falling ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 5000 ++} ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME qs ++} ++ ++source [find board/ampere_qs_mq_1s.cfg] +diff --git a/tcl/openocd.qs_2s_sil.cfg b/tcl/openocd.qs_2s_sil.cfg +new file mode 100644 +index 000000000..49dec1251 +--- /dev/null ++++ b/tcl/openocd.qs_2s_sil.cfg +@@ -0,0 +1,82 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the Ampere Altra ++# Development Platform ++# ++# Copyright (c) 2019-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "5000" kHz ++# Syntax: -c "set JTAGFREQ {5000}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "qs" ++# Syntax: -c "set SYSNAME {qs}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0, CORELIST_S1 ++# Specify available physical cores by number ++# Example syntax to connect to physical cores 16 and 17 for S0 and S1 ++# Syntax: -c "set CORELIST_S0 {16 17}" ++# Syntax: -c "set CORELIST_S1 {16 17}" ++# ++# COREMASK_S0_LO, COREMASK_S1_LO ++# Specify available physical cores 0-63 by mask ++# Example syntax to connect to physical cores 16 and 17 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_LO {0x0000000000030000}" ++# Syntax: -c "set COREMASK_S1_LO {0x0000000000030000}" ++# ++# COREMASK_S0_HI, COREMASK_S1_HI ++# Specify available physical cores 64 and above by mask ++# Example syntax to connect to physical cores 78 and 79 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_HI {0x000000000000C000}" ++# Syntax: -c "set COREMASK_S1_HI {0x000000000000C000}" ++# ++# SPLITSMP ++# Group all ARMv8 cores per socket into individual SMP sessions ++# If not specified, group ARMv8 cores from both sockets into one SMP session ++# Syntax: -c "set SPLITSMP {}" ++# ++# PHYS_IDX ++# Enable OpenOCD ARMv8 core target physical indexing ++# If not specified, defaults to OpenOCD ARMv8 core target logical indexing ++# Syntax: -c "set PHYS_IDX {}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] ++ftdi tdo_sample_edge falling ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 5000 ++} ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME qs ++} ++ ++source [find board/ampere_qs_mq_2s.cfg] +-- +2.25.1 + diff --git a/patches/0026-QS-MQ-BMC-remote-debug-user-configs-DO-NOT-UPSTREAM.patch b/patches/0026-QS-MQ-BMC-remote-debug-user-configs-DO-NOT-UPSTREAM.patch new file mode 100644 index 000000000..04aa09d1a --- /dev/null +++ b/patches/0026-QS-MQ-BMC-remote-debug-user-configs-DO-NOT-UPSTREAM.patch @@ -0,0 +1,360 @@ +From b009c0356e99fac19b257818d3f0480c161f0058 Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Thu, 4 Mar 2021 12:32:54 -0500 +Subject: [PATCH 26/33] QS|MQ: BMC remote debug user configs [DO NOT UPSTREAM] + +Add AST2500 BMC remote debug user configuration files for +Ampere Altra and Ampere Altra Max. + +Tested on Altra and Altra Max silicon systems with AST2500 BMC + +Change-Id: I45c93228e0fdd6bb8f5f91eeee5e6700ad0bdfa2 +Signed-off-by: Daniel Goehring +--- + tcl/openocd.mq_1s_bmc.cfg | 74 +++++++++++++++++++++++++++++++++++ + tcl/openocd.mq_2s_bmc.cfg | 82 +++++++++++++++++++++++++++++++++++++++ + tcl/openocd.qs_1s_bmc.cfg | 73 ++++++++++++++++++++++++++++++++++ + tcl/openocd.qs_2s_bmc.cfg | 81 ++++++++++++++++++++++++++++++++++++++ + 4 files changed, 310 insertions(+) + create mode 100644 tcl/openocd.mq_1s_bmc.cfg + create mode 100644 tcl/openocd.mq_2s_bmc.cfg + create mode 100644 tcl/openocd.qs_1s_bmc.cfg + create mode 100644 tcl/openocd.qs_2s_bmc.cfg + +diff --git a/tcl/openocd.mq_1s_bmc.cfg b/tcl/openocd.mq_1s_bmc.cfg +new file mode 100644 +index 000000000..308603b74 +--- /dev/null ++++ b/tcl/openocd.mq_1s_bmc.cfg +@@ -0,0 +1,74 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the AST2500 BMC ++# on the Ampere development platforms ++# ++# Copyright (c) 2020-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "12375" kHz ++# Syntax: -c "set JTAGFREQ {12375}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "mq" ++# Syntax: -c "set SYSNAME {mq}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0 ++# Specify available physical cores by number ++# Example syntax to connect to physical cores 16 and 17 for S0 ++# Syntax: -c "set CORELIST_S0 {16 17}" ++# ++# COREMASK_S0_LO ++# Specify available physical cores 0-63 by mask ++# Example syntax to connect to physical cores 16 and 17 for S0 ++# Syntax: -c "set COREMASK_S0_LO {0x0000000000030000}" ++# ++# COREMASK_S0_HI ++# Specify available physical cores 64 and above by mask ++# Example syntax to connect to physical cores 94 and 95 for S0 ++# Syntax: -c "set COREMASK_S0_HI {0x00000000C0000000}" ++# ++# PHYS_IDX ++# Enable OpenOCD ARMv8 core target physical indexing ++# If not specified, defaults to OpenOCD ARMv8 core target logical indexing ++# Syntax: -c "set PHYS_IDX {}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/jtag_driver.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 12375 ++} ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME mq ++} ++ ++set MQ_ENABLE "" ++source [find board/ampere_qs_mq_1s.cfg] +diff --git a/tcl/openocd.mq_2s_bmc.cfg b/tcl/openocd.mq_2s_bmc.cfg +new file mode 100644 +index 000000000..f097f24fa +--- /dev/null ++++ b/tcl/openocd.mq_2s_bmc.cfg +@@ -0,0 +1,82 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the AST2500 BMC ++# on the Ampere development platforms ++# ++# Copyright (c) 2020-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "12375" kHz ++# Syntax: -c "set JTAGFREQ {12375}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "mq" ++# Syntax: -c "set SYSNAME {mq}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0, CORELIST_S1 ++# Specify available physical cores by number ++# Example syntax to connect to physical cores 16 and 17 for S0 and S1 ++# Syntax: -c "set CORELIST_S0 {16 17}" ++# Syntax: -c "set CORELIST_S1 {16 17}" ++# ++# COREMASK_S0_LO, COREMASK_S1_LO ++# Specify available physical cores 0-63 by mask ++# Example syntax to connect to physical cores 16 and 17 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_LO {0x0000000000030000}" ++# Syntax: -c "set COREMASK_S1_LO {0x0000000000030000}" ++# ++# COREMASK_S0_HI, COREMASK_S1_HI ++# Specify available physical cores 64 and above by mask ++# Example syntax to connect to physical cores 94 and 95 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_HI {0x00000000C0000000}" ++# Syntax: -c "set COREMASK_S1_HI {0x00000000C0000000}" ++# ++# SPLITSMP ++# Group all ARMv8 cores per socket into individual SMP sessions ++# If not specified, group ARMv8 cores from both sockets into one SMP session ++# Syntax: -c "set SPLITSMP {}" ++# ++# PHYS_IDX ++# Enable OpenOCD ARMv8 core target physical indexing ++# If not specified, defaults to OpenOCD ARMv8 core target logical indexing ++# Syntax: -c "set PHYS_IDX {}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/jtag_driver.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 12375 ++} ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME mq ++} ++ ++set MQ_ENABLE "" ++source [find board/ampere_qs_mq_2s.cfg] +diff --git a/tcl/openocd.qs_1s_bmc.cfg b/tcl/openocd.qs_1s_bmc.cfg +new file mode 100644 +index 000000000..f188fff3c +--- /dev/null ++++ b/tcl/openocd.qs_1s_bmc.cfg +@@ -0,0 +1,73 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the AST2500 BMC ++# on the Ampere development platforms ++# ++# Copyright (c) 2020-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "12375" kHz ++# Syntax: -c "set JTAGFREQ {12375}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "qs" ++# Syntax: -c "set SYSNAME {qs}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0 ++# Specify available physical cores by number ++# Example syntax to connect to physical cores 16 and 17 for S0 ++# Syntax: -c "set CORELIST_S0 {16 17}" ++# ++# COREMASK_S0_LO ++# Specify available physical cores 0-63 by mask ++# Example syntax to connect to physical cores 16 and 17 for S0 ++# Syntax: -c "set COREMASK_S0_LO {0x0000000000030000}" ++# ++# COREMASK_S0_HI ++# Specify available physical cores 64 and above by mask ++# Example syntax to connect to physical cores 78 and 79 for S0 ++# Syntax: -c "set COREMASK_S0_HI {0x000000000000C000}" ++# ++# PHYS_IDX ++# Enable OpenOCD ARMv8 core target physical indexing ++# If not specified, defaults to OpenOCD ARMv8 core target logical indexing ++# Syntax: -c "set PHYS_IDX {}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/jtag_driver.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 12375 ++} ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME qs ++} ++ ++source [find board/ampere_qs_mq_1s.cfg] +diff --git a/tcl/openocd.qs_2s_bmc.cfg b/tcl/openocd.qs_2s_bmc.cfg +new file mode 100644 +index 000000000..d009ab243 +--- /dev/null ++++ b/tcl/openocd.qs_2s_bmc.cfg +@@ -0,0 +1,81 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the AST2500 BMC ++# on the Ampere development platforms ++# ++# Copyright (c) 2020-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "12375" kHz ++# Syntax: -c "set JTAGFREQ {12375}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "qs" ++# Syntax: -c "set SYSNAME {qs}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0, CORELIST_S1 ++# Specify available physical cores by number ++# Example syntax to connect to physical cores 16 and 17 for S0 and S1 ++# Syntax: -c "set CORELIST_S0 {16 17}" ++# Syntax: -c "set CORELIST_S1 {16 17}" ++# ++# COREMASK_S0_LO, COREMASK_S1_LO ++# Specify available physical cores 0-63 by mask ++# Example syntax to connect to physical cores 16 and 17 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_LO {0x0000000000030000}" ++# Syntax: -c "set COREMASK_S1_LO {0x0000000000030000}" ++# ++# COREMASK_S0_HI, COREMASK_S1_HI ++# Specify available physical cores 64 and above by mask ++# Example syntax to connect to physical cores 78 and 79 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_HI {0x000000000000C000}" ++# Syntax: -c "set COREMASK_S1_HI {0x000000000000C000}" ++# ++# SPLITSMP ++# Group all ARMv8 cores per socket into individual SMP sessions ++# If not specified, group ARMv8 cores from both sockets into one SMP session ++# Syntax: -c "set SPLITSMP {}" ++# ++# PHYS_IDX ++# Enable OpenOCD ARMv8 core target physical indexing ++# If not specified, defaults to OpenOCD ARMv8 core target logical indexing ++# Syntax: -c "set PHYS_IDX {}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/jtag_driver.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 12375 ++} ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME qs ++} ++ ++source [find board/ampere_qs_mq_2s.cfg] +-- +2.25.1 + diff --git a/patches/0027-QS-MQ-boundary-scan-user-configs-DO-NOT-UPSTREAM.patch b/patches/0027-QS-MQ-boundary-scan-user-configs-DO-NOT-UPSTREAM.patch new file mode 100644 index 000000000..f15b4d58a --- /dev/null +++ b/patches/0027-QS-MQ-boundary-scan-user-configs-DO-NOT-UPSTREAM.patch @@ -0,0 +1,240 @@ +From 41980f0e2fba1ec8858078f57f419f4a30903701 Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Fri, 12 Mar 2021 17:46:20 -0500 +Subject: [PATCH 27/33] QS|MQ: boundary-scan user configs [DO NOT UPSTREAM] + +Add boundary-scan user configuration files for +Ampere Altra and Ampere Altra Max + +Configured for the Olimex ARM-USB-OCD-H JTAG probe. +https://www.olimex.com/Products/ARM/JTAG/ARM-USB-OCD-H/ + +OpenOCD configured for the Ampere Altra and Ampere Altra Max options +1. One and two socket platforms + +Change-Id: I5ac67718692293f722d1c787820f89bc61888503 +Signed-off-by: Daniel Goehring +--- + tcl/openocd.mq_1s_bs.cfg | 47 ++++++++++++++++++++++++++++++++++++++++ + tcl/openocd.mq_2s_bs.cfg | 47 ++++++++++++++++++++++++++++++++++++++++ + tcl/openocd.qs_1s_bs.cfg | 46 +++++++++++++++++++++++++++++++++++++++ + tcl/openocd.qs_2s_bs.cfg | 46 +++++++++++++++++++++++++++++++++++++++ + 4 files changed, 186 insertions(+) + create mode 100644 tcl/openocd.mq_1s_bs.cfg + create mode 100644 tcl/openocd.mq_2s_bs.cfg + create mode 100644 tcl/openocd.qs_1s_bs.cfg + create mode 100644 tcl/openocd.qs_2s_bs.cfg + +diff --git a/tcl/openocd.mq_1s_bs.cfg b/tcl/openocd.mq_1s_bs.cfg +new file mode 100644 +index 000000000..17c5a4215 +--- /dev/null ++++ b/tcl/openocd.mq_1s_bs.cfg +@@ -0,0 +1,47 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the Ampere Altra Max ++# Development Platform ++# ++# Copyright (c) 2020-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "5000" kHz ++# Syntax: -c "set JTAGFREQ {5000}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "mq" ++# Syntax: -c "set SYSNAME {mq}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 5000 ++} ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME mq ++} ++ ++set MQ_ENABLE "" ++source [find board/ampere_qs_mq_1s_bs.cfg] +diff --git a/tcl/openocd.mq_2s_bs.cfg b/tcl/openocd.mq_2s_bs.cfg +new file mode 100644 +index 000000000..f22fae197 +--- /dev/null ++++ b/tcl/openocd.mq_2s_bs.cfg +@@ -0,0 +1,47 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the Ampere Altra Max ++# Development Platform ++# ++# Copyright (c) 2020-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "5000" kHz ++# Syntax: -c "set JTAGFREQ {5000}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "mq" ++# Syntax: -c "set SYSNAME {mq}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 5000 ++} ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME mq ++} ++ ++set MQ_ENABLE "" ++source [find board/ampere_qs_mq_2s_bs.cfg] +diff --git a/tcl/openocd.qs_1s_bs.cfg b/tcl/openocd.qs_1s_bs.cfg +new file mode 100644 +index 000000000..e59ec637c +--- /dev/null ++++ b/tcl/openocd.qs_1s_bs.cfg +@@ -0,0 +1,46 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the Ampere Altra ++# Development Platform ++# ++# Copyright (c) 2019-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "5000" kHz ++# Syntax: -c "set JTAGFREQ {5000}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "qs" ++# Syntax: -c "set SYSNAME {qs}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 5000 ++} ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME qs ++} ++ ++source [find board/ampere_qs_mq_1s_bs.cfg] +diff --git a/tcl/openocd.qs_2s_bs.cfg b/tcl/openocd.qs_2s_bs.cfg +new file mode 100644 +index 000000000..7e1129b71 +--- /dev/null ++++ b/tcl/openocd.qs_2s_bs.cfg +@@ -0,0 +1,46 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the Ampere Altra ++# Development Platform ++# ++# Copyright (c) 2019-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "5000" kHz ++# Syntax: -c "set JTAGFREQ {5000}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "qs" ++# Syntax: -c "set SYSNAME {qs}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 5000 ++} ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME qs ++} ++ ++source [find board/ampere_qs_mq_2s_bs.cfg] +-- +2.25.1 + diff --git a/patches/0028-QS-MQ-emulation-user-configs-DO-NOT-UPSTREAM.patch b/patches/0028-QS-MQ-emulation-user-configs-DO-NOT-UPSTREAM.patch new file mode 100644 index 000000000..1083bae3f --- /dev/null +++ b/patches/0028-QS-MQ-emulation-user-configs-DO-NOT-UPSTREAM.patch @@ -0,0 +1,692 @@ +From 4301ad631b5d00d6a1477c6907e5a2dc9159d455 Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Thu, 16 Apr 2020 15:43:37 -0400 +Subject: [PATCH 28/33] QS|MQ: emulation user configs [DO NOT UPSTREAM] + +Add user configuration files for Ampere Altra +and Ampere Altra Max in Emulation. + +Protium configuration uses an Olimex ARM-USB-OCD_H JTAG probe. +https://www.olimex.com/Products/ARM/JTAG/ARM-USB-OCD-H/ + +OpenOCD configured for the following QS options +1. JTAG DPI Emulation interface (Palladium) +2. JTAG Olimex (Protium) +3. One and two socket platforms + +Tested on the following system platforms +* Palladium 1S2C1M and 2S2C1M +* Protium + +Change-Id: Ia8d5b29418557c947cb603a2070bc927152ee415 +Signed-off-by: Daniel Goehring +--- + tcl/openocd.mq_1s_pal.cfg | 69 ++++++++++++++++++++++++++++++++ + tcl/openocd.mq_1s_prot.cfg | 74 ++++++++++++++++++++++++++++++++++ + tcl/openocd.mq_2s_pal.cfg | 77 +++++++++++++++++++++++++++++++++++ + tcl/openocd.mq_2s_prot.cfg | 82 ++++++++++++++++++++++++++++++++++++++ + tcl/openocd.qs_1s_pal.cfg | 68 +++++++++++++++++++++++++++++++ + tcl/openocd.qs_1s_prot.cfg | 73 +++++++++++++++++++++++++++++++++ + tcl/openocd.qs_2s_pal.cfg | 76 +++++++++++++++++++++++++++++++++++ + tcl/openocd.qs_2s_prot.cfg | 81 +++++++++++++++++++++++++++++++++++++ + 8 files changed, 600 insertions(+) + create mode 100644 tcl/openocd.mq_1s_pal.cfg + create mode 100644 tcl/openocd.mq_1s_prot.cfg + create mode 100644 tcl/openocd.mq_2s_pal.cfg + create mode 100644 tcl/openocd.mq_2s_prot.cfg + create mode 100644 tcl/openocd.qs_1s_pal.cfg + create mode 100644 tcl/openocd.qs_1s_prot.cfg + create mode 100644 tcl/openocd.qs_2s_pal.cfg + create mode 100644 tcl/openocd.qs_2s_prot.cfg + +diff --git a/tcl/openocd.mq_1s_pal.cfg b/tcl/openocd.mq_1s_pal.cfg +new file mode 100644 +index 000000000..21ce60d90 +--- /dev/null ++++ b/tcl/openocd.mq_1s_pal.cfg +@@ -0,0 +1,69 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the Ampere Altra Max ++# Development Platform ++# ++# Copyright (c) 2020-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# DPI_PORT ++# Set the DPI JTAG server port assigned to the emulator BFM transactor ++# Syntax: -c "set DPI_PORT {5555}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "mq" ++# Syntax: -c "set SYSNAME {mq}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0 ++# Specify available physical cores by number ++# Example syntax to connect to physical cores 16 and 17 for S0 ++# Syntax: -c "set CORELIST_S0 {16 17}" ++# ++# COREMASK_S0_LO ++# Specify available physical cores 0-63 by mask ++# Example syntax to connect to physical cores 16 and 17 for S0 ++# Syntax: -c "set COREMASK_S0_LO {0x0000000000030000}" ++# ++# COREMASK_S0_HI ++# Specify available physical cores 64 and above by mask ++# Example syntax to connect to physical cores 94 and 95 for S0 ++# Syntax: -c "set COREMASK_S0_HI {0x00000000C0000000}" ++# ++# PHYS_IDX ++# Enable OpenOCD ARMv8 core target physical indexing ++# If not specified, defaults to OpenOCD ARMv8 core target logical indexing ++# Syntax: -c "set PHYS_IDX {}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/jtag_dpi.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME mq ++} ++ ++set MQ_ENABLE "" ++source [find board/ampere_qs_mq_1s.cfg] +diff --git a/tcl/openocd.mq_1s_prot.cfg b/tcl/openocd.mq_1s_prot.cfg +new file mode 100644 +index 000000000..a5109db2f +--- /dev/null ++++ b/tcl/openocd.mq_1s_prot.cfg +@@ -0,0 +1,74 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the Ampere Altra Max ++# Development Platform ++# ++# Copyright (c) 2020-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "100" kHz ++# Syntax: -c "set JTAGFREQ {100}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "mq" ++# Syntax: -c "set SYSNAME {mq}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0 ++# Specify available physical cores by number ++# Example syntax to connect to physical cores 16 and 17 for S0 ++# Syntax: -c "set CORELIST_S0 {16 17}" ++# ++# COREMASK_S0_LO ++# Specify available physical cores 0-63 by mask ++# Example syntax to connect to physical cores 16 and 17 for S0 ++# Syntax: -c "set COREMASK_S0_LO {0x0000000000030000}" ++# ++# COREMASK_S0_HI ++# Specify available physical cores 64 and above by mask ++# Example syntax to connect to physical cores 94 and 95 for S0 ++# Syntax: -c "set COREMASK_S0_HI {0x00000000C0000000}" ++# ++# PHYS_IDX ++# Enable OpenOCD ARMv8 core target physical indexing ++# If not specified, defaults to OpenOCD ARMv8 core target logical indexing ++# Syntax: -c "set PHYS_IDX {}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 100 ++} ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME mq ++} ++ ++set MQ_ENABLE "" ++source [find board/ampere_qs_mq_1s.cfg] +diff --git a/tcl/openocd.mq_2s_pal.cfg b/tcl/openocd.mq_2s_pal.cfg +new file mode 100644 +index 000000000..0496b7d3a +--- /dev/null ++++ b/tcl/openocd.mq_2s_pal.cfg +@@ -0,0 +1,77 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the Ampere Altra Max ++# Development Platform ++# ++# Copyright (c) 2020-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# DPI_PORT ++# Set the DPI JTAG server port assigned to the emulator BFM transactor ++# Syntax: -c "set DPI_PORT {5555}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "mq" ++# Syntax: -c "set SYSNAME {mq}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0, CORELIST_S1 ++# Specify available physical cores by number ++# Example syntax to connect to physical cores 16 and 17 for S0 and S1 ++# Syntax: -c "set CORELIST_S0 {16 17}" ++# Syntax: -c "set CORELIST_S1 {16 17}" ++# ++# COREMASK_S0_LO, COREMASK_S1_LO ++# Specify available physical cores 0-63 by mask ++# Example syntax to connect to physical cores 16 and 17 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_LO {0x0000000000030000}" ++# Syntax: -c "set COREMASK_S1_LO {0x0000000000030000}" ++# ++# COREMASK_S0_HI, COREMASK_S1_HI ++# Specify available physical cores 64 and above by mask ++# Example syntax to connect to physical cores 94 and 95 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_HI {0x00000000C0000000}" ++# Syntax: -c "set COREMASK_S1_HI {0x00000000C0000000}" ++# ++# SPLITSMP ++# Group all ARMv8 cores per socket into individual SMP sessions ++# If not specified, group ARMv8 cores from both sockets into one SMP session ++# Syntax: -c "set SPLITSMP {}" ++# ++# PHYS_IDX ++# Enable OpenOCD ARMv8 core target physical indexing ++# If not specified, defaults to OpenOCD ARMv8 core target logical indexing ++# Syntax: -c "set PHYS_IDX {}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/jtag_dpi.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME mq ++} ++ ++set MQ_ENABLE "" ++source [find board/ampere_qs_mq_2s.cfg] +diff --git a/tcl/openocd.mq_2s_prot.cfg b/tcl/openocd.mq_2s_prot.cfg +new file mode 100644 +index 000000000..c33cb1bcc +--- /dev/null ++++ b/tcl/openocd.mq_2s_prot.cfg +@@ -0,0 +1,82 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the Ampere Altra Max ++# Development Platform ++# ++# Copyright (c) 2020-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "100" kHz ++# Syntax: -c "set JTAGFREQ {100}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "mq" ++# Syntax: -c "set SYSNAME {mq}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0, CORELIST_S1 ++# Specify available physical cores by number ++# Example syntax to connect to physical cores 16 and 17 for S0 and S1 ++# Syntax: -c "set CORELIST_S0 {16 17}" ++# Syntax: -c "set CORELIST_S1 {16 17}" ++# ++# COREMASK_S0_LO, COREMASK_S1_LO ++# Specify available physical cores 0-63 by mask ++# Example syntax to connect to physical cores 16 and 17 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_LO {0x0000000000030000}" ++# Syntax: -c "set COREMASK_S1_LO {0x0000000000030000}" ++# ++# COREMASK_S0_HI, COREMASK_S1_HI ++# Specify available physical cores 64 and above by mask ++# Example syntax to connect to physical cores 94 and 95 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_HI {0x00000000C0000000}" ++# Syntax: -c "set COREMASK_S1_HI {0x00000000C0000000}" ++# ++# SPLITSMP ++# Group all ARMv8 cores per socket into individual SMP sessions ++# If not specified, group ARMv8 cores from both sockets into one SMP session ++# Syntax: -c "set SPLITSMP {}" ++# ++# PHYS_IDX ++# Enable OpenOCD ARMv8 core target physical indexing ++# If not specified, defaults to OpenOCD ARMv8 core target logical indexing ++# Syntax: -c "set PHYS_IDX {}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 100 ++} ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME mq ++} ++ ++set MQ_ENABLE "" ++source [find board/ampere_qs_mq_2s.cfg] +diff --git a/tcl/openocd.qs_1s_pal.cfg b/tcl/openocd.qs_1s_pal.cfg +new file mode 100644 +index 000000000..349b82ee3 +--- /dev/null ++++ b/tcl/openocd.qs_1s_pal.cfg +@@ -0,0 +1,68 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the Ampere Altra ++# Development Platform ++# ++# Copyright (c) 2019-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# DPI_PORT ++# Set the DPI JTAG server port assigned to the emulator BFM transactor ++# Syntax: -c "set DPI_PORT {5555}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "qs" ++# Syntax: -c "set SYSNAME {qs}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0 ++# Specify available physical cores by number ++# Example syntax to connect to physical cores 16 and 17 for S0 ++# Syntax: -c "set CORELIST_S0 {16 17}" ++# ++# COREMASK_S0_LO ++# Specify available physical cores 0-63 by mask ++# Example syntax to connect to physical cores 16 and 17 for S0 ++# Syntax: -c "set COREMASK_S0_LO {0x0000000000030000}" ++# ++# COREMASK_S0_HI ++# Specify available physical cores 64 and above by mask ++# Example syntax to connect to physical cores 78 and 79 for S0 ++# Syntax: -c "set COREMASK_S0_HI {0x000000000000C000}" ++# ++# PHYS_IDX ++# Enable OpenOCD ARMv8 core target physical indexing ++# If not specified, defaults to OpenOCD ARMv8 core target logical indexing ++# Syntax: -c "set PHYS_IDX {}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/jtag_dpi.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME qs ++} ++ ++source [find board/ampere_qs_mq_1s.cfg] +diff --git a/tcl/openocd.qs_1s_prot.cfg b/tcl/openocd.qs_1s_prot.cfg +new file mode 100644 +index 000000000..514b464eb +--- /dev/null ++++ b/tcl/openocd.qs_1s_prot.cfg +@@ -0,0 +1,73 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the Ampere Altra ++# Development Platform ++# ++# Copyright (c) 2019-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "100" kHz ++# Syntax: -c "set JTAGFREQ {100}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "qs" ++# Syntax: -c "set SYSNAME {qs}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0 ++# Specify available physical cores by number ++# Example syntax to connect to physical cores 16 and 17 for S0 ++# Syntax: -c "set CORELIST_S0 {16 17}" ++# ++# COREMASK_S0_LO ++# Specify available physical cores 0-63 by mask ++# Example syntax to connect to physical cores 16 and 17 for S0 ++# Syntax: -c "set COREMASK_S0_LO {0x0000000000030000}" ++# ++# COREMASK_S0_HI ++# Specify available physical cores 64 and above by mask ++# Example syntax to connect to physical cores 78 and 79 for S0 ++# Syntax: -c "set COREMASK_S0_HI {0x000000000000C000}" ++# ++# PHYS_IDX ++# Enable OpenOCD ARMv8 core target physical indexing ++# If not specified, defaults to OpenOCD ARMv8 core target logical indexing ++# Syntax: -c "set PHYS_IDX {}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 100 ++} ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME qs ++} ++ ++source [find board/ampere_qs_mq_1s.cfg] +diff --git a/tcl/openocd.qs_2s_pal.cfg b/tcl/openocd.qs_2s_pal.cfg +new file mode 100644 +index 000000000..ea1a79562 +--- /dev/null ++++ b/tcl/openocd.qs_2s_pal.cfg +@@ -0,0 +1,76 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the Ampere Altra ++# Development Platform ++# ++# Copyright (c) 2019-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# DPI_PORT ++# Set the DPI JTAG server port assigned to the emulator BFM transactor ++# Syntax: -c "set DPI_PORT {5555}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "qs" ++# Syntax: -c "set SYSNAME {qs}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0, CORELIST_S1 ++# Specify available physical cores by number ++# Example syntax to connect to physical cores 16 and 17 for S0 and S1 ++# Syntax: -c "set CORELIST_S0 {16 17}" ++# Syntax: -c "set CORELIST_S1 {16 17}" ++# ++# COREMASK_S0_LO, COREMASK_S1_LO ++# Specify available physical cores 0-63 by mask ++# Example syntax to connect to physical cores 16 and 17 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_LO {0x0000000000030000}" ++# Syntax: -c "set COREMASK_S1_LO {0x0000000000030000}" ++# ++# COREMASK_S0_HI, COREMASK_S1_HI ++# Specify available physical cores 64 and above by mask ++# Example syntax to connect to physical cores 78 and 79 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_HI {0x000000000000C000}" ++# Syntax: -c "set COREMASK_S1_HI {0x000000000000C000}" ++# ++# SPLITSMP ++# Group all ARMv8 cores per socket into individual SMP sessions ++# If not specified, group ARMv8 cores from both sockets into one SMP session ++# Syntax: -c "set SPLITSMP {}" ++# ++# PHYS_IDX ++# Enable OpenOCD ARMv8 core target physical indexing ++# If not specified, defaults to OpenOCD ARMv8 core target logical indexing ++# Syntax: -c "set PHYS_IDX {}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/jtag_dpi.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME qs ++} ++ ++source [find board/ampere_qs_mq_2s.cfg] +diff --git a/tcl/openocd.qs_2s_prot.cfg b/tcl/openocd.qs_2s_prot.cfg +new file mode 100644 +index 000000000..e5afcd1ea +--- /dev/null ++++ b/tcl/openocd.qs_2s_prot.cfg +@@ -0,0 +1,81 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the Ampere Altra ++# Development Platform ++# ++# Copyright (c) 2019-2023, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "100" kHz ++# Syntax: -c "set JTAGFREQ {100}" ++# ++# SYSNAME ++# Override the default system name ++# If not specified, defaults to "qs" ++# Syntax: -c "set SYSNAME {qs}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0, CORELIST_S1 ++# Specify available physical cores by number ++# Example syntax to connect to physical cores 16 and 17 for S0 and S1 ++# Syntax: -c "set CORELIST_S0 {16 17}" ++# Syntax: -c "set CORELIST_S1 {16 17}" ++# ++# COREMASK_S0_LO, COREMASK_S1_LO ++# Specify available physical cores 0-63 by mask ++# Example syntax to connect to physical cores 16 and 17 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_LO {0x0000000000030000}" ++# Syntax: -c "set COREMASK_S1_LO {0x0000000000030000}" ++# ++# COREMASK_S0_HI, COREMASK_S1_HI ++# Specify available physical cores 64 and above by mask ++# Example syntax to connect to physical cores 78 and 79 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_HI {0x000000000000C000}" ++# Syntax: -c "set COREMASK_S1_HI {0x000000000000C000}" ++# ++# SPLITSMP ++# Group all ARMv8 cores per socket into individual SMP sessions ++# If not specified, group ARMv8 cores from both sockets into one SMP session ++# Syntax: -c "set SPLITSMP {}" ++# ++# PHYS_IDX ++# Enable OpenOCD ARMv8 core target physical indexing ++# If not specified, defaults to OpenOCD ARMv8 core target logical indexing ++# Syntax: -c "set PHYS_IDX {}" ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++#gdb_port 3333 ++#telnet_port 4444 ++#tcl_port 6666 ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 100 ++} ++ ++if { ![info exists SYSNAME] } { ++ set SYSNAME qs ++} ++ ++source [find board/ampere_qs_mq_2s.cfg] +-- +2.25.1 + diff --git a/patches/0029-ac03-target-board-AmpereOne-configs-DO-NOT-UPSTREAM.patch b/patches/0029-ac03-target-board-AmpereOne-configs-DO-NOT-UPSTREAM.patch new file mode 100644 index 000000000..618eb48b7 --- /dev/null +++ b/patches/0029-ac03-target-board-AmpereOne-configs-DO-NOT-UPSTREAM.patch @@ -0,0 +1,803 @@ +From 92eee07d315c1c10887060100f900b78348648a4 Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Thu, 28 Jan 2021 16:41:22 -0500 +Subject: [PATCH 29/33] ac03: target/board: AmpereOne configs [DO NOT UPSTREAM] + +Add AmpereOne Family board and target configuration files. + +Change-Id: I871d3d3dfa09a0f45cffc8458d50fae26cb38618 +Signed-off-by: Daniel Goehring +--- + tcl/board/ampere_ac03_1s.cfg | 100 ++++++++ + tcl/board/ampere_ac03_2s.cfg | 154 +++++++++++++ + tcl/target/ampere_ac03.cfg | 403 +++++++++++++++++++++++++++++++++ + tcl/target/ampere_ac03_tap.cfg | 99 ++++++++ + 4 files changed, 756 insertions(+) + create mode 100644 tcl/board/ampere_ac03_1s.cfg + create mode 100644 tcl/board/ampere_ac03_2s.cfg + create mode 100644 tcl/target/ampere_ac03.cfg + create mode 100644 tcl/target/ampere_ac03_tap.cfg + +diff --git a/tcl/board/ampere_ac03_1s.cfg b/tcl/board/ampere_ac03_1s.cfg +new file mode 100644 +index 000000000..5d5867adf +--- /dev/null ++++ b/tcl/board/ampere_ac03_1s.cfg +@@ -0,0 +1,100 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# OpenOCD Board Configuration for the AmpereOne Family processors ++# ++# Copyright (c) 2021-2024, Ampere Computing LLC ++# ++ ++# Argument Description ++# ++# JTAGFREQ ++# Set the JTAG clock frequency ++# Syntax: -c "set JTAGFREQ {freq_in_khz}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0 ++# Specify available physical cores by number ++# Example syntax to attach to physical cores 16, 17, 94, 95, 128 and 129 for S0 ++# Syntax: -c "set CORELIST_S0 {16 17 94 95 128 129}" ++# ++# COREMASK_S0_0 ++# Specify available physical cores 0-63 by mask ++# Example syntax to attach to physical cores 16 and 17 for S0 ++# Syntax: -c "set COREMASK_S0_0 {0x0000000000030000}" ++# ++# COREMASK_S0_1 ++# Specify available physical cores 64-127 by mask ++# Example syntax to attach to physical cores 94 and 95 for S0 ++# Syntax: -c "set COREMASK_S0_1 {0x00000000C0000000}" ++# ++# COREMASK_S0_2 ++# Specify available physical cores 128 and above by mask ++# Example syntax to attach to physical cores 128 and 129 for S0 ++# Syntax: -c "set COREMASK_S0_2 {0x0000000000000003}" ++ ++# ++# Configure JTAG speed ++# ++ ++if { [info exists JTAGFREQ] } { ++ adapter speed $JTAGFREQ ++} else { ++ adapter speed 100 ++} ++ ++# ++# Configure Resets ++# ++ ++adapter srst delay 100 ++jtag_ntrst_delay 100 ++reset_config trst_and_srst separate ++ ++# ++# Configure JTAG chain and determine IDCODE ++# ++ ++set AMPERE_SOCKETMAX 1 ++source [find target/ampere_ac03_tap.cfg] ++ ++# ++# Configure Targets ++# ++ ++if { [info exists CORELIST_S0] || [info exists COREMASK_S0_0] || [info exists COREMASK_S0_1] || [info exists COREMASK_S0_2] } { ++ set CHIPNAME s0 ++ if { [info exists CORELIST_S0] } { ++ set CORELIST $CORELIST_S0 ++ } else { ++ if { [info exists COREMASK_S0_0] } { ++ set COREMASK_0 $COREMASK_S0_0 ++ } else { ++ set COREMASK_0 0x0 ++ } ++ ++ if { [info exists COREMASK_S0_1] } { ++ set COREMASK_1 $COREMASK_S0_1 ++ } else { ++ set COREMASK_1 0x0 ++ } ++ ++ if { [info exists COREMASK_S0_2] } { ++ set COREMASK_2 $COREMASK_S0_2 ++ } else { ++ set COREMASK_2 0x0 ++ } ++ } ++} else { ++ set CHIPNAME s0 ++ set COREMASK_0 0x1 ++ set COREMASK_1 0x0 ++ set COREMASK_2 0x0 ++} ++ ++source [find target/ampere_ac03.cfg] +diff --git a/tcl/board/ampere_ac03_2s.cfg b/tcl/board/ampere_ac03_2s.cfg +new file mode 100644 +index 000000000..dd624cfdf +--- /dev/null ++++ b/tcl/board/ampere_ac03_2s.cfg +@@ -0,0 +1,154 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# OpenOCD Board Configuration for the AmpereOne Family processors ++# ++# Copyright (c) 2021-2024, Ampere Computing LLC ++# ++ ++# Argument Description ++# ++# JTAGFREQ ++# Set the JTAG clock frequency ++# Syntax: -c "set JTAGFREQ {freq_in_khz}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0, CORELIST_S1 ++# Specify available physical cores by number ++# Example syntax to attach to physical cores 16, 17, 94, 95, 128 and 129 for S0 and S1 ++# Syntax: -c "set CORELIST_S0 {16 17 94 95 128 129}" ++# Syntax: -c "set CORELIST_S1 {16 17 94 95 128 129}" ++# ++# COREMASK_S0_0, COREMASK_S1_0 ++# Specify available physical cores 0-63 by mask ++# Example syntax to attach to physical cores 16 and 17 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_0 {0x0000000000030000}" ++# Syntax: -c "set COREMASK_S1_0 {0x0000000000030000}" ++# ++# COREMASK_S0_1, COREMASK_S1_1 ++# Specify available physical cores 64-127 by mask ++# Example syntax to attach to physical cores 94 and 95 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_1 {0x00000000C0000000}" ++# Syntax: -c "set COREMASK_S1_1 {0x00000000C0000000}" ++# ++# COREMASK_S0_2, COREMASK_S1_2 ++# Specify available physical cores 128 and above by mask ++# Example syntax to attach to physical cores 128 and 129 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_2 {0x0000000000000003}" ++# Syntax: -c "set COREMASK_S1_2 {0x0000000000000003}" ++# ++# SPLITSMP ++# Group all ARMv8 cores per socket into individual SMP sessions ++# If not specified, group ARMv8 cores from both sockets into one SMP session ++# Syntax: -c "set SPLITSMP {}" ++ ++# ++# Configure JTAG speed ++# ++ ++if { [info exists JTAGFREQ] } { ++ adapter speed $JTAGFREQ ++} else { ++ adapter speed 100 ++} ++ ++# ++# Configure Board level SMP configuration if necessary ++# ++ ++if { ![info exists SPLITSMP] } { ++ # Group dual chip into a single SMP configuration ++ set SMP_STR "target smp" ++ set CORE_INDEX_OFFSET 0 ++} ++ ++# ++# Configure Resets ++# ++ ++adapter srst delay 100 ++jtag_ntrst_delay 100 ++reset_config trst_and_srst separate ++ ++# ++# Configure JTAG chain and determine IDCODE ++# ++ ++set AMPERE_SOCKETMAX 2 ++source [find target/ampere_ac03_tap.cfg] ++ ++# ++# Configure Targets ++# ++ ++if { [info exists CORELIST_S0] || [info exists COREMASK_S0_0] || [info exists COREMASK_S0_1] || [info exists COREMASK_S0_2] || [info exists CORELIST_S1] || [info exists COREMASK_S1_0] || [info exists COREMASK_S1_1] || [info exists COREMASK_S1_2] } { ++ set CHIPNAME s1 ++ if { [info exists CORELIST_S1] } { ++ set CORELIST $CORELIST_S1 ++ } else { ++ if { [info exists COREMASK_S1_0] } { ++ set COREMASK_0 $COREMASK_S1_0 ++ } else { ++ set COREMASK_0 0x0 ++ } ++ ++ if { [info exists COREMASK_S1_1] } { ++ set COREMASK_1 $COREMASK_S1_1 ++ } else { ++ set COREMASK_1 0x0 ++ } ++ ++ if { [info exists COREMASK_S1_2] } { ++ set COREMASK_2 $COREMASK_S1_2 ++ } else { ++ set COREMASK_2 0x0 ++ } ++ } ++ source [find target/ampere_ac03.cfg] ++ ++ set CHIPNAME s0 ++ if { [info exists CORELIST_S0] } { ++ set CORELIST $CORELIST_S0 ++ } else { ++ if { [info exists COREMASK_S0_0] } { ++ set COREMASK_0 $COREMASK_S0_0 ++ } else { ++ set COREMASK_0 0x0 ++ } ++ ++ if { [info exists COREMASK_S0_1] } { ++ set COREMASK_1 $COREMASK_S0_1 ++ } else { ++ set COREMASK_1 0x0 ++ } ++ ++ if { [info exists COREMASK_S0_2] } { ++ set COREMASK_2 $COREMASK_S0_2 ++ } else { ++ set COREMASK_2 0x0 ++ } ++ } ++ source [find target/ampere_ac03.cfg] ++} else { ++ set CHIPNAME s1 ++ set COREMASK_0 0x0 ++ set COREMASK_1 0x0 ++ set COREMASK_2 0x0 ++ source [find target/ampere_ac03.cfg] ++ ++ set CHIPNAME s0 ++ set COREMASK_0 0x1 ++ set COREMASK_1 0x0 ++ set COREMASK_2 0x0 ++ source [find target/ampere_ac03.cfg] ++} ++ ++if { ![info exists SPLITSMP] } { ++ # For dual socket SMP configuration, evaluate the string ++ eval $SMP_STR ++} +diff --git a/tcl/target/ampere_ac03.cfg b/tcl/target/ampere_ac03.cfg +new file mode 100644 +index 000000000..135b6e3fc +--- /dev/null ++++ b/tcl/target/ampere_ac03.cfg +@@ -0,0 +1,403 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# OpenOCD Target Configuration for the AmpereOne Family processors ++# ++# Copyright (c) 2021-2024, Ampere Computing LLC ++# ++ ++# Note: ++# The following script must be called before executing this script. ++# tcl/target/ampere_ac03_tap.cfg ++# This script establishes the TAPs in the JTAG chain and initializes the ++# "AMPERE_CHIP" variable used in this script. ++# ++# Command Line Argument Description ++# ++# SPLITSMP ++# Only used for dual socket systems. Do not use for a single socket setup. ++# Option pertains to the ARMv8 target core naming in a dual socket setup. ++# If specified, name all ARMv8 cores per socket as individual SMP sessions. ++# If not specified, name ARMv8 cores from both sockets as one SMP session. ++# This option is used in conjunction with the SMP_STR board file option. ++# Syntax: -c "set SPLITSMP {}" ++# ++# CHIPNAME ++# Specifies the chip socket. ++# Will typically be either s0 or s1 ++# If not specified, defaults to s0 ++# Syntax: -c "set CHIPNAME {s0}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# Automated Test Environment State (ATE) ++# If not specified, disables ATE boot mode ++# ATE=0, ATE boot mode disabled ++# ATE=1, ATE boot mode enabled ++# Syntax: -c "set ATE {0}" ++# Syntax: -c "set ATE {1}" ++# ++# CORELIST ++# Specify available physical cores by number ++# Example syntax to attach to physical cores 16 and 17 ++# Syntax: -c "set CORELIST {16 17}" ++# ++# COREMASK_0 ++# Specify available physical cores 0-63 by mask ++# Example syntax to connect to physical cores 16 and 17 ++# Syntax: -c "set COREMASK_0 {0x0000000000030000}" ++# ++# COREMASK_1 ++# Specify available physical cores 64-127 by mask ++# Example syntax to connect to physical cores 94 and 95 ++# Syntax: -c "set COREMASK_1 {0x00000000C0000000}" ++# ++# COREMASK_2 ++# Specify available physical cores 128 and above by mask ++# Example syntax to connect to physical cores 128 and 129 ++# Syntax: -c "set COREMASK_2 {0x0000000000000003}" ++ ++# Board File Argument Description ++# ++# These optional arguments are defined in the board file and ++# referenced by the target file. See the corresponding board ++# files for examples of their use. ++# ++# SMP_STR ++# This option is used primarily for a dual socket system and it is not ++# recommended for a single socket setup. This option configures whether ++# the SMP ARMv8 core grouping is maintained at the board or target cfg level. ++# Specify the option if the SMP core grouping is defined at the board level. ++# Do not specify if the SMP core grouping is defined at the chip level. ++# If not specified, defaults to SMP core grouping defined per socket. ++# If specified, "SMP_STR=target smp", the SMP core grouping is maintained ++# at the board cfg level. ++# Used in conjunction with the SPLITSMP option to group two chips into ++# a single SMP configuration or maintain as two separate SMP sessions. ++# ++# CORE_INDEX_OFFSET ++# Specifies the starting logical core index value. ++# Used for dual-socket systems. ++# For socket #0, set to 0 ++# For socket #1, set the starting logical core based from ++# the last logical core on socket #0. ++# If not specified, defaults to 0 ++ ++# ++# Configure defaults for target ++# These settings can be overridden in the board configuration file ++# ++ ++if { [info exists SMP_STR] } { ++ # SMP configured at the dual socket board level ++ set _SMP_STR $SMP_STR ++} else { ++ # SMP configured at the single socket target level ++ set _SMP_STR "target smp" ++} ++ ++if { [info exists CHIPNAME] } { ++ set _CHIPNAME $CHIPNAME ++} else { ++ set _CHIPNAME s0 ++} ++ ++if { [info exists CORE_INDEX_OFFSET] } { ++ set _CORE_INDEX_OFFSET $CORE_INDEX_OFFSET ++} else { ++ set _CORE_INDEX_OFFSET 0 ++} ++ ++if { [info exists ENDIAN] } { ++ set _ENDIAN $ENDIAN ++} else { ++ set _ENDIAN little ++} ++ ++if { [info exists CORELIST] } { ++ set _CORELIST $CORELIST ++} else { ++ if { [info exists COREMASK_0] } { ++ set _COREMASK_0 $COREMASK_0 ++ } else { ++ set _COREMASK_0 0x0 ++ } ++ ++ if { [info exists COREMASK_1] } { ++ set _COREMASK_1 $COREMASK_1 ++ } else { ++ set _COREMASK_1 0x0 ++ } ++ ++ if { [info exists COREMASK_2] } { ++ set _COREMASK_2 $COREMASK_2 ++ } else { ++ set _COREMASK_2 0x0 ++ } ++ ++ set _CORELIST {} ++ ++ set corenum 0 ++ set _MASK 0x1 ++ for {set i 0} {$i < 64} {incr i} { ++ if { [expr {$_COREMASK_0 & $_MASK}] != 0x0 } { ++ set _CORELIST "$_CORELIST $corenum" ++ } ++ set _MASK [expr {$_MASK << 0x1}] ++ incr corenum ++ } ++ ++ set _MASK 0x1 ++ for {set i 0} {$i < 64} {incr i} { ++ if { [expr {$_COREMASK_1 & $_MASK}] != 0x0 } { ++ set _CORELIST "$_CORELIST $corenum" ++ } ++ set _MASK [expr {$_MASK << 0x1}] ++ incr corenum ++ } ++ ++ set _MASK 0x1 ++ for {set i 0} {$i < 64} {incr i} { ++ if { [expr {$_COREMASK_2 & $_MASK}] != 0x0 } { ++ set _CORELIST "$_CORELIST $corenum" ++ } ++ set _MASK [expr {$_MASK << 0x1}] ++ incr corenum ++ } ++} ++ ++# ++# Definitions ++# ++ ++set _SYSTAPNAME sys ++ ++set _TARGETNAME_PCP pcp ++set _TARGETNAME_SECPRO secpro ++set _TARGETNAME_MPRO mpro ++set _TARGETNAME_BSV bsv ++ ++set _AP_ROM 0x00000000 ++set _AP_PCP_APB 0x00010000 ++set _AP_PCP_AXI 0x00020000 ++set _AP_SECPRO_AHB 0x00030000 ++set _AP_MPRO_AHB 0x00040000 ++set _AP_BSV 0x00050000 ++ ++if {! [info exists AMPERE_CHIP] } { ++ puts "FATAL ERROR: CHIP NOT DETECTED" ++ shutdown ++} ++ ++if {$AMPERE_CHIP == {ac03}} { ++ set options {-ignore-syspwrupack -ignore-dbgpwrupack} ++} elseif {$AMPERE_CHIP == {ac04}} { ++ set options {} ++} else { ++ set options {} ++} ++ ++set _TAPNAME_SYS $_CHIPNAME.$_SYSTAPNAME.tap ++set _DAPNAME_SYS $_CHIPNAME.$_SYSTAPNAME.dap ++ ++# ++# Configure JTAG DAP ++# ++ ++dap create $_DAPNAME_SYS -adiv6 -chain-position $_TAPNAME_SYS {*}$options ++ ++# ++# Create the DAP BSV AP target for the BSV block ++# ++ ++target create $_CHIPNAME.$_TARGETNAME_BSV mem_ap -endian $_ENDIAN -dap $_DAPNAME_SYS -ap-num $_AP_BSV ++ ++if { [info exists LCS] && [expr {"$LCS"!="0"}] } { ++ # ++ # Create the DAP AHB-AP MEM-AP target for the SECPRO CPU ++ # ++ ++ target create $_CHIPNAME.$_TARGETNAME_SECPRO.ahb mem_ap -endian $_ENDIAN -dap $_DAPNAME_SYS -ap-num $_AP_SECPRO_AHB ++ if { [info exists ATE] && [expr {"$ATE"!="0"}] } { ++ $_CHIPNAME.$_TARGETNAME_SECPRO.ahb configure -defer-examine ++ } ++ ++ # ++ # Configure target SECPRO CPU ++ # ++ ++ target create $_CHIPNAME.$_TARGETNAME_SECPRO cortex_m -endian $_ENDIAN -dap $_DAPNAME_SYS -ap-num $_AP_SECPRO_AHB ++ if { [info exists ATE] && [expr {"$ATE"!="0"}] } { ++ $_CHIPNAME.$_TARGETNAME_SECPRO configure -defer-examine ++ } ++ ++ # ++ # Create the DAP AHB-AP MEM-AP target for the MPRO CPU ++ # ++ ++ target create $_CHIPNAME.$_TARGETNAME_MPRO.ahb mem_ap -endian $_ENDIAN -dap $_DAPNAME_SYS -ap-num $_AP_MPRO_AHB ++ if { [info exists ATE] && [expr {"$ATE"!="0"}] } { ++ $_CHIPNAME.$_TARGETNAME_MPRO.ahb configure -defer-examine ++ } ++ ++ # ++ # Configure target MPRO CPU ++ # ++ ++ target create $_CHIPNAME.$_TARGETNAME_MPRO cortex_m -endian $_ENDIAN -dap $_DAPNAME_SYS -ap-num $_AP_MPRO_AHB ++ if { [info exists ATE] && [expr {"$ATE"!="0"}] } { ++ $_CHIPNAME.$_TARGETNAME_MPRO configure -defer-examine ++ } ++} ++ ++# ++# Create the DAP APB-AP MEM-AP target for the PCP block ++# ++ ++target create $_CHIPNAME.$_TARGETNAME_PCP.apb mem_ap -endian $_ENDIAN -dap $_DAPNAME_SYS -ap-num $_AP_PCP_APB ++if { [info exists ATE] && [expr {"$ATE"!="0"}] } { ++ $_CHIPNAME.$_TARGETNAME_PCP.apb configure -defer-examine ++} ++ ++# ++# Create the DAP AXI-AP MEM-AP target for the PCP block ++# ++ ++target create $_CHIPNAME.$_TARGETNAME_PCP.axi mem_ap -endian $_ENDIAN -dap $_DAPNAME_SYS -ap-num $_AP_PCP_AXI ++if { [info exists ATE] && [expr {"$ATE"!="0"}] } { ++ $_CHIPNAME.$_TARGETNAME_PCP.axi configure -defer-examine ++} ++ ++# Set CSW register value default correctly for AXI accessible device memory ++# Select the correct Access Port Number ++$_DAPNAME_SYS apsel $_AP_PCP_AXI ++ ++# First set the CSW to OpenOCD's internal default ++$_DAPNAME_SYS apcsw default ++ ++# Set Domain[1:0]=b'11 (CSW[14:13]=b'11) ++# Set Cache[3:0]=b'0000 (CSW[27:24]=b'0000) ++# Porter Cfg registers require secure access. AxPROT[1] (CSW[29]) must be b'0'. ++# Set AxPROT[2:0]=b'000 (CSW[30:28]=b'000) for an Unpriveleged, Secure, Data access. ++$_DAPNAME_SYS apcsw 0x00006000 0x7F006000 ++ ++# ++# Configure target CPUs ++# ++ ++# Zero index core number being operated on ++set _core 0 ++ ++# Zero index CCM number being operated on ++set _ccm 0 ++ ++# Base APB address of the Debug Bus in the system ++set _apb_base 0xA0000000 ++ ++# APB address offset and increment value for each CPM in the system ++set _apb_ccm_offset 0 ++set _apb_ccm_incr 0x400000 ++ ++# APB increment value for each CTI and Debug block per CCM ++set _apb_cti_incr 0x70000 ++set _apb_dbg_incr 0x80000 ++ ++# Set the logical core numbering starting value ++set logical_index $_CORE_INDEX_OFFSET ++ ++while { $_CORELIST != {} } { ++ if { $AMPERE_CHIP == {ac03} } { ++ if { [expr {($_ccm % 6) != 2}] && [expr {($_ccm % 6) != 3}] } { ++ # Every 1st (ccm=0), 2nd (ccm=1), 5th (ccm=4) and 6th (ccm=5) CCM is a CCM4 containing 4 PEs ++ set _num_pe 4 ++ } else { ++ # Every 3rd (ccm=2) and 4th (ccm=3) CCM is a CCM2 containing 2 PEs ++ set _num_pe 2 ++ } ++ } else { ++ set _num_pe 4 ++ } ++ ++ set _pe 0 ++ set _apb_cti_offset 0x70000 ++ set _apb_dbg_offset 0x200000 ++ ++ while { $_pe < $_num_pe } { ++ if { [lsearch -inline $_CORELIST $_core] == $_core } { ++ # Remove the core number from the list ++ set _CORELIST [lsearch -inline -all -not -exact $_CORELIST $_core] ++ ++ # Format a string to reference which CPU target to use ++ if { [info exists SPLITSMP] } { ++ set _TARGETNAME $_CHIPNAME.${_TARGETNAME_PCP}_$logical_index ++ } else { ++ set _TARGETNAME ${_TARGETNAME_PCP}_$logical_index ++ } ++ ++ # Create and configure Cross Trigger Interface (CTI) - required for halt and resume ++ set _CTINAME $_TARGETNAME.cti ++ set _cti_addr [expr {$_apb_base + $_apb_ccm_offset + $_apb_cti_offset}] ++ cti create $_CTINAME -dap $_DAPNAME_SYS -ap-num $_AP_PCP_APB -baseaddr $_cti_addr ++ ++ # Create the target ++ set _dbg_addr [expr {$_apb_base + $_apb_ccm_offset + $_apb_dbg_offset}] ++ target create $_TARGETNAME aarch64 -endian $_ENDIAN -dap $_DAPNAME_SYS -ap-num $_AP_PCP_APB -dbgbase $_dbg_addr -rtos hwthread -cti $_CTINAME -coreid $logical_index ++ ++ # Build string used to enable SMP mode for the ARMv8 CPU cores ++ set _SMP_STR "$_SMP_STR $_TARGETNAME" ++ ++ # Mesh must be initialized before PE cores can be accessed. Defer examination. ++ $_TARGETNAME configure -defer-examine ++ ++ # Clear CTI output/input enables that are not configured by OpenOCD for aarch64 ++ $_TARGETNAME configure -event reset-init [subst { ++ $_CTINAME write INEN0 0x00000000 ++ $_CTINAME write INEN1 0x00000000 ++ $_CTINAME write INEN2 0x00000000 ++ $_CTINAME write INEN3 0x00000000 ++ $_CTINAME write INEN4 0x00000000 ++ $_CTINAME write INEN5 0x00000000 ++ $_CTINAME write INEN6 0x00000000 ++ $_CTINAME write INEN7 0x00000000 ++ $_CTINAME write INEN8 0x00000000 ++ ++ $_CTINAME write OUTEN0 0x00000000 ++ $_CTINAME write OUTEN1 0x00000000 ++ $_CTINAME write OUTEN2 0x00000000 ++ $_CTINAME write OUTEN3 0x00000000 ++ $_CTINAME write OUTEN4 0x00000000 ++ $_CTINAME write OUTEN5 0x00000000 ++ $_CTINAME write OUTEN6 0x00000000 ++ $_CTINAME write OUTEN7 0x00000000 ++ $_CTINAME write OUTEN8 0x00000000 ++ }] ++ ++ incr logical_index ++ } ++ ++ incr _core ++ incr _pe ++ set _apb_cti_offset [expr {$_apb_cti_offset + $_apb_cti_incr}] ++ set _apb_dbg_offset [expr {$_apb_dbg_offset + $_apb_dbg_incr}] ++ } ++ ++ incr _ccm ++ set _apb_ccm_offset [expr {$_apb_ccm_offset + $_apb_ccm_incr}] ++} ++ ++if { [info exists SMP_STR] } { ++ # Return updated SMP configuration string back to board level ++ set SMP_STR $_SMP_STR ++} else { ++ # For single socket per SMP configuration, evaluate the string ++ eval $_SMP_STR ++} ++ ++if { [info exists CORE_INDEX_OFFSET] } { ++ # For multi-socket, return total number of cores back to board level ++ set CORE_INDEX_OFFSET $logical_index ++} +diff --git a/tcl/target/ampere_ac03_tap.cfg b/tcl/target/ampere_ac03_tap.cfg +new file mode 100644 +index 000000000..f4a2b756e +--- /dev/null ++++ b/tcl/target/ampere_ac03_tap.cfg +@@ -0,0 +1,99 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# OpenOCD JTAG Chain configuration for the AmpereOne Family processors ++# ++# Copyright (c) 2021-2024, Ampere Computing LLC ++# ++ ++set _CHIPNAME s ++ ++set _SYSTAPNAME sys ++set _DFTTAPNAME dft ++ ++set SYSTAPID_AC03 0x3BA06477 ++set SYSTAPID_AC04 0x4BA06477 ++ ++set DFTTAPID_AC03_A0 0x03100A2D ++set DFTTAPID_AC03_B0 0x13100A2D ++set DFTTAPID_AC04_A0 0x04100A2D ++set DFTTAPID_AC04_1_A0 0x04101A2D ++ ++if { [info exists AMPERE_SOCKETMAX] } { ++ set _AMPERE_SOCKETMAX $AMPERE_SOCKETMAX ++ set socket_num [expr {$_AMPERE_SOCKETMAX - 1}] ++} else { ++ set _AMPERE_SOCKETMAX 1 ++ set socket_num 0 ++} ++ ++for {set socket_idx 0} {$socket_idx < $_AMPERE_SOCKETMAX} {incr socket_idx} { ++ if { [info exists DFTTAPID] } { ++ jtag newtap ${_CHIPNAME}${socket_num} ${_DFTTAPNAME}.tap -irlen 8 -ircapture 0x1 -irmask 0x3 \ ++ -expected-id $DFTTAPID ++ } else { ++ jtag newtap ${_CHIPNAME}${socket_num} ${_DFTTAPNAME}.tap -irlen 8 -ircapture 0x1 -irmask 0x3 \ ++ -expected-id $DFTTAPID_AC03_A0 \ ++ -expected-id $DFTTAPID_AC03_B0 \ ++ -expected-id $DFTTAPID_AC04_A0 \ ++ -expected-id $DFTTAPID_AC04_1_A0 ++ } ++ ++ if { [info exists SYSTAPID] } { ++ jtag newtap ${_CHIPNAME}${socket_num} ${_SYSTAPNAME}.tap -irlen 4 -ircapture 0x1 -irmask 0x3 \ ++ -expected-id $SYSTAPID ++ } else { ++ jtag newtap ${_CHIPNAME}${socket_num} ${_SYSTAPNAME}.tap -irlen 4 -ircapture 0x1 -irmask 0x3 \ ++ -expected-id $SYSTAPID_AC03 \ ++ -expected-id $SYSTAPID_AC04 ++ } ++ ++ incr socket_num -1 ++} ++ ++# ++# Initialize the JTAG chain for the defined TAPs ++# Detect chip idcode ++# ++ ++set result [capture {jtag init}] ++set dft_tap_start [string first ${_CHIPNAME}0.${_DFTTAPNAME}.tap $result] ++set sys_tap_start [string first ${_CHIPNAME}0.${_SYSTAPNAME}.tap $result] ++ ++if { $dft_tap_start >= 0 } { ++ set dft_tap_string [string range $result $dft_tap_start end] ++ lassign $dft_tap_string c0 c1 c2 dft_tap_idcode ++ set dft_tap_idcode [expr {$dft_tap_idcode}] ++ echo "IDCODE found: $dft_tap_idcode" ++} else { ++ set dft_tap_idcode 0x00000000 ++} ++ ++if { $sys_tap_start >= 0 } { ++ set sys_tap_string [string range $result $sys_tap_start end] ++ lassign $sys_tap_string c0 c1 c2 sys_tap_idcode ++ set sys_tap_idcode [expr {$sys_tap_idcode}] ++ echo "IDCODE found: $sys_tap_idcode" ++} else { ++ set sys_tap_idcode 0x00000000 ++} ++ ++if { $dft_tap_idcode == $DFTTAPID_AC03_A0 } { ++ set AMPERE_CHIP ac03 ++ set AMPERE_REV A0 ++} elseif { $dft_tap_idcode == $DFTTAPID_AC03_B0 } { ++ set AMPERE_CHIP ac03 ++ set AMPERE_REV B0 ++} elseif { $dft_tap_idcode == $DFTTAPID_AC04_A0 } { ++ set AMPERE_CHIP ac04 ++ set AMPERE_REV A0 ++} elseif { $dft_tap_idcode == $DFTTAPID_AC04_1_A0 } { ++ set AMPERE_CHIP ac04_1 ++ set AMPERE_REV A0 ++} else { ++ set AMPERE_CHIP unknown ++ set AMPERE_REV unknown ++} ++ ++if { ![info exists AMPERE_PLATFORM] } { ++ set AMPERE_PLATFORM unknown ++} +-- +2.25.1 + diff --git a/patches/0030-ac03-target-board-AmpereOne-boundary-scan-configs-DO.patch b/patches/0030-ac03-target-board-AmpereOne-boundary-scan-configs-DO.patch new file mode 100644 index 000000000..6865d54f3 --- /dev/null +++ b/patches/0030-ac03-target-board-AmpereOne-boundary-scan-configs-DO.patch @@ -0,0 +1,109 @@ +From 1c61bcf4aef92855a60cf9dec84ad9085d205096 Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Mon, 5 Dec 2022 13:49:28 -0800 +Subject: [PATCH 30/33] ac03: target/board: AmpereOne boundary-scan configs [DO + NOT UPSTREAM] + +Add AmpereOne Family target/board boundary-scan configuration files. + +The target configuration file supports silicon and emulation. +The board configuration files support 1 and 2 socket platforms. + +Change-Id: I355433e09656ba3b2dff4c07353ace7345b9c403 +Signed-off-by: Daniel Goehring +--- + tcl/board/ampere_ac03_1s_bs.cfg | 37 +++++++++++++++++++++++++++++++++ + tcl/board/ampere_ac03_2s_bs.cfg | 37 +++++++++++++++++++++++++++++++++ + 2 files changed, 74 insertions(+) + create mode 100644 tcl/board/ampere_ac03_1s_bs.cfg + create mode 100644 tcl/board/ampere_ac03_2s_bs.cfg + +diff --git a/tcl/board/ampere_ac03_1s_bs.cfg b/tcl/board/ampere_ac03_1s_bs.cfg +new file mode 100644 +index 000000000..9e9f04b25 +--- /dev/null ++++ b/tcl/board/ampere_ac03_1s_bs.cfg +@@ -0,0 +1,37 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# OpenOCD Board Configuration for the AmpereOne Family processors ++# ++# Copyright (c) 2022-2024, Ampere Computing LLC ++# ++ ++# Argument Description ++# ++# JTAGFREQ ++# Set the JTAG clock frequency ++# Syntax: -c "set JTAGFREQ {freq_in_khz}" ++ ++# ++# Configure JTAG speed ++# ++ ++if { [info exists JTAGFREQ] } { ++ adapter speed $JTAGFREQ ++} else { ++ adapter speed 100 ++} ++ ++# ++# Configure Resets ++# ++ ++adapter srst delay 100 ++jtag_ntrst_delay 100 ++reset_config trst_and_srst separate ++ ++# ++# Configure Targets ++# ++ ++set AMPERE_SOCKETMAX 1 ++source [find target/ampere_ac03_tap.cfg] +diff --git a/tcl/board/ampere_ac03_2s_bs.cfg b/tcl/board/ampere_ac03_2s_bs.cfg +new file mode 100644 +index 000000000..25d8c18e8 +--- /dev/null ++++ b/tcl/board/ampere_ac03_2s_bs.cfg +@@ -0,0 +1,37 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# OpenOCD Board Configuration for the AmpereOne Family processors ++# ++# Copyright (c) 2022-2024, Ampere Computing LLC ++# ++ ++# Argument Description ++# ++# JTAGFREQ ++# Set the JTAG clock frequency ++# Syntax: -c "set JTAGFREQ {freq_in_khz}" ++ ++# ++# Configure JTAG speed ++# ++ ++if { [info exists JTAGFREQ] } { ++ adapter speed $JTAGFREQ ++} else { ++ adapter speed 100 ++} ++ ++# ++# Configure Resets ++# ++ ++adapter srst delay 100 ++jtag_ntrst_delay 100 ++reset_config trst_and_srst separate ++ ++# ++# Configure Targets ++# ++ ++set AMPERE_SOCKETMAX 2 ++source [find target/ampere_ac03_tap.cfg] +-- +2.25.1 + diff --git a/patches/0031-ac03-silicon-user-configs-DO-NOT-UPSTREAM.patch b/patches/0031-ac03-silicon-user-configs-DO-NOT-UPSTREAM.patch new file mode 100644 index 000000000..e695b5929 --- /dev/null +++ b/patches/0031-ac03-silicon-user-configs-DO-NOT-UPSTREAM.patch @@ -0,0 +1,226 @@ +From b758142734639a4b22cb5781fa26a5f726c11886 Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Fri, 7 May 2021 13:53:34 -0400 +Subject: [PATCH 31/33] ac03: silicon user configs [DO NOT UPSTREAM] + +Add user configuration files for AmpereOne Family chips. + +Configured for the Olimex ARM-USB-OCD_H JTAG probe. +https://www.olimex.com/Products/ARM/JTAG/ARM-USB-OCD-H/ + +OpenOCD configured for the following AmpereOne Family options +1. One and two socket platforms + +Change-Id: I196af0a39cb920427d1f489fa2699a5e97edb704 +Signed-off-by: Daniel Goehring +--- + tcl/openocd.ac03_1s_sil.cfg | 90 +++++++++++++++++++++++++++++++++ + tcl/openocd.ac03_2s_sil.cfg | 99 +++++++++++++++++++++++++++++++++++++ + 2 files changed, 189 insertions(+) + create mode 100644 tcl/openocd.ac03_1s_sil.cfg + create mode 100644 tcl/openocd.ac03_2s_sil.cfg + +diff --git a/tcl/openocd.ac03_1s_sil.cfg b/tcl/openocd.ac03_1s_sil.cfg +new file mode 100644 +index 000000000..56fb35f71 +--- /dev/null ++++ b/tcl/openocd.ac03_1s_sil.cfg +@@ -0,0 +1,90 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the AmpereOne ++# and AmpereOne X Development Platforms ++# ++# Copyright (c) 2021-2024, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "4000" kHz ++# Syntax: -c "set JTAGFREQ {4000}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0 ++# Specify available physical cores by number ++# Example syntax to attach to physical cores 16, 17, 94, 95, 128 and 129 for S0 ++# Syntax: -c "set CORELIST_S0 {16 17 94 95 128 129}" ++# ++# COREMASK_S0_0 ++# Specify available physical cores 0-63 by mask ++# Example syntax to attach to physical cores 16 and 17 for S0 ++# Syntax: -c "set COREMASK_S0_0 {0x0000000000030000}" ++# ++# COREMASK_S0_1 ++# Specify available physical cores 64-127 by mask ++# Example syntax to attach to physical cores 94 and 95 for S0 ++# Syntax: -c "set COREMASK_S0_1 {0x00000000C0000000}" ++# ++# COREMASK_S0_2 ++# Specify available physical cores 128 and above by mask ++# Example syntax to attach to physical cores 128 and 129 for S0 ++# Syntax: -c "set COREMASK_S0_2 {0x0000000000000003}" ++ ++# Operating System Environment Variable Overrides ++# ++# OCD_GDB_PORT ++# Specify OpenOCD's GDB port ++# csh: setenv OCD_GDB_PORT 3333 ++# bash: export OCD_GDB_PORT=3333 ++# ++# OCD_TELNET_PORT ++# Specify OpenOCD's Telnet port ++# csh: setenv OCD_TELNET_PORT 4444 ++# bash: export OCD_TELNET_PORT=4444 ++# ++# OCD_TCL_PORT ++# Specify OpenOCD's TCL port ++# csh: setenv OCD_TCL_PORT 6666 ++# bash: export OCD_TCL_PORT=6666 ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++if { [info exists env(OCD_GDB_PORT)] } { ++ gdb_port $::env(OCD_GDB_PORT) ++} ++ ++if { [info exists env(OCD_TELNET_PORT)] } { ++ telnet_port $::env(OCD_TELNET_PORT) ++} ++ ++if { [info exists env(OCD_TCL_PORT)] } { ++ tcl_port $::env(OCD_TCL_PORT) ++} ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 4000 ++} ++ ++set AMPERE_PLATFORM silicon ++source [find board/ampere_ac03_1s.cfg] +diff --git a/tcl/openocd.ac03_2s_sil.cfg b/tcl/openocd.ac03_2s_sil.cfg +new file mode 100644 +index 000000000..e7a785f13 +--- /dev/null ++++ b/tcl/openocd.ac03_2s_sil.cfg +@@ -0,0 +1,99 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the AmpereOne ++# and AmpereOne X Development Platforms ++# ++# Copyright (c) 2021-2024, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "3000" kHz ++# Syntax: -c "set JTAGFREQ {3000}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0, CORELIST_S1 ++# Specify available physical cores by number ++# Example syntax to attach to physical cores 16, 17, 94, 95, 128 and 129 for S0 and S1 ++# Syntax: -c "set CORELIST_S0 {16 17 94 95 128 129}" ++# Syntax: -c "set CORELIST_S1 {16 17 94 95 128 129}" ++# ++# COREMASK_S0_0, COREMASK_S1_0 ++# Specify available physical cores 0-63 by mask ++# Example syntax to attach to physical cores 16 and 17 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_0 {0x0000000000030000}" ++# Syntax: -c "set COREMASK_S1_0 {0x0000000000030000}" ++# ++# COREMASK_S0_1, COREMASK_S1_1 ++# Specify available physical cores 64-127 by mask ++# Example syntax to attach to physical cores 94 and 95 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_1 {0x00000000C0000000}" ++# Syntax: -c "set COREMASK_S1_1 {0x00000000C0000000}" ++# ++# COREMASK_S0_2, COREMASK_S1_2 ++# Specify available physical cores 128 and above by mask ++# Example syntax to attach to physical cores 128 and 129 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_2 {0x0000000000000003}" ++# Syntax: -c "set COREMASK_S1_2 {0x0000000000000003}" ++# ++# SPLITSMP ++# Group all ARMv8 cores per socket into individual SMP sessions ++# If not specified, group ARMv8 cores from both sockets into one SMP session ++# Syntax: -c "set SPLITSMP {}" ++ ++# Operating System Environment Variable Overrides ++# ++# OCD_GDB_PORT ++# Specify OpenOCD's GDB port ++# csh: setenv OCD_GDB_PORT 3333 ++# bash: export OCD_GDB_PORT=3333 ++# ++# OCD_TELNET_PORT ++# Specify OpenOCD's Telnet port ++# csh: setenv OCD_TELNET_PORT 4444 ++# bash: export OCD_TELNET_PORT=4444 ++# ++# OCD_TCL_PORT ++# Specify OpenOCD's TCL port ++# csh: setenv OCD_TCL_PORT 6666 ++# bash: export OCD_TCL_PORT=6666 ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++if { [info exists env(OCD_GDB_PORT)] } { ++ gdb_port $::env(OCD_GDB_PORT) ++} ++ ++if { [info exists env(OCD_TELNET_PORT)] } { ++ telnet_port $::env(OCD_TELNET_PORT) ++} ++ ++if { [info exists env(OCD_TCL_PORT)] } { ++ tcl_port $::env(OCD_TCL_PORT) ++} ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 3000 ++} ++ ++set AMPERE_PLATFORM silicon ++source [find board/ampere_ac03_2s.cfg] +-- +2.25.1 + diff --git a/patches/0032-ac03-BMC-remote-debug-user-configs-DO-NOT-UPSTREAM.patch b/patches/0032-ac03-BMC-remote-debug-user-configs-DO-NOT-UPSTREAM.patch new file mode 100644 index 000000000..ce3bfa814 --- /dev/null +++ b/patches/0032-ac03-BMC-remote-debug-user-configs-DO-NOT-UPSTREAM.patch @@ -0,0 +1,221 @@ +From acc360de2f4a0f8ba0646f7973c0f73dbef28a35 Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Fri, 7 May 2021 14:16:08 -0400 +Subject: [PATCH 32/33] ac03: BMC remote debug user configs [DO NOT UPSTREAM] + +Add AST2600 BMC remote debug user configuration files for AmpereOne +Family chips. + +Change-Id: I13c052db59912fe24861292ca13610772dc9d05a +Signed-off-by: Daniel Goehring +--- + tcl/openocd.ac03_1s_bmc.cfg | 90 +++++++++++++++++++++++++++++++++ + tcl/openocd.ac03_2s_bmc.cfg | 99 +++++++++++++++++++++++++++++++++++++ + 2 files changed, 189 insertions(+) + create mode 100644 tcl/openocd.ac03_1s_bmc.cfg + create mode 100644 tcl/openocd.ac03_2s_bmc.cfg + +diff --git a/tcl/openocd.ac03_1s_bmc.cfg b/tcl/openocd.ac03_1s_bmc.cfg +new file mode 100644 +index 000000000..c81053114 +--- /dev/null ++++ b/tcl/openocd.ac03_1s_bmc.cfg +@@ -0,0 +1,90 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the AST2600 BMC ++# on the AmpereOne and AmpereOne X development platforms ++# ++# Copyright (c) 2021-2024, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "12375" kHz ++# Syntax: -c "set JTAGFREQ {12375}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0 ++# Specify available physical cores by number ++# Example syntax to attach to physical cores 16, 17, 94, 95, 128 and 129 for S0 ++# Syntax: -c "set CORELIST_S0 {16 17 94 95 128 129}" ++# ++# COREMASK_S0_0 ++# Specify available physical cores 0-63 by mask ++# Example syntax to attach to physical cores 16 and 17 for S0 ++# Syntax: -c "set COREMASK_S0_0 {0x0000000000030000}" ++# ++# COREMASK_S0_1 ++# Specify available physical cores 64-127 by mask ++# Example syntax to attach to physical cores 94 and 95 for S0 ++# Syntax: -c "set COREMASK_S0_1 {0x00000000C0000000}" ++# ++# COREMASK_S0_2 ++# Specify available physical cores 128 and above by mask ++# Example syntax to attach to physical cores 128 and 129 for S0 ++# Syntax: -c "set COREMASK_S0_2 {0x0000000000000003}" ++ ++# Operating System Environment Variable Overrides ++# ++# OCD_GDB_PORT ++# Specify OpenOCD's GDB port ++# csh: setenv OCD_GDB_PORT 3333 ++# bash: export OCD_GDB_PORT=3333 ++# ++# OCD_TELNET_PORT ++# Specify OpenOCD's Telnet port ++# csh: setenv OCD_TELNET_PORT 4444 ++# bash: export OCD_TELNET_PORT=4444 ++# ++# OCD_TCL_PORT ++# Specify OpenOCD's TCL port ++# csh: setenv OCD_TCL_PORT 6666 ++# bash: export OCD_TCL_PORT=6666 ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++if { [info exists env(OCD_GDB_PORT)] } { ++ gdb_port $::env(OCD_GDB_PORT) ++} ++ ++if { [info exists env(OCD_TELNET_PORT)] } { ++ telnet_port $::env(OCD_TELNET_PORT) ++} ++ ++if { [info exists env(OCD_TCL_PORT)] } { ++ tcl_port $::env(OCD_TCL_PORT) ++} ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/jtag_driver.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 12375 ++} ++ ++set AMPERE_PLATFORM silicon ++source [find board/ampere_ac03_1s.cfg] +diff --git a/tcl/openocd.ac03_2s_bmc.cfg b/tcl/openocd.ac03_2s_bmc.cfg +new file mode 100644 +index 000000000..3ad64649e +--- /dev/null ++++ b/tcl/openocd.ac03_2s_bmc.cfg +@@ -0,0 +1,99 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the AST2600 BMC ++# on the AmpereOne and AmpereOne X development platforms ++# ++# Copyright (c) 2021-2024, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "12375" kHz ++# Syntax: -c "set JTAGFREQ {12375}" ++# ++# Life-Cycle State (LCS) ++# If not specified, defaults to "Secure LCS" ++# LCS=0, "Secure LCS" ++# LCS=1, "Chip Manufacturing LCS" ++# Syntax: -c "set LCS {0}" ++# Syntax: -c "set LCS {1}" ++# ++# CORELIST_S0, CORELIST_S1 ++# Specify available physical cores by number ++# Example syntax to attach to physical cores 16, 17, 94, 95, 128 and 129 for S0 and S1 ++# Syntax: -c "set CORELIST_S0 {16 17 94 95 128 129}" ++# Syntax: -c "set CORELIST_S1 {16 17 94 95 128 129}" ++# ++# COREMASK_S0_0, COREMASK_S1_0 ++# Specify available physical cores 0-63 by mask ++# Example syntax to attach to physical cores 16 and 17 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_0 {0x0000000000030000}" ++# Syntax: -c "set COREMASK_S1_0 {0x0000000000030000}" ++# ++# COREMASK_S0_1, COREMASK_S1_1 ++# Specify available physical cores 64-127 by mask ++# Example syntax to attach to physical cores 94 and 95 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_1 {0x00000000C0000000}" ++# Syntax: -c "set COREMASK_S1_1 {0x00000000C0000000}" ++# ++# COREMASK_S0_2, COREMASK_S1_2 ++# Specify available physical cores 128 and above by mask ++# Example syntax to attach to physical cores 128 and 129 for S0 and S1 ++# Syntax: -c "set COREMASK_S0_2 {0x0000000000000003}" ++# Syntax: -c "set COREMASK_S1_2 {0x0000000000000003}" ++# ++# SPLITSMP ++# Group all ARMv8 cores per socket into individual SMP sessions ++# If not specified, group ARMv8 cores from both sockets into one SMP session ++# Syntax: -c "set SPLITSMP {}" ++ ++# Operating System Environment Variable Overrides ++# ++# OCD_GDB_PORT ++# Specify OpenOCD's GDB port ++# csh: setenv OCD_GDB_PORT 3333 ++# bash: export OCD_GDB_PORT=3333 ++# ++# OCD_TELNET_PORT ++# Specify OpenOCD's Telnet port ++# csh: setenv OCD_TELNET_PORT 4444 ++# bash: export OCD_TELNET_PORT=4444 ++# ++# OCD_TCL_PORT ++# Specify OpenOCD's TCL port ++# csh: setenv OCD_TCL_PORT 6666 ++# bash: export OCD_TCL_PORT=6666 ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++if { [info exists env(OCD_GDB_PORT)] } { ++ gdb_port $::env(OCD_GDB_PORT) ++} ++ ++if { [info exists env(OCD_TELNET_PORT)] } { ++ telnet_port $::env(OCD_TELNET_PORT) ++} ++ ++if { [info exists env(OCD_TCL_PORT)] } { ++ tcl_port $::env(OCD_TCL_PORT) ++} ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/jtag_driver.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 12375 ++} ++ ++set AMPERE_PLATFORM silicon ++source [find board/ampere_ac03_2s.cfg] +-- +2.25.1 + diff --git a/patches/0033-ac03-boundary-scan-user-configs-DO-NOT-UPSTREAM.patch b/patches/0033-ac03-boundary-scan-user-configs-DO-NOT-UPSTREAM.patch new file mode 100644 index 000000000..e181fa362 --- /dev/null +++ b/patches/0033-ac03-boundary-scan-user-configs-DO-NOT-UPSTREAM.patch @@ -0,0 +1,264 @@ +From 6a9fcf23cdffb31670c5db331547e30ce6b8be3b Mon Sep 17 00:00:00 2001 +From: Daniel Goehring +Date: Mon, 5 Dec 2022 13:53:34 -0800 +Subject: [PATCH 33/33] ac03: boundary-scan user configs [DO NOT UPSTREAM] + +Add 1P and 2P boundary-scan user configuration files for AmpereOne +Family chips. + +Change-Id: Iacd78fe64846ecbc7fff2796f47ca30d4168189b +Signed-off-by: Daniel Goehring +--- + tcl/openocd.ac03_1s_bmc_bs.cfg | 54 ++++++++++++++++++++++++++++++++++ + tcl/openocd.ac03_1s_sil_bs.cfg | 54 ++++++++++++++++++++++++++++++++++ + tcl/openocd.ac03_2s_bmc_bs.cfg | 54 ++++++++++++++++++++++++++++++++++ + tcl/openocd.ac03_2s_sil_bs.cfg | 54 ++++++++++++++++++++++++++++++++++ + 4 files changed, 216 insertions(+) + create mode 100644 tcl/openocd.ac03_1s_bmc_bs.cfg + create mode 100644 tcl/openocd.ac03_1s_sil_bs.cfg + create mode 100644 tcl/openocd.ac03_2s_bmc_bs.cfg + create mode 100644 tcl/openocd.ac03_2s_sil_bs.cfg + +diff --git a/tcl/openocd.ac03_1s_bmc_bs.cfg b/tcl/openocd.ac03_1s_bmc_bs.cfg +new file mode 100644 +index 000000000..ed780cd8f +--- /dev/null ++++ b/tcl/openocd.ac03_1s_bmc_bs.cfg +@@ -0,0 +1,54 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the AST2600 BMC ++# on the AmpereOne and AmpereOne X development platforms ++# ++# Copyright (c) 2022-2024, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "1000" kHz ++# Syntax: -c "set JTAGFREQ {1000}" ++ ++# Operating System Environment Variable Overrides ++# ++# OCD_TELNET_PORT ++# Specify OpenOCD's Telnet port ++# csh: setenv OCD_TELNET_PORT 4444 ++# bash: export OCD_TELNET_PORT=4444 ++# ++# OCD_TCL_PORT ++# Specify OpenOCD's TCL port ++# csh: setenv OCD_TCL_PORT 6666 ++# bash: export OCD_TCL_PORT=6666 ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++if { [info exists env(OCD_TELNET_PORT)] } { ++ telnet_port $::env(OCD_TELNET_PORT) ++} ++ ++if { [info exists env(OCD_TCL_PORT)] } { ++ tcl_port $::env(OCD_TCL_PORT) ++} ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/jtag_driver.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 1000 ++} ++ ++set AMPERE_PLATFORM silicon ++source [find board/ampere_ac03_1s_bs.cfg] +diff --git a/tcl/openocd.ac03_1s_sil_bs.cfg b/tcl/openocd.ac03_1s_sil_bs.cfg +new file mode 100644 +index 000000000..2844cd330 +--- /dev/null ++++ b/tcl/openocd.ac03_1s_sil_bs.cfg +@@ -0,0 +1,54 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the AmpereOne ++# and AmpereOne X Development Platforms ++# ++# Copyright (c) 2022-2024, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "1000" kHz ++# Syntax: -c "set JTAGFREQ {1000}" ++ ++# Operating System Environment Variable Overrides ++# ++# OCD_TELNET_PORT ++# Specify OpenOCD's Telnet port ++# csh: setenv OCD_TELNET_PORT 4444 ++# bash: export OCD_TELNET_PORT=4444 ++# ++# OCD_TCL_PORT ++# Specify OpenOCD's TCL port ++# csh: setenv OCD_TCL_PORT 6666 ++# bash: export OCD_TCL_PORT=6666 ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++if { [info exists env(OCD_TELNET_PORT)] } { ++ telnet_port $::env(OCD_TELNET_PORT) ++} ++ ++if { [info exists env(OCD_TCL_PORT)] } { ++ tcl_port $::env(OCD_TCL_PORT) ++} ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 1000 ++} ++ ++set AMPERE_PLATFORM silicon ++source [find board/ampere_ac03_1s_bs.cfg] +diff --git a/tcl/openocd.ac03_2s_bmc_bs.cfg b/tcl/openocd.ac03_2s_bmc_bs.cfg +new file mode 100644 +index 000000000..0518e0bf0 +--- /dev/null ++++ b/tcl/openocd.ac03_2s_bmc_bs.cfg +@@ -0,0 +1,54 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the AST2600 BMC ++# on the AmpereOne and AmpereOne X development platforms ++# ++# Copyright (c) 2022-2024, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "1000" kHz ++# Syntax: -c "set JTAGFREQ {1000}" ++ ++# Operating System Environment Variable Overrides ++# ++# OCD_TELNET_PORT ++# Specify OpenOCD's Telnet port ++# csh: setenv OCD_TELNET_PORT 4444 ++# bash: export OCD_TELNET_PORT=4444 ++# ++# OCD_TCL_PORT ++# Specify OpenOCD's TCL port ++# csh: setenv OCD_TCL_PORT 6666 ++# bash: export OCD_TCL_PORT=6666 ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++if { [info exists env(OCD_TELNET_PORT)] } { ++ telnet_port $::env(OCD_TELNET_PORT) ++} ++ ++if { [info exists env(OCD_TCL_PORT)] } { ++ tcl_port $::env(OCD_TCL_PORT) ++} ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/jtag_driver.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 1000 ++} ++ ++set AMPERE_PLATFORM silicon ++source [find board/ampere_ac03_2s_bs.cfg] +diff --git a/tcl/openocd.ac03_2s_sil_bs.cfg b/tcl/openocd.ac03_2s_sil_bs.cfg +new file mode 100644 +index 000000000..51681508f +--- /dev/null ++++ b/tcl/openocd.ac03_2s_sil_bs.cfg +@@ -0,0 +1,54 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++# ++# Example OpenOCD user configuration for the AmpereOne ++# and AmpereOne X Development Platforms ++# ++# Copyright (c) 2022-2024, Ampere Computing LLC ++# ++ ++# Command Line Argument Description ++# ++# JTAGFREQ ++# Override the default JTAG clock frequency ++# If not specified, defaults to "1000" kHz ++# Syntax: -c "set JTAGFREQ {1000}" ++ ++# Operating System Environment Variable Overrides ++# ++# OCD_TELNET_PORT ++# Specify OpenOCD's Telnet port ++# csh: setenv OCD_TELNET_PORT 4444 ++# bash: export OCD_TELNET_PORT=4444 ++# ++# OCD_TCL_PORT ++# Specify OpenOCD's TCL port ++# csh: setenv OCD_TCL_PORT 6666 ++# bash: export OCD_TCL_PORT=6666 ++ ++bindto 0.0.0.0 ++#debug_level 3 ++ ++if { [info exists env(OCD_TELNET_PORT)] } { ++ telnet_port $::env(OCD_TELNET_PORT) ++} ++ ++if { [info exists env(OCD_TCL_PORT)] } { ++ tcl_port $::env(OCD_TCL_PORT) ++} ++ ++# ++# Interface Configuration ++# ++ ++source [find interface/ftdi/olimex-arm-usb-ocd-h.cfg] ++ ++# ++# Board (Platform) Configuration ++# ++ ++if { ![info exists JTAGFREQ] } { ++ set JTAGFREQ 1000 ++} ++ ++set AMPERE_PLATFORM silicon ++source [find board/ampere_ac03_2s_bs.cfg] +-- +2.25.1 + diff --git a/patches/README b/patches/README new file mode 100644 index 000000000..3a38215c3 --- /dev/null +++ b/patches/README @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (c) 2020-2024, Ampere Computing LLC +# + +To apply the Ampere feature patches... + +$ git clone https://git.code.sf.net/p/openocd/code openocd +$ cd openocd +$ git checkout 437dde701c13e707e5fd912ef6403e09052e4d9b +$ git am /openocd/patches/*.patch