Re: [PATCH 0/7] RISC-V: Support version controling for ISA standard extensions and CSR

Palmer Dabbelt
2020-04-23T20:59:42Z

On Sat, 18 Apr 2020 04:17:15 PDT (-0700), nelson.chu@sifive.com wrote:
> Sorry for not sending these patches to Palmer :)
> CC Palmer.

That's fine, I subscribe to the lists :)

>
> Thanks
> Nelson
>
> On Sat, Apr 18, 2020 at 7:08 PM Nelson Chu <nelson.chu@sifive.com> wrote:
>>
>> Hi binutils and gdb,
>>
>> I know every RISCV contirbutors all do the best to maintain the compatibility
>> between different spec versions. But the specs are changed frequently, and
>> sometimes it is very hard to keep the compatibility if we don't have a good
>> way to deal with versioning problems. Since different ISA specs define
>> different instructions, and different privilege specs define different CSR,
>> both of them need the version checking and controling mechanism.
>>
>> For the ISA versions, you can set them by the RISCV ELF architecture attribute
>> and assembler option -march, but you have to set them one by one for each
>> extension. It seems not so friendly for user, so Kito Cheng proposed a good
>> solution to resolve the problem. That is, support the new assembler options and
>> default configure options to reduce the burdens when setting ISA versions.
>> The original idea and discussion are come from the following link,
>>
>> https://groups.google.com/a/groups.riscv.org/forum/#!msg/sw-dev/aZhMG7NIVTk/PTZEaTWiAwAJ)
>>
>> === New Assembler Options ===
>>
>> * -misa-spec = [2p0|2p1|2p2|20190608|20191213]
>> You can simply choose the ISA spec by this option, and then assembler will set
>> the version for the standard extensions if you don’t set in the ELF arch
>> attributes or -march option.
>>
>> * -mriscv-isa-version = <ISA-string>
>> The syntax of <ISA-string> is same as -march option, but without rv32 or rv64
>> prefix. There are two reasons that you may need this option,
>>
>> 1. Some versions of extensions defined in the ISA spec are not matched to the
>> toolchain’s implementation. For example, V-ext is defined to version 0.7 in
>> ISA spec, but we only have implementations for 0.8 and 0.9. Therefore, you
>> have to use this option to choose the correct version for V-ext.
>>
>> 2. You want to update the version for the specific standard extensions if the
>> version are not set in the ELF arch attributes and -march option.
>>
>> === New Default Configure Options ===
>>
>> * --with-arch = <ISA-string>
>> The syntax of <ISA-string> is same as -march option. Assembler will check this
>> if -march option and ELF arch attributes aren’t set.
>>
>> * --with-isa-spec = [2p0|2p1|2p2|20190608|20191213]
>> The syntax is same as -misa-spec option. Assembler will check this if
>> -misa-spec option isn’t set.
>>
>> * --with-riscv-isa-version = <ISA-string>
>> The syntax of <ISA-string> is same as -mriscv-isa-version option. Assembler
>> will check this if -mriscv-isa-version option isn’t set.
>>
>> === The Priority of these options ===
>>
>> * ELF arch attributes > Assembler options > Default configure options
>> * For GAS options, -march > -mriscv-isa-version > -misa-spec
>> * For configure options, --with-arch > --with-riscv-isa-version > --with-isa-spec
>>
>> === Example ===
>>
>> $ cat test.s
>> .attribute arch, "rv32i1p9fv_zicsr"
>>
>> $ riscv32-unknown-elf-as -march-attr -misa-spec=2p2 -mriscv-isa-version=i2p1a2p1v0p9 test.s -o test.o
>>
>> $ riscv32-unknown-elf-readelf -A test.o
>> Attribute Section: riscv
>> File Attributes
>> Tag_RISCV_arch: "rv32i1p9_f2p0_v0p9_zicsr0p0"
>> ...
>>
>> The above example covers most cases.
>>
>> * For i-ext, we already set the version 1p9 in elf attribute, so -misa-spec and
>> -mriscv-isa-version don't update the version to 2p0 and 2p1.
>>
>> * For f-ext, we don't set the version to it, so use the default version 2p0
>> according to the ISA spec 2p2.
>>
>> * For v-ext, the default version is 0p7 according to ISA spec 2p2, but we use
>> -mriscv-isa-version to update it to 0p9.
>>
>> * For a-ext, it isn't enabled by -march or elf attribute, so we don't update it's
>> version even if -mriscv-isa-version is set.
>>
>> * As for the zicsr extension, it is defined in the lastest ISA spec rather than 2p2,
>> so set it's version to 0p0.
>>
>>
>> As for the privilege version, I get the related request in the following link,
>> https://github.com/riscv/riscv-binutils-gdb/issues/202
>>
>> We also support new assembler options to choose the spec you want, and then
>> assembler will generate the correct CSR address according to the chosen spec.
>> If the obselete CSR name is used, then report the warning message when the
>> -mcsr-check is set, and use the latest defined address for the CSR. Of course,
>> you can also choose the spec by setting the orginal RISCV ELF priv attributes.
>> Beside, the disassembler can show the CSR according to the chosen privilege spec
>> by the new disassmebler option. However, the CSR address is showed directly if
>> it is invalid for the chosen spec.
>>
>> === New Assembler Option ===
>>
>> * -mpriv-spec=[1p9|1p9p1|1p10|1p11]
>> This is used to set the privileged spec’s version, and we can decide whether
>> the CSR is valid or not.
>>
>> === New Default Configure Option ===
>>
>> * --with-priv-spec = [1p9|1p9p1|1p10|1p11]
>> The syntax is same as -mpriv-spec option. Assembler will check this setting
>> if -mpriv-spec option isn’t set.
>>
>> === New Disassmebler Option ===
>>
>> * -Mpriv-spec=[1p9|1p9p1|1p10|1p11]
>> The syntax is same as -mpriv-spec option. The disassembler can show the CSR
>> correctly according to the chosen privilege spec.
>>
>>
>> Notes,
>>
>> 1. I'm not sure if GDB needs the above version checking, but I think the current
>> modifications won't change the behavior of GDB. We still use the DECLARE_CSR
>> to generate the gdb/features/riscv/[32|64]bit-csr.xml, that means we only generate
>> the CSR which are valid in the latest privilege spec. Also, the objdump shows
>> the CSR according to the latest privilege spec by default.
>>
>> 2. The default ISA spec is set to 2p2 rather than the lastest version. The reason
>> is that compiler generates the ISA string with fixed 2p0 verisons only for the
>> RISCV ELF architecture attributes, but not for the -march option. Therefore, we
>> should update the compiler or linker to resolve this problem in the futrue patches.
>>
>> 3. How to extend the default versions and new ISA spec?
>> You only need to update the riscv_ext_version_table which is defined in the
>> opcodes/riscv-opc.c.
>>
>> const struct riscv_ext_version riscv_ext_version_table[] =
>> {
>> /* name, spec name, major, minor. */
>> {"e", "20191213", 1, 9},
>> {"e", "20190608", 1, 9},
>> {"e", "2p2", 1, 9},
>>
>> {"i", "20191213", 2, 1},
>> {"i", "20190608", 2, 1},
>> {"i", "2p2", 2, 0},
>> ...
>> };
>>
>> 4. How to extend new privilege spec and new CSR?
>>
>> * include/opcode/riscv.h
>> enum riscv_csr_vclass
>> {
>> CSR_CLASS_VNONE, /* Default value */
>>
>> CSR_CLASS_V1P9, /* v1.9 */
>> CSR_CLASS_V1P9P1, /* v1.9.1 */
>> CSR_CLASS_V1P10, /* v1.10 */
>> CSR_CLASS_V1P11, /* v1.11 */
>> CSR_CLASS_VDRAFT
>> };
>>
>> * opcodes/riscv-opc.c
>>
>> static const struct priv_version_t priv_versions[] =
>> {
>> {"1p9", CSR_CLASS_V1P9},
>> {"1p9p1", CSR_CLASS_V1P9P1},
>> {"1p10", CSR_CLASS_V1P10},
>> {"1p11", CSR_CLASS_V1P11},
>>
>> /* Terminate the list. */
>> {NULL, 0}
>> };
>>
>> * include/opcode/riscv-opc.h
>>
>> Format, DECLARE_CSR (NAME, VALUE, CLASS, DEFINE_VER, ABORT_VER)
>> DECLARE_CSR_ALIAS(NAME, VALUE, CLASS, DEFINE_VER, ABORT_VER)
>>
>> NAME: CSR name.
>> VALUE: CSR address
>> CLASS: ISA dependency
>> DEFINE_VER: First defined in which privilege spec.
>> ABORT_VER: Aborted in which privilege spec. If the CSR is still valid in
>> the lastest version, then it should be CSR_CLASS_VDRAFT.
>>
>> If the CSR is aborted in the latest spec, or has not only one information, then
>> use DECLARE_CSR_ALIAS. Otherwise, use DECLARE_CSR.
>>
>> For example,
>> DECLARE_CSR(ustatus, CSR_USTATUS, CSR_CLASS_I, CSR_CLASS_V1P9, CSR_CLASS_VDRAFT)
>> DECLARE_CSR_ALIAS(ubadaddr, CSR_UTVAL, CSR_CLASS_I, CSR_CLASS_V1P9, CSR_CLASS_V1P10)
>>
>>
>> Thanks
>> Nelson
>>