riscv / riscv-isa-manual

RISC-V Instruction Set Manual
https://riscv.org/
Creative Commons Attribution 4.0 International
3.71k stars 644 forks source link

instret, cycle, time outside of Zicntr (and hpmpcounterN outside Zihpm) #1734

Open dhower-qc opened 3 days ago

dhower-qc commented 3 days ago

It's unclear if instret, cycle, and time can exist without implementing Zicntr.

If they do not exist outside Zicntr, the priv spec needs to be clear on that when mentioning those CSRs (currently, Zicntr is not mentioned at all).

If they can exist outside of Zicntr, the unpriv spec needs to be clear that Zicntr does not define the CSRs (and only defines pseudoinstructions).

<sed g/Zicntr/Ziphm/> # same for hpm

A protracted debate among CSC members shows there is no consensus based on the spec text.

gfavor commented 3 days ago

Priv 1.13 defines the mtime, mcycle, minstret counters and associated machine-level CSRs, and says that the user-level time, cycle, and instret CSRs (assuming they are implemented) are read-only shadows of the machine-level CSRs. (And note that these two sets of CSRs ARE distinct CSRs with different access permissions, with the Priv spec specifying how they are related.)

Then the Unpriv (i.e. user-level) Zicntr extension defines the time, cycle, and instret CSRs. This extension would typically also be implemented (as is recommended in the spec), but if it isn't, then that is fine. That just means that the user-level time, cycle, and instret CSRs are not implemented (and obviously then inaccessible to user-level).

allenjbaum commented 3 days ago

Huh - maybe we were looking at an older version of the spec? I could have sworn the wording was that Zicntr defined the 3 pseudoinstructions, but said nothing about the CSRs themselves, and I'm not seeing that now. But I do see the read-only shadow description (in the priv spec, later in the mcounteren/inh description) but not in unpriv.

If Zicntr isn't supported, then those CSRs may or may not return the time - that's a custom extension effectively. IF they are supported... my understanding is they could the return shadow values OR trap (and so higher level SW would provide the values)? Mcounteren CSR could also be used to do this, of course.

Corner case:

On some simple platforms, cycle count might represent a valid implementation of RDTIME,

in which case RDTIME and RDCYCLE may return the same result.

Is it the case that they simply count at the same rate?, or can they be shadows of each other (e.g. writing one will change the value of the other)?

On Thu, Nov 21, 2024 at 11:06 PM gfavor @.***> wrote:

Priv 1.13 defines the mtime, mcycle, minstret counters and associated machine-level CSRs, and says that the user-level time, cycle, and instret CSRs (assuming they are implemented) are read-only shadows of the machine-level CSRs. (And note that these two sets of CSRs ARE distinct CSRs with different access permissions, with the Priv spec specifying how they are related.)

Then the Unpriv (i.e. user-level) Zicntr extension defines the time, cycle, and instret CSRs. This extension would typically also be implemented (as is recommended in the spec), but if it isn't, then that is fine. That just means that the user-level time, cycle, and instret CSRs are not implemented (and obviously then inaccessible to user-level).

— Reply to this email directly, view it on GitHub https://github.com/riscv/riscv-isa-manual/issues/1734#issuecomment-2493016308, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHPXVJVYOLHV4O3VFBS5XQL2B3JXDAVCNFSM6AAAAABSIL4UIOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDIOJTGAYTMMZQHA . You are receiving this because you are subscribed to this thread.Message ID: @.***>

dhower-qc commented 3 days ago

Priv 1.13 defines the mtime, mcycle, minstret counters and associated machine-level CSRs, and says that the user-level time, cycle, and instret CSRs (assuming they are implemented) are read-only shadows of the machine-level CSRs. (And note that these two sets of CSRs ARE distinct CSRs with different access permissions, with the Priv spec specifying how they are related.)

Yes, but what it doesn't say is whether or not time, cycle, and instret can exist (can be read without causing a trap) independent of Zicntr.

Then the Unpriv (i.e. user-level) Zicntr extension defines the time, cycle, and instret CSRs. This extension would typically also be implemented (as is recommended in the spec), but if it isn't, then that is fine. That just means that the user-level time, cycle, and instret CSRs are not implemented (and obviously then inaccessible to user-level).

Like Allen said, I'm not sure the Unpriv spec actually says that (thus the confusion). And even if it does, it's confusing because "implemented" isn't well-defined. time, in particular, might be defined/implemented by Zicntr but will still always cause an IllegalInstruction exception (how is that different than not implemented?).

