Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

openOCD can not configures the related "Width of System Bus Access" (sbcs.sbaccess) by return value of sbcs.sbacccess128/64/32/16/8 ? #1177

Closed
Qidi-ic opened this issue Dec 2, 2024 · 5 comments

Comments

@Qidi-ic
Copy link

Qidi-ic commented Dec 2, 2024

cfg file has add system bus access option:
riscv set_mem_access sysbus

source code also shows how openOCD handle the sbcs.sbaccess field:

static uint32_t sb_sbaccess(unsigned int size_bytes)

However, this function is called by others in context. I'm not sure whether openOCD will modify sbcs.sbaccess according to sbaccess8/16/32/64 in sbcs to achieve access with different bit widths.

Moreover, I also noticed that "size_bytes" finally is called by this:

if (write_memory(target, scratch->debug_address, 4, 2, buffer) != ERROR_OK)

@en-sc
Copy link
Collaborator

en-sc commented Dec 2, 2024

@Qidi-ic, I didn't quite get what your question is.

Memory access requests in OpenOCD specify the width of the access.

If the requested access width is not supported by System Bus (i.e. the corresponding sbcs.sbaccess bit is low) the access will fail.

@Qidi-ic
Copy link
Author

Qidi-ic commented Dec 3, 2024

If the requested access width is not supported by System Bus (i.e. the corresponding sbcs.sbaccess bit is low) the access will fail.

Really thanks for your reply, @en-sc !

Surely, the width of System Bus access depends on sbcs.sbaccess in hardware. I've also noticed that sbcs.sbaccess8/16/32/64/128 (Preset) fields indicate the access width supported by the current hardware. I'm wondering whether openOCD will configure the width of Memory access based on sbcs.sbaccess8/16/32/64/128 ?

e.g.
sbcs.sbaccess8 = 1'b1
sbcs.sbaccess16 = 1'b1
sbcs.sbaccess32 = 1'b1
sbcs.sbaccess64 = 1'b0
sbcs.sbaccess128 = 1'b0

When a new Memory access is requested, which access width is configured in the sbcs,sbaccess by openOCD?

@en-sc
Copy link
Collaborator

en-sc commented Dec 9, 2024

When a new Memory access is requested, which access width is configured in the sbcs,sbaccess by openOCD?

When a user requests a memory access via TCL interface, they specify the width they want to use for this access.
E.g.:

However, GDB's packets do not specify the access width (https://sourceware.org/gdb/current/onlinedocs/gdb.html/Packets.html#Packets), and OpenOCD is free to choose the access width.

Currently RISC-V targets use the default implementation that first aligns the access and then accesses the memory using riscv013_data_bits-wide accesses:

static int target_read_buffer_default(struct target *target, target_addr_t address, uint32_t count, uint8_t *buffer)
{
uint32_t size;
unsigned int data_bytes = target_data_bits(target) / 8;
/* Align up to maximum bytes. The loop condition makes sure the next pass
* will have something to do with the size we leave to it. */
for (size = 1;
size < data_bytes && count >= size * 2 + (address & size);
size *= 2) {
if (address & size) {
int retval = target_read_memory(target, address, size, 1, buffer);
if (retval != ERROR_OK)
return retval;
address += size;
count -= size;
buffer += size;
}
}
/* Read the data with as large access size as possible. */
for (; size > 0; size /= 2) {
uint32_t aligned = count - count % size;
if (aligned > 0) {
int retval = target_read_memory(target, address, size, aligned / size, buffer);
if (retval != ERROR_OK)
return retval;
address += aligned;
count -= aligned;
buffer += aligned;
}
}
return ERROR_OK;
}

/* Try to find out the widest memory access size depending on the selected memory access methods. */
static unsigned int riscv013_data_bits(struct target *target)
{
RISCV013_INFO(info);
RISCV_INFO(r);
for (unsigned int i = 0; i < r->num_enabled_mem_access_methods; i++) {
riscv_mem_access_method_t method = r->mem_access_methods[i];
if (method == RISCV_MEM_ACCESS_PROGBUF) {
if (has_sufficient_progbuf(target, 3))
return riscv_xlen(target);
} else if (method == RISCV_MEM_ACCESS_SYSBUS) {
if (get_field(info->sbcs, DM_SBCS_SBACCESS128))
return 128;
if (get_field(info->sbcs, DM_SBCS_SBACCESS64))
return 64;
if (get_field(info->sbcs, DM_SBCS_SBACCESS32))
return 32;
if (get_field(info->sbcs, DM_SBCS_SBACCESS16))
return 16;
if (get_field(info->sbcs, DM_SBCS_SBACCESS8))
return 8;
} else if (method == RISCV_MEM_ACCESS_ABSTRACT) {
/* TODO: Once there is a spec for discovering abstract commands, we can
* take those into account as well. For now we assume abstract commands
* support XLEN-wide accesses. */
return riscv_xlen(target);
} else {
assert(false);
}
}
LOG_TARGET_ERROR(target, "Unable to determine supported data bits on this target. Assuming 32 bits.");
return 32;
}

There is definitely room for improvement there, e.g. on a target that supports only 32-bit wide unaligned System Bus Access, current algorithm will fail to write a memory region that does is not aligned, since it will attempt to align the start address using accesses with smaller sizes.

@Qidi-ic
Copy link
Author

Qidi-ic commented Dec 10, 2024

Very appreciate for such a detailed answer!

I now have a clearer understanding of the SBA access mechanism.

Furthermore, over the past few days, I've been trying to use GDB to try to configure 64bit access on a platform that supports up to 32 bits. OpenOCD would initiate 2 time 32-bit accesses to complete 64-bit System Bus Access request by calling this code:

https://github.com/riscv-collab/riscv-openocd/blob/ea8f9d51954b979ff6b4d90afa70352763199b63/src/target/riscv/riscv.c#L1393C1-L1423C2

This function is not easy to found in debugging process, this may be that this mechanism is not explicitly stated in the User Guide. By the way, the aim of this issue is to find out the System Bus Access width configuration in openOCD. It seems to be solved!

Thanks!

@en-sc
Copy link
Collaborator

en-sc commented Dec 10, 2024

Closing this one. Created #1184 to track the work on improving target->type->read/write_buffer.

@en-sc en-sc closed this as completed Dec 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants