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

riscv_read_by_any_size() is redundant #1205

Open
en-sc opened this issue Jan 15, 2025 · 3 comments
Open

riscv_read_by_any_size() is redundant #1205

en-sc opened this issue Jan 15, 2025 · 3 comments
Labels
Good First Issue This label marks the first good issue for anyone willing to contribute to the project.

Comments

@en-sc
Copy link
Collaborator

en-sc commented Jan 15, 2025

riscv_read_by_any_size() is used to try all available sizes when reading memory:

/**
* Read one memory item using any memory access size that will work.
* Read larger section of memory and pick out the required portion, if needed.
* */
int riscv_read_by_any_size(struct target *target, target_addr_t address, uint32_t size, uint8_t *buffer)
{

riscv_read_by_any_size() is currently used in riscv_semihosting() and in riscv_add_breakpoint() to read instructions.

There is also target_read_buffer(). It provides the same interface.
Seems like riscv_read_by_any_size() should be the implementation of target_read_buffer() (currently target_read_buffer_default() is used).

@en-sc en-sc added the Good First Issue This label marks the first good issue for anyone willing to contribute to the project. label Jan 15, 2025
@JanMatCodasip
Copy link
Collaborator

JanMatCodasip commented Jan 20, 2025

Actually, the functions riscv_read_by_any_size() and target_read_buffer_default() work differently:

  • riscv_read_by_any_size() tries to read certain amount of data from memory, and will try to use various access sizes until one of them succeeds. This function was introduced for architectures that do not support all access sizes when accessing special areas of memory that can hold program instructions (namely ICCM memory in VeeR EH1).
  • target_read_buffer_default() will read certain amount of bytes using the largest transfer size possible in order to improve performance. It will not fall back to a different access size if the attempted access size is not supported - it will end with an error immediately.

@en-sc
Copy link
Collaborator Author

en-sc commented Jan 20, 2025

This function was introduced for architectures that do not support all access sizes when accessing special areas of memory that can hold program instructions

But the issue is target_read_buffer/target_write_buffer seems to be the functions intended to be used to access instruction memory.
This is evident from:

  • The comment in target.h
    /*
    * Write to target memory using the virtual address.
    *
    * Note that this fn is used to implement software breakpoints. Targets
    * can implement support for software breakpoints to memory marked as read
    * only by making this fn write to ram even if it is read only(MMU or
    * MPUs).
  • The use in load_image handler:
    retval = target_write_buffer(target,
    image.sections[i].base_address + offset, length, buffer + offset);

Moreover, they are used throughout riscv.c for exactly that purpose:

Finally, I don't get why the function can't do both: try multiple access sizes to be able to read any memory and try the largest size first to achieve the best possible performance.

@en-sc
Copy link
Collaborator Author

en-sc commented Jan 20, 2025

Somewhat related to #1184.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Good First Issue This label marks the first good issue for anyone willing to contribute to the project.
Projects
None yet
Development

No branches or pull requests

2 participants