Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1647525 > unrolled thread

RISC-V Linux Port v1

Started byPalmer Dabbelt <palmer@dabbelt.com>
First post2017-05-23 02:50 +0200
Last post2017-05-23 15:40 +0200
Articles 10 on this page of 30 — 7 participants

Back to article view | Back to linux.kernel


Contents

  RISC-V Linux Port v1 Palmer Dabbelt <palmer@dabbelt.com> - 2017-05-23 02:50 +0200
    [PATCH 5/7] RISC-V: arch/riscv/lib Palmer Dabbelt <palmer@dabbelt.com> - 2017-05-23 02:50 +0200
      Re: [PATCH 5/7] RISC-V: arch/riscv/lib Geert Uytterhoeven <geert@linux-m68k.org> - 2017-05-23 12:50 +0200
        Re: [PATCH 5/7] RISC-V: arch/riscv/lib Palmer Dabbelt <palmer@dabbelt.com> - 2017-05-24 00:10 +0200
      Re: [PATCH 5/7] RISC-V: arch/riscv/lib Arnd Bergmann <arnd@arndb.de> - 2017-05-23 13:30 +0200
    [PATCH 2/7] RISC-V: arch/riscv Makefile and Kconfigs Palmer Dabbelt <palmer@dabbelt.com> - 2017-05-23 02:50 +0200
      Re: [PATCH 2/7] RISC-V: arch/riscv Makefile and Kconfigs Olof Johansson <olof@lixom.net> - 2017-05-23 03:30 +0200
        Re: [PATCH 2/7] RISC-V: arch/riscv Makefile and Kconfigs Randy Dunlap <rdunlap@infradead.org> - 2017-05-23 03:40 +0200
          Re: [PATCH 2/7] RISC-V: arch/riscv Makefile and Kconfigs Palmer Dabbelt <palmer@dabbelt.com> - 2017-05-23 06:50 +0200
        Re: [PATCH 2/7] RISC-V: arch/riscv Makefile and Kconfigs Palmer Dabbelt <palmer@dabbelt.com> - 2017-05-23 06:50 +0200
          Re: [patches] Re: [PATCH 2/7] RISC-V: arch/riscv Makefile and Kconfigs Olof Johansson <olof@lixom.net> - 2017-05-23 07:20 +0200
            Re: [patches] Re: [PATCH 2/7] RISC-V: arch/riscv Makefile and  Kconfigs Benjamin Herrenschmidt <benh@kernel.crashing.org> - 2017-05-23 23:10 +0200
      Re: [PATCH 2/7] RISC-V: arch/riscv Makefile and Kconfigs Olof Johansson <olof@lixom.net> - 2017-05-23 07:30 +0200
        Re: [PATCH 2/7] RISC-V: arch/riscv Makefile and Kconfigs Palmer Dabbelt <palmer@dabbelt.com> - 2017-05-23 17:30 +0200
      Re: [PATCH 2/7] RISC-V: arch/riscv Makefile and Kconfigs Geert Uytterhoeven <geert@linux-m68k.org> - 2017-05-23 13:00 +0200
      Re: [PATCH 2/7] RISC-V: arch/riscv Makefile and Kconfigs Arnd Bergmann <arnd@arndb.de> - 2017-05-23 13:50 +0200
    [PATCH 3/7] RISC-V: Device Tree Documentation Palmer Dabbelt <palmer@dabbelt.com> - 2017-05-23 02:50 +0200
      Re: [PATCH 3/7] RISC-V: Device Tree Documentation Arnd Bergmann <arnd@arndb.de> - 2017-05-23 14:10 +0200
    Re: RISC-V Linux Port v1 Olof Johansson <olof@lixom.net> - 2017-05-23 03:20 +0200
      Re: RISC-V Linux Port v1 Randy Dunlap <rdunlap@infradead.org> - 2017-05-23 03:30 +0200
        Re: RISC-V Linux Port v1 Palmer Dabbelt <palmer@dabbelt.com> - 2017-05-23 05:40 +0200
      Re: RISC-V Linux Port v1 Palmer Dabbelt <palmer@dabbelt.com> - 2017-05-23 05:40 +0200
        Re: RISC-V Linux Port v1 Tobias Klauser <tklauser@distanz.ch> - 2017-05-23 08:50 +0200
          Re: RISC-V Linux Port v1 Palmer Dabbelt <palmer@dabbelt.com> - 2017-05-23 17:50 +0200
    Re: RISC-V Linux Port v1 Randy Dunlap <rdunlap@infradead.org> - 2017-05-23 04:20 +0200
      Re: RISC-V Linux Port v1 Palmer Dabbelt <palmer@dabbelt.com> - 2017-05-23 06:50 +0200
    Re: [PATCH 6/7] RISC-V: arch/riscv/kernel Olof Johansson <olof@lixom.net> - 2017-05-23 04:20 +0200
    Re: [PATCH 4/7] RISC-V: arch/riscv/include Arnd Bergmann <arnd@arndb.de> - 2017-05-23 15:00 +0200
      Re: [PATCH 4/7] RISC-V: arch/riscv/include Benjamin Herrenschmidt <benh@kernel.crashing.org> - 2017-05-23 23:30 +0200
    Re: [PATCH 6/7] RISC-V: arch/riscv/kernel Arnd Bergmann <arnd@arndb.de> - 2017-05-23 15:40 +0200

Page 2 of 2 — ← Prev page 1 [2]


#1647608

FromPalmer Dabbelt <palmer@dabbelt.com>
Date2017-05-23 05:40 +0200
Message-ID<tK8PU-64y-5@gated-at.bofh.it>
In reply to#1647554
On Mon, 22 May 2017 18:25:41 PDT (-0700), rdunlap@infradead.org wrote:
> On 05/22/17 18:16, Olof Johansson wrote:
>> Hi Palmer,
>>
>> On Mon, May 22, 2017 at 5:41 PM, Palmer Dabbelt <palmer@dabbelt.com> wrote:
>>
>>> In addition to the threaded messages, our port can be found on Git Hib
>>>
>>>   https://github.com/riscv/riscv-linux/tree/riscv-for-submission-v1
>>>
>>> [PATCH 1/7] RISC-V: Top-Level Makefile for riscv{32,64}
>>> [PATCH 2/7] RISC-V: arch/riscv Makefile and Kconfigs
>>> [PATCH 3/7] RISC-V: Device Tree Documentation
>>> [PATCH 4/7] RISC-V: arch/riscv/include
>>> [PATCH 5/7] RISC-V: arch/riscv/lib
>>> [PATCH 6/7] RISC-V: arch/riscv/kernel
>>> [PATCH 7/7] RISC-V: arch/riscv/mm
>>
>> So, one overall comment on this patchset is that it's not bisectable
>> (i.e. early patches add Makefile contents that refers to directories
>> not yet introduced).
>>
>> While it's not overly important to really split up a new architecture
>> introduction into small incremental patches, we generally strive to
>> have the tree fully buildable at any given commit. Some minor
>> rearranging would alleviate these problems.
>
> Neither the email patches nor the git tree have any Signed-off-by:
> entries AFAICT.

Makes sense.  I went through and checked everything for copyright, so I'll sign
off on the next patch set.

Thanks!

[toc] | [prev] | [next] | [standalone]


#1647605

FromPalmer Dabbelt <palmer@dabbelt.com>
Date2017-05-23 05:40 +0200
Message-ID<tK8PU-64y-1@gated-at.bofh.it>
In reply to#1647549
On Mon, 22 May 2017 18:16:20 PDT (-0700), olof@lixom.net wrote:
> Hi Palmer,
>
> On Mon, May 22, 2017 at 5:41 PM, Palmer Dabbelt <palmer@dabbelt.com> wrote:
>> We'd like to submit for inclusion in Linux a port for the RISC-V architecture.
>> While it is doubtlessly not complete, we think it is far enough along to start
>> the upstreaming process.  Our binutils and GCC ports have been accepted and
>> released, and we plan on submitting glibc patches soon.
>>
>> This port targets Version 1.10 of the RISC-V Privileged ISA, and supports both
>> the RV32 and RV64 user ISAs.  The RISC-V community and the 60-some member
>> companies of the RISC-V Foundation are quite eager to have a single, standard
>> Linux port.  We thank you in advance for your help in this process and for your
>> feedback on the software contribution itself.
>>
>> These patches build and boot on top of 4.12-rc2.  I understand that the merge
>> window is closed, but it was suggested that the best time to submit a new
>> architecture port would be right after an RC2 as the earliest point at which
>> the tree is usually generally churn-free enough.  While we optimistically hope
>> that we can get the port in for the 4.13 merge window, we're also eager to
>> ensure that the user-visible ABI is sane so we can proceed with our glibc port.
>> We'd like to at least get any user ABI issues shaken out as soon as possible,
>> even if we don't make it into 4.13.
>
> Time is right for review and eventual merge of this. Whether it makes
> 4.13 depends on how much discussion ensues. :)
>
>> Albert and I will volunteer to maintain this port if it's OK with everyone.
>
> It always makes sense to have architecture-knowledge people maintain
> it; no complaints from me.
>
> What we've seen been useful on other platforms (i.e. arm/arm64) is to
> offload the per-vendor stuff to a separate tree. It might or might not
> be needed here; likely to start out it won't be enough material to
> need it.

I'm OK with that.  We've been using http://github.com/riscv to hold all our
other "riscv-next" branches, but if you think another place is more appropriate
then I'm OK with that as well.

>> We'd like to thank the various members of the RISC-V software community who
>> have helped us with the port.
>>
>> Thanks!
>>
>> In addition to the threaded messages, our port can be found on Git Hib
>>
>>   https://github.com/riscv/riscv-linux/tree/riscv-for-submission-v1
>>
>> [PATCH 1/7] RISC-V: Top-Level Makefile for riscv{32,64}
>> [PATCH 2/7] RISC-V: arch/riscv Makefile and Kconfigs
>> [PATCH 3/7] RISC-V: Device Tree Documentation
>> [PATCH 4/7] RISC-V: arch/riscv/include
>> [PATCH 5/7] RISC-V: arch/riscv/lib
>> [PATCH 6/7] RISC-V: arch/riscv/kernel
>> [PATCH 7/7] RISC-V: arch/riscv/mm
>
> So, one overall comment on this patchset is that it's not bisectable
> (i.e. early patches add Makefile contents that refers to directories
> not yet introduced).
>
> While it's not overly important to really split up a new architecture
> introduction into small incremental patches, we generally strive to
> have the tree fully buildable at any given commit. Some minor
> rearranging would alleviate these problems.

I only really split things up so they'll get through the various mailing lists,
I think of this as one logical commit so I didn't really worry about ordering.
I'll swizzle them around next time so everything always builds.

> Also, none of the patches seem to have any descriptions. Adding some
> high-level descriptions of what's in each patch in the patch itself is
> useful both for reviewing now, and for educating anyone coming along
> later on trying to learn about the code and why it's been implemented
> as it has.

I guess I just wasn't really sure what to say in the big code dumps.  I'll look
through and try to come up with something better for next time.

>
> I'll add more comments on some of the individual patches; expect this
> review to take a little while. Reposting once or twice a week to show
> incorporated changes can be useful; more than that and it can be
> harder to follow along in the discussion. It all depends on how much
> comments you end up receiving.

OK.  I'll incorporate all the feedback I get over the next week or so into a v2
patch set.

Thanks!

[toc] | [prev] | [next] | [standalone]


#1647685

FromTobias Klauser <tklauser@distanz.ch>
Date2017-05-23 08:50 +0200
Message-ID<tKbNM-7U4-11@gated-at.bofh.it>
In reply to#1647605
Hi Palmer,

On 2017-05-23 at 05:36:55 +0200, Palmer Dabbelt <palmer@dabbelt.com> wrote:
> On Mon, 22 May 2017 18:16:20 PDT (-0700), olof@lixom.net wrote:
> > On Mon, May 22, 2017 at 5:41 PM, Palmer Dabbelt <palmer@dabbelt.com> wrote:
> >> We'd like to submit for inclusion in Linux a port for the RISC-V architecture.
> >> While it is doubtlessly not complete, we think it is far enough along to start
> >> the upstreaming process.  Our binutils and GCC ports have been accepted and
> >> released, and we plan on submitting glibc patches soon.
> >>
> >> This port targets Version 1.10 of the RISC-V Privileged ISA, and supports both
> >> the RV32 and RV64 user ISAs.  The RISC-V community and the 60-some member
> >> companies of the RISC-V Foundation are quite eager to have a single, standard
> >> Linux port.  We thank you in advance for your help in this process and for your
> >> feedback on the software contribution itself.
> >>
> >> These patches build and boot on top of 4.12-rc2.  I understand that the merge
> >> window is closed, but it was suggested that the best time to submit a new
> >> architecture port would be right after an RC2 as the earliest point at which
> >> the tree is usually generally churn-free enough.  While we optimistically hope
> >> that we can get the port in for the 4.13 merge window, we're also eager to
> >> ensure that the user-visible ABI is sane so we can proceed with our glibc port.
> >> We'd like to at least get any user ABI issues shaken out as soon as possible,
> >> even if we don't make it into 4.13.

[...]

> > I'll add more comments on some of the individual patches; expect this
> > review to take a little while. Reposting once or twice a week to show
> > incorporated changes can be useful; more than that and it can be
> > harder to follow along in the discussion. It all depends on how much
> > comments you end up receiving.
> 
> OK.  I'll incorporate all the feedback I get over the next week or so into a v2
> patch set.

You might want to Cc linux-arch@vger.kernel.org on future iterations of
this patchset where there's less "noise" than on LKML and the relevant
people are more likely to notice ;) Likewise, the device-tree specific
bits (e.g.  the bindings documentation) should probably be Cc'ed to
devicetree@vger.kernel.org

Tobias

[toc] | [prev] | [next] | [standalone]


#1648215

FromPalmer Dabbelt <palmer@dabbelt.com>
Date2017-05-23 17:50 +0200
Message-ID<tKkem-58v-13@gated-at.bofh.it>
In reply to#1647685
On Mon, 22 May 2017 23:45:34 PDT (-0700), tklauser@distanz.ch wrote:
> Hi Palmer,
>
> On 2017-05-23 at 05:36:55 +0200, Palmer Dabbelt <palmer@dabbelt.com> wrote:
>> On Mon, 22 May 2017 18:16:20 PDT (-0700), olof@lixom.net wrote:
>> > On Mon, May 22, 2017 at 5:41 PM, Palmer Dabbelt <palmer@dabbelt.com> wrote:
>> >> We'd like to submit for inclusion in Linux a port for the RISC-V architecture.
>> >> While it is doubtlessly not complete, we think it is far enough along to start
>> >> the upstreaming process.  Our binutils and GCC ports have been accepted and
>> >> released, and we plan on submitting glibc patches soon.
>> >>
>> >> This port targets Version 1.10 of the RISC-V Privileged ISA, and supports both
>> >> the RV32 and RV64 user ISAs.  The RISC-V community and the 60-some member
>> >> companies of the RISC-V Foundation are quite eager to have a single, standard
>> >> Linux port.  We thank you in advance for your help in this process and for your
>> >> feedback on the software contribution itself.
>> >>
>> >> These patches build and boot on top of 4.12-rc2.  I understand that the merge
>> >> window is closed, but it was suggested that the best time to submit a new
>> >> architecture port would be right after an RC2 as the earliest point at which
>> >> the tree is usually generally churn-free enough.  While we optimistically hope
>> >> that we can get the port in for the 4.13 merge window, we're also eager to
>> >> ensure that the user-visible ABI is sane so we can proceed with our glibc port.
>> >> We'd like to at least get any user ABI issues shaken out as soon as possible,
>> >> even if we don't make it into 4.13.
>
> [...]
>
>> > I'll add more comments on some of the individual patches; expect this
>> > review to take a little while. Reposting once or twice a week to show
>> > incorporated changes can be useful; more than that and it can be
>> > harder to follow along in the discussion. It all depends on how much
>> > comments you end up receiving.
>>
>> OK.  I'll incorporate all the feedback I get over the next week or so into a v2
>> patch set.
>
> You might want to Cc linux-arch@vger.kernel.org on future iterations of
> this patchset where there's less "noise" than on LKML and the relevant
> people are more likely to notice ;) Likewise, the device-tree specific
> bits (e.g.  the bindings documentation) should probably be Cc'ed to
> devicetree@vger.kernel.org

OK, thanks.  I'll do that for the v2.

[toc] | [prev] | [next] | [standalone]


#1647580

FromRandy Dunlap <rdunlap@infradead.org>
Date2017-05-23 04:20 +0200
Message-ID<tK7Au-5p7-11@gated-at.bofh.it>
In reply to#1647525
On 05/22/17 17:41, Palmer Dabbelt wrote:

> [PATCH 1/7] RISC-V: Top-Level Makefile for riscv{32,64}
> [PATCH 2/7] RISC-V: arch/riscv Makefile and Kconfigs
> [PATCH 3/7] RISC-V: Device Tree Documentation
> [PATCH 4/7] RISC-V: arch/riscv/include
> [PATCH 5/7] RISC-V: arch/riscv/lib
> [PATCH 6/7] RISC-V: arch/riscv/kernel
> [PATCH 7/7] RISC-V: arch/riscv/mm
> 

Now at patch 0004-riscv.patch
Warning: trailing whitespace in line 3 of arch/riscv/include/asm/asm.h
Warning: trailing whitespace in line 115 of arch/riscv/include/asm/spinlock.h

Now at patch 0006-riscv.patch
Warning: trailing whitespace in line 271 of arch/riscv/kernel/entry.S
Warning: trailing whitespace in line 77 of arch/riscv/kernel/process.c
Warning: trailing whitespace in line 78 of arch/riscv/kernel/smpboot.c


-- 
~Randy

[toc] | [prev] | [next] | [standalone]


#1647626

FromPalmer Dabbelt <palmer@dabbelt.com>
Date2017-05-23 06:50 +0200
Message-ID<tK9VE-6JS-3@gated-at.bofh.it>
In reply to#1647580
On Mon, 22 May 2017 19:16:43 PDT (-0700), rdunlap@infradead.org wrote:
> On 05/22/17 17:41, Palmer Dabbelt wrote:
>
>> [PATCH 1/7] RISC-V: Top-Level Makefile for riscv{32,64}
>> [PATCH 2/7] RISC-V: arch/riscv Makefile and Kconfigs
>> [PATCH 3/7] RISC-V: Device Tree Documentation
>> [PATCH 4/7] RISC-V: arch/riscv/include
>> [PATCH 5/7] RISC-V: arch/riscv/lib
>> [PATCH 6/7] RISC-V: arch/riscv/kernel
>> [PATCH 7/7] RISC-V: arch/riscv/mm
>>
>
> Now at patch 0004-riscv.patch
> Warning: trailing whitespace in line 3 of arch/riscv/include/asm/asm.h
> Warning: trailing whitespace in line 115 of arch/riscv/include/asm/spinlock.h
>
> Now at patch 0006-riscv.patch
> Warning: trailing whitespace in line 271 of arch/riscv/kernel/entry.S
> Warning: trailing whitespace in line 77 of arch/riscv/kernel/process.c
> Warning: trailing whitespace in line 78 of arch/riscv/kernel/smpboot.c

Sorry about that, I'll fix these for v2.

[toc] | [prev] | [next] | [standalone]


#1647581 — Re: [PATCH 6/7] RISC-V: arch/riscv/kernel

FromOlof Johansson <olof@lixom.net>
Date2017-05-23 04:20 +0200
SubjectRe: [PATCH 6/7] RISC-V: arch/riscv/kernel
Message-ID<tK7Au-5p7-7@gated-at.bofh.it>
In reply to#1647525
On Mon, May 22, 2017 at 5:41 PM, Palmer Dabbelt <palmer@dabbelt.com> wrote:
> ---
>  arch/riscv/kernel/Makefile         |  19 ++
>  arch/riscv/kernel/asm-offsets.c    | 113 ++++++++++
>  arch/riscv/kernel/cacheinfo.c      |  82 ++++++++
>  arch/riscv/kernel/cpu.c            |  81 ++++++++
>  arch/riscv/kernel/entry.S          | 414 +++++++++++++++++++++++++++++++++++++
>  arch/riscv/kernel/head.S           | 139 +++++++++++++
>  arch/riscv/kernel/irq.c            | 205 ++++++++++++++++++
>  arch/riscv/kernel/module.c         | 185 +++++++++++++++++
>  arch/riscv/kernel/pci.c            |  36 ++++
>  arch/riscv/kernel/plic.c           | 208 +++++++++++++++++++
>  arch/riscv/kernel/process.c        | 130 ++++++++++++
>  arch/riscv/kernel/ptrace.c         | 148 +++++++++++++
>  arch/riscv/kernel/reset.c          |  33 +++
>  arch/riscv/kernel/riscv_ksyms.c    |  16 ++
>  arch/riscv/kernel/sbi-con.c        | 214 +++++++++++++++++++
>  arch/riscv/kernel/setup.c          | 234 +++++++++++++++++++++
>  arch/riscv/kernel/signal.c         | 258 +++++++++++++++++++++++
>  arch/riscv/kernel/smp.c            | 107 ++++++++++
>  arch/riscv/kernel/smpboot.c        | 105 ++++++++++
>  arch/riscv/kernel/stacktrace.c     | 183 ++++++++++++++++
>  arch/riscv/kernel/sys_riscv.c      |  85 ++++++++
>  arch/riscv/kernel/syscall_table.c  |  26 +++
>  arch/riscv/kernel/time.c           | 116 +++++++++++
>  arch/riscv/kernel/traps.c          | 167 +++++++++++++++
>  arch/riscv/kernel/vdso.c           | 125 +++++++++++
>  arch/riscv/kernel/vdso/.gitignore  |   1 +
>  arch/riscv/kernel/vdso/Makefile    |  61 ++++++
>  arch/riscv/kernel/vdso/sigreturn.S |  25 +++
>  arch/riscv/kernel/vdso/vdso.S      |  28 +++
>  arch/riscv/kernel/vdso/vdso.lds.S  |  77 +++++++
>  arch/riscv/kernel/vmlinux.lds.S    |  93 +++++++++
>  31 files changed, 3714 insertions(+)
>  create mode 100644 arch/riscv/kernel/Makefile
>  create mode 100644 arch/riscv/kernel/asm-offsets.c
>  create mode 100644 arch/riscv/kernel/cacheinfo.c
>  create mode 100644 arch/riscv/kernel/cpu.c
>  create mode 100644 arch/riscv/kernel/entry.S
>  create mode 100644 arch/riscv/kernel/head.S
>  create mode 100644 arch/riscv/kernel/irq.c
>  create mode 100644 arch/riscv/kernel/module.c
>  create mode 100644 arch/riscv/kernel/pci.c
>  create mode 100644 arch/riscv/kernel/plic.c
>  create mode 100644 arch/riscv/kernel/process.c
>  create mode 100644 arch/riscv/kernel/ptrace.c
>  create mode 100644 arch/riscv/kernel/reset.c
>  create mode 100644 arch/riscv/kernel/riscv_ksyms.c
>  create mode 100644 arch/riscv/kernel/sbi-con.c
>  create mode 100644 arch/riscv/kernel/setup.c
>  create mode 100644 arch/riscv/kernel/signal.c
>  create mode 100644 arch/riscv/kernel/smp.c
>  create mode 100644 arch/riscv/kernel/smpboot.c
>  create mode 100644 arch/riscv/kernel/stacktrace.c
>  create mode 100644 arch/riscv/kernel/sys_riscv.c
>  create mode 100644 arch/riscv/kernel/syscall_table.c
>  create mode 100644 arch/riscv/kernel/time.c
>  create mode 100644 arch/riscv/kernel/traps.c
>  create mode 100644 arch/riscv/kernel/vdso.c
>  create mode 100644 arch/riscv/kernel/vdso/.gitignore
>  create mode 100644 arch/riscv/kernel/vdso/Makefile
>  create mode 100644 arch/riscv/kernel/vdso/sigreturn.S
>  create mode 100644 arch/riscv/kernel/vdso/vdso.S
>  create mode 100644 arch/riscv/kernel/vdso/vdso.lds.S
>  create mode 100644 arch/riscv/kernel/vmlinux.lds.S

What's missing from this patchset (ideally) is a good writeup under
DOcumentation/ on expectations of system state (and/or configuration)
upon entry of the kernel. For comparison, see the arm64 documentation
where they were quite specific in this.


This patch is also pushing size limits, and is getting unwieldy to
comment on. I'll point out a few things below with plenty of snipped
out lines.

>
> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> new file mode 100644
> index 000000000000..94ac2931c56a
> --- /dev/null
> +++ b/arch/riscv/kernel/Makefile
> @@ -0,0 +1,19 @@
> +#
> +# Makefile for the RISC-V Linux kernel
> +#
> +
> +extra-y := head.o vmlinux.lds
> +
> +obj-y  := cpu.o entry.o irq.o process.o ptrace.o reset.o setup.o \
> +          signal.o syscall_table.o sys_riscv.o time.o traps.o \
> +          riscv_ksyms.o stacktrace.o vdso.o cacheinfo.o vdso/
> +
> +CFLAGS_setup.o := -mcmodel=medany
> +
> +obj-$(CONFIG_SMP)              += smpboot.o smp.o
> +obj-$(CONFIG_SBI_CONSOLE)      += sbi-con.o
> +obj-$(CONFIG_PCI)              += pci.o
> +obj-$(CONFIG_MODULES)          += module.o
> +obj-$(CONFIG_PLIC)             += plic.o
> +
> +clean:
> diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
> new file mode 100644
> index 000000000000..ac2e0cfaf8a3
> --- /dev/null
> +++ b/arch/riscv/kernel/asm-offsets.c
> @@ -0,0 +1,113 @@
> +/*
> + * Copyright (C) 2012 Regents of the University of California
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful, but
> + *   WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
> + *   NON INFRINGEMENT.  See the GNU General Public License for
> + *   more details.

Hmm, I haven't seen these terms used often, but they seem to exist
around the tree in a few places. arch/tile is littered with them.

I am not a lawyer, but I can't seem any reference to "good title" in
the GPLv2 text.

Rather than having to go through the process of figuring out if this
license header is acceptable or not, you might find it easier to just
go with something more established.

> diff --git a/arch/riscv/kernel/cacheinfo.c b/arch/riscv/kernel/cacheinfo.c
> new file mode 100644
> index 000000000000..a22ea8abbf3c
> --- /dev/null
> +++ b/arch/riscv/kernel/cacheinfo.c
> @@ -0,0 +1,82 @@
> +/*
> + * Copyright (C) 2017 SiFive
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful, but
> + *   WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
> + *   NON INFRINGEMENT.  See the GNU General Public License for
> + *   more details.
> + */
> +
> +#include <linux/cacheinfo.h>
> +#include <linux/cpu.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +
> +static void ci_leaf_init(struct cacheinfo *this_leaf,
> +                         struct device_node *node,
> +                         enum cache_type type, unsigned int level)
> +{
> +        this_leaf->of_node = node;
> +        this_leaf->level = level;
> +        this_leaf->type = type;
> +        this_leaf->physical_line_partition = 1; // not a sector cache
> +        this_leaf->attributes = CACHE_WRITE_BACK | CACHE_READ_ALLOCATE | CACHE_WRITE_ALLOCATE; // TODO: add to DTS
> +}
> +
> +static int __init_cache_level(unsigned int cpu)
> +{
> +       struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
> +       struct device_node *np = of_cpu_device_node_get(cpu);
> +       int levels = 0, leaves = 0, level;
> +
> +       if (of_property_read_bool(np, "cache-size")) ++leaves;
> +       if (of_property_read_bool(np, "i-cache-size")) ++leaves;
> +       if (of_property_read_bool(np, "d-cache-size")) ++leaves;
> +       if (leaves > 0) levels = 1;
> +
> +       while ((np = of_find_next_cache_node(np))) {
> +               if (!of_device_is_compatible(np, "cache")) break;
> +               if (of_property_read_u32(np, "cache-level", &level)) break;
> +               if (level <= levels) break;
> +               if (of_property_read_bool(np, "cache-size")) ++leaves;
> +               if (of_property_read_bool(np, "i-cache-size")) ++leaves;
> +               if (of_property_read_bool(np, "d-cache-size")) ++leaves;
> +               levels = level;
> +       }
> +
> +       this_cpu_ci->num_levels = levels;
> +       this_cpu_ci->num_leaves = leaves;
> +       return 0;
> +}
> +
> +static int __populate_cache_leaves(unsigned int cpu)
> +{
> +       struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
> +       struct cacheinfo *this_leaf = this_cpu_ci->info_list;
> +       struct device_node *np = of_cpu_device_node_get(cpu);
> +       int levels = 1, level = 1;
> +
> +       if (of_property_read_bool(np, "cache-size"))   ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, level);
> +       if (of_property_read_bool(np, "i-cache-size")) ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level);
> +       if (of_property_read_bool(np, "d-cache-size")) ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);

