clarification on memory mapped CSRs

761 views
Skip to first unread message

Mauro Olivieri

unread,
Feb 27, 2017, 1:11:12 PM2/27/17
to isa...@groups.riscv.org


Dear all,

I apologize if this question is too basic for the standard discussions in this group.

I am referring to M-mode execution only.

In the Privileged Architecture V1.9.1, it is clearly stated that some CSRs (e.g. time) are shadows of memory-mapped registers. Moreover, it is also stated that the interrupt pending bit MSIP of a hart may be set by another hart, by means of a non-cached write to a memory mapped CSR. The following basic questions arise to me in order to set up a clear picture:

- in a RISCV compliant architecture, which CSRs, if present, are _mandatorily_ memory-mapped?

- in a RISCV compliant architecture, which CSRs, if present, are _possibly_ memory-mapped?

- I assume memory mapped CSRs are accessed via regular load/store instructions. So, a hart may indifferently access its own CSRs through a dedicated CSRxx instruction or through a load/store instruction. Am I correct?

- in an actual implmentation, must there be (or be preferrable) any relation between the 12-bit CSR address and the memory-mapped address of the CSR?

- Some memory-mapped CSRs, e.g.'time', are single, global memory-mapped registers. Other CSRs, e.g. the 'mip' CSR, must be memory-mapped in multiple versions (i.e. one for each hart) to implement the access to per-hart MSIP bits. Am I correct?

Thank you in advance for any answer.
Mauro

Stefan O'Rear

unread,
Feb 27, 2017, 1:30:17 PM2/27/17
to Mauro Olivieri, RISC-V ISA Dev
On Mon, Feb 27, 2017 at 10:11 AM, Mauro Olivieri
<olivieri...@gmail.com> wrote:
>
>
> Dear all,
>
> I apologize if this question is too basic for the standard discussions in
> this group.

This isn't a RISC-V question, it's a semantic question about ISAs themselves.

> I am referring to M-mode execution only.
>
> In the Privileged Architecture V1.9.1, it is clearly stated that some CSRs
> (e.g. time) are shadows of memory-mapped registers. Moreover, it is also
> stated that the interrupt pending bit MSIP of a hart may be set by another
> hart, by means of a non-cached write to a memory mapped CSR. The following

Insofar as no means is described for discovering addresses I regard
both of those as more implementation guidance and less normative.

> basic questions arise to me in order to set up a clear picture:
>
> - in a RISCV compliant architecture, which CSRs, if present, are
> _mandatorily_ memory-mapped?

A CSR is not a thing. A CSR is a means of accessing a physical or
logical register. There is nothing in the notion of CSR which forbids
the same physical or logical register from being accessed by other
means.

So there's no such thing as a "memory-mapped CSR". There are logical
registers which can be accessed in one or more ways. Memory, CSR,
front panel switches, something else entirely.

A minimal RISC-V compliant M-mode system is not required to have any
memory-mapped resources of any kind (although the initial program and
config string have to be in memory).

> - in a RISCV compliant architecture, which CSRs, if present, are _possibly_
> memory-mapped?

You can add additional access paths to any register without harming compliance.

> - I assume memory mapped CSRs are accessed via regular load/store
> instructions. So, a hart may indifferently access its own CSRs through a
> dedicated CSRxx instruction or through a load/store instruction. Am I
> correct?

If a register is CSR-mapped it can be accessed through CSRxx instructions.

If a register is memory-mapped it can be accessed through load-store
instructions.

If a register is both it can be accessed through either indifferently.

> - in an actual implmentation, must there be (or be preferrable) any relation
> between the 12-bit CSR address and the memory-mapped address of the CSR?

No.

> - Some memory-mapped CSRs, e.g.'time', are single, global memory-mapped
> registers. Other CSRs, e.g. the 'mip' CSR, must be memory-mapped in multiple
> versions (i.e. one for each hart) to implement the access to per-hart MSIP
> bits. Am I correct?

