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

Make register dump output more concise. #909

Merged
merged 1 commit into from
Nov 7, 2023
Merged

Conversation

timsifive
Copy link
Contributor

Don't mention fields whose value is 0.
New format:
{sbautoincrement=1 sbaccess=64bit sbreadonaddr=1 }

@timsifive
Copy link
Contributor Author

@kr-sc @en-sc

Copy link
Collaborator

@pdonahue-ventana pdonahue-ventana left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

curr += get_len_or_sprintf(buf, curr, ", ");
if (len) {
curr += len;
curr += get_len_or_sprintf(buf, curr, " ");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
curr += get_len_or_sprintf(buf, curr, " ");
curr += get_len_or_sprintf(buf, curr, ", ");

I would suggest to leave the comma between the fields, since some value names include a space e.g. not supported.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't you also like to skip the last separator (the one before the last field)? If so, I would suggest to move the check out of riscv_debug_reg_field_to_s() and rewrite the loop like so:

        const char *separator = "";
        for (struct riscv_debug_reg_field_list_t list; get_next; get_next = list.get_next) {
                list = get_next(context);
                if (<condition to skip the field>)
                        continue;
                curr += get_len_or_sprintf(buf, curr, separator);
                curr += riscv_debug_reg_field_to_s(buf, curr, list.field,
                                context, field_value);
                separator = ", ";
        }

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest to leave the comma between the fields, since some value names include a space e.g. not supported.

Good point. I prefer to solve that by replacing whitespace in value names with _.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't you also like to skip the last separator (the one before the last field)?

Yes, but I thought that was a pre-existing issue and it didn't bother me that much. I'll address it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@@ -46,6 +46,9 @@ static unsigned int riscv_debug_reg_field_to_s(char *buf, unsigned int offset,
riscv_debug_reg_field_info_t field, riscv_debug_reg_ctx_t context,
uint64_t field_value)
{
if (field_value == 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be preferable to only skip value if it is zero and there is no name for such field value?
Like so:

static const char *get_field_value_name(riscv_debug_reg_field_info_t field,
                uint64_t field_value)
{
        return field.values ? field.values[field_value] : NULL;
}
Suggested change
if (field_value == 0)
if (field_value == 0 && !get_field_value_name(list.field, field_value))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that's preferable. Almost everywhere the 0 value means inactive, so not interesting to list.
E.g. dmstatus=0 would be {version=none stickyunavail=current ndmresetpending=false confstrptrvalid=invalid authbusy=ready authenticated=false} which is a lot to visually parse through just to see nothing is going on. And there's nothing preventing the XML to be edited in the future to be more consistent or whatever and to name every 0 field, in which case the output would be even larger.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that's preferable. Almost everywhere the 0 value means inactive, so not interesting to list.

The issue, in my opinion is that it is exactly almost everywhere. E.g. dtmcs.version == 0 means 0.11 which is quite important information, considering the use of this code in OpenOCD's riscv-013.c.

E.g. dmstatus=0 would be {version=none stickyunavail=current ndmresetpending=false confstrptrvalid=invalid authbusy=ready authenticated=false} which is a lot to visually parse through just to see nothing is going on.

IMHO this particular issue is caused by attempting to get a meaningful result from decoding a meaningless value and should be addressed in OpenOCD code. Please, take a look at this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we could mark the handful of fields where 0 is significant, but I'm not going to do that work right now. It's much better to have the output be concise than it is to be readable by someone with no experience.

I chose the 0 example because it was easy. The problem is just as bad in a realistic example:
dmstatus=0x430382 {version=0.13 anyresumeack=1 allresumeack=1 impebreak=1 stickyunavail=current ndmresetpending=false confstrptrvalid=invalid authbusy=ready authenticated=true anyhalted=1 allhalted=1}
vs
dmstatus=0x430382 {version=0.13 anyresumeack=1 allresumeack=1 impebreak=1 authenticated=true anyhalted=1 allhalted=1}

The former has a bunch of uninteresting fields that just make it harder to read the ones you usually care about.

On top of that, the XML might change in the future to add more explicit true/false encodings, which would make the problem worse. The contents of that XML are primarily for the formatting of the document, not for this automated field generation.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@timsifive

Ideally we could mark the handful of fields where 0 is significant,
It's much better to have the output be concise than it is to be readable by someone with no experience.

The former seems an unfeasible goal since it won't be easy to maintain (you've actually alluded to that already). The latter seems like an aesthetic preference - there are people who prefer verbose printouts and there are people who hate these logs and want them to be as short as possible (me included). However, I can see the reason some may want to decode every field. I'd like to suggest a compromise: we can add an extra argument to the printing function and a corresponding riscv-specific OpenOCD command to control it. So we can enable verbose decoding of fields. I can even volunteer to provide a patch (if no objections).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. Done.

registers.py Outdated

# Remove whitespace from the names, so when they're displayed we can use
# only ' ' as a separator.
def remove_whitespace(s):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

toCIdentifier() can be used here, if you like.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That works. Thanks.

uint64_t field_value = riscv_debug_reg_field_value(list.field, value);

if ((show == RISCV_DEBUG_REG_SHOW_ALL) ||
(show == RISCV_DEBUG_REG_HIDE_UNNAMED_0 && list.field.values) ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hides all fields with no named values. The correct condition:

Suggested change
(show == RISCV_DEBUG_REG_HIDE_UNNAMED_0 && list.field.values) ||
(show == RISCV_DEBUG_REG_HIDE_UNNAMED_0 && !(field_value == 0 && list.field.values && !list.field.values[0]) ||

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Thanks.


if ((show == RISCV_DEBUG_REG_SHOW_ALL) ||
(show == RISCV_DEBUG_REG_HIDE_UNNAMED_0 &&
(field_value != 0 || list.field.values)) ||
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will not hide an unnamed zero if there is a name for any other value (list.field.values == {[0] = NULL, [1] = "some name"})

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, I think. I don't see any examples of this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will not hide an unnamed zero if there is a name for any other value (list.field.values == {[0] = NULL, [1] = "some name"})

For an example, please, take a look at csr_dcsr_cause_values ([0] is zero-initialized by default).

Add `show` argument that lets user decide how to deal with fields whose
value is 0:
* Show them all.
* Show them if they have a symbolic name.
* Don't show them.

Use underscores instead of whitespace in field names, so we don't need a
comma in the separator.

New format:
```
{datacount=2 cmderr=not_supported}
{version=0.13 anyresumeack=1 allresumeack=1 impebreak=1 authenticated=true anyhalted=1 allhalted=1}
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants