possible to determin what extensions are available at run time?

384 views
Skip to first unread message

Mark Manning

unread,
Jan 24, 2022, 10:06:04 AM1/24/22
to RISC-V ISA Dev
Is it possible for a user level application to determine which ratified extensions are active on a given CPU at run time?


Tommy Murphy

unread,
Jan 24, 2022, 10:31:53 AM1/24/22
to Mark Manning, RISC-V ISA Dev
Read the $misa CSR?

Mark Manning

unread,
Jan 24, 2022, 10:54:05 AM1/24/22
to RISC-V ISA Dev, Tommy Murphy, Mark Manning
meant to ask this here for public view but replied to you directly TM

"now for my next dumb question, where is this documented?" 

I can find a bunch of web sites telling me what CSRs exist and none of them seem to have info on what bit fields exist in what CSR etc.  


On Monday, January 24, 2022 at 9:31:53 AM UTC-6 Tommy Murphy wrote:
Read the $misa CSR?

Mark Manning

unread,
Jan 24, 2022, 10:58:40 AM1/24/22
to RISC-V ISA Dev, Mark Manning, Tommy Murphy
nevermind, I fould a reference.
would have been nice to find something like this on the RISC V web site.

Tommy Murphy

unread,
Jan 24, 2022, 11:03:09 AM1/24/22
to Mark Manning, RISC-V ISA Dev, Mark Manning
The misa CSR is fully described in the spec.

Jeff Scott

unread,
Jan 24, 2022, 11:22:31 AM1/24/22
to Tommy Murphy, Mark Manning, RISC-V ISA Dev, Mark Manning

Yes, but MISA does not have room for all ratified extensions.  The answer is there is no standard RISC-V way for software to know every ratified extension included on a core.

 

Jeff

 

From: Tommy Murphy <tommy_...@hotmail.com>
Sent: Monday, January 24, 2022 10:03 AM
To: Mark Manning <mman...@int-bio.com>; RISC-V ISA Dev <isa...@groups.riscv.org>
Cc: Mark Manning <mman...@int-bio.com>
Subject: [EXT] Re: [isa-dev] possible to determin what extensions are available at run time?

 

Caution: EXT Email

The misa CSR is fully described in the spec.

 

--
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 view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/isa-dev/LO2P265MB4776C185942235F16AACBE60F95E9%40LO2P265MB4776.GBRP265.PROD.OUTLOOK.COM.

Nick Knight

unread,
Jan 24, 2022, 11:24:24 AM1/24/22
to Tommy Murphy, Mark Manning, RISC-V ISA Dev
Hi Mark,

The "misa" functionality that Tommy mentioned --- specified in Vol. II, Sec. 3.1.1 --- is a standard mechanism to detect ISA functionality. An alternative is to try an instruction, and catch an (illegal-instruction) exception. As you gain experience using misa, you'll quickly become aware of its limitations --- several ratified extensions are unaccounted for --- and you may find yourself resorting to that alternative. There is hope on the horizon: the Configuration Structure (task group, current draft spec).

If you're developing software for an operating system, there may be a configuration structure already in place. For example, Linux uses things like "DTS" and "HWCAP". The developers of your operating system will know more.

Best,
Nick Knight

On Mon, Jan 24, 2022 at 8:03 AM Tommy Murphy <tommy_...@hotmail.com> wrote:
The misa CSR is fully described in the spec.

--

Greg Favor

unread,
Jan 24, 2022, 11:26:17 AM1/24/22
to Nick Knight, Tommy Murphy, Mark Manning, RISC-V ISA Dev
On Mon, Jan 24, 2022 at 8:24 AM Nick Knight <nick....@sifive.com> wrote:
The "misa" functionality that Tommy mentioned --- specified in Vol. II, Sec. 3.1.1 --- is a standard mechanism to detect ISA functionality. An alternative is to try an instruction, and catch an (illegal-instruction) exception. As you gain experience using misa, you'll quickly become aware of its limitations --- several ratified extensions are unaccounted for --- and you may find yourself resorting to that alternative. There is hope on the horizon: the Configuration Structure (task group, current draft spec).

If you're developing software for an operating system, there may be a configuration structure already in place. For example, Linux uses things like "DTS" and "HWCAP". The developers of your operating system will know more.

Yes, the new (in development by the tech-config TG) "RISC-V unified low-level discovery method" will support discovery of lots of information - such as what arch extensions are supported, what optional extension features are supported, what parameters are supported, etc. In Linux-class systems, for example, this would be employed during boot by M-mode software, and some of that information may then be populated into Device Tree or ACPI tables that are passed to the OS.

Greg 

Allen Baum

unread,
Jan 24, 2022, 11:29:52 AM1/24/22
to Jeff Scott, Tommy Murphy, Mark Manning, RISC-V ISA Dev
Well, the salient point was 
"Is it possible for a user level application to determine which ratified extensions are active on a given CPU at run time?
No, you can't, because, even if they were listed in MISA, MISA is a machine prive level CSR, and cannot be accessed by user code.
In general, there is no architectural way to do what is being asked. 
In general, there isn't even a way for machine level code to do it, except try it and see if it give the right answer, or it traps. 
 (user code could try that too, but not be able to recover from that trap)
The configuration structure extension and spec is supposed to fix that (see previous emails)
It is possible that there could be an SBI call that user code could execute and get that information from the OS (and similarly, the OS could do that to Machine mode firmware)

atish patra

unread,
Jan 25, 2022, 3:25:25 AM1/25/22
to Allen Baum, Jeff Scott, Tommy Murphy, Mark Manning, RISC-V ISA Dev
On Mon, Jan 24, 2022 at 8:29 AM Allen Baum <allen...@esperantotech.com> wrote:
Well, the salient point was 
"Is it possible for a user level application to determine which ratified extensions are active on a given CPU at run time?
No, you can't, because, even if they were listed in MISA, MISA is a machine prive level CSR, and cannot be accessed by user code.

In Linux land, these informations can be obtained via the DeviceTree. There are no provisions for user space programs to get that information in Linux yet.
However, the current plan is that all the ratified extensions that is required for Linux kernel/user space will be encoded the "riscv,isa" device tree property.
The kernel will parse it and provide this information to the user space via /proc/cpuinfo.

Here is a version of the linux kernel patch that took a different approach (separate DT node) to populate extension information.

Mark Manning

unread,
Jan 25, 2022, 9:54:37 AM1/25/22
to RISC-V ISA Dev, atish patra, Jeff Scott, Tommy Murphy, Mark Manning, RISC-V ISA Dev, Allen Baum
This is a HORRENDOUSLY bad state of affairs.    There is absolutely no good reason why available core functionality should be hidden from user applications.

I am developing a forth compiler.  One of the "words" in said compiler shall be "/" (pronounced "slash") which does a division.  If there is hardware division available it should use that, if not it should call the much slower software division function - THIS IS NOT a compile time selection, this is a RUN time selection.
This is just one of many instances where my user application code needs to know the capabilities of the hardware it is running on. 

The ***ONLY*** other option is for me to write a new, ultra specific forth compiler for every single RISC-V processor I want to support.

My ONE binary should be able to run on any RISC-V processor and "just know" what it can do there.

NOT good,

Allen Baum

unread,
Jan 25, 2022, 10:44:26 AM1/25/22
to Mark Manning, RISC-V ISA Dev, atish patra, Jeff Scott, Tommy Murphy
I'm going to violently disagree. If that was a requirement, you can't cross-assemble code for one version of a RISC-V core on a different RISC-V core (or even on an x86 or ARM or Power or...).
You don't need an on-line resource to do this. You need an ISA-string that you can use as a command line argument, and DT is one way to get it. There are others.

The other reason that it isn't allowed is for virtualization. Extensions can be enabled and disabled - but not from user code. If a user (or even an OS) could interrogate whether an extension has been disabled, it can break the virtualization barrier.


Connect with us!

Save the Date! May 4-6, 2022 | https://int-bio.com/airborne-conference/

