Re: [PATCH 2/7] RISC-V: arch/riscv Makefile and Kconfigs

From: Palmer Dabbelt
Date: Tue Jun 06 2017 - 16:38:09 EST


On Tue, 06 Jun 2017 02:20:50 PDT (-0700), Arnd Bergmann wrote:
> On Tue, Jun 6, 2017 at 6:56 AM, Palmer Dabbelt <palmer@xxxxxxxxxxx> wrote:
>> On Mon, 29 May 2017 04:17:40 PDT (-0700), Arnd Bergmann wrote:
>>> On Sat, May 27, 2017 at 2:57 AM, Palmer Dabbelt <palmer@xxxxxxxxxxx> wrote:
>>>> On Tue, 23 May 2017 04:46:22 PDT (-0700), Arnd Bergmann wrote:
>>> This raises a much more general question about how you want to deal
>>> with SoC implementations in the future. The two most common ways of
>>> doing this are:
>>>
>>> - Every major platform gets a Kconfig option in the architecture menu,
>>> and that selects the essential drivers (irqchip, clocksource, pinctrl,
>>> clk, ...) that you need for that platform, along with architecture features
>>> (ISA level and optional features, ...)
>>>
>>> - The architecture code knows nothing about the SoC and just keeps
>>> to the basics (CPU architecture level selection, SMP/MMU/etc enabled,
>>> selecting drivers that everyone needs) and leaves the rest up to be
>>> selected in the defconfig file.
>>>
>>> On ARM, we have a bit of both, which is not as good as being
>>> consistent one way or another.
>>
>> This is actually an open question in RISC-V land right now. We should be
>> spinning up a platform specification working group this summer to try and work
>> things out. While this will have to be ironed out, I believe the plan is to
>> define a small number of base platforms (maybe one for embedded systems with no
>> programmable PMAs, and one for larger machines with a bit more
>> configurability). I'd anticipate that we'll have a platform Kconfig menu entry
>> for every platform that gets written down in a specification (just like we have
>> an entry for our base ISAs) and then defconfig entries for various
>> implementations that select the relevant platform in addition to the drivers
>> actually on board.
>>
>> For now we've got a handful of defconfig entries for the various platforms we
>> support (the ISA simulator and our FPGA implementation), but there's no silicon
>> so we're not stuck with what's there. I don't anticipate we'll add more than a
>> handful of these until the platform spec work is underway.
>
> Ok. Another related point, which may or may not be obvious: when you
> come up with platform definitions, they should not be mutually exclusive.
>
> For instance, supporting both MMU/NOMMU, big/little-endian or 32/64-bit
> kernels will of course require building separate binaries, but almost every
> other configuration option should be backward compatible: An SMP
> kernel should run on a uniprocessor machine and vice versa (using only
> one CPU), and you should be able to run a kernel with support multiple
> instruction set revisions by restricting the build to the smallest subset
> of instructions.

We're actually trying really hard to ensure a single binary can run anywhere:
for example, an XLEN (the RISC-V term for the general purpose register bit
width) agnostic code sequence can be run that determines if you're on a 32-bit
or 64-bit platform without taking any traps, then enumerate the entire set of
user and supervisor extensions available. In theory one could build a kernel
image that supports both RV32I and RV64I, as well as optionally supporting
paging. This won't happen for Linux, but our debugger examines the target chip
using this mechanism.

An explicit goal of the supervisor specification is to make it possible for one
Linux image to run on every platform. Right now the only constraints we have
is that SMP kernels require atomics. Specifically:

* non-SMP kernels run on multiprocessor systems, picking an arbitrary hart to
run on (or hart 0 if there's no atomics).
* The kernel is always built with floating-point enabled, it just never sees
the "FPU is on" bit if there's no FPU and therefor doesn't execute any
F-extension instructions.

[Though of course after writing this I went to check our boot code and found it
using an unguarded AMO... Luckily it was an easy fix. Thanks!]

The big hole right now is that the SBI (our version of Alpha's PAL code) isn't
specified because it's part of the upcoming platform spec. We'll just have to
home this isn't a problem.

> On older ARM platforms and most MIPS platforms, we are still
> restricted to building a kernel binary that will only run on a particular
> SoC family and not even another SoC with the same CPU core.
> Fixing this for most ARM platforms required a lot of work that you
> should avoid by requiring them all to work with a common kernel
> from the start.

We're hoping that everyone is more amenable to play ball here after seeing how
much pain it was in ARM land. We'll see how well the platform specification
goes.

> Similarly, ARM has an incompatibility that prevents us from running
> on older (ARMv4/v5) along with newer (ARMv6 or higher) instruction
> set versions with a single kernel. Avoiding this on RISC-V may
> become challenging as one of the strengths of the architecture is
> its flexibility: Someone may come up with their own architecture
> extensions that they really want to support in the kernel but can't
> get it to work without making the kernel binary incompatible with
> other implementations. Do you already have a policy for how to
> deal with this? Usually by the time someone ships hardware, it's
> too late and it becomes hard to argue for their kernel port to not
> get merged.

The RISC-V ISA defines extension mechanisms that allows new non-standard
extensions to coexist, so as long as everyone is well behaved we should be
safe. I believe there is some mechanism to disallow bad behavior via the
RISC-V foundation and a certification process, but we'll see if that actually
has any teeth.

Of course, we're hoping to only need to support standard extensions, but
nothing ever goes that well :).