[RISC-V] [tech-config] Architecture extension proposal for ConfigPtr CSR to "Unified RISC-V Discovery Method" config structure


Jonathan Behrens <behrensj@...>
 

Why does it need to be a CSR? In other parts of the boot flow the device tree pointer is passed via a normal general purpose register. Why can't the same be done here?

Jonathan


On Mon, Jun 28, 2021 at 3:30 PM Greg Favor via lists.riscv.org <gfavor=ventanamicro.com@...> wrote:
The new "unified RISC-V low-level discovery method" being developed by tech-config (for use by all extensions that have information that needs to be easily discoverable by software), is almost completely software-based.  The compressed binary config structure (containing all the discovery information) will reside somewhere in system physical address space and will be read and decoded (based on a standardized RISC-V schema) by an M-mode parser/decoder into all the individual discoverable items available for use by software.

Typically M-mode software, during the boot flow, may make use of some of this information, but much of that information will be populated into a high-level discovery structure for use by other software components in the system (e.g. Device Tree or ACPI tables in Linux-class systems; Device Tree or some other suitable structure in embedded systems).  Other agents, such as an external debugger, may also read and parse this structure for discovering Debug and Trace architecture related information.

To support this, each hart needs to have a CSR that provides an address pointer to the memory-resident config data structure - which can reside anywhere in system address space and may physically reside on or off chip in whatever suitable form of storage.  This fast track extension standardizes this CSR.  This email (I'm helping out the people developing the overall discovery method) starts a prelim review of this extension on the tech-priv and tech-config email lists.

The proposed official extension name is 'Smdisc'.

The 'mconfigptr' CSR is an MXLEN-wide R/W M-mode CSR that provides a system physical address pointer to a memory-resident config data structure to be used by a software method for low-level discovery of configuration information about harts and the rest of the system.  Some implementations may hardwire this CSR to a suitable value.  The assigned CSR number is 0x750.

Greg

P.S. The Debug Architecture already contains config structure pointer registers in the Debug Module for use by an external debugger.


Greg Favor
 

On Mon, Jun 28, 2021 at 1:39 PM Jonathan Behrens <behrensj@...> wrote:
Why does it need to be a CSR? In other parts of the boot flow the device tree pointer is passed via a normal general purpose register. Why can't the same be done here?

That's one example of a high-level discovery method used by, for example, some Linux systems.  This low-level discovery method is used by early boot flow software and is used to populate implementation-specific information into the Device Tree (or ACPI) structure that is going to be passed to the OS.

In general, the nature of both low and high level discovery methods within the broad range of RISC-V-based systems is not the subject of this extension.  Architecting and/or standardizing those is the purview of other groups.  But insofar as it has been deemed necessary by various people that RVI develop a standard RISC-V low-level discovery method usable across a wide range of RISC-V systems, this extension provides the one needed ISA hook.

Greg


Jonathan Behrens <behrensj@...>
 



On Mon, Jun 28, 2021 at 4:51 PM Greg Favor via lists.riscv.org <gfavor=ventanamicro.com@...> wrote:
On Mon, Jun 28, 2021 at 1:39 PM Jonathan Behrens <behrensj@...> wrote:
Why does it need to be a CSR? In other parts of the boot flow the device tree pointer is passed via a normal general purpose register. Why can't the same be done here?

That's one example of a high-level discovery method used by, for example, some Linux systems.  This low-level discovery method is used by early boot flow software and is used to populate implementation-specific information into the Device Tree (or ACPI) structure that is going to be passed to the OS.

In general, the nature of both low and high level discovery methods within the broad range of RISC-V-based systems is not the subject of this extension.  Architecting and/or standardizing those is the purview of other groups.  But insofar as it has been deemed necessary by various people that RVI develop a standard RISC-V low-level discovery method usable across a wide range of RISC-V systems, this extension provides the one needed ISA hook.

I'm not sure I follow. I understand that the low-level and high-level discovery mechanisms are different, but is there a reason that the pointer to the low-level discovery method needs to be passed via a CSR? Instead, couldn't we just say for instance, "at boot register a5 contains a pointer to the low-level configuration structure."

Jonathan


Greg Favor
 

On Mon, Jun 28, 2021 at 2:14 PM Jonathan Behrens <behrensj@...> wrote:
I'm not sure I follow. I understand that the low-level and high-level discovery mechanisms are different, but is there a reason that the pointer to the low-level discovery method needs to be passed via a CSR? Instead, couldn't we just say for instance, "at boot register a5 contains a pointer to the low-level configuration structure."

The issue is that coming out of reset, early M-mode software needs to be able to find the config structure.  If the pointer is in a GPR, who sets the correct value into that register and how does that piece of software find out the correct value to put into the register?  In many systems this CSR value will be hardwired, or will be initialized by an implementation-specific mechanism, before the hart comes out of reset.  (For example, in some higher-end Linux-class systems there may be a platform microcontroller that brings up the system from power-on, establishes a secure boot root of trust, ..., and prepares the harts to be released from reset.)

Greg

 


Jonathan Behrens <behrensj@...>
 



On Mon, Jun 28, 2021 at 5:26 PM Greg Favor <gfavor@...> wrote:
On Mon, Jun 28, 2021 at 2:14 PM Jonathan Behrens <behrensj@...> wrote:
I'm not sure I follow. I understand that the low-level and high-level discovery mechanisms are different, but is there a reason that the pointer to the low-level discovery method needs to be passed via a CSR? Instead, couldn't we just say for instance, "at boot register a5 contains a pointer to the low-level configuration structure."

The issue is that coming out of reset, early M-mode software needs to be able to find the config structure.  If the pointer is in a GPR, who sets the correct value into that register and how does that piece of software find out the correct value to put into the register?  In many systems this CSR value will be hardwired, or will be initialized by an implementation-specific mechanism, before the hart comes out of reset.  (For example, in some higher-end Linux-class systems there may be a platform microcontroller that brings up the system from power-on, establishes a secure boot root of trust, ..., and prepares the harts to be released from reset.)

Couldn't the reset state itself just have a5=<pointer>? I don't see why that would be substantially harder to implement than a reset state with CSR[0x750]=<pointer>.

Jonathan


Philipp Tomsich <philipp.tomsich@...>
 



On Mon 28. Jun 2021 at 23:31, Jonathan Behrens <behrensj@...> wrote:


On Mon, Jun 28, 2021 at 5:26 PM Greg Favor <gfavor@...> wrote:
On Mon, Jun 28, 2021 at 2:14 PM Jonathan Behrens <behrensj@...> wrote:
I'm not sure I follow. I understand that the low-level and high-level discovery mechanisms are different, but is there a reason that the pointer to the low-level discovery method needs to be passed via a CSR? Instead, couldn't we just say for instance, "at boot register a5 contains a pointer to the low-level configuration structure."

The issue is that coming out of reset, early M-mode software needs to be able to find the config structure.  If the pointer is in a GPR, who sets the correct value into that register and how does that piece of software find out the correct value to put into the register?  In many systems this CSR value will be hardwired, or will be initialized by an implementation-specific mechanism, before the hart comes out of reset.  (For example, in some higher-end Linux-class systems there may be a platform microcontroller that brings up the system from power-on, establishes a secure boot root of trust, ..., and prepares the harts to be released from reset.)

Couldn't the reset state itself just have a5=<pointer>? I don't see why that would be substantially harder to implement than a reset state with CSR[0x750]=<pointer>.

Now we’d need to save $a5 somewhere we can get at it later on… with a CSR, the value can be retrieved whenever needed. Note that I’d love to have a sane C runtime (with at least a stack somewhere in OCM) at initialization, but I expect parts of the ecosystem (most likely hardware vendors) will not want to impose any further restrictions on initial boot firmware.

In other words: doing so would impose further requirements on the early boot firmware. Keeping it in a CSR decouples the extension/unified discovery fully.

Philipp.


Allen Baum
 

I'd like to add that there are technical reasons why the reset state of CSRs not be some fixed (non trivial) value, especially in high end systems that have large physical register files.
Some small implementations may not want to have any fixed reset value at all - it's a bunch of logic that needs to be added to a structure that's already substantial for those small cores.

On Mon, Jun 28, 2021 at 2:38 PM Philipp Tomsich <philipp.tomsich@...> wrote:


On Mon 28. Jun 2021 at 23:31, Jonathan Behrens <behrensj@...> wrote:


On Mon, Jun 28, 2021 at 5:26 PM Greg Favor <gfavor@...> wrote:
On Mon, Jun 28, 2021 at 2:14 PM Jonathan Behrens <behrensj@...> wrote:
I'm not sure I follow. I understand that the low-level and high-level discovery mechanisms are different, but is there a reason that the pointer to the low-level discovery method needs to be passed via a CSR? Instead, couldn't we just say for instance, "at boot register a5 contains a pointer to the low-level configuration structure."

The issue is that coming out of reset, early M-mode software needs to be able to find the config structure.  If the pointer is in a GPR, who sets the correct value into that register and how does that piece of software find out the correct value to put into the register?  In many systems this CSR value will be hardwired, or will be initialized by an implementation-specific mechanism, before the hart comes out of reset.  (For example, in some higher-end Linux-class systems there may be a platform microcontroller that brings up the system from power-on, establishes a secure boot root of trust, ..., and prepares the harts to be released from reset.)

Couldn't the reset state itself just have a5=<pointer>? I don't see why that would be substantially harder to implement than a reset state with CSR[0x750]=<pointer>.

Now we’d need to save $a5 somewhere we can get at it later on… with a CSR, the value can be retrieved whenever needed. Note that I’d love to have a sane C runtime (with at least a stack somewhere in OCM) at initialization, but I expect parts of the ecosystem (most likely hardware vendors) will not want to impose any further restrictions on initial boot firmware.

In other words: doing so would impose further requirements on the early boot firmware. Keeping it in a CSR decouples the extension/unified discovery fully.

Philipp.


Allen Baum
 

and to add more detail to Tin's comment: the debug spec has 4 debug registers (which are not aCSRs) which hold the address of the configuration string:

When confstrptrvalid is set, reading this register returns bits 31:0 of the configuration string pointer. 
Reading the other confstrptr registers returns the upper bits of the address. 
When system bus mastering is implemented, this must be an address that can be used with the System Bus Access module. 
Otherwise, this must be an address that can be used to access the configuration string from the hart with ID 0. 
If confstrptrvalid is 0, then the confstrptr registers hold identifier information which is not further specified in this document. 
The configuration string itself is described in the Privileged Spec. This entire register is read-only

Note that there are already some debug registers that are shadowed by CSRs, so they can be accessed both using CSR accesses from a hart, and from an external debugger, thoug (given the CSR addresses) only from debug mode.


On Mon, Jun 28, 2021 at 3:30 PM Allen Baum <allen.baum@...> wrote:
I'd like to add that there are technical reasons why the reset state of CSRs not be some fixed (non trivial) value, especially in high end systems that have large physical register files.
Some small implementations may not want to have any fixed reset value at all - it's a bunch of logic that needs to be added to a structure that's already substantial for those small cores.

On Mon, Jun 28, 2021 at 2:38 PM Philipp Tomsich <philipp.tomsich@...> wrote:


On Mon 28. Jun 2021 at 23:31, Jonathan Behrens <behrensj@...> wrote:


On Mon, Jun 28, 2021 at 5:26 PM Greg Favor <gfavor@...> wrote:
On Mon, Jun 28, 2021 at 2:14 PM Jonathan Behrens <behrensj@...> wrote:
I'm not sure I follow. I understand that the low-level and high-level discovery mechanisms are different, but is there a reason that the pointer to the low-level discovery method needs to be passed via a CSR? Instead, couldn't we just say for instance, "at boot register a5 contains a pointer to the low-level configuration structure."

The issue is that coming out of reset, early M-mode software needs to be able to find the config structure.  If the pointer is in a GPR, who sets the correct value into that register and how does that piece of software find out the correct value to put into the register?  In many systems this CSR value will be hardwired, or will be initialized by an implementation-specific mechanism, before the hart comes out of reset.  (For example, in some higher-end Linux-class systems there may be a platform microcontroller that brings up the system from power-on, establishes a secure boot root of trust, ..., and prepares the harts to be released from reset.)

Couldn't the reset state itself just have a5=<pointer>? I don't see why that would be substantially harder to implement than a reset state with CSR[0x750]=<pointer>.

Now we’d need to save $a5 somewhere we can get at it later on… with a CSR, the value can be retrieved whenever needed. Note that I’d love to have a sane C runtime (with at least a stack somewhere in OCM) at initialization, but I expect parts of the ecosystem (most likely hardware vendors) will not want to impose any further restrictions on initial boot firmware.

In other words: doing so would impose further requirements on the early boot firmware. Keeping it in a CSR decouples the extension/unified discovery fully.

Philipp.


Greg Favor
 

On Mon, Jun 28, 2021 at 3:40 PM Allen Baum <allen.baum@...> wrote:
The configuration string itself is described in the Privileged Spec. 

Where?  The Priv spec does not discuss configuration strings.  And the Unpriv spec only discusses ISA naming strings.
 
Note that there are already some debug registers that are shadowed by CSRs, so they can be accessed both using CSR accesses from a hart, and from an external debugger, thoug (given the CSR addresses) only from debug mode.

Trigger Module registers are only CSR-mapped, and Debug Module registers are only memory-mapped.

Greg


Allen Baum
 

I am merely reporting verbatim from the debug spec. I don't remember where or if  it exists there.

I am misremembering about the shadowing; it could be, but the spec doesn't specify it; its an implementation option.
The spec gives an example of debug registers being shadowed - but  in low memory, not in CSRs

On Mon, Jun 28, 2021 at 4:01 PM Greg Favor <gfavor@...> wrote:
On Mon, Jun 28, 2021 at 3:40 PM Allen Baum <allen.baum@...> wrote:
The configuration string itself is described in the Privileged Spec. 

Where?  The Priv spec does not discuss configuration strings.  And the Unpriv spec only discusses ISA naming strings.
 
Note that there are already some debug registers that are shadowed by CSRs, so they can be accessed both using CSR accesses from a hart, and from an external debugger, thoug (given the CSR addresses) only from debug mode.

Trigger Module registers are only CSR-mapped, and Debug Module registers are only memory-mapped.

Greg


Greg Favor
 

On Mon, Jun 28, 2021 at 4:17 PM Allen Baum <allen.baum@...> wrote:
I am merely reporting verbatim from the debug spec. I don't remember where or if  it exists there.

A very, very old version of the Priv spec apparently talked about config strings (based on the preface for v1.9.1).
 
I am misremembering about the shadowing; it could be, but the spec doesn't specify it; its an implementation option.
The spec gives an example of debug registers being shadowed - but  in low memory, not in CSRs

Paul just pointed out to me that the 'dataaccess' field in the 'hartinfo' Debug Module register can optionally say that the DM's data registers are shadowed in hart CSRs.  Which is interesting - especially since there are no officially assigned CSR numbers for this.  Which means that an implementation can only use custom CSR numbers if dataaccess=0.

Greg



 


Allen Baum
 

Right - an implementation option then. I don't think it needs to be in the spec to do that, really.


On Mon, Jun 28, 2021 at 4:26 PM Greg Favor <gfavor@...> wrote:
On Mon, Jun 28, 2021 at 4:17 PM Allen Baum <allen.baum@...> wrote:
I am merely reporting verbatim from the debug spec. I don't remember where or if  it exists there.

A very, very old version of the Priv spec apparently talked about config strings (based on the preface for v1.9.1).
 
I am misremembering about the shadowing; it could be, but the spec doesn't specify it; its an implementation option.
The spec gives an example of debug registers being shadowed - but  in low memory, not in CSRs

Paul just pointed out to me that the 'dataaccess' field in the 'hartinfo' Debug Module register can optionally say that the DM's data registers are shadowed in hart CSRs.  Which is interesting - especially since there are no officially assigned CSR numbers for this.  Which means that an implementation can only use custom CSR numbers if dataaccess=0.

Greg



 


Allen Baum
 

One question: do we restrict accesses to the structure at the address in the CSR to be single byte accesses only?
(If this exists on a slow external flash device, they may want to load 4/8B at a time to speed up decode)
How does someone determine what size access is legal? 
The PMA can restrict it, and the structure could describe the PMA (I had a proposal for that), but it is a chicken/egg problem then)

