aboutsummaryrefslogtreecommitdiff
path: root/src/target/armv8_dpm.c
diff options
context:
space:
mode:
authorOmair Javaid <omair.javaid@linaro.org>2018-01-22 03:26:01 +0500
committerMatthias Welwarsky <matthias@welwarsky.de>2018-03-10 13:23:48 +0000
commita48264414e53d99ffe69df0687abf1effb13be22 (patch)
treef113994325915e9ee181c21d68aa159377a69b79 /src/target/armv8_dpm.c
parentb4a01f8cdc943fe03a827513aad2f4df2d2a7399 (diff)
downloadriscv-openocd-a48264414e53d99ffe69df0687abf1effb13be22.zip
riscv-openocd-a48264414e53d99ffe69df0687abf1effb13be22.tar.gz
riscv-openocd-a48264414e53d99ffe69df0687abf1effb13be22.tar.bz2
Support AArch64 SIMD/FP registers read/write
This patch adds support in openOCD to read/write AArch64 SIMD/FP registers. This patch depends on a previous patch which adds support to generation of target xml by openOCD with nested architecture defined types. AArch64 SIMD/FP registers assumes various types and to support all types we implement them as architecture defined type aarch64v which in turn consists of various architecture defined types. This is compatible with AArch64-FPU target xml in GDB. Please refer to binutils-gdb/gdb/features/aarch64-fpu.xml Change-Id: I7ffb0c21b3c2e08f13720b765408b30aab2a9808 Signed-off-by: Omair Javaid <omair.javaid@linaro.org> Reviewed-on: http://openocd.zylin.com/4373 Tested-by: jenkins Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de>
Diffstat (limited to 'src/target/armv8_dpm.c')
-rw-r--r--src/target/armv8_dpm.c80
1 files changed, 58 insertions, 22 deletions
diff --git a/src/target/armv8_dpm.c b/src/target/armv8_dpm.c
index c79b1a0..91b2f51 100644
--- a/src/target/armv8_dpm.c
+++ b/src/target/armv8_dpm.c
@@ -650,21 +650,37 @@ int armv8_dpm_modeswitch(struct arm_dpm *dpm, enum arm_mode mode)
static int dpmv8_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
{
struct armv8_common *armv8 = dpm->arm->arch_info;
- uint64_t value_64;
- int retval;
+ int retval = ERROR_FAIL;
+
+ if (r->size <= 64) {
+ uint64_t value_64;
+ retval = armv8->read_reg_u64(armv8, regnum, &value_64);
+
+ if (retval == ERROR_OK) {
+ r->valid = true;
+ r->dirty = false;
+ buf_set_u64(r->value, 0, r->size, value_64);
+ if (r->size == 64)
+ LOG_DEBUG("READ: %s, %16.8llx", r->name, (unsigned long long) value_64);
+ else
+ LOG_DEBUG("READ: %s, %8.8x", r->name, (unsigned int) value_64);
+ }
+ } else if (r->size <= 128) {
+ uint64_t lvalue = 0, hvalue = 0;
+ retval = armv8->read_reg_u128(armv8, regnum, &lvalue, &hvalue);
+
+ if (retval == ERROR_OK) {
+ r->valid = true;
+ r->dirty = false;
- retval = armv8->read_reg_u64(armv8, regnum, &value_64);
+ buf_set_u64(r->value, 0, 64, lvalue);
+ buf_set_u64(r->value + 8, 0, r->size - 64, hvalue);
- if (retval == ERROR_OK) {
- r->valid = true;
- r->dirty = false;
- buf_set_u64(r->value, 0, r->size, value_64);
- if (r->size == 64)
- LOG_DEBUG("READ: %s, %16.8llx", r->name, (unsigned long long) value_64);
- else
- LOG_DEBUG("READ: %s, %8.8x", r->name, (unsigned int) value_64);
+ LOG_DEBUG("READ: %s, lvalue=%16.8llx", r->name, (unsigned long long) lvalue);
+ LOG_DEBUG("READ: %s, hvalue=%16.8llx", r->name, (unsigned long long) hvalue);
+ }
}
- return ERROR_OK;
+ return retval;
}
/*
@@ -674,20 +690,36 @@ static int dpmv8_write_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
{
struct armv8_common *armv8 = dpm->arm->arch_info;
int retval = ERROR_FAIL;
- uint64_t value_64;
- value_64 = buf_get_u64(r->value, 0, r->size);
+ if (r->size <= 64) {
+ uint64_t value_64;
+
+ value_64 = buf_get_u64(r->value, 0, r->size);
+ retval = armv8->write_reg_u64(armv8, regnum, value_64);
- retval = armv8->write_reg_u64(armv8, regnum, value_64);
- if (retval == ERROR_OK) {
- r->dirty = false;
- if (r->size == 64)
- LOG_DEBUG("WRITE: %s, %16.8llx", r->name, (unsigned long long)value_64);
- else
- LOG_DEBUG("WRITE: %s, %8.8x", r->name, (unsigned int)value_64);
+ if (retval == ERROR_OK) {
+ r->dirty = false;
+ if (r->size == 64)
+ LOG_DEBUG("WRITE: %s, %16.8llx", r->name, (unsigned long long)value_64);
+ else
+ LOG_DEBUG("WRITE: %s, %8.8x", r->name, (unsigned int)value_64);
+ }
+ } else if (r->size <= 128) {
+ uint64_t lvalue, hvalue;
+
+ lvalue = buf_get_u64(r->value, 0, 64);
+ hvalue = buf_get_u64(r->value + 8, 0, r->size - 64);
+ retval = armv8->write_reg_u128(armv8, regnum, lvalue, hvalue);
+
+ if (retval == ERROR_OK) {
+ r->dirty = false;
+
+ LOG_DEBUG("WRITE: %s, lvalue=%16.8llx", r->name, (unsigned long long) lvalue);
+ LOG_DEBUG("WRITE: %s, hvalue=%16.8llx", r->name, (unsigned long long) hvalue);
+ }
}
- return ERROR_OK;
+ return retval;
}
/**
@@ -745,6 +777,10 @@ int armv8_dpm_read_current_registers(struct arm_dpm *dpm)
if (r->valid)
continue;
+ /* Skip reading FP-SIMD registers */
+ if (r->number >= ARMV8_V0 && r->number <= ARMV8_FPCR)
+ continue;
+
/*
* Only read registers that are available from the
* current EL (or core mode).