This e-mail and any files transmitted with it are the property of International Biomedical, Ltd. and/or its affiliates, are confidential, and are intended solely for the use of the individual or entity to whom this e-mail is addressed. If you are not one of the named recipient(s) or otherwise have reason to believe that you have received this message in error, please notify the sender and delete this message immediately.  Any other use, retention, dissemination,  forwarding, printing, or copying of this e-mail is strictly prohibited.

L Peter Deutsch

unread,
Jan 25, 2022, 11:19:07 AM1/25/22
to Allen Baum, mman...@int-bio.com, isa...@groups.riscv.org, atis...@gmail.com, jeff....@nxp.com, tommy_...@hotmail.com
> I'm going to violently disagree. If that was a requirement, you can't
> cross-assemble code for one version of a RISC-V core on a different RISC-V
> core (or even on an x86 or ARM or Power or...).

Cross-assembly/cross-compilation requires being able to specify the
configuration of the *target*. What this requires is having a syntax and/or
API for specifying the configuration. This specification may, but need not,
have anything to do with the configuration of the system on which the
assembly/compilation is happening.

> You don't need an on-line resource to do this. You need an ISA-string that
> you can use as a command line argument, and DT is one way to get it. There
> are others.

I don't think that a command line argument is sufficient. A
high-performance library will want to exist in multiple versions depending
on the ISA configuration on which it is being run: this may be selected as
early as program startup time (which may not be from a command line), or at
link time (for dynamic linking), or when an initialization API is called, or
even on the fly if the library includes JIT functionality.

Perhaps I'm missing something here, but right now I have to agree that
knowing what instructions are implemented in hardware, what are being
emulated, and what are not available at all is something that user code
really needs to be able to determine dynamically and reasonably efficiently
at execution time.

> The other reason that it isn't allowed is for virtualization. Extensions can
> be enabled and disabled - but not from user code. If a user (or even an OS)
> could interrogate whether an extension has been disabled, it can break the
> virtualization barrier.

That only requires that the mechanism for determining the configuration has
to be virtualizable itself, doesn't it?

--

L Peter Deutsch <gh...@major2nd.com> :: Aladdin Enterprises :: Healdsburg, CA

Was your vote really counted? http://www.verifiedvoting.org

Mark Manning

unread,
Jan 25, 2022, 11:23:30 AM1/25/22
to L Peter Deutsch, Allen Baum, isa...@groups.riscv.org, atis...@gmail.com, jeff....@nxp.com, Tommy Murphy
Ty to L.P.D. for expressing the issue far more eloquently that I.


Samuel Falvo II

unread,
Jan 25, 2022, 11:24:39 AM1/25/22
to Mark Manning, RISC-V ISA Dev, atish patra, Jeff Scott, Tommy Murphy, Allen Baum
On Tue, Jan 25, 2022 at 6:54 AM Mark Manning <mman...@int-bio.com> wrote:
This is a HORRENDOUSLY bad state of affairs.    There is absolutely no good reason why available core functionality should be hidden from user applications.

Hi Mark,

Long time no see.  While I sympathize with your concerns, I must ask that you refrain from getting overly excited in this forum.  The frequent use of CAPS to emphasize content, even though I know from past interactions you are not intending on expressing a raised voice, really isn't necessary here and it can (and will, as I've seen it happen before) lead to uncooperative antagonism between parties.

This isn't c.l.f.  Please be polite and respectful.  Thanks.

--
Samuel A. Falvo II

Christian Brunschen