gfavor commented 3 days ago

On Fri, Nov 22, 2024, 5:52 AM Derek Hower @.***> wrote:

Priv 1.13 defines the mtime, mcycle, minstret counters and associated machine-level CSRs, and says that the user-level time, cycle, and instret CSRs (assuming they are implemented) are read-only shadows of the machine-level CSRs. (And note that these two sets of CSRs ARE distinct CSRs with different access permissions, with the Priv spec specifying how they are related.)

Yes, but what it doesn't say is whether or not time, cycle, and instret can exist (can be read without causing a trap) independent of Zicntr.

Yes, they can (although that would be an unusual implementation). If one can read these counters, but not using the Zicntr CSRs, then one is using different CSR numbers. If custom numbers, then one has essentially implemented a custom extension. If standard numbers, then one has implemented a nonconforming extension.

Lastly, if one uses the Zicntr-defined standard CSR numbers, but doesn't fully implement all the arch semantics as defined by Zicntr, then one has again implemented a nonconforming extension.

Then the Unpriv (i.e. user-level) Zicntr extension defines the time, cycle,

and instret CSRs. This extension would typically also be implemented (as is recommended in the spec), but if it isn't, then that is fine. That just means that the user-level time, cycle, and instret CSRs are not implemented (and obviously then inaccessible to user-level).

Like Allen said, I'm not sure the Unpriv spec actually says that (thus the confusion). And even if it does, it's confusing because "implemented" isn't well-defined. time, in particular, might be defined/implemented by Zicntr but will still always cause an Illegal instruction exception (how is that different than not implemented).

If one implements Zicntr (i.e. implements all the defined arch functionality), then always trapping CSR accesses would not be complying with the spec (i.e. a nonconforming implementation).

Lastly, I'm not sure if what you're trying to get at is a trap and emulate implementation of Zicntr and of the time CSR in this case. But one can certainly trap out of the User Execution Environment, emulate, and return back down to User level with user-level code non the wiser. That would be a compliant implementation of Zicntr.

Greg

dhower-qc commented 3 days ago

If standard numbers, then one has implemented a nonconforming extension.

So, to rephrase: Zicntr defines the standard CSR numbers for time, cycle, and instret. Reading any of them from M-mode will always trap in a conforming implementation if Zicntr is not implemented.

If I have that right, I think a manual update to clarify that is needed.

If one implements Zicntr (i.e. implements all the defined arch functionality), then always trapping CSR accesses would not be complying with the spec (i.e. a nonconforming implementation).

I think there is a disconnect in how we are thinking about this. From user-mode's perspective, you can't (without side channels) detect trap-and-emulate so this is moot. But, from M-mode's perspective (needed for certification), it's possible that some, all, or none of these do trap, and that is detectable. time in particular may always trap since its shadow, mtime, is an MMIO read.

ved-rivos commented 3 days ago

On some simple platforms, cycle count might represent a valid implementation of RDTIME, in which case RDTIME and RDCYCLE may return the same result. Is it the case that they simply count at the same rate?, or can they be shadows of each other (e.g. writing one will change the value of the other)?

I would consider such an implementation to be wrong. Many use cases require resetting/context-switching cycles but software expects time to be invariant and monotonic. When multiple harts exists, software also expects the time observed by harts to be within one-tick of each other. An implementation that aliases cycles may lead to unexpected/undesired behaviors such as time being observed to go backwards. Time may not be invariant or synchronized on such implementations.

gfavor commented 3 days ago

On Fri, Nov 22, 2024, 8:35 AM Derek Hower @.***> wrote:

If standard numbers, then one has implemented a nonconforming extension.

So, to rephrase: Zicntr defines the standard CSR numbers for time, cycle, and instret. Reading any of them from M-mode will always trap in a conforming implementation if Zicntr is not implemented.

If Zicntr is not implemented, then these CSRs remain Reserved. One valid implementation of Reserved CSRs, but not the only, is to trap all accesses to them.

If I have that right, I think a manual update to clarify that is needed.

If one implements Zicntr (i.e. implements all the defined arch functionality), then always trapping CSR accesses would not be complying with the spec (i.e. a nonconforming implementation).

I think there is a disconnect in how we are thinking about this. From user-mode's perspective, you can't (without side channels) detect trap-and-emulate so this is moot. But, from M-mode's perspective (needed for certification), it's possible that some, all, or none of these do trap, and that is detectable. time in particular may always trap since its shadow, mtime, is an MMIO read.