mip itself doesn't need to be memory-mapped; just something that
exposes the MSIP bit. Or you could use custom instructions. As long
as you can implement SBI_SEND_IPI and SBI_CLEAR_IPI the details are
less important for S-mode.

> Thank you in advance for any answer.
> Mauro

-s

Rogier Brussee

unread,
Feb 28, 2017, 9:35:10 AM2/28/17
to RISC-V ISA Dev
Actually I think it is a very good question. 

Why have CSR's if you can do mmio? This is what I suggested doing in Xcondensed where I tried to press an essentially complete RISCV like isa in 16 bit instructions that could also be used to compress the normal ISA like the C extension. CSR's take far too much room in such a scheme.

I do see three differences:

They are mandated to be atomic (i.e. essentially manipulated using atomic ops).
They have a standardised CSR value.
Andrew Waterman suggested that in most implementations they would actually be _slower_ than mmio because they would trigger a less optimised path.

Would it be a good idea to have a description of memory mapped CSR's in the config string, that state that CSR XYZ corresponds to address 0xabcdef?
It seems rather pointless for S mode to trap to M mode doing an amo, if they can just do an amo (or a non amo if it doesn't matter!) at a well defined address directly. In M mode I don't know if you are supposed to have a trap. 

Rogier



Op maandag 27 februari 2017 19:11:12 UTC+1 schreef Mauro Olivieri:

Andrew Waterman

unread,
Feb 28, 2017, 1:51:44 PM2/28/17
to RISC-V ISA Dev, Rogier Brussee
On Tue, Feb 28, 2017 at 6:35 AM Rogier Brussee <rogier....@gmail.com> wrote:
Actually I think it is a very good question. 

Why have CSR's if you can do mmio? This is what I suggested doing in Xcondensed where I tried to press an essentially complete RISCV like isa in 16 bit instructions that could also be used to compress the normal ISA like the C extension. CSR's take far too much room in such a scheme.

I do see three differences:

They are mandated to be atomic (i.e. essentially manipulated using atomic ops).
They have a standardised CSR value.
Andrew Waterman suggested that in most implementations they would actually be _slower_ than mmio because they would trigger a less optimised path.

To be clear, I meant _memory_ would be a more optimized path (IIRC this was in the context of adding another hart id register, which I argued should just be stored in thread-local memory instead).

Of course, for some implementations, CSR-mapped I/O is a fine approach and can be optimized accordingly.


Would it be a good idea to have a description of memory mapped CSR's in the config string, that state that CSR XYZ corresponds to address 0xabcdef?
It seems rather pointless for S mode to trap to M mode doing an amo, if they can just do an amo (or a non amo if it doesn't matter!) at a well defined address directly. In M mode I don't know if you are supposed to have a trap. 

Rogier



Op maandag 27 februari 2017 19:11:12 UTC+1 schreef Mauro Olivieri:


Dear all,

I apologize if this question is too basic for the standard discussions in this group.

I am referring to M-mode execution only.

In the Privileged Architecture V1.9.1, it is clearly stated that some CSRs (e.g. time) are shadows of memory-mapped registers. Moreover, it is also stated that the interrupt pending bit MSIP of a hart may be set by another hart, by means of a non-cached write to a memory mapped CSR. The following basic questions arise to me in order to set up a clear picture:

- in a RISCV compliant architecture, which CSRs, if present, are _mandatorily_ memory-mapped?

- in a RISCV compliant architecture, which CSRs, if present, are _possibly_ memory-mapped?

- I assume memory mapped CSRs are accessed via regular load/store instructions. So, a hart may indifferently access its own CSRs through a dedicated CSRxx instruction or through a load/store instruction. Am I correct?

- in an actual implmentation, must there be (or be preferrable) any relation between the 12-bit CSR address and the memory-mapped address of the CSR?

- Some memory-mapped CSRs, e.g.'time', are single, global memory-mapped registers. Other CSRs, e.g. the 'mip' CSR, must be memory-mapped in multiple versions (i.e. one for each hart) to implement the access to per-hart MSIP bits. Am I correct?

Thank you in advance for any answer.
Mauro

--
You received this message because you are subscribed to the Google Groups "RISC-V ISA Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to isa-dev+u...@groups.riscv.org.
To post to this group, send email to isa...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/isa-dev/.
To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/isa-dev/174cfc8e-8b0f-4d7b-898f-ff71cd1c87a7%40groups.riscv.org.

Allen J. Baum

unread,
Feb 28, 2017, 11:35:18 PM2/28/17
to Rogier Brussee, RISC-V ISA Dev
I agree it was a good question, if for no other reason than to expose and document the intent rather than the definition.

I think the slow path issue isn't (in general) critical for performance; CSRs are just not accessed that often . There are always latency critical CSRs (I think the timers - and interrupt related ones -  are possibly in that category). IF CSRs are accessed frequently, and slowly, then its an implementation issue, not an architectural one. Basically, if it hurts when you do that, then don't do that. Design it so it isn't so slow.

I don't think we are discussing standardization of format as an issue (in the sense that they should meet the architectural standard, regardless), but standarization of addresses are. CSRs should be available if an address map is not set up, is changing, or is disabled and standarizing on that MMIO address map is much more problematic than the CSR address map (not to mention the issues of power and clock domains out to MMIO, etc) AMOs are also a lot more difficult to implement as you get further and further from the core.

Unless it is known that CSRs must be in the MMIO domain (because they must use fixed clocks, like the RTC, then *architecturally* defined CSRs should use CSR read/write instructions.

That is not say that there aren't lots of CSRs that belong in the MMIO region; if they configure the DRAM controller or any other device outside the core boundary, that's just fine. Those are not architectural, however.

Shadowing in this sense is a weird mixture of addrss aliasing and protection. I'm actually not sure I understand the point of that, though I'm willing to be educated.

The other kind of shadowing is a single physical instance of a CSR that returns different sets of bits depending on the privilege level. That is much more useful.
--

You received this message because you are subscribed to the Google Groups "RISC-V ISA Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to isa-dev+u...@groups.riscv.org.
To post to this group, send email to isa...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/isa-dev/.
To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/isa-dev/174cfc8e-8b0f-4d7b-898f-ff71cd1c87a7%40groups.riscv.org.


-- 
**************************************************
* Allen Baum              tel. (908)BIT-BAUM     *
*                                   248-2286     *     
**************************************************

Alex Bradbury

unread,
Mar 1, 2017, 6:20:32 AM3/1/17
to Rogier Brussee, RISC-V ISA Dev
On 28 February 2017 at 14:35, Rogier Brussee <rogier....@gmail.com> wrote:
> Actually I think it is a very good question.
>
> Why have CSR's if you can do mmio? This is what I suggested doing in
> Xcondensed where I tried to press an essentially complete RISCV like isa in
> 16 bit instructions that could also be used to compress the normal ISA like
> the C extension. CSR's take far too much room in such a scheme.
>
> I do see three differences:
>
> They are mandated to be atomic (i.e. essentially manipulated using atomic
> ops).
> They have a standardised CSR value.
> Andrew Waterman suggested that in most implementations they would actually
> be _slower_ than mmio because they would trigger a less optimised path.

I know this is orthogonal to your encoding space issue, but
Implementations could (I think) almost just choose to translate the
CSR instructions to appropriate mmio accesses. The only wrinkle is
that the illegal instruction exceptions should be generated rather
than the memory access fault exceptions. Other than an extreme desire
for "uniformity", it's not clear why you'd want to do this though, and
you'd be left to provide appropriate access control via other means.

Best,

Alex

Rogier Brussee

unread,
Mar 1, 2017, 3:29:17 PM3/1/17
to RISC-V ISA Dev, rogier....@gmail.com


Op woensdag 1 maart 2017 12:20:32 UTC+1 schreef asb:
If you only have M mode and you implement CSR with mmio it saves you having to implement the CSR decoding in the hardware and a trap at run time if you can simply directly use load store instructions. 

Likewise if you have a high performance implementation and some of your csr's are implemented with mmio, what (documented) freedom do you have to optimise by using non atomic operations, or (I am thinking aloud here) saving lots of csr state in the mmaped csr's by only saving and updating a pointer to a data structure. 


 

Best,

Alex

Samuel Falvo II

unread,
Mar 2, 2017, 1:20:32 AM3/2/17
to Rogier Brussee, RISC-V ISA Dev
On Wed, Mar 1, 2017 at 12:29 PM, Rogier Brussee
<rogier....@gmail.com> wrote:
> If you only have M mode and you implement CSR with mmio it saves you having
> to implement the CSR decoding in the hardware and a trap at run time if you
> can simply directly use load store instructions.

You still need to decode the address synchronously with the
instruction execution. The reason is that references to unsupported
CSRs generate an illegal instruction trap (note: not a load or store
trap!). If you place CSRs in MMIO space, and just decode CSRRx
instructions into loads and stores, you'll no longer be user-lspec or
privilege-spec compliant.

> Likewise if you have a high performance implementation and some of your
> csr's are implemented with mmio, what (documented) freedom do you have to
> optimise by using non atomic operations, or (I am thinking aloud here)
> saving lots of csr state in the mmaped csr's by only saving and updating a
> pointer to a data structure.

If you can prove compatibility with the specification as it's written,
you should be good to use whatever implementation you choose.


--
Samuel A. Falvo II

Alex Bradbury

unread,
Mar 2, 2017, 6:27:58 AM3/2/17
to Samuel Falvo II, Rogier Brussee, RISC-V ISA Dev
On 2 March 2017 at 06:20, Samuel Falvo II <sam....@gmail.com> wrote:
> On Wed, Mar 1, 2017 at 12:29 PM, Rogier Brussee
> <rogier....@gmail.com> wrote:
>> If you only have M mode and you implement CSR with mmio it saves you having
>> to implement the CSR decoding in the hardware and a trap at run time if you
>> can simply directly use load store instructions.
>
> You still need to decode the address synchronously with the
> instruction execution. The reason is that references to unsupported
> CSRs generate an illegal instruction trap (note: not a load or store
> trap!). If you place CSRs in MMIO space, and just decode CSRRx
> instructions into loads and stores, you'll no longer be user-lspec or
> privilege-spec compliant.

Given that illegal instruction traps and traps in general are defined
outside of the user spec, you could probably get away with calling
yourself compliant with the user space. After all, any potential
difference would be totally unobservable to user-mode software.

Best,

Alex

Mauro Olivieri

unread,
Mar 2, 2017, 9:37:31 AM3/2/17
to RISC-V ISA Dev, sam....@gmail.com, rogier....@gmail.com

Hi all,
(sorry for this discussion has evolved in a way probably more suited to HW DEV group)
I may have missed something but in my opinoin  the assertion "we may avoid CSR decoding logic if we map CSRs as mmio" is not generally true. It is true if we assume CSRs are not only memory mapped but also physically resident in the memory (and nowhere else). The latter would be extremely inefficient at least for some CSRs such as for example the MIP, holding interrupt requests, not to mention other CSRs such as the instruction count.
So if we have some logical CSR that is logically memory-mapped, but is physically resident in a dedicated register or on input pins of the core or whatever else, we must implement dedicated decoding logic to reach it.
M

Allen J. Baum

unread,
Mar 2, 2017, 1:13:14 PM3/2/17
to Mauro Olivieri, RISC-V ISA Dev, sam....@gmail.com, rogier....@gmail.com
Thanks - I was going to go in that direction as well. Saving decoding logic in one place but adding it in another is not saving anything. And the amount of decoding you're trying to save is totally trivial. It's not exactly a compelling argument.
--

You received this message because you are subscribed to the Google Groups "RISC-V ISA Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to isa-dev+u...@groups.riscv.org.
To post to this group, send email to isa...@groups.riscv.org.
Visit this group at https://groups.google.com/a/groups.riscv.org/group/isa-dev/.
Reply all
Reply to author
Forward
0 new messages