unread,
Jan 25, 2022, 12:12:20 PM1/25/22
to L Peter Deutsch, Allen Baum, mman...@int-bio.com, isa...@groups.riscv.org, atis...@gmail.com, jeff....@nxp.com, tommy_...@hotmail.com
(I'm not someone who actually knows very much here, so please excuse errors, and do correct me)

Things are more complicated these days as there are heterogeneous multi-core systems, including on a single chip – ARM's big.little, Intel's 12-th gen P & E cores, for example, but also Esperanto's ET-SoC-1 with its mix of Minion and Maxion cores – which implement different sets of extensions. A piece of code might conceivably be moved at run-time from one core to another, from one set of supported extensions to another. "what instructions are implemented in hardware, what are being emulated" may thus change at arbitrary points at run-time. 

Imagine a piece of code that starts to run on a core with a particular set of extensions, queries the core it runs on for extensions, and notes that a particular high-performance extension that it would like to use is not present in hardware; and thus avoids using a high-performance instruction, using a small well-optimized subroutine instead, in order to avoid the overhead of the missing instruction having to be trapped and emulated. 

Now let that code get moved to a core that does have that extension; but the piece of code will continue to use its small subroutine, instead of using the instruction that would now be executed directly and at much higher speed.

At least theoretically, even what instructions are available at all could change at run-time, by loading new emulation routines into a higher privileged mode so that it can now handle those instructions, even though it could not do so when the piece of code in question originally started running and might have chosen to query what extensions are available; and as long as this happens before the piece of code actually tried to use the instructions in question, it could actually all still work.

On a heterogeneous multicore / multiprocessor system even the question becomes tricky – asking "what instructions are implemented in hardware and which are emulated", what should the answer be? should it be the information from the current core? should it err on the side of caution and only report those extensions that are on all cores as present, and return 'may be emulated' for everything that is only on some of the cores?

I have no answers here, and really these are just rhetorical questions to suggest that things are a touch more complex and that a simple answer may not be possible.

Best wishes 

// Christian Brunschen


--
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.

Allen Baum

unread,
Jan 25, 2022, 12:26:48 PM1/25/22
to L Peter Deutsch, Mark Manning, RISC-V ISA Dev, atish patra, Jeff Scott, Tommy Murphy
Good points, but (and this is my ignorance) Is requiring an SBI call to query the current configuration insufficient to either dynamically select  or compile a library?

There may be a bit of confusion in my response.
I interpreted the original requirement to be a native U-mode instruction that would be executed to do this.
It should be possible for user code to get the current configuration via an SBI call; that is the intent of the Configuration Structure extension - which is Mmode
(though only to the extent that accessing the pointer is only Mmode; once you have it, 
there is nothing to prevent nor require that it is accessible to Umode .

You can then argue whether an SBI call (using the ECALL opcode) is a user mode instruction or not that satisfies  (my interpetation of )the original requirement.
My answer was assuming  that, even with Zicsr implemented, reading MISA was not.

L Peter Deutsch

unread,
Jan 25, 2022, 12:38:28 PM1/25/22
to Christian Brunschen, allen...@esperantotech.com, mman...@int-bio.com, isa...@groups.riscv.org, atis...@gmail.com, jeff....@nxp.com, tommy_...@hotmail.com
Thanks for illuminating some complexities of which those of us from an
earlier era might not have been fully aware.

> Now let that code get moved to a core that does have that extension ...

It seems to me that in an environment in which different cores have
different instruction capabilities, even if emulation makes them
*functionally* equivalent, the environment must provide an API for user code
to have some control over this process, in order to avoid potential serious
performance hits or even error traps. On brief thought, I could imagine:

* Being able to say "require the following capabilities to run this process";

* Being able to say "require the following capabilities in hardware (not
emulated) to run this process";

* Being able to say "send a signal if this process is moved to a core that
has / doesn't have the following capabilities".

> On a heterogeneous multicore / multiprocessor system even the question
> becomes tricky ...

Indeed. So the designers of OSs on such systems need to think carefully
about the userland APIs for core assignment. Such systems are now common
enough that I'm sure this issue has already gotten some attention. Could
someone who has first-hand experience with it share their info?

Samuel Falvo II

unread,
Jan 25, 2022, 12:52:02 PM1/25/22
to Allen Baum, L Peter Deutsch, Mark Manning, RISC-V ISA Dev, atish patra, Jeff Scott, Tommy Murphy
I'd like to add to your statement if I can.  Reading MISA means that your privileged execution environment must comply with the privileged mode specification to some level.  RISC-V's instruction set architecture is factored by design so that the user-mode and privileged-mode environments are independent of each other.  It's possible to implement the RISC-V user-mode ISA but not the privileged-mode (e.g., in an emulator, for example; or, perhaps, with a different privileged mode operation all-together).  For instance, I could (if I had the time, money, and know-how) implement a single-address-space, orthogonally persistent environment that relies entirely on object capabilities instead of "user-mode/kernel-mode" flags and paging, and I'd still be able to claim RISC-V compatibility.

Believe it or not, I could also implement the RISC-V privileged specification (albeit with some opcode differences) for a processor core implementing the Z80 instruction set if I wanted to.  That's how cleanly divorced the privileged and user-mode ISAs are.  This is by intention and by design.

The MISA register is a first-order attempt at providing run-time guidance for hardware capability discovery.  However, it was quickly overwhelmed with all the different extensions that have since been proposed, and it becomes meaningless in a processor without the privilege specification.  For MISA to have meaning across environments, we'd need to specify CSRs independently of privileged environment specifications.  We would then need to specify additional CSRs to cover all the ratified extensions.  Then, if desired, user-mode mirrors of machine-mode registers.  All these features add logic to the core, whether they're useful for your applications or not.  It also adds a burden to the standards bodies to keep these up to date, which increases bureaucracy and coupling.

Hoping this helps explain why there's no ratified way for discovering hardware capabilities at this time.  The existence of MISA suggests there has always been a desire for this facility; but, it's been a very low priority compared to other tasks, especially when taking into consideration other standards, like device-tree.




--
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.

Samuel Falvo II

unread,
Jan 25, 2022, 12:57:29 PM1/25/22
to L Peter Deutsch, Christian Brunschen, Allen Baum, Mark Manning, RISC-V ISA Dev, atish patra, Jeff Scott, Tommy Murphy
On Tue, Jan 25, 2022 at 9:38 AM L Peter Deutsch <gh...@major2nd.com> wrote:
* Being able to say "require the following capabilities to run this process";

* Being able to say "require the following capabilities in hardware (not
emulated) to run this process";

* Being able to say "send a signal if this process is moved to a core that
has / doesn't have the following capabilities".

One more:

* Invoke my own functionality in case the following instructions are not supported.

In other words, delegate the illegal opcode handler for a given range of opcodes to the process itself, and let it handle its own emulation needs.  That way, you can include the emulation code in your binary, but it'll never be invoked if the instructions you otherwise depend on are supported.

Greg Favor

unread,
Jan 25, 2022, 1:11:43 PM1/25/22
to Allen Baum, L Peter Deutsch, Mark Manning, RISC-V ISA Dev, atish patra, Jeff Scott, Tommy Murphy
On Tue, Jan 25, 2022 at 9:26 AM Allen Baum <allen...@esperantotech.com> wrote:
Good points, but (and this is my ignorance) Is requiring an SBI call to query the current configuration insufficient to either dynamically select  or compile a library?

On the one hand, doing an ECALL to M-mode is heavy-weight.  And doing that for each individual query to discover a specific piece of info, is inefficient.  And caching or remembering discovered info can be problematic in some (not uncommon) types of systems.

In the case of Linux systems, Device Tree or ACPI tables are the mechanism for the OS to discover all the info that it needs.  Then the OS has its own mechanisms to use that info and to make that available to other supervisor and user level components.

Different operating environments will have different end-to-end discovery stories.

