target/riscv: Change 'authdata_read' output
[fw/openocd] / src / target / riscv / riscv.c
index 4ef969b016a2c43bc828c8fc466c943602b08d93..1e93ded9e6da15dd9d90c5ebfb534ca9e632fddb 100644 (file)
@@ -1446,7 +1446,7 @@ static int riscv_address_translate(struct target *target,
        uint64_t ppn_value;
        target_addr_t table_address;
        virt2phys_info_t *info;
-       uint64_t pte;
+       uint64_t pte = 0;
        int i;
 
        if (riscv_rtos_enabled(target))
@@ -1853,7 +1853,86 @@ static int riscv_checksum_memory(struct target *target,
                target_addr_t address, uint32_t count,
                uint32_t *checksum)
 {
-       return ERROR_FAIL;
+       struct working_area *crc_algorithm;
+       struct reg_param reg_params[2];
+       int retval;
+
+       LOG_DEBUG("address=0x%" TARGET_PRIxADDR "; count=0x%" PRIx32, address, count);
+
+       static const uint8_t riscv32_crc_code[] = {
+#include "../../contrib/loaders/checksum/riscv32_crc.inc"
+       };
+       static const uint8_t riscv64_crc_code[] = {
+#include "../../contrib/loaders/checksum/riscv64_crc.inc"
+       };
+
+       static const uint8_t *crc_code;
+
+       unsigned xlen = riscv_xlen(target);
+       unsigned crc_code_size;
+       if (xlen == 32) {
+               crc_code = riscv32_crc_code;
+               crc_code_size = sizeof(riscv32_crc_code);
+       } else {
+               crc_code = riscv64_crc_code;
+               crc_code_size = sizeof(riscv64_crc_code);
+       }
+
+       if (count < crc_code_size * 4) {
+               /* Don't use the algorithm for relatively small buffers. It's faster
+                * just to read the memory.  target_checksum_memory() will take care of
+                * that if we fail. */
+               return ERROR_FAIL;
+       }
+
+       retval = target_alloc_working_area(target, crc_code_size, &crc_algorithm);
+       if (retval != ERROR_OK)
+               return retval;
+
+       if (crc_algorithm->address + crc_algorithm->size > address &&
+                       crc_algorithm->address < address + count) {
+               /* Region to checksum overlaps with the work area we've been assigned.
+                * Bail. (Would be better to manually checksum what we read there, and
+                * use the algorithm for the rest.) */
+               target_free_working_area(target, crc_algorithm);
+               return ERROR_FAIL;
+       }
+
+       retval = target_write_buffer(target, crc_algorithm->address, crc_code_size,
+                       crc_code);
+       if (retval != ERROR_OK) {
+               LOG_ERROR("Failed to write code to " TARGET_ADDR_FMT ": %d",
+                               crc_algorithm->address, retval);
+               target_free_working_area(target, crc_algorithm);
+               return retval;
+       }
+
+       init_reg_param(&reg_params[0], "a0", xlen, PARAM_IN_OUT);
+       init_reg_param(&reg_params[1], "a1", xlen, PARAM_OUT);
+       buf_set_u64(reg_params[0].value, 0, xlen, address);
+       buf_set_u64(reg_params[1].value, 0, xlen, count);
+
+       /* 20 second timeout/megabyte */
+       int timeout = 20000 * (1 + (count / (1024 * 1024)));
+
+       retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
+                       crc_algorithm->address,
+                       0,      /* Leave exit point unspecified because we don't know. */
+                       timeout, NULL);
+
+       if (retval == ERROR_OK)
+               *checksum = buf_get_u32(reg_params[0].value, 0, 32);
+       else
+               LOG_ERROR("error executing RISC-V CRC algorithm");
+
+       destroy_reg_param(&reg_params[0]);
+       destroy_reg_param(&reg_params[1]);
+
+       target_free_working_area(target, crc_algorithm);
+
+       LOG_DEBUG("checksum=0x%" PRIx32 ", result=%d", *checksum, retval);
+
+       return retval;
 }
 
 /*** OpenOCD Helper Functions ***/
@@ -2293,7 +2372,7 @@ COMMAND_HANDLER(riscv_authdata_read)
                uint32_t value;
                if (r->authdata_read(target, &value) != ERROR_OK)
                        return ERROR_FAIL;
-               command_print(CMD, "0x%" PRIx32, value);
+               command_print_sameline(CMD, "0x%08" PRIx32, value);
                return ERROR_OK;
        } else {
                LOG_ERROR("authdata_read is not implemented for this target.");
@@ -3452,7 +3531,7 @@ static int register_get(struct reg *reg)
                buf_set_u64(reg->value, 0, reg->size, value);
        }
        reg->valid = gdb_regno_cacheable(reg->number, false);
-       char *str = buf_to_str(reg->value, reg->size, 16);
+       char *str = buf_to_hex_str(reg->value, reg->size);
        LOG_DEBUG("[%d]{%d} read 0x%s from %s (valid=%d)", target->coreid,
                        riscv_current_hartid(target), str, reg->name, reg->valid);
        free(str);
@@ -3465,7 +3544,7 @@ static int register_set(struct reg *reg, uint8_t *buf)
        struct target *target = reg_info->target;
        RISCV_INFO(r);
 
-       char *str = buf_to_str(buf, reg->size, 16);
+       char *str = buf_to_hex_str(buf, reg->size);
        LOG_DEBUG("[%d]{%d} write 0x%s to %s (valid=%d)", target->coreid,
                        riscv_current_hartid(target), str, reg->name, reg->valid);
        free(str);
@@ -4128,7 +4207,7 @@ int riscv_init_registers(struct target *target)
                reg_name += strlen(reg_name) + 1;
                assert(reg_name < info->reg_names + target->reg_cache->num_regs *
                                max_reg_name_len);
-               r->value = &info->reg_cache_values[number];
+               r->value = info->reg_cache_values[number];
        }
 
        return ERROR_OK;