Please run checkpatch, kernel coding style doesn't use one-line ifs
(here nor elsewhere).

> +
> +       while ((np = of_find_next_cache_node(np))) {
> +               if (!of_device_is_compatible(np, "cache")) break;
> +               if (of_property_read_u32(np, "cache-level", &level)) break;
> +               if (level <= levels) break;
> +               if (of_property_read_bool(np, "cache-size"))   ci_leaf_init(this_leaf++, np, CACHE_TYPE_UNIFIED, level);
> +               if (of_property_read_bool(np, "i-cache-size")) ci_leaf_init(this_leaf++, np, CACHE_TYPE_INST, level);
> +               if (of_property_read_bool(np, "d-cache-size")) ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);
> +               levels = level;
> +       }
> +
> +       return 0;
> +}
> +
> +DEFINE_SMP_CALL_CACHE_FUNCTION(init_cache_level)
> +DEFINE_SMP_CALL_CACHE_FUNCTION(populate_cache_leaves)
> diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c
> new file mode 100644
> index 000000000000..9cbf53eb58be
> --- /dev/null
> +++ b/arch/riscv/kernel/cpu.c
> @@ -0,0 +1,81 @@
> +/*
> + * Copyright (C) 2012 Regents of the University of California
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful, but
> + *   WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
> + *   NON INFRINGEMENT.  See the GNU General Public License for
> + *   more details.
> + */
> +
> +#include <linux/init.h>
> +#include <linux/seq_file.h>
> +#include <linux/of.h>
> +
> +/* Return -1 if not a valid hart */
> +int riscv_of_processor_hart(struct device_node *node)
> +{
> +       const char *isa, *status;
> +       u32 hart;
> +
> +       if (!of_device_is_compatible(node, "riscv")) return -1;
> +       if (of_property_read_u32(node, "reg", &hart) || hart >= NR_CPUS) return -1;
> +       if (of_property_read_string(node, "status", &status) || strcmp(status, "okay")) return -1;
> +       if (of_property_read_string(node, "riscv,isa", &isa) || isa[0] != 'r' || isa[1] != 'v') return -1;
> +
> +       return hart;
> +}

We usually prefer to see real -E<foo> returns instead of -1 in the kernel.

[...]

> diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S
> new file mode 100644
> index 000000000000..52d574206d76
> --- /dev/null
> +++ b/arch/riscv/kernel/head.S
> @@ -0,0 +1,139 @@
> +/*
> + * Copyright (C) 2012 Regents of the University of California
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful, but
> + *   WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
> + *   NON INFRINGEMENT.  See the GNU General Public License for
> + *   more details.
> + */
> +
> +#include <asm/thread_info.h>
> +#include <asm/asm-offsets.h>
> +#include <asm/asm.h>
> +#include <linux/init.h>
> +#include <linux/linkage.h>
> +#include <asm/thread_info.h>
> +#include <asm/page.h>
> +#include <asm/csr.h>
> +
> +__INIT
> +ENTRY(_start)
> +       /* Mask all interrupts */
> +       csrw sie, zero
> +
> +       /* Disable FPU to detect illegal usage of
> +          floating point in kernel space */
> +       li t0, SR_FS
> +       csrc sstatus, t0
> +
> +#ifndef CONFIG_RV_PUM
> +       /* Allow access to user memory */
> +       li t0, SR_SUM
> +       csrs sstatus, t0
> +#endif
> +
> +       /* Pick one hart to run the main boot sequence */
> +       la a3, hart_lottery
> +       li a2, 1
> +       amoadd.w a3, a2, (a3)
> +       bnez a3, .Lsecondary_start
> +
> +       /* Save hart ID and DTB physical address */
> +       mv s0, a0
> +       mv s1, a1
> +
> +       /* Initialize page tables and relocate to virtual addresses */
> +       la sp, init_thread_union + THREAD_SIZE
> +       call setup_vm
> +       call relocate
> +
> +       /* Restore C environment */
> +       la tp, init_thread_union
> +       li sp, THREAD_SIZE
> +       add sp, sp, tp
> +
> +       /* Start the kernel */
> +       mv a0, s0
> +       mv a1, s1
> +       call sbi_save
> +       tail start_kernel
> +
> +relocate:
> +       /* Relocate return address */
> +       li a1, PAGE_OFFSET
> +       la a0, _start
> +       sub a1, a1, a0
> +       add ra, ra, a1
> +
> +       /* Point stvec to virtual address of intruction after sptbr write */
> +       la a0, 1f
> +       add a0, a0, a1
> +       csrw stvec, a0
> +
> +       /* Compute sptbr for kernel page tables, but don't load it yet */
> +       la a2, swapper_pg_dir
> +       srl a2, a2, PAGE_SHIFT
> +       li a1, SPTBR_MODE
> +       or a2, a2, a1
> +
> +       /* Load trampoline page directory, which will cause us to trap to
> +          stvec if VA != PA, or simply fall through if VA == PA */
> +       la a0, trampoline_pg_dir
> +       srl a0, a0, PAGE_SHIFT
> +       or a0, a0, a1
> +       sfence.vma
> +       csrw sptbr, a0
> +1:
> +       /* Set trap vector to spin forever to help debug */
> +       la a0, .Lsecondary_park
> +       csrw stvec, a0
> +
> +       /* Load the global pointer */
> +       la gp, __global_pointer$
> +
> +       /* Switch to kernel page tables */
> +       csrw sptbr, a2
> +
> +       ret
> +
> +.Lsecondary_start:
> +#ifdef CONFIG_SMP
> +       li a1, CONFIG_NR_CPUS
> +       bgeu a0, a1, .Lsecondary_park
> +
> +       la a1, __cpu_up_stack_pointer
> +       slli a0, a0, LGREG
> +       add a0, a0, a1
> +
> +.Lwait_for_cpu_up:
> +       REG_L sp, (a0)
> +       beqz sp, .Lwait_for_cpu_up
> +       fence
> +
> +       /* Enable virtual memory and relocate to virtual address */
> +       call relocate
> +
> +       /* Initialize task_struct pointer */
> +       li tp, -THREAD_SIZE
> +       add tp, tp, sp
> +
> +       tail smp_callin
> +#endif
> +
> +.Lsecondary_park:
> +       /* We lack SMP support or have too many harts, so park this hart */
> +       wfi
> +       j .Lsecondary_park
> +END(_start)
> +
> +__PAGE_ALIGNED_BSS
> +       /* Empty zero page */
> +       .balign PAGE_SIZE
> +ENTRY(empty_zero_page)
> +       .fill (empty_zero_page + PAGE_SIZE) - ., 1, 0x00
> +END(empty_zero_page)
> diff --git a/arch/riscv/kernel/irq.c b/arch/riscv/kernel/irq.c
> new file mode 100644
> index 000000000000..b772bb9539cf
> --- /dev/null
> +++ b/arch/riscv/kernel/irq.c
> @@ -0,0 +1,205 @@
> +/*
> + * Copyright (C) 2012 Regents of the University of California
> + * Copyright (C) 2017 SiFive
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful, but
> + *   WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
> + *   NON INFRINGEMENT.  See the GNU General Public License for
> + *   more details.
> + */
> +
> +#include <linux/irq.h>
> +#include <linux/irqchip.h>
> +#include <linux/irqdomain.h>
> +#include <linux/interrupt.h>
> +#include <linux/ftrace.h>
> +#include <linux/of.h>
> +#include <linux/seq_file.h>
> +
> +#include <asm/ptrace.h>
> +#include <asm/sbi.h>
> +#include <asm/smp.h>
> +
> +struct riscv_irq_data {
> +       struct irq_chip         chip;
> +       struct irq_domain       *domain;
> +       int                     hart;
> +       char                    name[20];
> +};
> +DEFINE_PER_CPU(struct riscv_irq_data, riscv_irq_data);
> +DEFINE_PER_CPU(atomic_long_t, riscv_early_sie);
> +
> +static void riscv_software_interrupt(void)
> +{
> +#ifdef CONFIG_SMP
> +       irqreturn_t ret;
> +
> +       ret = handle_ipi();
> +       if (ret != IRQ_NONE)
> +               return;
> +#endif
> +
> +       BUG();
> +}
> +
> +asmlinkage void __irq_entry do_IRQ(unsigned int cause, struct pt_regs *regs)
> +{
> +       struct pt_regs *old_regs = set_irq_regs(regs);
> +       irq_enter();
> +
> +       /* There are three classes of interrupt: timer, software, and
> +          external devices.  We dispatch between them here.  External
> +          device interrupts use the generic IRQ mechanisms. */
> +       switch (cause) {
> +               case INTERRUPT_CAUSE_TIMER:
> +                       riscv_timer_interrupt();
> +                       break;
> +               case INTERRUPT_CAUSE_SOFTWARE:
> +                       riscv_software_interrupt();
> +                       break;
> +               default: {
> +                       struct irq_domain *domain = per_cpu(riscv_irq_data, smp_processor_id()).domain;

Move this up to top of function and remove the { } wrap, please.

> +                       generic_handle_irq(irq_find_mapping(domain, cause));
> +                       break;
> +               }
> +       }
> +
> +       irq_exit();
> +       set_irq_regs(old_regs);
> +}
> +
> +static int riscv_irqdomain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq)
> +{
> +       struct riscv_irq_data *data = d->host_data;
> +
> +        irq_set_chip_and_handler(irq, &data->chip, handle_simple_irq);
> +        irq_set_chip_data(irq, data);
> +        irq_set_noprobe(irq);
> +
> +        return 0;
> +}
> +
> +static const struct irq_domain_ops riscv_irqdomain_ops = {
> +       .map    = riscv_irqdomain_map,
> +       .xlate  = irq_domain_xlate_onecell,
> +};
> +
> +static void riscv_irq_mask(struct irq_data *d)
> +{
> +       struct riscv_irq_data *data = irq_data_get_irq_chip_data(d);
> +       BUG_ON(smp_processor_id() != data->hart);
> +       csr_clear(sie, 1 << (long)d->hwirq);
> +}
> +
> +static void riscv_irq_unmask(struct irq_data *d)
> +{
> +       struct riscv_irq_data *data = irq_data_get_irq_chip_data(d);
> +       BUG_ON(smp_processor_id() != data->hart);
> +       csr_set(sie, 1 << (long)d->hwirq);
> +}
> +
> +static void riscv_irq_enable_helper(void *d)
> +{
> +       riscv_irq_unmask(d);
> +}
> +
> +static void riscv_irq_enable(struct irq_data *d)
> +{
> +       struct riscv_irq_data *data = irq_data_get_irq_chip_data(d);
> +       atomic_long_or((1 << (long)d->hwirq), &per_cpu(riscv_early_sie, data->hart));

This is a bit dense to get into without a few words of how it's
expected to work.

> +       if (data->hart == smp_processor_id()) {
> +               riscv_irq_unmask(d);
> +       } else if (cpu_online(data->hart)) {
> +               smp_call_function_single(data->hart, riscv_irq_enable_helper, d, true);
> +       }
> +}
> +
> +static void riscv_irq_disable_helper(void *d)
> +{
> +       riscv_irq_mask(d);
> +}
> +
> +static void riscv_irq_disable(struct irq_data *d)
> +{
> +       struct riscv_irq_data *data = irq_data_get_irq_chip_data(d);
> +       atomic_long_and(~(1 << (long)d->hwirq), &per_cpu(riscv_early_sie, data->hart));
> +       if (data->hart == smp_processor_id()) {
> +               riscv_irq_mask(d);
> +       } else if (cpu_online(data->hart)) {
> +               smp_call_function_single(data->hart, riscv_irq_disable_helper, d, true);
> +       }
> +}
> +
> +static void riscv_irq_mask_noop(struct irq_data *d) { }
> +
> +static void riscv_irq_unmask_noop(struct irq_data *d) { }
> +
> +static void riscv_irq_enable_noop(struct irq_data *d)
> +{
> +       struct device_node *data = irq_data_get_irq_chip_data(d);
> +       u32 hart;
> +
> +       if (!of_property_read_u32(data, "reg", &hart)) {
> +               printk("WARNING: enabled interrupt %d for missing hart %d (this interrupt has no handler)\n", (int)d->hwirq, hart);
> +       }
> +}
> +
> +static struct irq_chip riscv_noop_chip = {
> +       .name = "riscv,cpu-intc,noop",
> +       .irq_mask = riscv_irq_mask_noop,
> +       .irq_unmask = riscv_irq_unmask_noop,
> +       .irq_enable = riscv_irq_enable_noop,
> +};
> +
> +static int riscv_irqdomain_map_noop(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq)
> +{
> +       struct device_node *data = d->host_data;
> +       irq_set_chip_and_handler(irq, &riscv_noop_chip, handle_simple_irq);
> +       irq_set_chip_data(irq, data);
> +       return 0;
> +}
> +
> +static const struct irq_domain_ops riscv_irqdomain_ops_noop = {
> +       .map    = riscv_irqdomain_map_noop,
> +       .xlate  = irq_domain_xlate_onecell,
> +};
> +
> +static int riscv_intc_init(struct device_node *node, struct device_node *parent)
> +{
> +       int hart;
> +
> +       if (parent) return 0; // should have no interrupt parent
> +
> +       if ((hart = riscv_of_processor_hart(node->parent)) >= 0) {

Common pattern in kernel is to detect error instead:
    hart = riscv_of_processor_hart(node->parent);
    if (hart < 0) {
        <from your else side here>
        return 0;
    }
    <body if your if statement here>

    return 0;

> +               struct riscv_irq_data *data = &per_cpu(riscv_irq_data, hart);
> +               snprintf(data->name, sizeof(data->name), "riscv,cpu_intc,%d", hart);
> +               data->hart = hart;
> +               data->chip.name = data->name;
> +               data->chip.irq_mask = riscv_irq_mask;
> +               data->chip.irq_unmask = riscv_irq_unmask;
> +               data->chip.irq_enable = riscv_irq_enable;
> +               data->chip.irq_disable = riscv_irq_disable;
> +               data->domain = irq_domain_add_linear(node, 8*sizeof(uintptr_t), &riscv_irqdomain_ops, data);
> +               WARN_ON(!data->domain);
> +               printk("%s: %d local interrupts mapped\n", data->name, 8*(int)sizeof(uintptr_t));
> +       } else {
> +               /* If a hart is disabled, create a no-op irq domain.
> +                * Devices may still have interrupts connected to those harts.
> +                * This is not wrong... unless they actually load a driver that needs it!
> +                */
> +               irq_domain_add_linear(node, 8*sizeof(uintptr_t), &riscv_irqdomain_ops_noop, node->parent);
> +       }
> +       return 0;
> +}
> +
> +IRQCHIP_DECLARE(riscv, "riscv,cpu-intc", riscv_intc_init);
> +
> +void __init init_IRQ(void)
> +{
> +       irqchip_init();
> +}

> diff --git a/arch/riscv/kernel/pci.c b/arch/riscv/kernel/pci.c
> new file mode 100644
> index 000000000000..4191a5ffdd67
> --- /dev/null
> +++ b/arch/riscv/kernel/pci.c
> @@ -0,0 +1,36 @@
> +/*
> + * Code borrowed from arch/arm64/kernel/pci.c

So, you should add recursive reference from there (i.e. powerpc).

But in the end, there's essentially no code in this file. :)


> + *
> + * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
> + * Copyright (C) 2014 ARM Ltd.
> + * Copyright (C) 2017 SiFive
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * version 2 as published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/mm.h>
> +#include <linux/slab.h>
> +#include <linux/pci.h>
> +
> +/*
> + * Called after each bus is probed, but before its children are examined
> + */
> +void pcibios_fixup_bus(struct pci_bus *bus)
> +{
> +       /* nothing to do, expected to be removed in the future */
> +}
> +
> +/*
> + * We don't have to worry about legacy ISA devices, so nothing to do here
> + */
> +resource_size_t pcibios_align_resource(void *data, const struct resource *res,
> +                               resource_size_t size, resource_size_t align)
> +{
> +       return res->start;
> +}
> diff --git a/arch/riscv/kernel/plic.c b/arch/riscv/kernel/plic.c
> new file mode 100644
> index 000000000000..5b3d4241f4e2
> --- /dev/null
> +++ b/arch/riscv/kernel/plic.c
> @@ -0,0 +1,208 @@
> +/*
> + * Copyright (C) 2017 SiFive
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful, but
> + *   WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
> + *   NON INFRINGEMENT.  See the GNU General Public License for
> + *   more details.
> + */
> +
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/irqchip.h>
> +#include <linux/irqchip/chained_irq.h>
> +#include <linux/irqdomain.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_irq.h>
> +#include <linux/platform_device.h>
> +
> +#define MAX_DEVICES    1024 // 0 is reserved

Seems like an odd comment to have here (and should probably not go at
the end of the line)