Lastly, the mention of an SBI call requires architecting/defining such an SBI "discovery" extension.  And presumes that most all RISC-V-based system designs implement SBI.  But at least in Linux-based systems that would be unused (since Linux boot simply expects to be handled DT or ACPI tables.

Greg

Allen Baum

unread,
Jan 25, 2022, 3:51:05 PM1/25/22
to Greg Favor, L Peter Deutsch, Mark Manning, RISC-V ISA Dev, atish patra, Jeff Scott, Tommy Murphy
SBI would be heavyweight, but really only needs to be done once, e.g. to get/build an ACPI table or a Device tree 
(assuming it isn't simply handed to the OS at boot time - more ignorance. )
One could do individual queries, or not, which is an "if it hurts when you do that, don't do that" case. (assuming the query can return more than a simple Boolean)

But, having the OS know or be able to determine it is different than having a user app know it - and that was the original ask. 
I think my question is relevant, but restated:
   Is using a query mechanism to higher level software insufficient to perform the functionality required?
   as well as: does user level software even need to know this at all, as opposed to having OS level software load the right library based on ELF headers?
   (with the assumption that there is an OS level mechanism, using ACPI tables of Device tree, to get the desired information).
The latter question might be answered "yes, it is needed" - in which case there would need to be a mechanism for user code to query this from OS level.

Philipp Tomsich

unread,
Jan 25, 2022, 5:38:08 PM1/25/22
to Allen Baum, Greg Favor, L Peter Deutsch, Mark Manning, RISC-V ISA Dev, atish patra, Jeff Scott, Tommy Murphy
Allen,

On Tue, 25 Jan 2022 at 21:51, Allen Baum <allen...@esperantotech.com> wrote:
SBI would be heavyweight, but really only needs to be done once, e.g. to get/build an ACPI table or a Device tree 
(assuming it isn't simply handed to the OS at boot time - more ignorance. )
One could do individual queries, or not, which is an "if it hurts when you do that, don't do that" case. (assuming the query can return more than a simple Boolean)

But, having the OS know or be able to determine it is different than having a user app know it - and that was the original ask. 
I think my question is relevant, but restated:
   Is using a query mechanism to higher level software insufficient to perform the functionality required?
   as well as: does user level software even need to know this at all, as opposed to having OS level software load the right library based on ELF headers?
   (with the assumption that there is an OS level mechanism, using ACPI tables of Device tree, to get the desired information).
The latter question might be answered "yes, it is needed" - in which case there would need to be a mechanism for user code to query this from OS level.

This is where dynamic resolution (like ifunc — i.e., indirect functions) come in…

So let's quickly review the state of discovery, top-to-bottom (i.e. low-level discovery will be at the end):
  • Userspace has multiple OS/runtime-dependent mechanisms available.
    In a typical Linux system this will be:
    • Reading of /proc/cpuinfo (and parsing the strings there…).
    • Accessing the ELF auxiliary vectors (via getauxval()) and looking at AT_HWCAPS, AT_HWCAPS2, AT_PLATFORM, et al.
    • Relying on the runtime-linker to handle library-paths (to resolve to the most optimal DSOs) and indirect functions (in case multiple versions of a single function exist in a single DSO).
  • Kernels will use device-tree/ACPI/etc. depending on the contract they have with their firmware (device-tree and ACPI are happening for Linux on RISC-V).
  • Firmware populates the device-tree/ACPI/etc. based on discovery (misa CSR, instruction test & trap, and the upcoming unified discovery config-message).
Today, there's a few gaps in the above on RISC-V that are being rapidly addressed:
  • The injection of info via the auxiliary vector does not reflect the fine-grained extensions yet — this is an active area of work and was discussed in the last Linux Plumbers Conference.  Consequently, ifunc does not rise up to its potential yet.  Both should be resolved in 2022.
  • The unified discovery message is being worked on by the tech-config TG, but the specification is not done.  Another priority for our ecosystem and targeting a 2022 resolution (at least on the "frozen specification" side of things).
Cheers,
Philipp.

Bruce Hoult

unread,
Jan 25, 2022, 6:14:27 PM1/25/22
to Mark Manning, RISC-V ISA Dev, atish patra, Jeff Scott, Tommy Murphy, Allen Baum
On Wed, Jan 26, 2022 at 3:54 AM Mark Manning <mman...@int-bio.com> wrote:
This is a HORRENDOUSLY bad state of affairs.    There is absolutely no good reason why available core functionality should be hidden from user applications.

I am developing a forth compiler.  One of the "words" in said compiler shall be "/" (pronounced "slash") which does a division.  If there is hardware division available it should use that, if not it should call the much slower software division function - THIS IS NOT a compile time selection, this is a RUN time selection.
This is just one of many instances where my user application code needs to know the capabilities of the hardware it is running on. 

Even if the division instruction works you should benchmark it against the software routine. You can have one small function compiled each way and test them. If you're on bare metal then you control the illegal instruction handler. If you're on Linux you can fork() off the tests [1] and check the exit status. You can cache the information gathered at whatever level of granularity you think appropriate.

[1] can be quite low overhead especially if the test function doesn't write to RAM -- but in any case much lower overhead than starting up a new ELF.
Reply all
Reply to author
Forward
0 new messages