On Mon, Jun 28, 2021 at 4:33 PM Allen Baum <allen.baum@...> wrote:
Right - an implementation option then. I don't think it needs to be in the spec to do that, really.

On Mon, Jun 28, 2021 at 4:26 PM Greg Favor <gfavor@...> wrote:
On Mon, Jun 28, 2021 at 4:17 PM Allen Baum <allen.baum@...> wrote:
I am merely reporting verbatim from the debug spec. I don't remember where or if  it exists there.

A very, very old version of the Priv spec apparently talked about config strings (based on the preface for v1.9.1).
 
I am misremembering about the shadowing; it could be, but the spec doesn't specify it; its an implementation option.
The spec gives an example of debug registers being shadowed - but  in low memory, not in CSRs

Paul just pointed out to me that the 'dataaccess' field in the 'hartinfo' Debug Module register can optionally say that the DM's data registers are shadowed in hart CSRs.  Which is interesting - especially since there are no officially assigned CSR numbers for this.  Which means that an implementation can only use custom CSR numbers if dataaccess=0.

Greg



 


Greg Favor
 

On Tue, Jun 29, 2021 at 12:01 AM Allen Baum <allen.baum@...> wrote:
One question: do we restrict accesses to the structure at the address in the CSR to be single byte accesses only?
(If this exists on a slow external flash device, they may want to load 4/8B at a time to speed up decode)
How does someone determine what size access is legal? 
The PMA can restrict it, and the structure could describe the PMA (I had a proposal for that), but it is a chicken/egg problem then)

This extension just provides a standard place to find the pointer to the structure.  Any and everything past that is up to specification by the discovery method making use of this CSR and/or a platform spec placing requirements and constraints on the whole matter.

But, with that big caveat and just as a comment, I would imagine that most on-chip and off-chip readily-accessible forms of storage are accessible by 4B loads.  Or the structure is transferred by platform power-on firmware from wherever else, into readily-accessible SRAM or DRAM memory.  Or one can imagine other scenarios.  (For the class of systems that I tend to deal with, one of the first two scenarios generally apply.) 

Greg