> +#define MAX_CONTEXTS   15872
> +
> +#define PRIORITY_BASE  0
> +#define ENABLE_BASE    0x2000
> +#define ENABLE_SIZE    0x80
> +#define HART_BASE      0x200000
> +#define HART_SIZE      0x1000
> +
> +#define PLIC_HART_CONTEXT(data, i)     (struct plic_hart_context *)((char*)data->reg + HART_BASE + HART_SIZE*i)
> +#define PLIC_ENABLE_CONTEXT(data, i)   (struct plic_enable_context *)((char*)data->reg + ENABLE_BASE + ENABLE_SIZE*i)
> +#define PLIC_PRIORITY(data)            (struct plic_priority *)((char *)data->reg + PRIORITY_BASE)

Since you have typecasting and stuff here, small static inlines with
appropriate return types seems slightly tidier.

> +
> +struct plic_hart_context {
> +       volatile u32 threshold;
> +       volatile u32 claim;
> +};
> +
> +struct plic_enable_context {
> +       atomic_t mask[32]; // 32-bit * 32-entry
> +};
> +
> +struct plic_priority {
> +       volatile u32 prio[MAX_DEVICES];
> +};
> +
> +struct plic_data {
> +       struct irq_chip         chip;
> +       struct irq_domain       *domain;
> +       u32                     ndev;
> +       void __iomem            *reg;
> +       int                     handlers;
> +       struct plic_handler     *handler;
> +       char                    name[30];
> +};
> +
> +struct plic_handler {
> +       struct plic_hart_context        *context;
> +       struct plic_data                *data;
> +};
> +
> +static void plic_disable(struct plic_data *data, int i, int hwirq)
> +{
> +       struct plic_enable_context *enable = PLIC_ENABLE_CONTEXT(data, i);
> +       atomic_and(~(1 << (hwirq % 32)), &enable->mask[hwirq / 32]);
> +}
> +
> +static void plic_enable(struct plic_data *data, int i, int hwirq)
> +{
> +       struct plic_enable_context *enable = PLIC_ENABLE_CONTEXT(data, i);
> +       atomic_or((1 << (hwirq % 32)), &enable->mask[hwirq / 32]);
> +}
> +
> +// There is no need to mask/unmask PLIC interrupts
> +// They are "masked" by reading claim and "unmasked" when writing it back.
> +static void plic_irq_mask(struct irq_data *d) { }
> +static void plic_irq_unmask(struct irq_data *d) { }
> +
> +static void plic_irq_enable(struct irq_data *d)
> +{
> +       struct plic_data *data = irq_data_get_irq_chip_data(d);
> +       struct plic_priority *priority = PLIC_PRIORITY(data);
> +       int i;
> +       iowrite32(1, &priority->prio[d->hwirq]);
> +       for (i = 0; i < data->handlers; ++i)
> +               if (data->handler[i].context)
> +                       plic_enable(data, i, d->hwirq);
> +}
> +
> +static void plic_irq_disable(struct irq_data *d)
> +{
> +       struct plic_data *data = irq_data_get_irq_chip_data(d);
> +       struct plic_priority *priority = PLIC_PRIORITY(data);
> +       int i;
> +       iowrite32(0, &priority->prio[d->hwirq]);
> +       for (i = 0; i < data->handlers; ++i)
> +               if (data->handler[i].context)
> +                       plic_disable(data, i, d->hwirq);
> +}
> +
> +static int plic_irqdomain_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hwirq)
> +{
> +       struct plic_data *data = d->host_data;
> +
> +        irq_set_chip_and_handler(irq, &data->chip, handle_simple_irq);
> +        irq_set_chip_data(irq, data);
> +        irq_set_noprobe(irq);
> +
> +        return 0;
> +}
> +
> +static const struct irq_domain_ops plic_irqdomain_ops = {
> +       .map    = plic_irqdomain_map,
> +       .xlate  = irq_domain_xlate_onecell,
> +};
> +
> +static void plic_chained_handle_irq(struct irq_desc *desc)
> +{
> +        struct plic_handler *handler = irq_desc_get_handler_data(desc);
> +       struct irq_chip *chip = irq_desc_get_chip(desc);

Whitespace.

> +       struct irq_domain *domain = handler->data->domain;
> +       u32 what;
> +
> +       chained_irq_enter(chip, desc);
> +
> +       while ((what = ioread32(&handler->context->claim))) {
> +               int irq = irq_find_mapping(domain, what);
> +               if (irq > 0) {
> +                       generic_handle_irq(irq);
> +               } else {
> +                       handle_bad_irq(desc);
> +               }
> +               iowrite32(what, &handler->context->claim);
> +       }
> +
> +       chained_irq_exit(chip, desc);
> +}
> +
> +// TODO: add a /sys interface to set priority + per-hart enables for steering
> +
> +static int plic_init(struct device_node *node, struct device_node *parent)
> +{
> +       struct plic_data *data;
> +       struct resource resource;
> +       int i, ok = 0;
> +
> +       data = kzalloc(sizeof(*data), GFP_KERNEL);
> +       if (WARN_ON(!data)) return -ENOMEM;
> +
> +       data->reg = of_iomap(node, 0);
> +       if (WARN_ON(!data->reg)) return -EIO;
> +
> +       of_property_read_u32(node, "riscv,ndev", &data->ndev);
> +       if (WARN_ON(!data->ndev)) return -EINVAL;
> +
> +       data->handlers = of_irq_count(node);
> +       if (WARN_ON(!data->handlers)) return -EINVAL;
> +
> +       data->handler = kzalloc(sizeof(*data->handler)*data->handlers, GFP_KERNEL);
> +       if (WARN_ON(!data->handler)) return -ENOMEM;
> +
> +       data->domain = irq_domain_add_linear(node, data->ndev+1, &plic_irqdomain_ops, data);
> +       if (WARN_ON(!data->domain)) return -ENOMEM;
> +
> +       of_address_to_resource(node, 0, &resource);
> +       snprintf(data->name, sizeof(data->name), "riscv,plic0,%llx", resource.start);
> +       data->chip.name = data->name;
> +       data->chip.irq_mask = plic_irq_mask;
> +       data->chip.irq_unmask = plic_irq_unmask;
> +       data->chip.irq_enable = plic_irq_enable;
> +       data->chip.irq_disable = plic_irq_disable;
> +
> +       for (i = 0; i < data->handlers; ++i) {
> +               struct plic_handler *handler = &data->handler[i];
> +               struct of_phandle_args parent;
> +               int parent_irq, hwirq;
> +
> +               if (of_irq_parse_one(node, i, &parent)) continue;
> +               if (parent.args[0] == -1) continue; // skip context holes
> +
> +               // skip any contexts that lead to inactive harts
> +               if (of_device_is_compatible(parent.np, "riscv,cpu-intc") &&
> +                   parent.np->parent &&
> +                   riscv_of_processor_hart(parent.np->parent) < 0) continue;
> +
> +               parent_irq = irq_create_of_mapping(&parent);
> +               if (!parent_irq) continue;
> +
> +               handler->context = PLIC_HART_CONTEXT(data, i);
> +               handler->data = data;
> +               iowrite32(0, &handler->context->threshold); // hwirq prio must be > this to trigger an interrupt
> +               for (hwirq = 1; hwirq <= data->ndev; ++hwirq) plic_disable(data, i, hwirq);
> +               irq_set_chained_handler_and_data(parent_irq, plic_chained_handle_irq, handler);
> +               ++ok;
> +       }
> +
> +       printk("%s: mapped %d interrupts to %d/%d handlers\n", data->name, data->ndev, ok, data->handlers);
> +       WARN_ON(!ok);
> +       return 0;
> +}
> +
> +IRQCHIP_DECLARE(plic0, "riscv,plic0", plic_init);


[wrapping up review of this patch at this point to keep size down]


-Olof

[toc] | [prev] | [next] | [standalone]


#1647997 — Re: [PATCH 4/7] RISC-V: arch/riscv/include

FromArnd Bergmann <arnd@arndb.de>
Date2017-05-23 15:00 +0200
SubjectRe: [PATCH 4/7] RISC-V: arch/riscv/include
Message-ID<tKhzP-3jV-9@gated-at.bofh.it>
In reply to#1647525
On Tue, May 23, 2017 at 2:41 AM, Palmer Dabbelt <palmer@dabbelt.com> wrote:
> +/**
> + * atomic_read - read atomic variable
> + * @v: pointer of type atomic_t
> + *
> + * Atomically reads the value of @v.
> + */
> +static inline int atomic_read(const atomic_t *v)
> +{
> +       return *((volatile int *)(&(v->counter)));
> +}
> +/**
> + * atomic_set - set atomic variable
> + * @v: pointer of type atomic_t
> + * @i: required value
> + *
> + * Atomically sets the value of @v to @i.
> + */
> +static inline void atomic_set(atomic_t *v, int i)
> +{
> +       v->counter = i;
> +}

These commonly use READ_ONCE() and WRITE_ONCE,
I'd recommend doing the same here to be on the safe side.