In M-mode one can implement transparent trap and emulate, or natively implement the CSRs, or treat the CSRs as unimplemented and Reserved.

Greg

P.S. Embedded/microcontroller designs may tend to T&E the tiem CSR, whereas higher-end apps processor designs will tend to do analogous to ARM and distribute mtime to each hart's time in a way that satisfies the synchronization requirements across harts.

allenjbaum commented 2 days ago

This has been a real rathole hasn't it? My interpretation is that if Zicntr defines 3 Umode counter CSE at addresses 0xC00, C01, and C02 are defined to be read-only shadows of their Mmode counterparts,. Application code will trap if a write is attempted (becasue read-only...) and will either return the corresponding contents of the Mmode counterparts, or trap (in any combination) for a read. Which of those options that they implement is invisible to the application, but is visible to Mmode. In theory, that is a total of 4 architectural parameters/configurations/options:

On Fri, Nov 22, 2024 at 11:01 AM gfavor @.***> wrote:

On Fri, Nov 22, 2024, 8:35 AM Derek Hower @.***> wrote:

If standard numbers, then one has implemented a nonconforming extension.

So, to rephrase: Zicntr defines the standard CSR numbers for time, cycle, and instret. Reading any of them from M-mode will always trap in a conforming implementation if Zicntr is not implemented.

If Zicntr is not implemented, then these CSRs remain Reserved. One valid implementation of Reserved CSRs, but not the only, is to trap all accesses to them.

If I have that right, I think a manual update to clarify that is needed.

If one implements Zicntr (i.e. implements all the defined arch functionality), then always trapping CSR accesses would not be complying with the spec (i.e. a nonconforming implementation).

I think there is a disconnect in how we are thinking about this. From user-mode's perspective, you can't (without side channels) detect trap-and-emulate so this is moot. But, from M-mode's perspective (needed for certification), it's possible that some, all, or none of these do trap, and that is detectable. time in particular may always trap since its shadow, mtime, is an MMIO read.

In M-mode one can implement transparent trap and emulate, or natively implement the CSRs, or treat the CSRs as unimplemented and Reserved.

Greg

P.S. Embedded/microcontroller designs may tend to T&E the tiem CSR, whereas higher-end apps processor designs will tend to do analogous to ARM and distribute mtime to each hart's time in a way that satisfies the synchronization requirements across harts.

— Reply to this email directly, view it on GitHub https://github.com/riscv/riscv-isa-manual/issues/1734#issuecomment-2494570525, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHPXVJUB72X5RWU6FTJBSTT2B55SNAVCNFSM6AAAAABSIL4UIOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDIOJUGU3TANJSGU . You are receiving this because you commented.Message ID: @.***>

kdockser commented 2 days ago

Why is this discussion limited to Zicntr? In theory nothing needs to exist, at least not in user mode. Everything in user mode, CSR accesses, memory accesses, and even the instruction execution itself can take an invisible trap to M-mode. Is the intent for M-mode certification to require that user mode is tested with the option of each instruction and register not "existing"?

dhower-qc commented 2 days ago

Keep in mind that this list isn’t limited to certification needs. It’s also to improve documentation, configure an ISS, etc. For such use cases, you do really want to know what happens when you read those CSRs. (For example, to test trap-and-emulate on an ISS)

Sent from phone


From: Ken Dockser @.> Sent: Friday, November 22, 2024 5:50:59 PM To: riscv/riscv-isa-manual @.> Cc: Derek Hower (QUIC) @.>; Author @.> Subject: Re: [riscv/riscv-isa-manual] instret, cycle, time outside of Zicntr (and hpmpcounterN outside Zihpm) (Issue #1734)

WARNING: This email originated from outside of Qualcomm. Please be wary of any links or attachments, and do not enable macros.

Why is this discussion limited to Zicntr? In theory nothing needs to exist, at least not in user mode. Everything in user mode, CSR accesses, memory accesses, and even the instruction execution itself can take an invisible trap to M-mode. Is the intent for M-mode certification to require that user mode is tested with the option of each instruction and register not "existing"?

— Reply to this email directly, view it on GitHubhttps://github.com/riscv/riscv-isa-manual/issues/1734#issuecomment-2495014582, or unsubscribehttps://github.com/notifications/unsubscribe-auth/BAD4U6E6SR7VDFIMZXQGDML2B6YNHAVCNFSM6AAAAABSIL4UIOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDIOJVGAYTINJYGI. You are receiving this because you authored the thread.Message ID: @.***>