> +/**
> + * atomic64_read - read atomic64 variable
> + * @v: pointer of type atomic64_t
> + *
> + * Atomically reads the value of @v.
> + */
> +static inline s64 atomic64_read(const atomic64_t *v)
> +{
> +       return *((volatile long *)(&(v->counter)));
> +}
> +
> +/**
> + * atomic64_set - set atomic64 variable
> + * @v: pointer to type atomic64_t
> + * @i: required value
> + *
> + * Atomically sets the value of @v to @i.
> + */
> +static inline void atomic64_set(atomic64_t *v, s64 i)
> +{
> +       v->counter = i;
> +}

same here

> diff --git a/arch/riscv/include/asm/bug.h b/arch/riscv/include/asm/bug.h
> new file mode 100644
> index 000000000000..10d894ac3137
> --- /dev/null
> +++ b/arch/riscv/include/asm/bug.h
> @@ -0,0 +1,81 @@
> +/*
>
> +#ifndef _ASM_RISCV_BUG_H
> +#define _ASM_RISCV_BUG_H

> +#ifdef CONFIG_GENERIC_BUG
> +#define __BUG_INSN     _AC(0x00100073, UL) /* sbreak */

Please have a look at the modifications I did for !CONFIG_BUG
on x86, arm and arm64. It's generally better to define BUG to a
trap even when CONFIG_BUG is disabled, otherwise you run
into undefined behavior in some code, and gcc will print annoying
warnings about that.

> +#ifndef _ASM_RISCV_CACHE_H
> +#define _ASM_RISCV_CACHE_H
> +
> +#define L1_CACHE_SHIFT         6
> +
> +#define L1_CACHE_BYTES         (1 << L1_CACHE_SHIFT)

Is this the only valid cache line size on riscv, or just the largest
one that is allowed?

> +
> +static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
> +{
> +       return (dma_addr_t)paddr;
> +}
> +
> +static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t dev_addr)
> +{
> +       return (phys_addr_t)dev_addr;
> +}

What do you need these for? If possible, try to remove them.

> +static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction dir)
> +{
> +       /*
> +        * RISC-V is cache-coherent, so this is mostly a no-op.
> +        * However, we do need to ensure that dma_cache_sync()
> +        * enforces order, hence the mb().
> +        */
> +       mb();
> +}

Do you even support any drivers that use
dma_alloc_noncoherent()/dma_cache_sync()?

I would guess you can just leave this out.

> diff --git a/arch/riscv/include/asm/io.h b/arch/riscv/include/asm/io.h
> new file mode 100644
> index 000000000000..d942555a7a08
> --- /dev/null
> +++ b/arch/riscv/include/asm/io.h
> @@ -0,0 +1,36 @@

> +#ifndef _ASM_RISCV_IO_H
> +#define _ASM_RISCV_IO_H
> +
> +#include <asm-generic/io.h>

I would recommend providing your own {read,write}{b,w,l,q}{,_relaxed}
helpers using inline assembly, to prevent the compiler for breaking
up accesses into byte accesses.

Also, most architectures require to some synchronization after a
non-relaxed readl() to prevent prefetching of DMA buffers, and
before a writel() to flush write buffers when a DMA gets triggered.

> +#ifdef __KERNEL__
> +
> +#ifdef CONFIG_MMU
> +
> +extern void __iomem *ioremap(phys_addr_t offset, unsigned long size);
> +
> +#define ioremap_nocache(addr, size) ioremap((addr), (size))
> +#define ioremap_wc(addr, size) ioremap((addr), (size))
> +#define ioremap_wt(addr, size) ioremap((addr), (size))

Is this a hard architecture limitation? Normally you really want
write-combined access on frame buffer memory and a few other
cases for performance reasons, and ioremap_wc() gets used
for by memremap() for addressing RAM in some cases, and you
normally don't want to have PTEs for the same memory using
cached and uncached page flags

> diff --git a/arch/riscv/include/asm/serial.h b/arch/riscv/include/asm/serial.h
> new file mode 100644
> index 000000000000..d783dbe80a4b
> --- /dev/null
> +++ b/arch/riscv/include/asm/serial.h
> @@ -0,0 +1,43 @@
> +/*
> + * Copyright (C) 2014 Regents of the University of California
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful, but
> + *   WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
> + *   NON INFRINGEMENT.  See the GNU General Public License for
> + *   more details.
> + */
> +
> +#ifndef _ASM_RISCV_SERIAL_H
> +#define _ASM_RISCV_SERIAL_H
> +
> +/*
> + * FIXME: interim serial support for riscv-qemu
> + *
> + * Currently requires that the emulator itself create a hole at addresses
> + * 0x3f8 - 0x3ff without looking through page tables.

This sounds like something we want to fix in qemu and not have in the
mainline kernel. In particular, something seems really wrong if your
inb()/outb() get remapped to physical CPU address 0+offset.

> diff --git a/arch/riscv/include/asm/setup.h b/arch/riscv/include/asm/setup.h
> new file mode 100644
> index 000000000000..e457854e9988
> --- /dev/null
> +++ b/arch/riscv/include/asm/setup.h
> @@ -0,0 +1,20 @@
> +/*
> + * Copyright (C) 2012 Regents of the University of California
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful, but
> + *   WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
> + *   NON INFRINGEMENT.  See the GNU General Public License for
> + *   more details.
> + */
> +
> +#ifndef _ASM_RISCV_SETUP_H
> +#define _ASM_RISCV_SETUP_H
> +
> +#include <asm-generic/setup.h>
> +
> +#endif /* _ASM_RISCV_SETUP_H */

Can you remove this file and add it to asm/Kbuild as generic-y instead?

> +/*
> + * low level task data that entry.S needs immediate access to
> + * - this struct should fit entirely inside of one cache line
> + * - this struct resides at the bottom of the supervisor stack
> + * - if the members of this struct changes, the assembly constants
> + *   in asm-offsets.c must be updated accordingly
> + */
> +struct thread_info {
> +       struct task_struct      *task;          /* main task structure */
> +       unsigned long           flags;          /* low level flags */
> +       __u32                   cpu;            /* current CPU */
> +       int                     preempt_count;  /* 0 => preemptable, <0 => BUG */
> +       mm_segment_t            addr_limit;
> +};

Please see 15f4eae70d36 ("x86: Move thread_info into task_struct")
and try to do the same.

> +#else /* !CONFIG_MMU */
> +
> +static inline void flush_tlb_all(void)
> +{
> +       BUG();
> +}
> +
> +static inline void flush_tlb_mm(struct mm_struct *mm)
> +{
> +       BUG();
> +}

The NOMMU support is rather incomplete and CONFIG_MMU is
hard-enabled, so I'd just drop any !CONFIG_MMU #ifdefs.

> diff --git a/arch/riscv/include/uapi/asm/Kbuild b/arch/riscv/include/uapi/asm/Kbuild
> new file mode 100644
> index 000000000000..276b6dae745c
> --- /dev/null
> +++ b/arch/riscv/include/uapi/asm/Kbuild
> @@ -0,0 +1,10 @@
> +# UAPI Header export list
> +include include/uapi/asm-generic/Kbuild.asm
> +
> +header-y += auxvec.h
> +header-y += bitsperlong.h
> +header-y += byteorder.h
> +header-y += ptrace.h
> +header-y += sigcontext.h
> +header-y += siginfo.h
> +header-y += unistd.h

Please see
fcc8487d477a ("uapi: export all headers under uapi directories")

and adapt the file accordingly

> +#include <asm-generic/unistd.h>
> +
> +#define __NR_sysriscv  __NR_arch_specific_syscall
> +#ifndef __riscv_atomic
> +__SYSCALL(__NR_sysriscv, sys_sysriscv)
> +#endif

Please make this a straight cmpxchg syscall and remove the multiplexer.
Why does the definition depend on __riscv_atomic rather than the
Kconfig symbol?

       Arnd

[toc] | [prev] | [next] | [standalone]


#1648763 — Re: [PATCH 4/7] RISC-V: arch/riscv/include

FromBenjamin Herrenschmidt <benh@kernel.crashing.org>
Date2017-05-23 23:30 +0200
SubjectRe: [PATCH 4/7] RISC-V: arch/riscv/include
Message-ID<tKpxo-AI-21@gated-at.bofh.it>
In reply to#1647997
On Tue, 2017-05-23 at 14:55 +0200, Arnd Bergmann wrote:
> > +
> > +#include <asm-generic/io.h>
> 
> I would recommend providing your own {read,write}{b,w,l,q}{,_relaxed}
> helpers using inline assembly, to prevent the compiler for breaking
> up accesses into byte accesses.
> 
> Also, most architectures require to some synchronization after a
> non-relaxed readl() to prevent prefetching of DMA buffers, and
> before a writel() to flush write buffers when a DMA gets triggered.

Right, I was about to comment on that one.

The question Palmer is about the ordering semantics of non-cached
storage.

What kind of ordering is provided architecturally ? Especially
between cachable and non-cachable loads and stores ?

Also, you have PCIe right ? What is the behaviour of MSIs ?

Does your HW provide a guarantee that in the case of a series of DMA
writes to memory by a device followed by an MSI, the CPU getting the
MSI will only get it after all the previous DMA writes have reached
coherency ? (Unlike LSIs where the driver is required to do an MMIO
read from the device, MSIs are expected to be ordered with data).

Another things with the read*() accessors. It's not uncommon for
a driver to do:

	writel(1, reset_reg);
	readl(reset_reg); /* flush posted writes */
	udelay(10);
	writel(0, reset_reg);

Now, in the above case, what can typically happen if you aren't careful
is that the readl which is intended to "push" the previous writel, will
not actually do its job because the return value hasn't been "consumed"
by the processor. Thus, the CPU will stick that on some kind of load
queue and won't actually wait for the return value before hitting the
delay loop.

Thus you might end up in a situation where the writel of 1 to the
device is itself reaching the device way after you started the delay
loop, and thus end up violating the delay requirement of the HW.

On powerpc we solve that by using a special instruction construct
inside the read* accessors that prevents the CPU from executing
subsequent instructions until the read value has been returned.

You may want to consider something similar.

Cheers,
Ben.

[toc] | [prev] | [next] | [standalone]


#1648050 — Re: [PATCH 6/7] RISC-V: arch/riscv/kernel

FromArnd Bergmann <arnd@arndb.de>
Date2017-05-23 15:40 +0200
SubjectRe: [PATCH 6/7] RISC-V: arch/riscv/kernel
Message-ID<tKicy-3OV-19@gated-at.bofh.it>
In reply to#1647525
> +IRQCHIP_DECLARE(riscv, "riscv,cpu-intc", riscv_intc_init);

Please move the majority of this file into drivers/irqchip as a
standalone driver.

> diff --git a/arch/riscv/kernel/pci.c b/arch/riscv/kernel/pci.c
> new file mode 100644
> index 000000000000..4191a5ffdd67
> --- /dev/null
> +++ b/arch/riscv/kernel/pci.c
> @@ -0,0 +1,36 @@
> +/*
> + * Code borrowed from arch/arm64/kernel/pci.c
> + *
> + * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
> + * Copyright (C) 2014 ARM Ltd.
> + * Copyright (C) 2017 SiFive
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * version 2 as published by the Free Software Foundation.
> + *
> + */
> +
> +#include <linux/init.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/mm.h>
> +#include <linux/slab.h>
> +#include <linux/pci.h>
> +
> +/*
> + * Called after each bus is probed, but before its children are examined
> + */
> +void pcibios_fixup_bus(struct pci_bus *bus)
> +{
> +       /* nothing to do, expected to be removed in the future */
> +}
> +/*
> + * We don't have to worry about legacy ISA devices, so nothing to do here
> + */
> +resource_size_t pcibios_align_resource(void *data, const struct resource *res,
> +                               resource_size_t size, resource_size_t align)
> +{
> +       return res->start;
> +}

Can you add a patch to remove the need for this, and send that to the
PCI maintainers?

In the long run, I think we want both of these to be pci host bridge
driver specific callbacks rather than per-architecture definitions, but
for the moment, moving the empty version as a __weak copy
into drivers/pci/ should be sufficient.

[note: don't ever use __weak elsewhere, the use in PCI is
 only done for historic reasons and we want to get rid of that
 too, but for now it's more important to avoid adding yet another
 pointless copy]

If you don't care about LPC/ISA devices, then your PCI_MIN_IO
should also be zero instead of 0x1000

> diff --git a/arch/riscv/kernel/plic.c b/arch/riscv/kernel/plic.c
> new file mode 100644
> index 000000000000..5b3d4241f4e2
> --- /dev/null
> +++ b/arch/riscv/kernel/plic.c

drivers/irqchip/riscv-plic.c

The file needs some work for following coding style, once that
is done, please submit to the irqchip maintainers.

> +#define PLIC_HART_CONTEXT(data, i)     (struct plic_hart_context *)((char*)data->reg + HART_BASE + HART_SIZE*i)
> +#define PLIC_ENABLE_CONTEXT(data, i)   (struct plic_enable_context *)((char*)data->reg + ENABLE_BASE + ENABLE_SIZE*i)
> +#define PLIC_PRIORITY(data)            (struct plic_priority *)((char *)data->reg + PRIORITY_BASE)
> +
> +struct plic_hart_context {
> +       volatile u32 threshold;
> +       volatile u32 claim;
> +};
> +
> +struct plic_enable_context {
> +       atomic_t mask[32]; // 32-bit * 32-entry
> +};
> +
> +struct plic_priority {
> +       volatile u32 prio[MAX_DEVICES];
> +};

The 'volatile' seems misplaced here. What is it for?

> +// TODO: add a /sys interface to set priority + per-hart enables for steering

No driver-private sysfs interfaces please for irqchips please.
See http://elixir.free-electrons.com/linux/latest/source/Documentation/IRQ-affinity.txt
for setting the affinity.

> diff --git a/arch/riscv/kernel/reset.c b/arch/riscv/kernel/reset.c
> new file mode 100644
> index 000000000000..58bad9598e21
> --- /dev/null
> +++ b/arch/riscv/kernel/reset.c
> @@ -0,0 +1,33 @@
> +/*
> + * Copyright (C) 2012 Regents of the University of California
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful, but
> + *   WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
> + *   NON INFRINGEMENT.  See the GNU General Public License for
> + *   more details.
> + */
> +
> +#include <linux/reboot.h>
> +#include <linux/export.h>
> +#include <asm/sbi.h>
> +
> +void (*pm_power_off)(void) = machine_power_off;
> +EXPORT_SYMBOL(pm_power_off);
> +
> +void machine_restart(char *cmd)
> +{
> +}

Call do_kernel_restart(cmd) here.

> +void machine_halt(void)
> +{
> +}

This should not return. Either make it call sbi_shutdown as well,
or use the ARM implementation:

void machine_halt(void)
{
        local_irq_disable();
        smp_send_stop();
        while (1);
}

> diff --git a/arch/riscv/kernel/sbi-con.c b/arch/riscv/kernel/sbi-con.c
> new file mode 100644
> index 000000000000..86baeb5ef0cd
> --- /dev/null
> +++ b/arch/riscv/kernel/sbi-con.c

As Olof said, move it to drivers/tty/hvc/ and use those helpers.

> diff --git a/arch/riscv/kernel/sys_riscv.c b/arch/riscv/kernel/sys_riscv.c
> new file mode 100644
> index 000000000000..3e07308e24f5
> --- /dev/null
> +++ b/arch/riscv/kernel/sys_riscv.c
> @@ -0,0 +1,85 @@
> +/*
> + * Copyright (C) 2012 Regents of the University of California
> + * Copyright (C) 2014 Darius Rad <darius@bluespec.com>
> + *
> + *   This program is free software; you can redistribute it and/or
> + *   modify it under the terms of the GNU General Public License
> + *   as published by the Free Software Foundation, version 2.
> + *
> + *   This program is distributed in the hope that it will be useful, but
> + *   WITHOUT ANY WARRANTY; without even the implied warranty of
> + *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
> + *   NON INFRINGEMENT.  See the GNU General Public License for
> + *   more details.
> + */
> +
> +#include <linux/syscalls.h>
> +#include <asm/unistd.h>
> +
> +SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len,
> +       unsigned long, prot, unsigned long, flags,
> +       unsigned long, fd, off_t, offset)
> +{
> +       if (unlikely(offset & (~PAGE_MASK)))
> +               return -EINVAL;
> +       return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
> +}
> +
> +#ifndef CONFIG_64BIT
> +SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len,
> +       unsigned long, prot, unsigned long, flags,
> +       unsigned long, fd, off_t, offset)
> +{
> +       /* Note that the shift for mmap2 is constant (12),
> +          regardless of PAGE_SIZE */
> +       if (unlikely(offset & (~PAGE_MASK >> 12)))
> +               return -EINVAL;
> +       return sys_mmap_pgoff(addr, len, prot, flags, fd,
> +               offset >> (PAGE_SHIFT - 12));
> +}
> +#endif /* !CONFIG_64BIT */

The first one should be CONFIG_64BIT only.

> +#ifdef CONFIG_RV_SYSRISCV_ATOMIC
> +SYSCALL_DEFINE4(sysriscv, unsigned long, cmd, unsigned long, arg1,
> +       unsigned long, arg2, unsigned long, arg3)
> +{
> +       unsigned long flags;
> +       unsigned long prev;
> +       unsigned int *ptr;
> +       unsigned int err;
> +
> +       switch (cmd) {
> +       case RISCV_ATOMIC_CMPXCHG:
> +               ptr = (unsigned int *)arg1;
> +               if (!access_ok(VERIFY_WRITE, ptr, sizeof(unsigned int)))
> +                       return -EFAULT;
> +
> +               preempt_disable();
> +               raw_local_irq_save(flags);
> +               err = __get_user(prev, ptr);
> +               if (likely(!err && prev == arg2))
> +                       err = __put_user(arg3, ptr);
> +               raw_local_irq_restore(flags);
> +               preempt_enable();
> +
> +               return unlikely(err) ? err : prev;
> +
> +       case RISCV_ATOMIC_CMPXCHG64:

Make these two separate syscalls and get rid of the wrapper
(I already mentioned it in the header file comments, but it
fits better here).

It may be good to have an optimized version in the vdso
that does an atomic operation directly if the CPU supports
it.

> diff --git a/arch/riscv/kernel/time.c b/arch/riscv/kernel/time.c
> new file mode 100644
> index 000000000000..ce8c459fadaa
> --- /dev/null
> +++ b/arch/riscv/kernel/time.c

drivers/clocksource/riscv-timer.c, and submit it to the
respective maintainers.

      Arnd

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | linux.kernel


csiph-web