Re: [Qemu-devel] qemu-riscv64 seg fault

2018-09-03 Thread Michael Clark
Thanks. I was just about to log an issue in the riscv-qemu issue tracker on
GitHub.

I reproduced it on my side. The fact that it is causes QEMU user to crash
in translate.c is interesting.

I ran your program with -d in_asm and it appears to crash in thread::join

On Mon, Sep 3, 2018 at 7:58 PM, Pranith Kumar  wrote:

> On second looks, running the benchmark on a RISCV processor is also
> giving a seg fault. So may be there is something wrong with the
> benchmark... OTOH, x86 version runs fine... hmm
>
> Please ignore this report, I will try to investigate further.
>
> Thanks,
> On Mon, Sep 3, 2018 at 12:45 AM Pranith Kumar 
> wrote:
> >
> > Hi Michael,
> >
> > qemu-riscv64 seg faults for me on a static binary. You can build the
> > binary from here: https://github.com/pranith/quickht
> >
> > $ STATIC=1 RISCV=1 make
> >
> > $ qemu-riscv64 ./bench -t 1 -u 1
> > 
> >
> > Thanks,
> > --
> > Pranith
>
>
>
> --
> Pranith
>


Re: [Qemu-devel] qemu-riscv64 seg fault

2018-09-03 Thread Michael Clark
On Mon, Sep 3, 2018 at 8:16 PM, Pranith Kumar  wrote:

> On Mon, Sep 3, 2018 at 1:07 AM Michael Clark  wrote:
> >
> > Thanks. I was just about to log an issue in the riscv-qemu issue tracker
> on GitHub.
> >
> > I reproduced it on my side. The fact that it is causes QEMU user to
> crash in translate.c is interesting.
> >
> > I ran your program with -d in_asm and it appears to crash in thread::join
>
> Interestingly, qemu-x86_64 crashes too. But running natively on x86
> works fine. There is something off somewhere...
>

Indeed. Another data-point. I tested it in both qemu-2.12 and qemu-3.0. It
still crashed in translate.c in qemu-2.12, but on another line. There was
quite a bit of restructuring of target/riscv/translate.c in qemu-3.0, which
is why I tried qemu-2.12, however, it seems that is likely not the cause.

This was the backtrace from riscv-qemu-2.12:

Thread 1 "qemu-riscv64" received signal SIGSEGV, Segmentation fault.
0x555e1347 in gen_intermediate_code (cs=cs@entry=0x57905590,
tb=tb@entry=0x558e1a00 )
at /home/mjc/src/sifive/riscv-qemu/target/riscv/translate.c:1934
1934 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
(gdb) print tb
$1 = (TranslationBlock *) 0x558e1a00 
(gdb) quit
A debugging session is active.

~/quickht$ qemu-x86_64 ./bench -t 2 -u 2
> qemu: uncaught target signal 11 (Segmentation fault) - core dumped
> Segmentation fault
>
> ~/quickht$ ./bench -t 2 -u 2
> Comparisons: 23922
> Buckets touched: 4933
> Operations: 2000
>


Re: [Qemu-devel] [sw-dev] RFC: QEMU RISC-V modular ISA decoding

2017-07-26 Thread Michael Clark

> On 27 Jul 2017, at 8:58 AM, kr...@berkeley.edu wrote:
> 
> 
> Given that one of the goals of RISC-V is extensibility, it would be
> nice if the QEMU port was done in a way to make it easier to extend by
> third parties, including other automated tools.  I'm sure that, over
> time, the preprocessor can be improved to automatically incorporate
> optimizations for better performance.

I had a look at the s390x code in more detail.

It essentially does some length and major opcode unpacking to 
construct/linearise the opcode space, and would be equivalent to constructing a 
15-bit opcode for RISC-V. It does some pre-decoding to find length, majors, and 
has a switch on majors to find instruction type, and then append minors, if any.

- https://hastebin.com/taceyuyore.cpp 

It would be akin to something list this (at a high-level):

len = inst_len(inst)/* bits[1:0] */
op = major_opcode(inst) /* bits[6:2] */

switch op
- rvc
/* hairy bit */
- r-type
op2 = funct7 << 3 | funct3
- i-type
- s-type
op2 = funct3
- u-type
op2 = 0

op = op | op2 << 5




Re: [Qemu-devel] [PULL 4/4] RISC-V: Respect fences for user-only emulators

2018-11-13 Thread Michael Clark
Nits. Please improve your commit message to make them more impersonal...

On Wed, Nov 14, 2018 at 12:52 PM Palmer Dabbelt  wrote:

> Our current fence implementation ignores fences for the user-only
> configurations.  This is incorrect but unlikely to manifest: it requires
> multi-threaded user-only code that takes advantage of the weakness in
> the host's memory model and can be inlined by TCG.
>

The RISC-V fence implementation...


> This patch simply treats fences the same way for all our emulators.
> I've given it to testing as I don't want to construct a test that would
> actually trigger the failure.
>

Testing has been limited to... ? Reproducer?


> Our fence implementation has an additional deficiency where we map all
> RISC-V fences to full fences.  Now that we have a formal memory model
> for RISC-V we can start to take advantage of the strength bits on our
> fence instructions.  This requires a bit more though, so I'm going to
> split it out because the implementation is still correct without taking
> advantage of these weaker fences.
>

The fence implementation...

A formal memory model for RISC-V allows...


> Thanks to Richard Henderson for pointing out both of the issues.
>
> Signed-off-by: Palmer Dabbelt 
> Reviewed-by: Alistair Francis 
> Reviewed-by: Richard Henderson 


Assuming you fix up the commit message. I am not sure if I am present in
any of the commit messages I wrote, however perhaps thats just a matter
style with respect to writing (or re-writing) history.

Reviewed-by: Michael Clark 

---
>  target/riscv/translate.c | 2 --
>  1 file changed, 2 deletions(-)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index f44eb9c41b48..312bf298b3c2 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -1776,7 +1776,6 @@ static void decode_RV32_64G(CPURISCVState *env,
> DisasContext *ctx)
>   GET_RM(ctx->opcode));
>  break;
>  case OPC_RISC_FENCE:
> -#ifndef CONFIG_USER_ONLY
>  if (ctx->opcode & 0x1000) {
>  /* FENCE_I is a no-op in QEMU,
>   * however we need to end the translation block */
> @@ -1787,7 +1786,6 @@ static void decode_RV32_64G(CPURISCVState *env,
> DisasContext *ctx)
>  /* FENCE is a full memory barrier. */
>  tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
>  }
> -#endif
>  break;
>  case OPC_RISC_SYSTEM:
>  gen_system(env, ctx, MASK_OP_SYSTEM(ctx->opcode), rd, rs1,
> --
> 2.18.1
>
>
>


Re: [Qemu-devel] [PR RFC] RISC-V Patches for 3.1-rc2

2018-11-13 Thread Michael Clark
On Wed, Nov 14, 2018 at 12:52 PM Palmer Dabbelt  wrote:

> The following changes since commit
> cb968d275c145467c8b385a3618a207ec111eab1:
>
>   Update version for v3.1.0-rc1 release (2018-11-13 18:16:14 +)
>
> are available in the Git repository at:
>
>   git://github.com/riscv/riscv-qemu.git tags/riscv-for-master-3.1-rc2
>
> for you to fetch changes up to 3502dc824a7b0218abb49f4350e80a49829748cf:
>
>   RISC-V: Respect fences for user-only emulators (2018-11-13 15:12:15
> -0800)
>
> 
> RISC-V Patches for 3.1-rc2
>
> This pull request contains four patches that aren't really related to
> each other aside from all being bug fixes that I think should go in for
> 3.1.0:
>

Here's I again. I guess its a somewhat arbitrary set of fixes. Although one
could say the same about the set of fixes in the github repo.

At least you don't have review feedback asking you split a patch up to make
it easier to review, after its already been reviewed (what I would call
"make work").

No objections from me. We just have to get these patches into the other
tree which also has RISC-V bug fixes (but I don't have an opinion about
which bugs are more or less critical). There will be some minor merge
conflicts because the RISC-V tree has writable misa suppoer. I'm planning
to rebase at 3.1.0, just so we don't trample on each other. It's probably
going to be quite a lot of work to get the patches in that tree here
because my patches tend to attract a lot of pedantic feedback. i.e. !! to
normalize a scalar into a bool and ~ to broadcast bit 1 e.g. C bitwise
logic that you find frequently in spike; has to be dumbed down into macro
wrappers. Feedback. These changes to keep people happy are the reason why
we broke things for folk like changing gp$ to __globalPointer$ (in
GCC/binutils). Suddendly all earlier asm is broken because someone wants to
give feedback about how RISC-V should be; someone who does not need to bear
the burden of those changes.

Change simply because we can make you change stuff to break things for
RISC-V users because we think those changes are a good idea. Don't get me
wrong. We get good feedback (in QEMU, mostly from RIchard Henderson), but
its not always the case. VSPILL/VFILL and vaddsz sp is a good idea. I need
to find that email of Richard's on the GCC list and forward it to Krste. I
hope the feedback makes it to folk working on the Vector spec because as
far as I can tell it is a good idea.

Apologies for the cynicism. I'll get over it.

* The second half of Alistair's memory leak patch set that I missed last
>   week.
> * A fix to make fclass.d availiable only on RV64IFD systems (without
>   this it's availiable on RV32IFD systems, truncating the result).
> * A fix to make sfence.vm availiable only in priv-1.9.1, and sfence.vma
>   only availiable in priv-1.10.
> * A change to respect fences in user-mode emulators, which were
>   previously treated as NOPs.
>
> As usual, this builds and boot Linux for me.  I don't think I have
> anything else planned for 3.1.0, but I may be wrong as things are a bit
> hectic this week.
>
> 
> Alistair Francis (1):
>   hw/riscv/virt: Free the test device tree node name
>
> Bastian Koppelmann (2):
>   target/riscv: Fix FCLASS_D being treated as RV64 only
>   target/riscv: Fix sfence.vm/a both available in any priv version
>
> Palmer Dabbelt (1):
>   RISC-V: Respect fences for user-only emulators
>
>  hw/riscv/virt.c  |  1 +
>  target/riscv/translate.c | 24 
>  2 files changed, 17 insertions(+), 8 deletions(-)
>
>
>


Re: [Qemu-devel] [PATCH v1 3/5] hw/riscv/virt: Connect the Xilinx PCIe

2018-06-23 Thread Michael Clark



> On 23/06/2018, at 1:07 PM, Peter Maydell  wrote:
> 
> On 22 June 2018 at 20:30, Alistair Francis  wrote:
>> Connect the Xilinx PCIe device based on the device tree included in the
>> HiFive Unleashed ROM.
> 
> Did you consider using the 'gpex' generic PCIe controller here?

Yes. Alastair and I talked about this yesterday and we agreed in principle to 
using ‘gpex’ on the virt machine and the Xilinx PCIe on the SiFive U 
(’sifive_u’) machine, as this reflects one of the IP configurations of SiFive’s 
Coreplex U series when run on FPGA.

By changing this patch to add Xilinx PCIe to ‘sifive_u’, we can plug IO devices 
into the U series machine, and instead add gpex to RISC-V virt. i.e. vendor 
agnostic generic PCIe controller for virt. We would like ‘virt’ to be a 
potential vendor agnostic hardware target when we have kvm, so using gpex fits 
with this strategy (speaking from a RISC-V perspective not a SiFive 
perspective).




Re: [Qemu-devel] [PATCH v1 0/5] Misc RISC-V patches

2018-10-11 Thread Michael Clark
Hi All,

On Thu, Oct 11, 2018 at 7:22 AM Palmer Dabbelt  wrote:

> On Wed, 10 Oct 2018 11:10:07 PDT (-0700), peter.mayd...@linaro.org wrote:
> > On 10 October 2018 at 18:49, Palmer Dabbelt  wrote:
> >> we should really
> >> get the ball rolling on our big patch backlog.
> >
> > Yes, please do. Softfreeze is not all that far away and I
> > would strongly prefer not to get an enormous sized pull
> > request at the last minute. The ideal pattern is that
> > code changes come in at a steady rate across the whole
> > of the 'open' part of the development cycle.
>
> Ya, sorry, we've been a bit out of it.  If I understand correctly, the
> soft
> freeze is the 30th?  If so it's really time to get started, and it looks
> like
> Michael is busy so I'll have to go figure this out.
>

Yes. I should think twice about the Signed-off-by: on my commits. I need to
run a regression on this out-of-order subset. I currently only run tests on
the top of the riscv-qemu tree in-order, and when I rebase against master.
If the commits need any significant effort to rebase because they are taken
in some random order then the testing will be invalidated. i.e. I haven't
checked the dependencies for these commits.

I am happy to review whoever posts the contents of the tree. I can test
apply the PRs against the riscv-qemu tree and if they give us lumps, we'll
reject, including my own changes (if rebased).

Alastair, I suggest you confer with Debian and Fedora folk. Don't break the
Linux distros... I'm petrified that we might break Debian.

Palmer, I disagree with idea, I would like to maintain the soft-fork until
we have the CI running our regression test suite (currently manual)

Peter, I have to pull in your remote wholesale. I don't cherry-pick from
your tree. I think this is truly dumb. This might serve the needs of some
folk running Linux but we have emulation fidelity fixes for the RISC-V
community as a whole. Alastair is the only person not submitting his
patches via the (sub)maintainer tree. BTW Who is the RISC-V port
maintainer? Puzzled.

Here is the pull queue. But I'm not ready to make a PR until we have the CI
running the regression. I certainly don't want rebases of random commits to
the riscv-qemu tree coming in when we pull.

- https://github.com/riscv/riscv-qemu/tree/qemu-for-upstream

That said, they have sign-off. There are plenty of other "RISC-V"
maintainers. Do what you think is wise.

Most important thing here is the Debian builders and other RISC-V virtual
machines in production. Having the Debian folk or some other helpful tester
running the entire tree. Pulling it in one go means we don't have a
bisection problem interspersed with a whole lot of other random patches.
You may not have all of the interrupt related changes that require
extensive parallel burn-in tests (GCC bootstrap). i.e. we do significantly
more than "make check" when we pull changes into our tree.

Thanks and Regards,
Michael.


Re: [Qemu-devel] [PATCH v1 1/1] configure: Add RISC-V host support

2018-07-27 Thread Michael Clark
On Sat, Jul 28, 2018 at 11:49 AM, Alistair Francis  wrote:

> Allow QEMU to be built to run on a RISC-V host.
>
> QEMU does not yet have a RISC-V TCG or user mode target port, but
> running other architectures on RISC-V using TCI does work.
>

There is this RISC-V TCG backend here:

https://github.com/riscv/riscv-qemu/tree/wip-riscv-tcg-backend

I realized I had not sent an update to the list. There is a working TCG
backend for RISC-V:

- I've so far tested it with user-mode translation only.
- It does not support large guests e.g. 64-bit hosts on riscv32.
- The softmmu implementation is there but needs testing.
- Some things are missing, e.g. memory fences. big-endian support

You might find some other relevant changes in the configure hunks in the
patch. IIRC there were a few changes to configure, one of them was to get
the riscv disassembler working.

Signed-off-by: Alistair Francis 
> ---
>  configure | 18 +-
>  1 file changed, 17 insertions(+), 1 deletion(-)
>
> diff --git a/configure b/configure
> index 2a7796ea80..c3ff3ae146 100755
> --- a/configure
> +++ b/configure
> @@ -606,6 +606,16 @@ EOF
>compile_object
>  }
>
> +check_define_value() {
> +cat > $TMPC < +#if (($1) != ($2))
> +#error $1 != ($2)
> +#endif
> +int main(void) { return 0; }
> +EOF
> +  compile_object
> +}
> +
>  check_include() {
>  cat > $TMPC <  #include <$1>
> @@ -704,6 +714,12 @@ elif check_define __arm__ ; then
>cpu="arm"
>  elif check_define __aarch64__ ; then
>cpu="aarch64"
> +elif check_define __riscv ; then
> +  if check_define_value __riscv_xlen 64 ; then
> +cpu="riscv64"
> +  else
> +cpu="riscv32"
> +  fi
>  else
>cpu=$(uname -m)
>  fi
> @@ -712,7 +728,7 @@ ARCH=
>  # Normalise host CPU name and set ARCH.
>  # Note that this case should only have supported host CPUs, not guests.
>  case "$cpu" in
> -  ppc|ppc64|s390|s390x|sparc64|x32)
> +  ppc|ppc64|s390|s390x|sparc64|x32|riscv32|riscv64)
>  cpu="$cpu"
>  supported_cpu="yes"
>  eval "cross_cc_${cpu}=\$host_cc"
> --
> 2.17.1
>
>


Re: [Qemu-devel] [PATCH] RISC-V: Correct typo in RV32 perf counters

2018-07-30 Thread Michael Clark
On Mon, 30 Jul 2018 at 10:46 PM, Peter Maydell 
wrote:

> On 25 May 2018 at 14:17, Richard Henderson  wrote:
> > On 05/24/2018 11:24 PM, Michael Clark wrote:
> >> This patch enables mhpmcounter3h through mhpmcounter31h on RV32.
> >> Previously the RV32 h versions (high 32-bits of 64-bit counters)
> >> of these counters would trap with an illegal instruction instead
> >> of returning 0 as intended.
> >>
> >> Reported-by: Richard Henderson 
> >> Signed-off-by: Michael Clark 
> >> ---
> >>  target/riscv/op_helper.c | 2 +-
> >>  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > Fixes: Coverity CID 1390849
> > Reviewed-by: Richard Henderson 
>
> Ping -- Coverity is still complaining about this -- did this
> patch get lost?


Sort of. I assumed it would go into a trivial queue.

Feel free to apply, however it’s going to create (another) rebase conflict
against my ‘for-upstream’ queue as this code has gone away, hence it is not
in my queue.

The bug is fixed in my tree in an alternate way as we have overhauled the
CSR system to support atomic read/modify/write CSRs, and the new code is
table driven versus using jumbo switch statements.

When we transcribed this code to the new CSR system the bug disappeared as
a consequence of the  nature of the new mechanism which matches the table
listings in the RISC-V Privileged ISA manual which makes this type of bug
much more obvious:

https://github.com/riscv/riscv-qemu/blob/qemu-for-upstream/target/riscv/csr.c#L912-L919

My tree is up-to-date as of 3.0-rc2, and has been rebased against
Alistair’s changes but I have a feeling we are still missing reviews.

We also have additional CSR fixes (such as vectored interrupts) that depend
on the context of the new CSR system and we don’t have enough bandwidth to
maintain a backport to the old code in upstream QEMU.

I guess it is problematic going via my tree as last time I looked we didn’t
have enough reviews.

I can include this change in my pull for 3.1, along with the patches in my
tree that have Reviewed-by and fix the rebase conflicts for anything that
depends on new context (hopefully not creating new bugs during that
process).

I haven’t reposted the code that has not been reviewed as I’ll do that when
I have a chance to reorder and split my queue based on what has been
reviewed and what hasn’t.

I’ve deferred that because i’m still working on new code that will be
shipping from the SiFive tree (for which i’m currently writing test cases
for).

Michael.


Re: [Qemu-devel] microblaze build failure due to definition clash on riscv

2018-08-01 Thread Michael Clark
On Thu, Aug 2, 2018 at 3:57 PM, Philippe Mathieu-Daudé 
wrote:

> Oops I just realized I forgot to Cc the QEMU list, doing it now.
>
> On 07/31/2018 07:40 AM, Edgar E. Iglesias wrote:
> > On Mon, Jul 30, 2018 at 03:22:46PM -0300, Philippe Mathieu-Daudé wrote:
> >> Hi, I'm getting this error while building microblaze on riscv host:
> >>
> >>   ...
> >>   CC  disas/microblaze.o
> >> disas/microblaze.c:179:0: error: "REG_SP" redefined [-Werror]
> >>
> >>  #define REG_SP  1 /* stack pointer */
> >>
> >> In file included from /usr/include/signal.h:306:0,
> >>  from include/qemu/osdep.h:101,
> >>  from disas/microblaze.c:36:
> >> /usr/include/sys/ucontext.h:36:0: note: this is the location of the
> >> previous definition
> >>  # define REG_SP 2
> >>
> >> cc1: all warnings being treated as errors
> >> make: *** [rules.mak:69: disas/microblaze.o] Error 1
> >>
> >>
> >> Having /usr/include/sys/ucontext.h:
> >>
> >>  31 #ifdef __USE_MISC
> >>  32 # define NGREG  32
> >>  33
> >>  34 # define REG_PC 0
> >>  35 # define REG_RA 1
> >>  36 # define REG_SP 2
> >>  37 # define REG_TP 4
> >>  38 # define REG_S0 8
> >>  39 # define REG_S1 9
> >>  40 # define REG_A0 10
> >>  41 # define REG_S2 18
> >>  42 # define REG_NARGS 8
> >>
> >> Edgar is it OK to rename REG_* -> MB_REG_*?
> >
> > Yes, no problems with me!
> >
> > Allthough it doesn't seem to be a good idea to have such generic names
> in riscv system header files.
>
> OK this might be a Linux problem indeed, maybe this file lacks some
> #ifdef __riscv (previous to the __USE_MISC?).
>
> I'll wait for the riscv folks before to send a dumb rename patch.
>

It seems to be a generic Linux problem or perhaps even a microblaze problem
in this case, where QEMU microblaze definitions just happen to clash with
system definitions. It depends on which way around you look at the problem.

x86_64 has REG_R8, REG_R9, REG_R10, etc so RISC-V is just following the
Linux scheme.

Indeed RISC-V in QEMU unlike microblaze has this in disas/riscv.c

typedef enum {
rv_ireg_zero,
rv_ireg_ra,
rv_ireg_sp,
rv_ireg_gp,
rv_ireg_tp,
rv_ireg_t0,
rv_ireg_t1,
rv_ireg_t2,
rv_ireg_s0,
rv_ireg_s1,
rv_ireg_a0,
rv_ireg_a1,
rv_ireg_a2,
rv_ireg_a3,
rv_ireg_a4,
rv_ireg_a5,
rv_ireg_a6,
rv_ireg_a7,
rv_ireg_s2,
rv_ireg_s3,
rv_ireg_s4,
rv_ireg_s5,
rv_ireg_s6,
rv_ireg_s7,
rv_ireg_s8,
rv_ireg_s9,
rv_ireg_s10,
rv_ireg_s11,
rv_ireg_t3,
rv_ireg_t4,
rv_ireg_t5,
rv_ireg_t6,
} rv_ireg;

So from that perspective, one could suggest to change microblaze. It will
be a lot harder to change glibc given it is already baked into a large
number of binary images, and they are system headers.

Prefixing the definitions inside the mircoblaze disassembler would cause
the least havoc. Changing system headers in glibc will take a long time to
propagate via the current distros.


Re: [Qemu-devel] [PULL v4 0/7] riscv-pull queue

2018-07-09 Thread Michael Clark
On Tue, Jul 10, 2018 at 9:52 AM, Alistair Francis 
wrote:

> On Mon, Jul 9, 2018 at 3:00 AM, Andreas Schwab  wrote:
> > What is the state of the sifive_u emulation?  When I tried to boot a bbl
> > with an included kernel I get these errors:
> >
> > qemu-system-riscv64: plic: invalid register write: 2090
> > qemu-system-riscv64: plic: invalid register write: 2094
> > qemu-system-riscv64: plic: invalid register write: 2098
> > qemu-system-riscv64: plic: invalid register write: 209c
> > qemu-system-riscv64: plic: invalid register write: 20a0
> > qemu-system-riscv64: plic: invalid register write: 20a4
> > qemu-system-riscv64: plic: invalid register write: 20a8
> > qemu-system-riscv64: plic: invalid register write: 20ac
> > qemu-system-riscv64: plic: invalid register write: 20b0
> > qemu-system-riscv64: plic: invalid register write: 20b4
>
> I see those as well. I haven't investigated but I assume we are just
> not completely modelling the PLIC. In saying that it should still
> boot. Do you not see the kernel booting?


It could be a PLIC bug or it could be a Linux interrupt controller driver
bug. We can see from the memory map docs for the U54 whether these memory
addresses are in bounds based on the number of configured interrupt
sources. I'm not sure how many sources we have configured on sifive_u. Last
time I booted Linux on sifive_u I did not see these errors. I'd need your
kernel config and to know what tree and branch you are building from. I
will be able to look when I get time... The PLIC however seems stable in
the 'virt' board at least...

Sorry I've been incommunicado for several weeks. I have been working on a
CLIC model (Core Local Interrupt Controller) which replaces the CLINT and
has a CLINT backwards compatibility mode. It is a Core Local vs the PLIC
which is the Platform Level router. Here is the "draft" spec. It will be a
candidate proposed to the RISC-V Fast Interrupts working group for
potential standardisation, however in any case it will be available from
SiFive so we may eventuall want to include our implementation in QEMU:

- https://github.com/sifive/clic-spec/blob/master/clic.adoc

When i'm done with modelling the first iteration of the CLIC I'll go
through my pending patch queue and make a PR for the Reviewed patches. I'll
also do some testing on master to make sure we have not regressed anything
in RISC-V QEMU given QEMU 2.12 and the riscv-qemu trees are both stable.

BTW - with respect to 'sifive_e' and 'sifive_u' SOC changes, we'll have to
see how the model matches SiFive's plans for these virtual machines. We
want to avoid a proliferation of boards, and as I've mentioned before we
want to be able to model the HiFive1, HiFiveU and other SiFive E Series and
U Series Coreplex configurations. There are many permutations from SiFive's
SOC generator so our goal is to avoid hardcoding all of the different SOC
combinations (hence the removal of model numbers in my initial review of
your patches). How we achieve this I do not know. We obviously want to
invest our time in something that is acceptable to upstream, while also
meeting the goal of modelling SiFive's many hardware configurations, given
these boards also model softcore IP such as the e31 arty and u54 on Xilinx
VC707. i.e. they are SiFive models.

I'm not too concerned with the SOC changes assuming we don't regress any
function, as we can always evolve the code in the future to match
configurations from SiFive's SOC generator. At present the models are like
a union of a subset of the real hardware as we are still missing many
emulation models for various parts of the SOCs. After i've finished up this
CLIC work, I'll go back through the list of things we still need to model.

Adding the Cadence GEM to the SiFive U Series is really nice, and so is
adding Xilinx PCI to the SiFive U and GPEX to virt (as discussed, given
virt is generic, we want to use GPEX there).

Thanks,
Michael.

>
> > Andreas.
> >
> > --
> > Andreas Schwab, SUSE Labs, sch...@suse.de
> > GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
> > "And now for something completely different."
>


Re: [Qemu-devel] [PATCH v2 6/6] riscv64-softmmu.mak: Build Virtio Block support

2018-07-09 Thread Michael Clark
On Tue, 10 Jul 2018 at 12:29 PM, Alistair Francis 
wrote:

> Add build time support for the VirtIO block device. This allows us to
> attach a drive using the virtio-blk-device.


I’m not sure what has changed in master, but VirtIO block and net for both
softmmu-riscv32 and softmmu-riscv64 were previously building by default and
working. Perhaps i’ve missed some patches that split up VirtIO support into
more granular config options.

In any case, we should enable both CONFIG_VIRTIO_NET and CONFIG_VIRTIO_BLK
for both riscv32 and riscv64 as these were working in QEMU 2.12. There are
folk using the “virt” machine for riscv32 Linux.

Thanks, at least I know what to expect when I rebase my patch queue against
master and of course make a PR for the reviewed patches...

I’m not sure of the soft-freeze date but the bulk of the patches are the
same ones that were posted about a month ago... I also have several patches
that are not yet on the list...

Vectored interrupts. Trap tracing. More spec wording clarifications
regarding load reservations and interrupts:

-
https://github.com/riscv/riscv-qemu/commits/qemu-2.13-for-upstream

Michael

Signed-off-by: Alistair Francis 
> ---
>  default-configs/riscv64-softmmu.mak | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/default-configs/riscv64-softmmu.mak
> b/default-configs/riscv64-softmmu.mak
> index 35e74bebe9..8790f3b115 100644
> --- a/default-configs/riscv64-softmmu.mak
> +++ b/default-configs/riscv64-softmmu.mak
> @@ -12,3 +12,5 @@ CONFIG_PCI_XILINX=y
>
>  CONFIG_VGA=y
>  CONFIG_VGA_PCI=y
> +
> +CONFIG_VIRTIO_BLK=y
> --
> 2.17.1
>
>


Re: [Qemu-devel] [PATCH v1 1/5] sifive_e: Fix crash when introspecting the device

2018-07-17 Thread Michael Clark
On Wed, Jul 18, 2018 at 8:27 AM, Alistair Francis 
wrote:

> Use the new object_initialize_child() and sysbus_init_child_obj() to
> fix the issue.
>
> Signed-off-by: Alistair Francis 
>

Reviewed-by: Michael Clark 


> ---
>  hw/riscv/sifive_e.c | 12 ++--
>  1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
> index 8a8dbe1c00..4577d72037 100644
> --- a/hw/riscv/sifive_e.c
> +++ b/hw/riscv/sifive_e.c
> @@ -105,9 +105,9 @@ static void riscv_sifive_e_init(MachineState *machine)
>  int i;
>
>  /* Initialize SoC */
> -object_initialize(&s->soc, sizeof(s->soc), TYPE_RISCV_E_SOC);
> -object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
> -  &error_abort);
> +object_initialize_child(OBJECT(machine), "soc", &s->soc,
> +sizeof(s->soc), TYPE_RISCV_E_SOC,
> +&error_abort, NULL);
>  object_property_set_bool(OBJECT(&s->soc), true, "realized",
>  &error_abort);
>
> @@ -139,9 +139,9 @@ static void riscv_sifive_e_soc_init(Object *obj)
>  {
>  SiFiveESoCState *s = RISCV_E_SOC(obj);
>
> -object_initialize(&s->cpus, sizeof(s->cpus), TYPE_RISCV_HART_ARRAY);
> -object_property_add_child(obj, "cpus", OBJECT(&s->cpus),
> -  &error_abort);
> +object_initialize_child(obj, "cpus", &s->cpus,
> +sizeof(s->cpus), TYPE_RISCV_HART_ARRAY,
> +&error_abort, NULL);
>  object_property_set_str(OBJECT(&s->cpus), SIFIVE_E_CPU, "cpu-type",
>  &error_abort);
>  object_property_set_int(OBJECT(&s->cpus), smp_cpus, "num-harts",
> --
> 2.17.1
>
>


Re: [Qemu-devel] [PATCH v1 4/5] riscv_hart: Fix crash when introspecting the device

2018-07-17 Thread Michael Clark
On Wed, Jul 18, 2018 at 8:28 AM, Alistair Francis 
wrote:

> Use the new object_initialize_child() and sysbus_init_child_obj() to
> fix the issue.
>
> Signed-off-by: Alistair Francis 
>

Reviewed-by: Michael Clark 


> ---
>  hw/riscv/riscv_hart.c | 7 +++
>  1 file changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c
> index 75ba7ed579..e34a26a0ef 100644
> --- a/hw/riscv/riscv_hart.c
> +++ b/hw/riscv/riscv_hart.c
> @@ -45,11 +45,10 @@ static void riscv_harts_realize(DeviceState *dev,
> Error **errp)
>  s->harts = g_new0(RISCVCPU, s->num_harts);
>
>  for (n = 0; n < s->num_harts; n++) {
> -
> -object_initialize(&s->harts[n], sizeof(RISCVCPU), s->cpu_type);
> +object_initialize_child(OBJECT(s), "harts[*]", &s->harts[n],
> +sizeof(RISCVCPU), s->cpu_type,
> +&error_abort, NULL);
>  s->harts[n].env.mhartid = n;
> -object_property_add_child(OBJECT(s), "harts[*]",
> OBJECT(&s->harts[n]),
> -  &error_abort);
>  qemu_register_reset(riscv_harts_cpu_reset, &s->harts[n]);
>  object_property_set_bool(OBJECT(&s->harts[n]), true,
>   "realized", &err);
> --
> 2.17.1
>
>


Re: [Qemu-devel] [PATCH v1 3/5] virt: Fix crash when introspecting the device

2018-07-17 Thread Michael Clark
On Wed, Jul 18, 2018 at 8:28 AM, Alistair Francis 
wrote:

> Use the new object_initialize_child() and sysbus_init_child_obj() to
> fix the issue.
>
> Signed-off-by: Alistair Francis 
>

Reviewed-by: Michael Clark 


> ---
>  hw/riscv/virt.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index aeada2498d..248bbdffd3 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -274,9 +274,8 @@ static void riscv_virt_board_init(MachineState
> *machine)
>  void *fdt;
>
>  /* Initialize SOC */
> -object_initialize(&s->soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY);
> -object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
> -  &error_abort);
> +object_initialize_child(OBJECT(machine), "soc", &s->soc,
> sizeof(s->soc),
> +TYPE_RISCV_HART_ARRAY, &error_abort, NULL);
>  object_property_set_str(OBJECT(&s->soc), VIRT_CPU, "cpu-type",
>  &error_abort);
>  object_property_set_int(OBJECT(&s->soc), smp_cpus, "num-harts",
> --
> 2.17.1
>
>


Re: [Qemu-devel] [PATCH v1 5/5] spike: Fix crash when introspecting the device

2018-07-17 Thread Michael Clark
On Wed, Jul 18, 2018 at 8:28 AM, Alistair Francis 
wrote:

> Use the new object_initialize_child() and sysbus_init_child_obj() to
> fix the issue.
>
> Signed-off-by: Alistair Francis 
>

Reviewed-by: Michael Clark 


> ---
>  hw/riscv/spike.c | 10 --
>  1 file changed, 4 insertions(+), 6 deletions(-)
>
> diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
> index f94e2b6707..c8c056c50b 100644
> --- a/hw/riscv/spike.c
> +++ b/hw/riscv/spike.c
> @@ -171,9 +171,8 @@ static void spike_v1_10_0_board_init(MachineState
> *machine)
>  int i;
>
>  /* Initialize SOC */
> -object_initialize(&s->soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY);
> -object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
> -  &error_abort);
> +object_initialize_child(OBJECT(machine), "soc", &s->soc,
> sizeof(s->soc),
> +TYPE_RISCV_HART_ARRAY, &error_abort, NULL);
>  object_property_set_str(OBJECT(&s->soc), SPIKE_V1_10_0_CPU,
> "cpu-type",
>  &error_abort);
>  object_property_set_int(OBJECT(&s->soc), smp_cpus, "num-harts",
> @@ -254,9 +253,8 @@ static void spike_v1_09_1_board_init(MachineState
> *machine)
>  int i;
>
>  /* Initialize SOC */
> -object_initialize(&s->soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY);
> -object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
> -  &error_abort);
> +object_initialize_child(OBJECT(machine), "soc", &s->soc,
> sizeof(s->soc),
> +TYPE_RISCV_HART_ARRAY, &error_abort, NULL);
>  object_property_set_str(OBJECT(&s->soc), SPIKE_V1_09_1_CPU,
> "cpu-type",
>  &error_abort);
>  object_property_set_int(OBJECT(&s->soc), smp_cpus, "num-harts",
> --
> 2.17.1
>
>


Re: [Qemu-devel] [PATCH v1 2/5] sifive_u: Fix crash when introspecting the device

2018-07-17 Thread Michael Clark
On Wed, Jul 18, 2018 at 8:28 AM, Alistair Francis 
wrote:

> Use the new object_initialize_child() and sysbus_init_child_obj() to
> fix the issue.
>
> Signed-off-by: Alistair Francis 
>

Reviewed-by: Michael Clark 


> ---
>  hw/riscv/sifive_u.c | 15 +++
>  1 file changed, 7 insertions(+), 8 deletions(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 3a6ffeb437..59ae1ce24a 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -244,9 +244,9 @@ static void riscv_sifive_u_init(MachineState *machine)
>  int i;
>
>  /* Initialize SoC */
> -object_initialize(&s->soc, sizeof(s->soc), TYPE_RISCV_U_SOC);
> -object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
> -  &error_abort);
> +object_initialize_child(OBJECT(machine), "soc", &s->soc,
> +sizeof(s->soc), TYPE_RISCV_U_SOC,
> +&error_abort, NULL);
>  object_property_set_bool(OBJECT(&s->soc), true, "realized",
>  &error_abort);
>
> @@ -303,16 +303,15 @@ static void riscv_sifive_u_soc_init(Object *obj)
>  {
>  SiFiveUSoCState *s = RISCV_U_SOC(obj);
>
> -object_initialize(&s->cpus, sizeof(s->cpus), TYPE_RISCV_HART_ARRAY);
> -object_property_add_child(obj, "cpus", OBJECT(&s->cpus),
> -  &error_abort);
> +object_initialize_child(obj, "cpus", &s->cpus, sizeof(s->cpus),
> +TYPE_RISCV_HART_ARRAY, &error_abort, NULL);
>  object_property_set_str(OBJECT(&s->cpus), SIFIVE_U_CPU, "cpu-type",
>  &error_abort);
>  object_property_set_int(OBJECT(&s->cpus), smp_cpus, "num-harts",
>  &error_abort);
>
> -object_initialize(&s->gem, sizeof(s->gem), TYPE_CADENCE_GEM);
> -qdev_set_parent_bus(DEVICE(&s->gem), sysbus_get_default());
> +sysbus_init_child_obj(obj, "gem", &s->gem, sizeof(s->gem),
> +  TYPE_CADENCE_GEM);
>  }
>
>  static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
> --
> 2.17.1
>
>


Re: [Qemu-devel] [PATCH v2] riscv: remove define cpu_init()

2018-07-25 Thread Michael Clark
On Fri, May 18, 2018 at 8:02 PM, Igor Mammedov  wrote:

> On Fri, 18 May 2018 14:10:24 +1200
> Michael Clark  wrote:
>
> > On Wed, May 16, 2018 at 4:00 AM, Igor Mammedov 
> wrote:
> >
> > > cpu_init() was removed since 2.12, so drop the define that is now
> unused.
> > >
> > > Signed-off-by: Igor Mammedov 
> > > Reviewed-by: Philippe Mathieu-Daudé 
> > >
> >
> > Reviewed-by: Michael Clark 
> Michael,
>
> could you merge it through RISCV queue?


Yes indeed. Sorry I missed this email.

I'm going to bring this into the riscv-qemu queue right away and move it to
the head of the queue, now we have Alastair's stuff in master. Although I
won't be making any PRs until after 3.0 is released.

I'm currently re-basing and testing the RISC-V tree against Alastair's
changes. There were quite a few conflicts so it is going to take a bit of
testing. I also need to spend some time re-testing master.

I've been AWOL for the last month and a half due to some work related to
SiFive's new E20 and E21 cores which were recently announced. In the QEMU
3.1 or 3.2 time-frame we should have the new CLIC interrupt controller
which supports multiple levels of interrupt pre-emption, interrupt tail
chaining and new vectored interrupt modes. In the proposed CLIC spec (Core
Level Interrupt Controller), pre-emption is mostly handled in software but
there is a tiny bit of hardware support. We don't have any magic hardware
state machines that save multiple registers at a time. The proposed CLIC
sticks pretty closely to a set of RISC-V ideals with respect to how much is
done in a micro-op in the ISA and avoidance of complex hardware state
machines (e.g. no wiring of the ABI caller save registers into hardware).
I'm currently working on test cases for the CLIC and hopefully SiFive will
have tests for other changes we have in the RISC-V tree, so we have
"proofs" accompanying each patch that makes any sufficiantly complex
change. It of course will take a bit of time for us to accompany each of
our changes with a test. SiFive do actually have resources devoted to
formal verification but I have not yet been able to convince them to devote
resources to formally verifying the RISC-V QEMU implementation. Anyway we
do at least hope to have some tests for the RISC-V QEMU target in the near
future...

Phillipe, I noticed the recent cross complier infrastructure support so we
could potentially bring in riscv-tests as a submodule in QEMU... this will
help...

Michael.


> > ---
> > > v2:
> > >   * refine commit message (Eric Blake )
> > > ---
> > >  target/riscv/cpu.h | 1 -
> > >  1 file changed, 1 deletion(-)
> > >
> > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > > index 34abc38..0562a02 100644
> > > --- a/target/riscv/cpu.h
> > > +++ b/target/riscv/cpu.h
> > > @@ -251,7 +251,6 @@ int riscv_cpu_handle_mmu_fault(CPUState *cpu,
> vaddr
> > > address, int size,
> > >  char *riscv_isa_string(RISCVCPU *cpu);
> > >  void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf);
> > >
> > > -#define cpu_init(cpu_model) cpu_generic_init(TYPE_RISCV_CPU,
> cpu_model)
> > >  #define cpu_signal_handler cpu_riscv_signal_handler
> > >  #define cpu_list riscv_cpu_list
> > >  #define cpu_mmu_index riscv_cpu_mmu_index
> > > --
> > > 2.7.4
> > >
> > >
>
>


Re: [Qemu-devel] [PATCH v4 16/40] hw/riscv: Use the IEC binary prefix definitions

2018-06-10 Thread Michael Clark
On Mon, Jun 11, 2018 at 1:14 PM, Philippe Mathieu-Daudé 
wrote:

> It eases code review, unit is explicit.
>
> Patch generated using:
>
>   $ git grep -E '(1024|2048|4096|8192|(<<|>>).?(10|20|30))' hw/
> include/hw/
>
> and modified manually.
>
> Signed-off-by: Philippe Mathieu-Daudé 
>

Reviewed-by: Michael Clark 


> ---
>  hw/riscv/virt.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index ad03113e0f..34d48993a2 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -19,6 +19,7 @@
>   */
>
>  #include "qemu/osdep.h"
> +#include "qemu/units.h"
>  #include "qemu/log.h"
>  #include "qemu/error-report.h"
>  #include "qapi/error.h"
> @@ -84,7 +85,7 @@ static hwaddr load_initrd(const char *filename, uint64_t
> mem_size,
>   * halfway into RAM, and for boards with 256MB of RAM or more we put
>   * the initrd at 128MB.
>   */
> -*start = kernel_entry + MIN(mem_size / 2, 128 * 1024 * 1024);
> +*start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
>
>  size = load_ramdisk(filename, *start, mem_size - *start);
>  if (size == -1) {
> --
> 2.17.1
>
>


Re: [Qemu-devel] [PATCH v8 10/23] RISC-V Linux User Emulation

2018-04-08 Thread Michael Clark
On Thu, Apr 5, 2018 at 12:44 AM, Laurent Vivier  wrote:

> Le 02/03/2018 à 14:51, Michael Clark a écrit :
> > Implementation of linux user emulation for RISC-V.
> >
> > Reviewed-by: Richard Henderson 
> > Signed-off-by: Sagar Karandikar 
> > Signed-off-by: Michael Clark 
> > ---
> >  linux-user/elfload.c  |  22 +++
> >  linux-user/main.c |  99 +
> >  linux-user/riscv/syscall_nr.h | 287 ++
> 
> >  linux-user/riscv/target_cpu.h |  18 +++
> >  linux-user/riscv/target_elf.h |  14 ++
> >  linux-user/riscv/target_signal.h  |  23 +++
> >  linux-user/riscv/target_structs.h |  46 ++
> >  linux-user/riscv/target_syscall.h |  56 
> >  linux-user/riscv/termbits.h   | 222 +
> >  linux-user/signal.c   | 203 ++-
> >  linux-user/syscall.c  |   2 +
> >  linux-user/syscall_defs.h |  13 +-
> >  target/riscv/cpu_user.h   |  13 ++
> >  13 files changed, 1012 insertions(+), 6 deletions(-)
> >  create mode 100644 linux-user/riscv/syscall_nr.h
> >  create mode 100644 linux-user/riscv/target_cpu.h
> >  create mode 100644 linux-user/riscv/target_elf.h
> >  create mode 100644 linux-user/riscv/target_signal.h
> >  create mode 100644 linux-user/riscv/target_structs.h
> >  create mode 100644 linux-user/riscv/target_syscall.h
> >  create mode 100644 linux-user/riscv/termbits.h
> >  create mode 100644 target/riscv/cpu_user.h
> >
> ...
> > diff --git a/linux-user/signal.c b/linux-user/signal.c
> > index 9a380b9..4d3f244 100644
> > --- a/linux-user/signal.c
> > +++ b/linux-user/signal.c
> ...
> > +static abi_ulong get_sigframe(struct target_sigaction *ka,
> > +  CPURISCVState *regs, size_t framesize)
> > +{
> > +abi_ulong sp = regs->gpr[xSP];
> > +int onsigstack = on_sig_stack(sp);
> > +
> > +/* redzone */
> > +/* This is the X/Open sanctioned signal stack switching.  */
> > +if ((ka->sa_flags & TARGET_SA_ONSTACK) != 0 && !onsigstack) {
> > +sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_
> size;
> > +}
> > +
> > +sp -= framesize;
> > +sp &= ~3UL; /* align sp on 4-byte boundary */
>
> kernel aligns using 0xf. Why do you use a different alignment?


Thanks for reviewing this! This looks like a bug!

I'm raising this as an issue on the riscv-qemu tracker so that its easier
than searching through the mail archive:

- https://github.com/riscv/riscv-qemu/issues/129

> +
> > +/* If we are on the alternate signal stack and would overflow it,
> don't.
> > +   Return an always-bogus address instead so we will die with
> SIGSEGV. */
> > +if (onsigstack && !likely(on_sig_stack(sp))) {
> > +return -1L;
> > +}
> > +
> > +return sp;
> > +}
> Other question why don't you use the same logic as in kernel?
>
> 1- check for signal stack overflow
> 2- check for X/Open sanctioned signal stack switching
>
> static inline void __user *get_sigframe(struct ksignal *ksig,
> struct pt_regs *regs, size_t framesize)
> {
> unsigned long sp;
> /* Default to using normal stack */
> sp = regs->sp;
>
> /*
>  * If we are on the alternate signal stack and would overflow
> it, don't.
>  * Return an always-bogus address instead so we will die with
> SIGSEGV.
>  */
> if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
> return (void __user __force *)(-1UL);
>
> /* This is the X/Open sanctioned signal stack switching. */
> sp = sigsp(sp, ksig) - framesize;
>
> /* Align the stack frame. */
> sp &= ~0xfUL;
>
> return (void __user *)sp;
> }
>
> Thanks,
> Laurent
>


Re: [Qemu-devel] [PATCH v8 19/23] SiFive RISC-V UART Device

2018-04-11 Thread Michael Clark
On Tue, Apr 10, 2018 at 8:04 PM, Antony Pavlov 
wrote:

> On Tue, 10 Apr 2018 08:17:32 +0200
> Thomas Huth  wrote:
>
> > On 10.04.2018 05:21, Antony Pavlov wrote:
> > > On Sat,  3 Mar 2018 02:51:47 +1300
> > > Michael Clark  wrote:
> > >
> > >> QEMU model of the UART on the SiFive E300 and U500 series SOCs.
> > >> BBL supports the SiFive UART for early console access via the SBI
> > >> (Supervisor Binary Interface) and the linux kernel SBI console.
> > >>
> > >> The SiFive UART implements the pre qom legacy interface consistent
> > >> with the 16550a UART in 'hw/char/serial.c'.
> > >>
> > >> Acked-by: Richard Henderson 
> > >> Signed-off-by: Stefan O'Rear 
> > >> Signed-off-by: Palmer Dabbelt 
> > >> Signed-off-by: Michael Clark 
> > >> ---
> > >>  hw/riscv/sifive_uart.c | 176 ++
> +++
> > >>  include/hw/riscv/sifive_uart.h |  71 +
> > >>  2 files changed, 247 insertions(+)
> > >>  create mode 100644 hw/riscv/sifive_uart.c
> > >>  create mode 100644 include/hw/riscv/sifive_uart.h
> > >>
> > >> diff --git a/hw/riscv/sifive_uart.c b/hw/riscv/sifive_uart.c
> > >> new file mode 100644
> > >> index 000..b0c3798
> > >> --- /dev/null
> > >> +++ b/hw/riscv/sifive_uart.c
> > >> @@ -0,0 +1,176 @@
> > >> +/*
> > >> + * QEMU model of the UART on the SiFive E300 and U500 series SOCs.
> > >> + *
> > >> + * Copyright (c) 2016 Stefan O'Rear
> > >> + *
> > >> + * This program is free software; you can redistribute it and/or
> modify it
> > >> + * under the terms and conditions of the GNU General Public License,
> > >> + * version 2 or later, as published by the Free Software Foundation.
> > >> + *
> > >> + * This program is distributed in the hope it will be useful, but
> WITHOUT
> > >> + * ANY WARRANTY; without even the implied warranty of
> MERCHANTABILITY or
> > >> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
> License for
> > >> + * more details.
> > >> + *
> > >> + * You should have received a copy of the GNU General Public License
> along with
> > >> + * this program.  If not, see <http://www.gnu.org/licenses/>.
> > >> + */
> > >> +
> > >> +#include "qemu/osdep.h"
> > >> +#include "qapi/error.h"
> > >> +#include "hw/sysbus.h"
> > >> +#include "chardev/char.h"
> > >> +#include "chardev/char-fe.h"
> > >> +#include "target/riscv/cpu.h"
> > >> +#include "hw/riscv/sifive_uart.h"
> > >>
> > >> +/*
> > >> + * Not yet implemented:
> > >> + *
> > >> + * Transmit FIFO using "qemu/fifo8.h"
> > >> + * SIFIVE_UART_IE_TXWM interrupts
> > >> + * SIFIVE_UART_IE_RXWM interrupts must honor fifo watermark
> > >> + * Rx FIFO watermark interrupt trigger threshold
> > >> + * Tx FIFO watermark interrupt trigger threshold.
> > >> + */
> > >> +
> > >> +static void update_irq(SiFiveUARTState *s)
> > >> +{
> > >> +int cond = 0;
> > >> +if ((s->ie & SIFIVE_UART_IE_RXWM) && s->rx_fifo_len) {
> > >> +cond = 1;
> > >> +}
> > >> +if (cond) {
> > >> +qemu_irq_raise(s->irq);
> > >> +} else {
> > >> +qemu_irq_lower(s->irq);
> > >> +}
> > >> +}
> > >> +
> > >> +static uint64_t
> > >> +uart_read(void *opaque, hwaddr addr, unsigned int size)
> > >> +{
> > >> +SiFiveUARTState *s = opaque;
> > >> +unsigned char r;
> > >> +switch (addr) {
> > >> +case SIFIVE_UART_RXFIFO:
> > >> +if (s->rx_fifo_len) {
> > >> +r = s->rx_fifo[0];
> > >> +memmove(s->rx_fifo, s->rx_fifo + 1, s->rx_fifo_len - 1);
> > >> +s->rx_fifo_len--;
> > >> +qemu_chr_fe_accept_input(&s->chr);
> > >> +update_irq(s);
> > >> +return r;
> > >> +}
> > >> +return 0x8000;
> > >&g

Re: [Qemu-devel] [PATCH 01/10] target/riscv: avoid integer overflow in next_page PC check

2018-04-11 Thread Michael Clark
On Wed, Apr 11, 2018 at 4:19 AM, Emilio G. Cota  wrote:

> If the PC is in the last page of the address space, next_page_start
> overflows to 0. Fix it.
>
> Reported-by: Richard Henderson 
> Suggested-by: Richard Henderson 
> Cc: Michael Clark 
> Cc: Palmer Dabbelt 
> Cc: Sagar Karandikar 
> Cc: Bastian Koppelmann 
> Signed-off-by: Emilio G. Cota 
>

Reviewed-by: Michael Clark 


> ---
>  target/riscv/translate.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 808eab7..d2d2e5e 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -1849,11 +1849,11 @@ void gen_intermediate_code(CPUState *cs,
> TranslationBlock *tb)
>  CPURISCVState *env = cs->env_ptr;
>  DisasContext ctx;
>  target_ulong pc_start;
> -target_ulong next_page_start;
> +target_ulong page_start;
>  int num_insns;
>  int max_insns;
>  pc_start = tb->pc;
> -next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
> +page_start = pc_start & TARGET_PAGE_MASK;
>  ctx.pc = pc_start;
>
>  /* once we have GDB, the rest of the translate.c implementation
> should be
> @@ -1903,7 +1903,7 @@ void gen_intermediate_code(CPUState *cs,
> TranslationBlock *tb)
>  if (cs->singlestep_enabled) {
>  break;
>  }
> -if (ctx.pc >= next_page_start) {
> +if (ctx.pc - page_start >= TARGET_PAGE_SIZE) {
>  break;
>  }
>  if (tcg_op_buf_full()) {
> --
> 2.7.4
>
>


Re: [Qemu-devel] [sw-dev] The problem of write misa on QEMU and BBL

2018-04-18 Thread Michael Clark
Hi Zong,

> On 19/04/2018, at 2:40 PM, Zong Li  wrote:
> 
> Hi all,
> 
> For BBL part, in fp_init at machine/minit.c,
> it will clear the D and F bits of misa register, and assertion that
> the bits is cleared.
> But the misa is WARL register, so there is no effect for writing it,
> and the assertion not be true.
> So is there has necessary to do that if toolchain not support D and F 
> extension?
> 
> For QEMU part, when writing misa, it will trigger the illegal
> instruction exception, but I think that the WARL allow write behavior?

QEMU in the riscv-all branch should have WARL behavior.

- https://github.com/riscv/riscv-qemu/commits/riscv-all

There is a bug in upstream. We have submitted patches to fix the issue for 
review on the qemu-devel mailing list. The patch series will be submitted for 
upstream review again shortly. We were holding off on the series as we didn’t 
classify it as a “critical bug” as QEMU was in soft-freeze for 2.12 and we 
weren’t able to get review in time to include this fix in the 2.12 release.

See “No traps on writes to misa,minstret,mcycle"

- https://github.com/riscv/riscv-qemu/commits/qemu-2.13-for-upstream

The history is that there were several unimplemented CSRs that had printf 
followed by exit. Richard Henderson said we should fix this. I changed several 
CSRs to cause illegal instruction traps instead of calling exit. That was a 
mistake as CSRs that don’t support write are WARL (Write Any Read Legal). It 
was certainly better than having the simulation exit as a cpu doesn’t typically 
have a way to ”exit” like a C program, nevertheless trapping was wrong. My 
mistake. See here for the history:

- 
https://github.com/riscv/riscv-qemu/blob/ff36f2f77ec3e6a6211c63bfe1707ec057b12f7d/target-riscv/op_helper.c

The implementation in the current tree is quite different. We have recently 
made the CSR system more modular so that with minor changes, custom CPUs will 
be able to hook their own control and status registers.

- 
https://github.com/riscv/riscv-qemu/blob/qemu-2.13-for-upstream/target/riscv/csr.c#L780-L867

See these changes:

- 
https://github.com/riscv/riscv-qemu/commit/9d9c1bfef911c520a35bd3f8c0ed2e14cc96bbb7
- 
https://github.com/riscv/riscv-qemu/commit/b5a4cd79ce6c7fbb65fdcf078fb9a8391da1d6b1

We know have a flexible system that will allow implementations to hook per-cpu 
control and status registers, and we have predicates that make CSRs appear on 
some processor but not on others. i.e. if misa.S is not present, then S-mode s* 
CSRs will trap. Sometimes WARL is the correct behaviour, but sometimes trapping 
is the correct behaviour i.e. if the processor does not implement S-mode.

misa traps on write should only affect bootloaders as Supervisor’s like Linux 
don’t yet have access to the isa register. It’s not a major issuse.

Michael.


Re: [Qemu-devel] [PATCH] riscv: requires libfdt

2018-04-19 Thread Michael Clark
On Fri, Apr 20, 2018 at 4:56 AM, Philippe Mathieu-Daudé 
wrote:

> > On 04/19/2018 12:51 PM, KONRAD Frederic wrote:
> >> When compiling on a machine without libfdt installed the configure
> script
> >> should try to get libfdt from the git or should die because otherwise
> >> CONFIG_LIBFDT is not set and the build process end in an error in the
> >> link
> >> phase.. eg:
> >>
> >> hw/riscv/virt.o: In function `riscv_virt_board_init':
> >> qemu/src/hw/riscv/virt.c:317: undefined reference to
> >> `qemu_fdt_setprop_cell'
> >> qemu/src/hw/riscv/virt.c:319: undefined reference to
> >> `qemu_fdt_setprop_cell'
> >> qemu/src/hw/riscv/virt.c:345: undefined reference to `qemu_fdt_dumpdtb'
> >> collect2: error: ld returned 1 exit status
> >> make[1]: *** [qemu-system-riscv64] Error 1
> >> make: *** [subdir-riscv64-softmmu] Error 2
> >>
> >> Signed-off-by: KONRAD Frederic 
> >> ---
> >>   configure | 2 +-
> >>   1 file changed, 1 insertion(+), 1 deletion(-)
> >>
> >> diff --git a/configure b/configure
> >> index 0a19b03..1587f08 100755
> >> --- a/configure
> >> +++ b/configure
> >> @@ -3732,7 +3732,7 @@ fi
> >>   fdt_required=no
> >>   for target in $target_list; do
> >> case $target in
> >> -
> >> aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-
> softmmu|mips64el-softmmu)
> >>
> >> +
> >> aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-
> softmmu|mips64el-softmmu|riscv64-softmmu)
> >>
> >
> > I just realized that riscv32 use it too so I'll correct with
> > riscv*-softmmu.
>
> Using "riscv*-softmmu":
>

Indeed.

We had this fix in our tree before one of the rebases against upstream:

https://github.com/riscv/riscv-qemu/commit/90cdfb86e81c54c1df42412b10b86fd83a6dee82

It must have somehow got dropped when we forward ported to QEMU master in
December 2017. My apologies.

Reviewed-by: Philippe Mathieu-Daudé 
>

Reviewed-by: Michael Clark 

>> fdt_required=yes
> >>   ;;
> >> esac
> >>
> >
>


Re: [Qemu-devel] [sw-dev] The problem of write misa on QEMU and BBL

2018-04-19 Thread Michael Clark
On Thu, Apr 19, 2018 at 9:28 PM, Zong Li  wrote:

> 2018-04-19 12:43 GMT+08:00 Michael Clark :
> > Hi Zong,
> >
> >> On 19/04/2018, at 2:40 PM, Zong Li  wrote:
> >>
> >> Hi all,
> >>
> >> For BBL part, in fp_init at machine/minit.c,
> >> it will clear the D and F bits of misa register, and assertion that
> >> the bits is cleared.
> >> But the misa is WARL register, so there is no effect for writing it,
> >> and the assertion not be true.
> >> So is there has necessary to do that if toolchain not support D and F
> extension?
> >>
> >> For QEMU part, when writing misa, it will trigger the illegal
> >> instruction exception, but I think that the WARL allow write behavior?
> >
> > QEMU in the riscv-all branch should have WARL behavior.
> >
> > - https://github.com/riscv/riscv-qemu/commits/riscv-all
> >
> > There is a bug in upstream. We have submitted patches to fix the issue
> for review on the qemu-devel mailing list. The patch series will be
> submitted for upstream review again shortly. We were holding off on the
> series as we didn’t classify it as a “critical bug” as QEMU was in
> soft-freeze for 2.12 and we weren’t able to get review in time to include
> this fix in the 2.12 release.
> >
> > See “No traps on writes to misa,minstret,mcycle"
> >
> > - https://github.com/riscv/riscv-qemu/commits/qemu-2.13-for-upstream
> >
> > The history is that there were several unimplemented CSRs that had
> printf followed by exit. Richard Henderson said we should fix this. I
> changed several CSRs to cause illegal instruction traps instead of calling
> exit. That was a mistake as CSRs that don’t support write are WARL (Write
> Any Read Legal). It was certainly better than having the simulation exit as
> a cpu doesn’t typically have a way to ”exit” like a C program, nevertheless
> trapping was wrong. My mistake. See here for the history:
> >
> > - https://github.com/riscv/riscv-qemu/blob/
> ff36f2f77ec3e6a6211c63bfe1707ec057b12f7d/target-riscv/op_helper.c
> >
> > The implementation in the current tree is quite different. We have
> recently made the CSR system more modular so that with minor changes,
> custom CPUs will be able to hook their own control and status registers.
> >
> > - https://github.com/riscv/riscv-qemu/blob/qemu-2.13-for-
> upstream/target/riscv/csr.c#L780-L867
> >
> > See these changes:
> >
> > - https://github.com/riscv/riscv-qemu/commit/
> 9d9c1bfef911c520a35bd3f8c0ed2e14cc96bbb7
> > - https://github.com/riscv/riscv-qemu/commit/
> b5a4cd79ce6c7fbb65fdcf078fb9a8391da1d6b1
> >
> > We know have a flexible system that will allow implementations to hook
> per-cpu control and status registers, and we have predicates that make CSRs
> appear on some processor but not on others. i.e. if misa.S is not present,
> then S-mode s* CSRs will trap. Sometimes WARL is the correct behaviour, but
> sometimes trapping is the correct behaviour i.e. if the processor does not
> implement S-mode.
> >
> > misa traps on write should only affect bootloaders as Supervisor’s like
> Linux don’t yet have access to the isa register. It’s not a major issuse.
> >
> > Michael.
>
> Hi Michael,
>
> Thanks for the information. The new CSR system is helpful for custom
> CPU such as ours. Thanks.
>
> In the future, maybe we can do something like this in BBL for flexible
> custom platform which has own device to control the timer, ipi and so
> on.
>
> Back to the misa problem in BBL, at fp_init in BBL initial phrase, the
> assertion will has problem because the bits of misa will not be
> cleared.
>
> the code piece like below:
> uintptr_t fd_mask = (1 << ('F' - 'A')) | (1 << ('D' - 'A'));
> clear_csr(misa, fd_mask);
> assert(!(read_csr(misa) & fd_mask));
>
> I think that the assertion is not necessary even the clear misa.
>

I agree. The specification makes no guarantee that misa writes are not
ignored so it is legal for a processor that supports FD to drop misa writes
and the assertion will trigger on legal RISC-V implementations. That code
piece does not support legal RISC-V implementations that can't disable F
and D. Disabling F and D should not be asserted because it is harmless if
an unused extension is present.

This assertion will always trigger in QEMU until we support the 'optional'
feature to allow changes to 'misa'.

Just noting this is not QEMU specifc so we should drop qemu-devel if we
continue to discuss misa on RISC-V in bbl.

Nevertheless, we do plan to support 'misa' writes however we n

Re: [Qemu-devel] [sw-dev] The problem of write misa on QEMU and BBL

2018-04-19 Thread Michael Clark
On Fri, Apr 20, 2018 at 12:05 PM, Michael Clark  wrote:

>
>
> On Thu, Apr 19, 2018 at 9:28 PM, Zong Li  wrote:
>
>> 2018-04-19 12:43 GMT+08:00 Michael Clark :
>> > Hi Zong,
>> >
>> >> On 19/04/2018, at 2:40 PM, Zong Li  wrote:
>> >>
>> >> Hi all,
>> >>
>> >> For BBL part, in fp_init at machine/minit.c,
>> >> it will clear the D and F bits of misa register, and assertion that
>> >> the bits is cleared.
>> >> But the misa is WARL register, so there is no effect for writing it,
>> >> and the assertion not be true.
>> >> So is there has necessary to do that if toolchain not support D and F
>> extension?
>> >>
>> >> For QEMU part, when writing misa, it will trigger the illegal
>> >> instruction exception, but I think that the WARL allow write behavior?
>> >
>> > QEMU in the riscv-all branch should have WARL behavior.
>> >
>> > - https://github.com/riscv/riscv-qemu/commits/riscv-all
>> >
>> > There is a bug in upstream. We have submitted patches to fix the issue
>> for review on the qemu-devel mailing list. The patch series will be
>> submitted for upstream review again shortly. We were holding off on the
>> series as we didn’t classify it as a “critical bug” as QEMU was in
>> soft-freeze for 2.12 and we weren’t able to get review in time to include
>> this fix in the 2.12 release.
>> >
>> > See “No traps on writes to misa,minstret,mcycle"
>> >
>> > - https://github.com/riscv/riscv-qemu/commits/qemu-2.13-for-upstream
>> >
>> > The history is that there were several unimplemented CSRs that had
>> printf followed by exit. Richard Henderson said we should fix this. I
>> changed several CSRs to cause illegal instruction traps instead of calling
>> exit. That was a mistake as CSRs that don’t support write are WARL (Write
>> Any Read Legal). It was certainly better than having the simulation exit as
>> a cpu doesn’t typically have a way to ”exit” like a C program, nevertheless
>> trapping was wrong. My mistake. See here for the history:
>> >
>> > - https://github.com/riscv/riscv-qemu/blob/ff36f2f77ec3e6a6211
>> c63bfe1707ec057b12f7d/target-riscv/op_helper.c
>> >
>> > The implementation in the current tree is quite different. We have
>> recently made the CSR system more modular so that with minor changes,
>> custom CPUs will be able to hook their own control and status registers.
>> >
>> > - https://github.com/riscv/riscv-qemu/blob/qemu-2.13-for-upstr
>> eam/target/riscv/csr.c#L780-L867
>> >
>> > See these changes:
>> >
>> > - https://github.com/riscv/riscv-qemu/commit/9d9c1bfef911c520a
>> 35bd3f8c0ed2e14cc96bbb7
>> > - https://github.com/riscv/riscv-qemu/commit/b5a4cd79ce6c7fbb6
>> 5fdcf078fb9a8391da1d6b1
>> >
>> > We know have a flexible system that will allow implementations to hook
>> per-cpu control and status registers, and we have predicates that make CSRs
>> appear on some processor but not on others. i.e. if misa.S is not present,
>> then S-mode s* CSRs will trap. Sometimes WARL is the correct behaviour, but
>> sometimes trapping is the correct behaviour i.e. if the processor does not
>> implement S-mode.
>> >
>> > misa traps on write should only affect bootloaders as Supervisor’s like
>> Linux don’t yet have access to the isa register. It’s not a major issuse.
>> >
>> > Michael.
>>
>> Hi Michael,
>>
>> Thanks for the information. The new CSR system is helpful for custom
>> CPU such as ours. Thanks.
>>
>> In the future, maybe we can do something like this in BBL for flexible
>> custom platform which has own device to control the timer, ipi and so
>> on.
>>
>> Back to the misa problem in BBL, at fp_init in BBL initial phrase, the
>> assertion will has problem because the bits of misa will not be
>> cleared.
>>
>> the code piece like below:
>> uintptr_t fd_mask = (1 << ('F' - 'A')) | (1 << ('D' - 'A'));
>> clear_csr(misa, fd_mask);
>> assert(!(read_csr(misa) & fd_mask));
>>
>> I think that the assertion is not necessary even the clear misa.
>>
>
> I agree. The specification makes no guarantee that misa writes are not
> ignored so it is legal for a processor that supports FD to drop misa writes
> and the assertion will trigger on legal RISC-V implementations. That code
> piece does not support leg

Re: [Qemu-devel] [sw-dev] The problem of write misa on QEMU and BBL

2018-04-19 Thread Michael Clark
On Fri, Apr 20, 2018 at 12:12 PM, Andrew Waterman  wrote:

>
>
> On Thu, Apr 19, 2018 at 5:11 PM, Michael Clark  wrote:
>
>>
>>
>> On Fri, Apr 20, 2018 at 12:05 PM, Michael Clark  wrote:
>>
>>>
>>>
>>> On Thu, Apr 19, 2018 at 9:28 PM, Zong Li  wrote:
>>>
>>>> 2018-04-19 12:43 GMT+08:00 Michael Clark :
>>>> > Hi Zong,
>>>> >
>>>> >> On 19/04/2018, at 2:40 PM, Zong Li  wrote:
>>>> >>
>>>> >> Hi all,
>>>> >>
>>>> >> For BBL part, in fp_init at machine/minit.c,
>>>> >> it will clear the D and F bits of misa register, and assertion that
>>>> >> the bits is cleared.
>>>> >> But the misa is WARL register, so there is no effect for writing it,
>>>> >> and the assertion not be true.
>>>> >> So is there has necessary to do that if toolchain not support D and
>>>> F extension?
>>>> >>
>>>> >> For QEMU part, when writing misa, it will trigger the illegal
>>>> >> instruction exception, but I think that the WARL allow write
>>>> behavior?
>>>> >
>>>> > QEMU in the riscv-all branch should have WARL behavior.
>>>> >
>>>> > - https://github.com/riscv/riscv-qemu/commits/riscv-all
>>>> >
>>>> > There is a bug in upstream. We have submitted patches to fix the
>>>> issue for review on the qemu-devel mailing list. The patch series will be
>>>> submitted for upstream review again shortly. We were holding off on the
>>>> series as we didn’t classify it as a “critical bug” as QEMU was in
>>>> soft-freeze for 2.12 and we weren’t able to get review in time to include
>>>> this fix in the 2.12 release.
>>>> >
>>>> > See “No traps on writes to misa,minstret,mcycle"
>>>> >
>>>> > - https://github.com/riscv/riscv-qemu/commits/qemu-2.13-for-upstream
>>>> >
>>>> > The history is that there were several unimplemented CSRs that had
>>>> printf followed by exit. Richard Henderson said we should fix this. I
>>>> changed several CSRs to cause illegal instruction traps instead of calling
>>>> exit. That was a mistake as CSRs that don’t support write are WARL (Write
>>>> Any Read Legal). It was certainly better than having the simulation exit as
>>>> a cpu doesn’t typically have a way to ”exit” like a C program, nevertheless
>>>> trapping was wrong. My mistake. See here for the history:
>>>> >
>>>> > - https://github.com/riscv/riscv-qemu/blob/ff36f2f77ec3e6a6211
>>>> c63bfe1707ec057b12f7d/target-riscv/op_helper.c
>>>> >
>>>> > The implementation in the current tree is quite different. We have
>>>> recently made the CSR system more modular so that with minor changes,
>>>> custom CPUs will be able to hook their own control and status registers.
>>>> >
>>>> > - https://github.com/riscv/riscv-qemu/blob/qemu-2.13-for-upstr
>>>> eam/target/riscv/csr.c#L780-L867
>>>> >
>>>> > See these changes:
>>>> >
>>>> > - https://github.com/riscv/riscv-qemu/commit/9d9c1bfef911c520a
>>>> 35bd3f8c0ed2e14cc96bbb7
>>>> > - https://github.com/riscv/riscv-qemu/commit/b5a4cd79ce6c7fbb6
>>>> 5fdcf078fb9a8391da1d6b1
>>>> >
>>>> > We know have a flexible system that will allow implementations to
>>>> hook per-cpu control and status registers, and we have predicates that make
>>>> CSRs appear on some processor but not on others. i.e. if misa.S is not
>>>> present, then S-mode s* CSRs will trap. Sometimes WARL is the correct
>>>> behaviour, but sometimes trapping is the correct behaviour i.e. if the
>>>> processor does not implement S-mode.
>>>> >
>>>> > misa traps on write should only affect bootloaders as Supervisor’s
>>>> like Linux don’t yet have access to the isa register. It’s not a major
>>>> issuse.
>>>> >
>>>> > Michael.
>>>>
>>>> Hi Michael,
>>>>
>>>> Thanks for the information. The new CSR system is helpful for custom
>>>> CPU such as ours. Thanks.
>>>>
>>>> In the future, maybe we can do something like this in BBL for flexible
>>>> custom platform which has own device to control the timer,

Re: [Qemu-devel] [PATCH v1 2/2] riscv: htif: increase the priority of the htif subregion

2018-04-19 Thread Michael Clark
On Wed, Apr 18, 2018 at 10:16 PM, KONRAD Frederic <
frederic.kon...@adacore.com> wrote:

> The htif device is supposed to be mapped over an other subregion. So
> increase
> its priority to one to avoid any conflict.
>
> Here is the output of info mtree:
>
> Before:
> (qemu) info mtree
>  address-space: memory
>- (prio 0, i/o): system
>  -000f (prio 0, i/o): riscv.htif.uart
>  -00011fff (prio 0, ram): riscv.spike.bootrom
>  0200-0200 (prio 0, i/o): riscv.sifive.clint
>  8000-87ff (prio 0, ram): riscv.spike.ram
>
>  address-space: I/O
>- (prio 0, i/o): io
>
>  address-space: cpu-memory-0
>- (prio 0, i/o): system
>  -000f (prio 0, i/o): riscv.htif.uart
>  -00011fff (prio 0, ram): riscv.spike.bootrom
>  0200-0200 (prio 0, i/o): riscv.sifive.clint
>  8000-87ff (prio 0, ram): riscv.spike.ram
>
> After:
>  (qemu) info mtree
>  address-space: memory
>- (prio 0, i/o): system
>  -000f (prio 1, i/o): riscv.htif.uart
>  -00011fff (prio 0, ram): riscv.spike.bootrom
>  0200-0200 (prio 0, i/o): riscv.sifive.clint
>  8000-87ff (prio 0, ram): riscv.spike.ram
>
>  address-space: I/O
>- (prio 0, i/o): io
>
>  address-space: cpu-memory-0
>- (prio 0, i/o): system
>  -000f (prio 1, i/o): riscv.htif.uart
>  -00011fff (prio 0, ram): riscv.spike.bootrom
>  0200-0200 (prio 0, i/o): riscv.sifive.clint
>  8000-87ff (prio 0, ram): riscv.spike.ram
>
> Signed-off-by: KONRAD Frederic 
>

Reviewed-by: Michael Clark 

BTW if you like I can incorporate these into the riscv tree. e.g. here,
feel free to make a PR in GitHub:

https://github.com/riscv/riscv-qemu/tree/qemu-2.13-for-upstream

(however the riscv.org tree has a lot of changes in it so you might be
better off getting these changes merged in upstream as the review backlog
is large)

It's just that i'd like to keep the trees in sync with upstream while at
the same time incorporating as many fixes as I can in the riscv tree
(before they are in upstream) so that the riscv tree is complete for users
who want to pull a branch that includes the outstanding riscv fixes. I have
scripts that can merge mutliple branches into 'riscv-all' in the riscv
github so if you make a PR against the riscv github I can merge them in
that tree, and drop them if they get accepted upstream independently. I'm
pulling from master frequently so its fine either way.

Just i'd like the riscv tree to accumulate all of the fixes that haven't
yet made it upstream.

---
>  hw/riscv/riscv_htif.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/hw/riscv/riscv_htif.c b/hw/riscv/riscv_htif.c
> index 6e687f2..48e5452 100644
> --- a/hw/riscv/riscv_htif.c
> +++ b/hw/riscv/riscv_htif.c
> @@ -253,8 +253,9 @@ HTIFState *htif_mm_init(MemoryRegion *address_space,
> MemoryRegion *main_mem,
>  htif_be_change, s, NULL, true);
>  if (address_symbol_set) {
>  memory_region_init_io(&s->mmio, NULL, &htif_mm_ops, s,
> -TYPE_HTIF_UART, size);
> -memory_region_add_subregion(address_space, base, &s->mmio);
> +  TYPE_HTIF_UART, size);
> +memory_region_add_subregion_overlap(address_space, base,
> +&s->mmio, 1);
>  }
>
>  return s;
> --
> 1.8.3.1
>
>


Re: [Qemu-devel] [PATCH v1 06/21] RISC-V FPU Support

2018-01-23 Thread Michael Clark
On Wed, Jan 3, 2018 at 12:10 PM, Richard Henderson <
richard.hender...@linaro.org> wrote:

> On 01/02/2018 04:44 PM, Michael Clark wrote:
> > +/* convert RISC-V rounding mode to IEEE library numbers */
> > +unsigned int ieee_rm[] = {
>
> static const.


Done.

> +/* obtain rm value to use in computation
> > + * as the last step, convert rm codes to what the softfloat library
> expects
> > + * Adapted from Spike's decode.h:RM
> > + */
> > +#define RM ({ \
> > +if (rm == 7) {\
> > +rm = env->frm;   \
> > +} \
> > +if (rm > 4) { \
> > +helper_raise_exception(env, RISCV_EXCP_ILLEGAL_INST); \
> > +} \
> > +ieee_rm[rm]; })
>
> Please use inline functions and not these macros.
>

Done.

In fact the previous code would, with normal control flow, dereference
ieee_rm[rm] with an out of bounds round mode so assuming
helper_raise_exception does a longjmp, i've inserted g_assert_not_reached()
after the exception. An analyser could detect that ieee_rm has an out of
bounds access assuming normal control flow. e.g.

static inline void set_fp_round_mode(CPURISCVState *env, uint64_t rm)
{
if (rm == 7) {
rm = env->frm;
} else if (rm > 4) {
helper_raise_exception(env, RISCV_EXCP_ILLEGAL_INST);
g_assert_not_reached();
}
set_float_rounding_mode(ieee_rm[rm], &env->fp_status);
}



> Probably this applies to some of the helpers that I've already reviewed,
> but
> you're going to need to use an exception raising function that also
> performs an
> unwind (usually via cpu_loop_exit_restore).  The GETPC() that feeds the
> unwind
> must be placed in the outer-most helper (including inlines).
>
> > +#ifndef CONFIG_USER_ONLY
> > +#define require_fp if (!(env->mstatus & MSTATUS_FS)) { \
> > +helper_raise_exception(env, RISCV_EXCP_ILLEGAL_INST); \
> > +}
>
> If you included MSTATUS_FS in cpu_get_tb_cpu_state flags, then you could be
> checking for this at translation time instead of at run time.


I'll keep a note of this but I might attempt this later. We have some other
changes in this area with repsect to cpu_mmu_index.

Are translations not implicitly indexed by cpu_mmu_index? i.e. do we also
need to add cpu_mmu_index to cpu_get_tb_cpu_state flags to prevent code
translated for one value of mmu_index running in code with another value of
mmu_index (in the case of riscv, we currently return processor mode /
privilege level in cpu_mmu_index).


> > +/* convert softfloat library flag numbers to RISC-V */
> > +unsigned int softfloat_flags_to_riscv(unsigned int flags)
> > +{
> > +int rv_flags = 0;
> > +rv_flags |= (flags & float_flag_inexact) ? 1 : 0;
> > +rv_flags |= (flags & float_flag_underflow) ? 2 : 0;
> > +rv_flags |= (flags & float_flag_overflow) ? 4 : 0;
> > +rv_flags |= (flags & float_flag_divbyzero) ? 8 : 0;
> > +rv_flags |= (flags & float_flag_invalid) ? 16 : 0;
>
> FPEXC_NX et al.
>
> > +/* adapted from Spike's decode.h:set_fp_exceptions */
> > +#define set_fp_exceptions() do { \
> > +env->fflags |= softfloat_flags_to_riscv(get_float_exception_flags(\
> > +&env->fp_status)); \
> > +set_float_exception_flags(0, &env->fp_status); \
> > +} while (0)
>
> inline function.  Usually written as
>
>   int flags = get_float_exception_flags(&env->fp_status);
>   if (flags) {
> set_float_exception_flags(0, &env->fp_status);
> env->fflags |= softfloat_flags_to_riscv(flags);
>   }
>
> since we really do expect exceptions to be exceptional.


Done.

> +uint64_t helper_fmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2,
> > +uint64_t frs3, uint64_t rm)
> > +{
> > +require_fp;
> > +set_float_rounding_mode(RM, &env->fp_status);
> > +frs1 = float32_muladd(frs1, frs2, frs3 ^ (uint32_t)INT32_MIN, 0,
> > +  &env->fp_status);
>
> Given that RISC-V always returns a default NaN, you obviously do not care
> about
> the sign of a NaN result.  Therefore you should use float_muladd_negate_c
> as
> the fourth argument here and not perform the sign flip manually.


Now working on feedback from here on...

Here is the WIP changelog for the v4 spin...

v4

- Move code to set round mode into set_fp_round_mode function
- Convert set_fp_exception

Re: [Qemu-devel] [PATCH v1 06/21] RISC-V FPU Support

2018-01-23 Thread Michael Clark
On Wed, Jan 3, 2018 at 12:10 PM, Richard Henderson <
richard.hender...@linaro.org> wrote:

> On 01/02/2018 04:44 PM, Michael Clark wrote:
> > +/* convert RISC-V rounding mode to IEEE library numbers */
> > +unsigned int ieee_rm[] = {
>
> static const.
>
> > +/* obtain rm value to use in computation
> > + * as the last step, convert rm codes to what the softfloat library
> expects
> > + * Adapted from Spike's decode.h:RM
> > + */
> > +#define RM ({ \
> > +if (rm == 7) {\
> > +rm = env->frm;   \
> > +} \
> > +if (rm > 4) { \
> > +helper_raise_exception(env, RISCV_EXCP_ILLEGAL_INST); \
> > +} \
> > +ieee_rm[rm]; })
>
> Please use inline functions and not these macros.
>
> Probably this applies to some of the helpers that I've already reviewed,
> but
> you're going to need to use an exception raising function that also
> performs an
> unwind (usually via cpu_loop_exit_restore).  The GETPC() that feeds the
> unwind
> must be placed in the outer-most helper (including inlines).
>
> > +#ifndef CONFIG_USER_ONLY
> > +#define require_fp if (!(env->mstatus & MSTATUS_FS)) { \
> > +helper_raise_exception(env, RISCV_EXCP_ILLEGAL_INST); \
> > +}
>
> If you included MSTATUS_FS in cpu_get_tb_cpu_state flags, then you could be
> checking for this at translation time instead of at run time.
>
> > +/* convert softfloat library flag numbers to RISC-V */
> > +unsigned int softfloat_flags_to_riscv(unsigned int flags)
> > +{
> > +int rv_flags = 0;
> > +rv_flags |= (flags & float_flag_inexact) ? 1 : 0;
> > +rv_flags |= (flags & float_flag_underflow) ? 2 : 0;
> > +rv_flags |= (flags & float_flag_overflow) ? 4 : 0;
> > +rv_flags |= (flags & float_flag_divbyzero) ? 8 : 0;
> > +rv_flags |= (flags & float_flag_invalid) ? 16 : 0;
>
> FPEXC_NX et al.
>
> > +/* adapted from Spike's decode.h:set_fp_exceptions */
> > +#define set_fp_exceptions() do { \
> > +env->fflags |= softfloat_flags_to_riscv(get_float_exception_flags(\
> > +&env->fp_status)); \
> > +set_float_exception_flags(0, &env->fp_status); \
> > +} while (0)
>
> inline function.  Usually written as
>
>   int flags = get_float_exception_flags(&env->fp_status);
>   if (flags) {
> set_float_exception_flags(0, &env->fp_status);
> env->fflags |= softfloat_flags_to_riscv(flags);
>   }
>
> since we really do expect exceptions to be exceptional.
>
> > +uint64_t helper_fmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t
> frs2,
> > +uint64_t frs3, uint64_t rm)
> > +{
> > +require_fp;
> > +set_float_rounding_mode(RM, &env->fp_status);
> > +frs1 = float32_muladd(frs1, frs2, frs3 ^ (uint32_t)INT32_MIN, 0,
> > +  &env->fp_status);
>
> Given that RISC-V always returns a default NaN, you obviously do not care
> about
> the sign of a NaN result.  Therefore you should use float_muladd_negate_c
> as
> the fourth argument here and not perform the sign flip manually.


We do care about the sign of NaN results.

Jim Wilson spotted this bug and removed a call to set_default_nan_mode

https://github.com/riscv/riscv-qemu/commit/4223d89b0c5c671332d66bcd649db5c6f46559f5


> > +uint64_t helper_fnmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t
> frs2,
> > + uint64_t frs3, uint64_t rm)
> > +{
> > +require_fp;
> > +set_float_rounding_mode(RM, &env->fp_status);
> > +frs1 = float32_muladd(frs1 ^ (uint32_t)INT32_MIN, frs2, frs3, 0,
> > +  &env->fp_status);
>
> float_muladd_negate_product.
>
> > +uint64_t helper_fnmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t
> frs2,
> > + uint64_t frs3, uint64_t rm)
> > +{
> > +require_fp;
> > +set_float_rounding_mode(RM, &env->fp_status);
> > +frs1 = float32_muladd(frs1 ^ (uint32_t)INT32_MIN, frs2,
> > +  frs3 ^ (uint32_t)INT32_MIN, 0,
> &env->fp_status);
>
> float_muladd_negate_c | float_muladd_negate_product
>
> > +uint64_t helper_fmin_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2)
> > +{
> > +require_fp;
> &g

Re: [Qemu-devel] [PATCH v1 06/21] RISC-V FPU Support

2018-01-23 Thread Michael Clark
On Tue, Jan 23, 2018 at 3:15 PM, Michael Clark  wrote:

>
>
> On Wed, Jan 3, 2018 at 12:10 PM, Richard Henderson <
> richard.hender...@linaro.org> wrote:
>
>> On 01/02/2018 04:44 PM, Michael Clark wrote:
>> > +/* convert RISC-V rounding mode to IEEE library numbers */
>> > +unsigned int ieee_rm[] = {
>>
>> static const.
>>
>> > +/* obtain rm value to use in computation
>> > + * as the last step, convert rm codes to what the softfloat library
>> expects
>> > + * Adapted from Spike's decode.h:RM
>> > + */
>> > +#define RM ({ \
>> > +if (rm == 7) {\
>> > +rm = env->frm;   \
>> > +} \
>> > +if (rm > 4) { \
>> > +helper_raise_exception(env, RISCV_EXCP_ILLEGAL_INST); \
>> > +} \
>> > +ieee_rm[rm]; })
>>
>> Please use inline functions and not these macros.
>>
>> Probably this applies to some of the helpers that I've already reviewed,
>> but
>> you're going to need to use an exception raising function that also
>> performs an
>> unwind (usually via cpu_loop_exit_restore).  The GETPC() that feeds the
>> unwind
>> must be placed in the outer-most helper (including inlines).
>>
>> > +#ifndef CONFIG_USER_ONLY
>> > +#define require_fp if (!(env->mstatus & MSTATUS_FS)) { \
>> > +helper_raise_exception(env, RISCV_EXCP_ILLEGAL_INST); \
>> > +}
>>
>> If you included MSTATUS_FS in cpu_get_tb_cpu_state flags, then you could
>> be
>> checking for this at translation time instead of at run time.
>>
>> > +/* convert softfloat library flag numbers to RISC-V */
>> > +unsigned int softfloat_flags_to_riscv(unsigned int flags)
>> > +{
>> > +int rv_flags = 0;
>> > +rv_flags |= (flags & float_flag_inexact) ? 1 : 0;
>> > +rv_flags |= (flags & float_flag_underflow) ? 2 : 0;
>> > +rv_flags |= (flags & float_flag_overflow) ? 4 : 0;
>> > +rv_flags |= (flags & float_flag_divbyzero) ? 8 : 0;
>> > +rv_flags |= (flags & float_flag_invalid) ? 16 : 0;
>>
>> FPEXC_NX et al.
>>
>> > +/* adapted from Spike's decode.h:set_fp_exceptions */
>> > +#define set_fp_exceptions() do { \
>> > +env->fflags |= softfloat_flags_to_riscv(get_f
>> loat_exception_flags(\
>> > +&env->fp_status)); \
>> > +set_float_exception_flags(0, &env->fp_status); \
>> > +} while (0)
>>
>> inline function.  Usually written as
>>
>>   int flags = get_float_exception_flags(&env->fp_status);
>>   if (flags) {
>> set_float_exception_flags(0, &env->fp_status);
>> env->fflags |= softfloat_flags_to_riscv(flags);
>>   }
>>
>> since we really do expect exceptions to be exceptional.
>>
>> > +uint64_t helper_fmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t
>> frs2,
>> > +uint64_t frs3, uint64_t rm)
>> > +{
>> > +require_fp;
>> > +set_float_rounding_mode(RM, &env->fp_status);
>> > +frs1 = float32_muladd(frs1, frs2, frs3 ^ (uint32_t)INT32_MIN, 0,
>> > +  &env->fp_status);
>>
>> Given that RISC-V always returns a default NaN, you obviously do not care
>> about
>> the sign of a NaN result.  Therefore you should use float_muladd_negate_c
>> as
>> the fourth argument here and not perform the sign flip manually.
>
>
> We do care about the sign of NaN results.
>
> Jim Wilson spotted this bug and removed a call to set_default_nan_mode
>
> https://github.com/riscv/riscv-qemu/commit/4223d89b0c5c671332d66bcd649db5
> c6f46559f5
>
>
>> > +uint64_t helper_fnmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t
>> frs2,
>> > + uint64_t frs3, uint64_t rm)
>> > +{
>> > +require_fp;
>> > +set_float_rounding_mode(RM, &env->fp_status);
>> > +frs1 = float32_muladd(frs1 ^ (uint32_t)INT32_MIN, frs2, frs3, 0,
>> > +  &env->fp_status);
>>
>> float_muladd_negate_product.
>>
>> > +uint64_t helper_fnmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t
>> frs2,
>> > +

Re: [Qemu-devel] [PATCH v1 06/21] RISC-V FPU Support

2018-01-23 Thread Michael Clark
On Tue, Jan 23, 2018 at 4:01 PM, Richard Henderson <
richard.hender...@linaro.org> wrote:

> On 01/23/2018 01:37 PM, Michael Clark wrote:
> >
> >
> > On Wed, Jan 3, 2018 at 12:10 PM, Richard Henderson
> > mailto:richard.hender...@linaro.org>>
> wrote:
> >
> > On 01/02/2018 04:44 PM, Michael Clark wrote:
> > > +/* convert RISC-V rounding mode to IEEE library numbers */
> > > +unsigned int ieee_rm[] = {
> >
> > static const.
> >
> >
> > Done.
> >
> > > +/* obtain rm value to use in computation
> > > + * as the last step, convert rm codes to what the softfloat
> library expects
> > > + * Adapted from Spike's decode.h:RM
> > > + */
> > > +#define RM ({ \
> > > +if (rm == 7) {\
> > > +rm = env->frm;   \
> > > +} \
> > > +if (rm > 4) { \
> > > +helper_raise_exception(env, RISCV_EXCP_ILLEGAL_INST); \
> > > +} \
> > > +ieee_rm[rm]; })
> >
> > Please use inline functions and not these macros.
> >
> >
> > Done.
> >
> > In fact the previous code would, with normal control flow, dereference
> > ieee_rm[rm] with an out of bounds round mode so assuming
> helper_raise_exception
> > does a longjmp, i've inserted g_assert_not_reached() after the
> exception. An
> > analyser could detect that ieee_rm has an out of bounds access assuming
> normal
> > control flow. e.g.
> >
> > static inline void set_fp_round_mode(CPURISCVState *env, uint64_t rm)
> > {
> > if (rm == 7) {
> > rm = env->frm;
> > } else if (rm > 4) {
> > helper_raise_exception(env, RISCV_EXCP_ILLEGAL_INST);
> > g_assert_not_reached();
>
> Yes, raise_exception exits via longjmp.  This is a good change.
>
> > Are translations not implicitly indexed by cpu_mmu_index? i.e. do we
> also need
> > to add cpu_mmu_index to cpu_get_tb_cpu_state flags to prevent code
> translated
> > for one value of mmu_index running in code with another value of
> mmu_index (in
> > the case of riscv, we currently return processor mode / privilege level
> in
> > cpu_mmu_index).
>
> No, there is no implicit indexing.  That's why I've mentioned exactly this
> at
> least twice in review so far.
>
> There are two ways to do this correctly.  One is to add all the bits that
> specify processor state (e.g. Alpha stores pal_code bit and supervisor
> bit).
> Another is to actually encode the mmu_idx into the flags (e.g. ARM).


I reviewed Stefan's patches. Stefan has some code that encoded processor
flags in mmu_index however it removed some well-tested code paths and I was
hesitant to make such a large change to get_physical_address at this point
in time. I read Stefan's code and used some fragments from it but was
relatively cautious with regard to changing relatively well tested code
paths. I tried to make the most minimal change for the sake of correctness.

For the meantime we've greatly simplified cpu_mmu_index to just return the
processor mode as well as adding the processor mode to cpu_get_tb_cpu_state
flags. cpu_mmu_index previously returned a permutation of env->priv
(containing processer mode), mstatus.MPP (previous mode) and mstatus.MPRV.
When MPRV is set, M mode loads and stores operate as per the mode in
mstatus.MPP and the previous cpu_mmu_index function returned the mode the
processor should do loads and stores as, not the current mode. This is
problematic as mstatus.MPRV can be altered from user code via register
values so there was a potential to re-enter a pre-existing trace with a
different mmu_index. I believe we have eliminated that issue.

These two changes should fix the issue and we've performed testing with
these patches:

-
https://github.com/michaeljclark/riscv-qemu/commit/82012aef90e5c4500f926523b3b2ff621b0cd512
-
https://github.com/michaeljclark/riscv-qemu/commit/abdb897a4a607d00cfce577ac37ca6119004658f

There is a possibility to further improve this code and potentially avoid
TLB flushes, by encoding more state in cpu_mmu_index
and cpu_get_tb_cpu_state flags. I would say that mstatus.SUM flag is
altered frequently in Linux's copy_to/from_user and is likely to result in
decent performance improvement if we can eliminate the TLB flush when the
SUM bit is changed (it is in concept similar to SMAP on x86). mstatus.MPRV
is use

Re: [Qemu-devel] [PATCH v1 06/21] RISC-V FPU Support

2018-01-24 Thread Michael Clark
On Wed, Jan 24, 2018 at 8:16 AM, Richard Henderson <
richard.hender...@linaro.org> wrote:

> On 01/23/2018 05:31 PM, Michael Clark wrote:
> > For the meantime we've greatly simplified cpu_mmu_index to just return
> the
> > processor mode as well as adding the processor mode to
> cpu_get_tb_cpu_state
> > flags. cpu_mmu_index previously returned a permutation of env->priv
> (containing
> > processer mode), mstatus.MPP (previous mode) and mstatus.MPRV. When MPRV
> is
> > set, M mode loads and stores operate as per the mode in mstatus.MPP and
> the
> > previous cpu_mmu_index function returned the mode the processor should
> do loads
> > and stores as, not the current mode. This is problematic as mstatus.MPRV
> can be
> > altered from user code via register values so there was a potential to
> re-enter
> > a pre-existing trace with a different mmu_index. I believe we have
> eliminated
> > that issue.
> >
> > These two changes should fix the issue and we've performed testing with
> these
> > patches:
> >
> > -
> > https://github.com/michaeljclark/riscv-qemu/commit/
> 82012aef90e5c4500f926523b3b2ff621b0cd512
> > - https://github.com/michaeljclark/riscv-qemu/commit/
> abdb897a4a607d00cfce577ac37ca6119004658f
>
>
> I had been concerned, because solely within the context of these patches I
> didn't see the additional flushing being added.  However, on checking out
> the
> branch I see that they are all there on changing mstatus.
>
> No need for it immediately, but as an incremental improvement you can use
> targeted flushing.  E.g. when only MPRV changes, only PRV_M's mmu_idx is
> invalidated; PRV_S and PRV_U are unaffected.  For this, use
> tlb_flush_by_mmuidx.


Right. I saw those APIs. I experimented with a patch that did this but
didn't see a noticeable performance improvement so didn't pursue it.


> > During the process, we also found some bugs in the accessed/dirty bit
> handling
> > in get_physical_address. i.e. when the accessed/dirty bits don't change,
> we now
> > elide the store. This allows various use cases such as PTE entries in
> ROM. We
> > coalesced some of the flag setting in get_physical_address based on
> Stefan's
> > patch (PAGE_READ+PAGE_EXEC) which likely reduces the number of TLB
> misses, but
> > we don't set PAGE_WRITE unless the access_type is MMU_DATA_STORE. The
> previous
> > code would only set the TLB prot flag for the specific access type. We
> set
> > PAGE_READ+PAGE_EXEC based on the PTE flags for load and fetch but we
> don't set
> > PAGE_WRITE on loads or fetches because we want a TLB miss for subsequent
> stores
> > so we don't miss updating the dirty bit if the first access on a RW page
> is a
> > load or fetch. I saw code in i386 that does essentially the same thing.
>
> You should still set PAGE_WRITE for MMU_DATA_LOAD if the dirty bit is
> already
> set.  Consider:
>

Good spotting. I'll fix this case right now...


> Addresses A and B alias in the TLB.  Since our tlb implementation is of
> necessity trivial, an access to B will remove A from the table.  Assuming
> both
> pages are initially dirty, the access sequence
>
> load A
> load B
> store B
>
> will fault 3 times with your code, but only twice if you consider the
> dirty bit
> right away.
>
> > We still need to make PTE updates atomic but given we only have
> multiplexed
> > SMP, it should not be too much of an issue right now.
>
> I'm sure that enabling multi-threading will be high on the list of
> post-merge
> improvements.  There's certainly a lot of bang to be had there.


Agree.


Re: [Qemu-devel] [PATCH v2 03/21] RISC-V CPU Core Definition

2018-01-24 Thread Michael Clark
On Mon, Jan 15, 2018 at 5:44 AM, Igor Mammedov  wrote:

> On Wed, 10 Jan 2018 15:46:22 -0800
> Michael Clark  wrote:
>
> > Add CPU state header, CPU definitions and initialization routines
> >
> > Signed-off-by: Michael Clark 
> > ---
> >  target/riscv/cpu.c  | 391 ++
> +++
> >  target/riscv/cpu.h  | 271 +++
> >  target/riscv/cpu_bits.h | 417 ++
> ++
> >  3 files changed, 1079 insertions(+)
> >  create mode 100644 target/riscv/cpu.c
> >  create mode 100644 target/riscv/cpu.h
> >  create mode 100644 target/riscv/cpu_bits.h
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > new file mode 100644
> > index 000..035dd39
> > --- /dev/null
> > +++ b/target/riscv/cpu.c
> > @@ -0,0 +1,391 @@
> > +/*
> > + * QEMU RISC-V CPU
> > + *
> > + * Author: Sagar Karandikar, sag...@eecs.berkeley.edu
> > + *
> > + * This library is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU Lesser General Public
> > + * License as published by the Free Software Foundation; either
> > + * version 2.1 of the License, or (at your option) any later version.
> > + *
> > + * This library 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.  See the GNU
> > + * Lesser General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU Lesser General Public
> > + * License along with this library; if not, see
> > + * <http://www.gnu.org/licenses/lgpl-2.1.html>
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qemu/log.h"
> > +#include "cpu.h"
> > +#include "exec/exec-all.h"
> > +#include "qapi/error.h"
> > +#include "migration/vmstate.h"
> > +
> > +/* RISC-V CPU definitions */
> > +
> > +const char * const riscv_int_regnames[] = {
> > +  "zero", "ra  ", "sp  ", "gp  ", "tp  ", "t0  ", "t1  ", "t2  ",
> > +  "s0  ", "s1  ", "a0  ", "a1  ", "a2  ", "a3  ", "a4  ", "a5  ",
> > +  "a6  ", "a7  ", "s2  ", "s3  ", "s4  ", "s5  ", "s6  ", "s7  ",
> > +  "s8  ", "s9  ", "s10 ", "s11 ", "t3  ", "t4  ", "t5  ", "t6  "
> > +};
> > +
> > +const char * const riscv_fpr_regnames[] = {
> > +  "ft0 ", "ft1 ", "ft2 ", "ft3 ", "ft4 ", "ft5 ", "ft6 ",  "ft7 ",
> > +  "fs0 ", "fs1 ", "fa0 ", "fa1 ", "fa2 ", "fa3 ", "fa4 ",  "fa5 ",
> > +  "fa6 ", "fa7 ", "fs2 ", "fs3 ", "fs4 ", "fs5 ", "fs6 ",  "fs7 ",
> > +  "fs8 ", "fs9 ", "fs10", "fs11", "ft8 ", "ft9 ", "ft10",  "ft11"
> > +};
> > +
> > +const char * const riscv_excp_names[] = {
> > +"misaligned_fetch",
> > +"fault_fetch",
> > +"illegal_instruction",
> > +"breakpoint",
> > +"misaligned_load",
> > +"fault_load",
> > +"misaligned_store",
> > +"fault_store",
> > +"user_ecall",
> > +"supervisor_ecall",
> > +"hypervisor_ecall",
> > +"machine_ecall",
> > +"exec_page_fault",
> > +"load_page_fault",
> > +"reserved",
> > +"store_page_fault"
> > +};
> > +
> > +const char * const riscv_intr_names[] = {
> > +"u_software",
> > +"s_software",
> > +"h_software",
> > +"m_software",
> > +"u_timer",
> > +"s_timer",
> > +"h_timer",
> > +"m_timer",
> > +"u_external",
> > +"s_external",
> > +"h_external",
> > +"m_external",
> > +"co

[Qemu-devel] [PULL 0/3] RISC-V: QEMU 2.13 Minor Fixes

2018-05-07 Thread Michael Clark
The following changes since commit c8b7e627b4269a3bc3ae41d9f420547a47e6d9b9:

  Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2018-05-04' into 
staging (2018-05-04 14:42:46 +0100)

are available in the git repository at:

  https://github.com/riscv/riscv-qemu.git tags/riscv-qemu-2.13-minor-fixes-1

for you to fetch changes up to d4a63373c0e6349c6f36f56a6290ad639bfa20cb:

  riscv: requires libfdt (2018-05-08 10:57:21 +1200)


RISC-V: QEMU 2.13 Minor Fixes

* Require libfdt when configuring for 'riscv*-softmmu'
* Increase HTIF priority and allow zero address


KONRAD Frederic (3):
  riscv: spike: allow base == 0
  riscv: htif: increase the priority of the htif subregion
  riscv: requires libfdt

 configure |  2 +-
 hw/riscv/riscv_htif.c | 12 
 2 files changed, 9 insertions(+), 5 deletions(-)

-- 
2.7.0




[Qemu-devel] [PULL 2/3] riscv: htif: increase the priority of the htif subregion

2018-05-07 Thread Michael Clark
From: KONRAD Frederic 

The htif device is supposed to be mapped over an other subregion. So increase
its priority to one to avoid any conflict.

Here is the output of info mtree:

Before:
(qemu) info mtree
 address-space: memory
   - (prio 0, i/o): system
 -000f (prio 0, i/o): riscv.htif.uart
 -00011fff (prio 0, ram): riscv.spike.bootrom
 0200-0200 (prio 0, i/o): riscv.sifive.clint
 8000-87ff (prio 0, ram): riscv.spike.ram

 address-space: I/O
   - (prio 0, i/o): io

 address-space: cpu-memory-0
   - (prio 0, i/o): system
 -000f (prio 0, i/o): riscv.htif.uart
 -00011fff (prio 0, ram): riscv.spike.bootrom
 0200-0200 (prio 0, i/o): riscv.sifive.clint
 8000-87ff (prio 0, ram): riscv.spike.ram

After:
 (qemu) info mtree
 address-space: memory
   - (prio 0, i/o): system
 -000f (prio 1, i/o): riscv.htif.uart
 -00011fff (prio 0, ram): riscv.spike.bootrom
 0200-0200 (prio 0, i/o): riscv.sifive.clint
 8000-87ff (prio 0, ram): riscv.spike.ram

 address-space: I/O
   - (prio 0, i/o): io

 address-space: cpu-memory-0
   - (prio 0, i/o): system
 -000f (prio 1, i/o): riscv.htif.uart
 -00011fff (prio 0, ram): riscv.spike.bootrom
 0200-0200 (prio 0, i/o): riscv.sifive.clint
 8000-87ff (prio 0, ram): riscv.spike.ram

Reviewed-by: Michael Clark 
Signed-off-by: KONRAD Frederic 
Message-Id: <1525360636-18229-3-git-send-email-frederic.kon...@adacore.com>
---
 hw/riscv/riscv_htif.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/riscv_htif.c b/hw/riscv/riscv_htif.c
index be252ec8cce9..f73512941fb6 100644
--- a/hw/riscv/riscv_htif.c
+++ b/hw/riscv/riscv_htif.c
@@ -253,8 +253,9 @@ HTIFState *htif_mm_init(MemoryRegion *address_space, 
MemoryRegion *main_mem,
 htif_be_change, s, NULL, true);
 if (address_symbol_set == 3) {
 memory_region_init_io(&s->mmio, NULL, &htif_mm_ops, s,
-TYPE_HTIF_UART, size);
-memory_region_add_subregion(address_space, base, &s->mmio);
+  TYPE_HTIF_UART, size);
+memory_region_add_subregion_overlap(address_space, base,
+&s->mmio, 1);
 }
 
 return s;
-- 
2.7.0




[Qemu-devel] [PULL 1/3] riscv: spike: allow base == 0

2018-05-07 Thread Michael Clark
From: KONRAD Frederic 

The sanity check on base doesn't allow htif to be mapped @0. Check if the
symbol exists instead so we can map it where we want.

Reviewed-by: Michael Clark 
Signed-off-by: KONRAD Frederic 

Message-Id: <1525360636-18229-2-git-send-email-frederic.kon...@adacore.com>
---
 hw/riscv/riscv_htif.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/riscv_htif.c b/hw/riscv/riscv_htif.c
index 3e17f3025106..be252ec8cce9 100644
--- a/hw/riscv/riscv_htif.c
+++ b/hw/riscv/riscv_htif.c
@@ -41,17 +41,20 @@
 } while (0)
 
 static uint64_t fromhost_addr, tohost_addr;
+static int address_symbol_set;
 
 void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value,
-uint64_t st_size)
+  uint64_t st_size)
 {
 if (strcmp("fromhost", st_name) == 0) {
+address_symbol_set |= 1;
 fromhost_addr = st_value;
 if (st_size != 8) {
 error_report("HTIF fromhost must be 8 bytes");
 exit(1);
 }
 } else if (strcmp("tohost", st_name) == 0) {
+address_symbol_set |= 2;
 tohost_addr = st_value;
 if (st_size != 8) {
 error_report("HTIF tohost must be 8 bytes");
@@ -248,7 +251,7 @@ HTIFState *htif_mm_init(MemoryRegion *address_space, 
MemoryRegion *main_mem,
 qemu_chr_fe_init(&s->chr, chr, &error_abort);
 qemu_chr_fe_set_handlers(&s->chr, htif_can_recv, htif_recv, htif_event,
 htif_be_change, s, NULL, true);
-if (base) {
+if (address_symbol_set == 3) {
 memory_region_init_io(&s->mmio, NULL, &htif_mm_ops, s,
 TYPE_HTIF_UART, size);
 memory_region_add_subregion(address_space, base, &s->mmio);
-- 
2.7.0




[Qemu-devel] [PULL 3/3] riscv: requires libfdt

2018-05-07 Thread Michael Clark
From: KONRAD Frederic 

When compiling on a machine without libfdt installed the configure script
should try to get libfdt from the git or should die because otherwise
CONFIG_LIBFDT is not set and the build process end in an error in the link
phase.. eg:

hw/riscv/virt.o: In function `riscv_virt_board_init':
qemu/src/hw/riscv/virt.c:317: undefined reference to `qemu_fdt_setprop_cell'
qemu/src/hw/riscv/virt.c:319: undefined reference to `qemu_fdt_setprop_cell'
qemu/src/hw/riscv/virt.c:345: undefined reference to `qemu_fdt_dumpdtb'
collect2: error: ld returned 1 exit status
make[1]: *** [qemu-system-riscv64] Error 1
make: *** [subdir-riscv64-softmmu] Error 2

Reviewed-by: Bastian Koppelmann 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Michael Clark 
Signed-off-by: KONRAD Frederic 

Message-Id: <1525360636-18229-4-git-send-email-frederic.kon...@adacore.com>
---
 configure | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure b/configure
index 1443422e83f1..479e9a787e6e 100755
--- a/configure
+++ b/configure
@@ -3761,7 +3761,7 @@ fi
 fdt_required=no
 for target in $target_list; do
   case $target in
-
aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-softmmu|mips64el-softmmu)
+
aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-softmmu|mips64el-softmmu|riscv*-softmmu)
   fdt_required=yes
 ;;
   esac
-- 
2.7.0




Re: [Qemu-devel] [PULL 0/3] RISC-V: QEMU 2.13 Minor Fixes

2018-05-08 Thread Michael Clark
On Wed, May 9, 2018 at 4:05 AM, Peter Maydell 
wrote:

> On 8 May 2018 at 00:14, Michael Clark  wrote:
> > The following changes since commit c8b7e627b4269a3bc3ae41d9f42054
> 7a47e6d9b9:
> >
> >   Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2018-05-04'
> into staging (2018-05-04 14:42:46 +0100)
> >
> > are available in the git repository at:
> >
> >   https://github.com/riscv/riscv-qemu.git tags/riscv-qemu-2.13-minor-
> fixes-1
> >
> > for you to fetch changes up to d4a63373c0e6349c6f36f56a6290ad639bfa20cb:
> >
> >   riscv: requires libfdt (2018-05-08 10:57:21 +1200)
> >
> > 
> > RISC-V: QEMU 2.13 Minor Fixes
> >
> > * Require libfdt when configuring for 'riscv*-softmmu'
> > * Increase HTIF priority and allow zero address
> >
> > 
> > KONRAD Frederic (3):
> >   riscv: spike: allow base == 0
> >   riscv: htif: increase the priority of the htif subregion
> >   riscv: requires libfdt
>
> Hi Michael -- these patches from Fred need your Signed-off-by:
> line in the commit messages as well as his. (This indicates that
> they've passed through your hands to get to master; see item 3
> in https://wiki.qemu.org/Contribute/SubmitAPullRequest )
>

I was thinking about that but was not sure. This is my first pull with
changes that originated outside the riscv tree.


> I did a build test and they passed that fine, so if you can just
> respin this pullreq with the signoff lines added to each commit
> message I should be able to apply it.
>

Okay, thanks. I've boot tested Linux kernel in the 'spike' machines. These
changes are very low risk. I'll respin with my "Signed-off-by" added.

The configure libfdt patch is the main one to cherry-pick for 2.12.1,
however, the other changes are innocuous enough if you want to merge the
whole PR to stable, as there are 3 commits. BTW I still need to test 'sifive_u'
in stable 2.12.0 to figure out the changes that need to be cherry-picked or
I can backport changes if necessary.


[Qemu-devel] [PULL 3/3] riscv: requires libfdt

2018-05-08 Thread Michael Clark
From: KONRAD Frederic 

When compiling on a machine without libfdt installed the configure script
should try to get libfdt from the git or should die because otherwise
CONFIG_LIBFDT is not set and the build process end in an error in the link
phase.. eg:

hw/riscv/virt.o: In function `riscv_virt_board_init':
qemu/src/hw/riscv/virt.c:317: undefined reference to `qemu_fdt_setprop_cell'
qemu/src/hw/riscv/virt.c:319: undefined reference to `qemu_fdt_setprop_cell'
qemu/src/hw/riscv/virt.c:345: undefined reference to `qemu_fdt_dumpdtb'
collect2: error: ld returned 1 exit status
make[1]: *** [qemu-system-riscv64] Error 1
make: *** [subdir-riscv64-softmmu] Error 2

Reviewed-by: Bastian Koppelmann 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Michael Clark 
Signed-off-by: KONRAD Frederic 
Signed-off-by: Michael Clark 

Message-Id: <1525360636-18229-4-git-send-email-frederic.kon...@adacore.com>
---
 configure | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure b/configure
index 1443422e83f1..479e9a787e6e 100755
--- a/configure
+++ b/configure
@@ -3761,7 +3761,7 @@ fi
 fdt_required=no
 for target in $target_list; do
   case $target in
-
aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-softmmu|mips64el-softmmu)
+
aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-softmmu|mips64el-softmmu|riscv*-softmmu)
   fdt_required=yes
 ;;
   esac
-- 
2.7.0




[Qemu-devel] [PULL 0/3] RISC-V: QEMU 2.13 Minor Fixes

2018-05-08 Thread Michael Clark
The following changes since commit c8b7e627b4269a3bc3ae41d9f420547a47e6d9b9:

  Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2018-05-04' into 
staging (2018-05-04 14:42:46 +0100)

are available in the git repository at:

  https://github.com/riscv/riscv-qemu.git tags/riscv-qemu-2.13-minor-fixes-2

for you to fetch changes up to fc28db142ea9331d24d08a6418efa93e258a6876:

  riscv: requires libfdt (2018-05-09 07:57:57 +1200)


RISC-V: QEMU 2.13 Minor Fixes

* Require libfdt when configuring for 'riscv*-softmmu'
* Increase HTIF priority and allow zero base address

Consider backporting to stable branch for 2.12.1


KONRAD Frederic (3):
  riscv: spike: allow base == 0
  riscv: htif: increase the priority of the htif subregion
  riscv: requires libfdt

 configure |  2 +-
 hw/riscv/riscv_htif.c | 12 
 2 files changed, 9 insertions(+), 5 deletions(-)

-- 
2.7.0




[Qemu-devel] [PULL 1/3] riscv: spike: allow base == 0

2018-05-08 Thread Michael Clark
From: KONRAD Frederic 

The sanity check on base doesn't allow htif to be mapped @0. Check if the
symbol exists instead so we can map it where we want.

Reviewed-by: Michael Clark 
Signed-off-by: KONRAD Frederic 
Signed-off-by: Michael Clark 

Message-Id: <1525360636-18229-2-git-send-email-frederic.kon...@adacore.com>
---
 hw/riscv/riscv_htif.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/riscv_htif.c b/hw/riscv/riscv_htif.c
index 3e17f3025106..be252ec8cce9 100644
--- a/hw/riscv/riscv_htif.c
+++ b/hw/riscv/riscv_htif.c
@@ -41,17 +41,20 @@
 } while (0)
 
 static uint64_t fromhost_addr, tohost_addr;
+static int address_symbol_set;
 
 void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value,
-uint64_t st_size)
+  uint64_t st_size)
 {
 if (strcmp("fromhost", st_name) == 0) {
+address_symbol_set |= 1;
 fromhost_addr = st_value;
 if (st_size != 8) {
 error_report("HTIF fromhost must be 8 bytes");
 exit(1);
 }
 } else if (strcmp("tohost", st_name) == 0) {
+address_symbol_set |= 2;
 tohost_addr = st_value;
 if (st_size != 8) {
 error_report("HTIF tohost must be 8 bytes");
@@ -248,7 +251,7 @@ HTIFState *htif_mm_init(MemoryRegion *address_space, 
MemoryRegion *main_mem,
 qemu_chr_fe_init(&s->chr, chr, &error_abort);
 qemu_chr_fe_set_handlers(&s->chr, htif_can_recv, htif_recv, htif_event,
 htif_be_change, s, NULL, true);
-if (base) {
+if (address_symbol_set == 3) {
 memory_region_init_io(&s->mmio, NULL, &htif_mm_ops, s,
 TYPE_HTIF_UART, size);
 memory_region_add_subregion(address_space, base, &s->mmio);
-- 
2.7.0




[Qemu-devel] [PULL 2/3] riscv: htif: increase the priority of the htif subregion

2018-05-08 Thread Michael Clark
From: KONRAD Frederic 

The htif device is supposed to be mapped over an other subregion. So increase
its priority to one to avoid any conflict.

Here is the output of info mtree:

Before:
(qemu) info mtree
 address-space: memory
   - (prio 0, i/o): system
 -000f (prio 0, i/o): riscv.htif.uart
 -00011fff (prio 0, ram): riscv.spike.bootrom
 0200-0200 (prio 0, i/o): riscv.sifive.clint
 8000-87ff (prio 0, ram): riscv.spike.ram

 address-space: I/O
   - (prio 0, i/o): io

 address-space: cpu-memory-0
   - (prio 0, i/o): system
 -000f (prio 0, i/o): riscv.htif.uart
 -00011fff (prio 0, ram): riscv.spike.bootrom
 0200-0200 (prio 0, i/o): riscv.sifive.clint
 8000-87ff (prio 0, ram): riscv.spike.ram

After:
 (qemu) info mtree
 address-space: memory
   - (prio 0, i/o): system
 -000f (prio 1, i/o): riscv.htif.uart
 -00011fff (prio 0, ram): riscv.spike.bootrom
 0200-0200 (prio 0, i/o): riscv.sifive.clint
 8000-87ff (prio 0, ram): riscv.spike.ram

 address-space: I/O
   - (prio 0, i/o): io

 address-space: cpu-memory-0
   - (prio 0, i/o): system
 -000f (prio 1, i/o): riscv.htif.uart
 -00011fff (prio 0, ram): riscv.spike.bootrom
 0200-0200 (prio 0, i/o): riscv.sifive.clint
 8000-87ff (prio 0, ram): riscv.spike.ram

Reviewed-by: Michael Clark 
Signed-off-by: KONRAD Frederic 
Signed-off-by: Michael Clark 

Message-Id: <1525360636-18229-3-git-send-email-frederic.kon...@adacore.com>
---
 hw/riscv/riscv_htif.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/riscv_htif.c b/hw/riscv/riscv_htif.c
index be252ec8cce9..f73512941fb6 100644
--- a/hw/riscv/riscv_htif.c
+++ b/hw/riscv/riscv_htif.c
@@ -253,8 +253,9 @@ HTIFState *htif_mm_init(MemoryRegion *address_space, 
MemoryRegion *main_mem,
 htif_be_change, s, NULL, true);
 if (address_symbol_set == 3) {
 memory_region_init_io(&s->mmio, NULL, &htif_mm_ops, s,
-TYPE_HTIF_UART, size);
-memory_region_add_subregion(address_space, base, &s->mmio);
+  TYPE_HTIF_UART, size);
+memory_region_add_subregion_overlap(address_space, base,
+&s->mmio, 1);
 }
 
 return s;
-- 
2.7.0




Re: [Qemu-devel] [PULL 0/3] RISC-V: QEMU 2.13 Minor Fixes

2018-05-08 Thread Michael Clark
On Wed, May 9, 2018 at 8:49 AM, Peter Maydell 
wrote:

> On 8 May 2018 at 21:07, Michael Clark  wrote:
> > The following changes since commit c8b7e627b4269a3bc3ae41d9f42054
> 7a47e6d9b9:
> >
> >   Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2018-05-04'
> into staging (2018-05-04 14:42:46 +0100)
> >
> > are available in the git repository at:
> >
> >   https://github.com/riscv/riscv-qemu.git tags/riscv-qemu-2.13-minor-
> fixes-2
> >
> > for you to fetch changes up to fc28db142ea9331d24d08a6418efa93e258a6876:
> >
> >   riscv: requires libfdt (2018-05-09 07:57:57 +1200)
> >
> > 
> > RISC-V: QEMU 2.13 Minor Fixes
> >
> > * Require libfdt when configuring for 'riscv*-softmmu'
> > * Increase HTIF priority and allow zero base address
> >
> > Consider backporting to stable branch for 2.12.1
>
> Ah, if you want something flagged to be backported to
> the stable branch, the way to do that is to include
> the line "Cc: qemu-sta...@nongnu.org" in the commit
> message. We use the same approach for flagging things
> for stable as the Linux kernel. (Individual submaintainers
> are generally in the best position to decide whether
> something should go into stable, and this system leaves
> that choice up to them. A patch submitter can also suggest
> something for stable when you submit the initial patch for
> review by adding the Cc: line and cc'ing qemu-stable on the
> patchmail.)
>

Okay. Given the 'Cc is missing in the commit (only on the cover) I could
send a separate patch.

Or I can respin with the 'Cc on the configure libfdt dependency fix commit
and remove the backport message from the tag...


Re: [Qemu-devel] [PATCH] RISC-V: Remove unnecessary header include

2018-05-08 Thread Michael Clark
On Wed, May 9, 2018 at 2:42 AM, Philippe Mathieu-Daudé 
wrote:

> Signed-off-by: Philippe Mathieu-Daudé 
>

Reviewed-by: Michael Clark 

---
>  hw/riscv/riscv_htif.c | 1 -
>  hw/riscv/sifive_e.c   | 1 -
>  hw/riscv/sifive_u.c   | 1 -
>  hw/riscv/spike.c  | 1 -
>  hw/riscv/virt.c   | 1 -
>  5 files changed, 5 deletions(-)
>
> diff --git a/hw/riscv/riscv_htif.c b/hw/riscv/riscv_htif.c
> index 3e17f30251..43533f9dc2 100644
> --- a/hw/riscv/riscv_htif.c
> +++ b/hw/riscv/riscv_htif.c
> @@ -29,7 +29,6 @@
>  #include "chardev/char-fe.h"
>  #include "hw/riscv/riscv_htif.h"
>  #include "qemu/timer.h"
> -#include "exec/address-spaces.h"
>  #include "qemu/error-report.h"
>
>  #define RISCV_DEBUG_HTIF 0
> diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
> index e4ecb7aa4b..d3d11e849b 100644
> --- a/hw/riscv/sifive_e.c
> +++ b/hw/riscv/sifive_e.c
> @@ -46,7 +46,6 @@
>  #include "hw/riscv/sifive_e.h"
>  #include "chardev/char.h"
>  #include "sysemu/arch_init.h"
> -#include "exec/address-spaces.h"
>  #include "elf.h"
>
>  static const struct MemmapEntry {
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index c05dcbba95..07f8644695 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -44,7 +44,6 @@
>  #include "chardev/char.h"
>  #include "sysemu/arch_init.h"
>  #include "sysemu/device_tree.h"
> -#include "exec/address-spaces.h"
>  #include "elf.h"
>
>  #include 
> diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
> index f94e2b6707..aecdf296cc 100644
> --- a/hw/riscv/spike.c
> +++ b/hw/riscv/spike.c
> @@ -39,7 +39,6 @@
>  #include "chardev/char.h"
>  #include "sysemu/arch_init.h"
>  #include "sysemu/device_tree.h"
> -#include "exec/address-spaces.h"
>  #include "elf.h"
>
>  #include 
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index ad03113e0f..d967624bcc 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -37,7 +37,6 @@
>  #include "chardev/char.h"
>  #include "sysemu/arch_init.h"
>  #include "sysemu/device_tree.h"
> -#include "exec/address-spaces.h"
>  #include "elf.h"
>
>  #include 
> --
> 2.17.0
>
>


Re: [Qemu-devel] [PULL 00/20] RISC-V: QEMU 2.13 Privileged ISA emulation updates

2018-05-08 Thread Michael Clark
On Wed, May 9, 2018 at 1:22 AM, Peter Maydell 
wrote:

> On 6 May 2018 at 00:35, Michael Clark  wrote:
> > The following changes since commit c8b7e627b4269a3bc3ae41d9f42054
> 7a47e6d9b9:
> >
> >   Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2018-05-04'
> into staging (2018-05-04 14:42:46 +0100)
> >
> > are available in the git repository at:
> >
> >   https://github.com/riscv/riscv-qemu.git tags/riscv-qemu-2.13-pull-
> 20180506
> >
> > for you to fetch changes up to 5aec3247c190f10654250203a1742490ae7343a2:
> >
> >   RISC-V: Mark ROM read-only after copying in code (2018-05-06 10:54:21
> +1200)
> >
> > 
> > RISC-V: QEMU 2.13 Privileged ISA emulation updates
> >
> > Several code cleanups, minor specification conformance changes,
> > fixes to make ROM read-only and add device-tree size checks.
> >
> > * Honour privileged ISA v1.10 counter enable CSRs.
> > * Implements WARL behavior for CSRs that don't support writes
> >   * Past behavior of raising traps was non-conformant
> > with the RISC-V Privileged ISA Specification v1.10.
> > * Allow S-mode access to sstatus.MXR when priv ISA >= v1.10
> > * Sets mtval/stval to zero on exceptions without addresses
> >   * Past behavior of leaving the last value was non-conformant
> > with the RISC-V Privileged ISA Specition v1.10. mtval/stval
> > must be set on all exceptions; to zero if not supported.
> > * Make ROMs read-only and implement device-tree size checks
> >   * Uses memory_region_init_rom and rom_add_blob_fixed_as
> > * Adds hexidecimal instruction bytes to disassembly output.
> > * Fixes missing break statement for rv128 disassembly.
> > * Several code cleanups
> >   * Replacing hard-coded constants with enums
> >   * Dead-code elimination
> >
> > This is an incremental pull that contains 20 reviewed changes out
> > of 38 changes currently queued in the qemu-2.13-for-upstream branch.
> >
>
> Applied, thanks.
>

Thanks!

I didn't include qemu-stable on this series as I simply hadn't spent the
time to locally test the issue with 'sifive_u' that Alastair mentioned.
I've now locally reproduced Alastair's results confirming that the last
commit in this series, namely "RISC-V: Mark ROM read-only after copying in
code", fixes the 'sifive_u' board.

-
https://git.qemu.org/?p=qemu.git;a=commit;h=5aec3247c190f10654250203a1742490ae7343a2

There are however several other usability issues and bugs fixess in this
series that could be considered for 'qemu-stable'.

- "RISC-V: Mark ROM read-only after copying in code" fixes the 'sifive_u'
board issue (bug fix)
- "RISC-V: No traps on writes to misa,minstret,mcycle" fixes a case where
an illegal instruction should not be generated (bug fix - misa write bug
was hit by Andes Technology)
- "RISC-V: Make mtvec/stvec ignore vectored traps" fixes a case where an
illegal instruction should not be generated (bug fix - not hit yet, but
nevertheless is a fix)
- "RISC-V: Use [ms]counteren CSRs when priv ISA >= v1.10" fixes the counter
enable CSRs, so they actually work (bug fix - hit by someone working on
'perf' for riscv-linux)
- "RISC-V: Include instruction hex in disassembly" adds instruction bytes
to disassembly to improbe usability, and was on the list before soft-freeze
(small usability issue)
- "RISC-V: Make virt board description match spike" makes the -help listing
use consistent naming for privileged ISA version (small usability issue)

The rest of the series are the innocuous fixes and code cleanups (replacing
constants with enums, etc) that had been on the list mid-March, with the
exception of "RISC-V: Fix missing break statement in disassembler" which
fixes the rv128 disassembly issue picked up recently by coverity and the
"RISC-V: Add mcycle/minstret support for -icount auto" is a small new
feature.

It would be safe to import the tag as the cleanup commits or I can
selectively backport changes. The issue is the fixes depending on context
of the cleanup commits early in the series. The sifive_u fix: "RISC-V: Mark
ROM read-only after copying in code" depends on diff context from "RISC-V:
Remove identity_translate from load_elf" and "RISC-V: Use ROM base address
and size from memmap" which were both code cleanups.

The question is whether code cleanups can come into qemu-stable (i.e. merge
this tag to stable) or whether we should cherry-pick and solve merge
conflicts to get the minimal set of commits with what we classify as
important fixes or usability issue into qemu-stab

Re: [Qemu-devel] [PATCH 00/10] Avoid integer overflow in next_page_start

2018-05-08 Thread Michael Clark
On Thu, Apr 12, 2018 at 11:56 AM, Richard Henderson <
richard.hender...@linaro.org> wrote:

> On 04/12/2018 01:29 AM, Emilio G. Cota wrote:
> > To ease an eventual merge I'll be updating the patches' R-b tags as
> > they come in this branch:
> >   https://github.com/cota/qemu/tree/next_page_overflow-r-b
> >
> > BTW to avoid conflicts we should merge this before the translator loop
> > conversion series; I'll make that clear when I send a new version
> > of that patch set.
>
> Right-o.  Thanks.  We'll get these in right away once development starts
> again
> so that you don't have to carry it long.


Emilio,

Is this your latest branch for these changes?

- https://github.com/cota/qemu/tree/trloop-conv-v3

I see that this branch has this change "target/riscv: avoid integer
overflow in next_page PC check"

I have some changes for target/riscv/translate.c and was thinking of basing
them on your patches so we don't have conflicts.

Thanks,
Michael


[Qemu-devel] [PATCH v1] RISC-V: Add misa to DisasContext

2018-05-09 Thread Michael Clark
gen methods should access state from DisasContext. Add misa
field to the DisasContext struct and remove CPURISCVState
argument from all gen methods.

Cc: Palmer Dabbelt 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Alistair Francis 
Cc: Emilio G. Cota 
Signed-off-by: Michael Clark 
---
 target/riscv/translate.c | 74 ++--
 1 file changed, 40 insertions(+), 34 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index c0e6a044d383..5b9e5fe343d2 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -44,6 +44,7 @@ typedef struct DisasContext {
 target_ulong next_pc;
 uint32_t opcode;
 uint32_t flags;
+uint32_t misa;
 uint32_t mem_idx;
 int singlestep_enabled;
 int bstate;
@@ -82,6 +83,11 @@ static const int tcg_memop_lookup[8] = {
 #define CASE_OP_32_64(X) case X
 #endif
 
+static inline bool has_ext(DisasContext *ctx, uint32_t ext)
+{
+return ctx->misa & ext;
+}
+
 static void generate_exception(DisasContext *ctx, int excp)
 {
 tcg_gen_movi_tl(cpu_pc, ctx->pc);
@@ -513,14 +519,13 @@ static void gen_arith_imm(DisasContext *ctx, uint32_t 
opc, int rd,
 tcg_temp_free(source1);
 }
 
-static void gen_jal(CPURISCVState *env, DisasContext *ctx, int rd,
-target_ulong imm)
+static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
 {
 target_ulong next_pc;
 
 /* check misaligned: */
 next_pc = ctx->pc + imm;
-if (!riscv_has_ext(env, RVC)) {
+if (!has_ext(ctx, RVC)) {
 if ((next_pc & 0x3) != 0) {
 gen_exception_inst_addr_mis(ctx);
 return;
@@ -534,8 +539,8 @@ static void gen_jal(CPURISCVState *env, DisasContext *ctx, 
int rd,
 ctx->bstate = BS_BRANCH;
 }
 
-static void gen_jalr(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
- int rd, int rs1, target_long imm)
+static void gen_jalr(DisasContext *ctx, uint32_t opc, int rd, int rs1,
+ target_long imm)
 {
 /* no chaining with JALR */
 TCGLabel *misaligned = NULL;
@@ -547,7 +552,7 @@ static void gen_jalr(CPURISCVState *env, DisasContext *ctx, 
uint32_t opc,
 tcg_gen_addi_tl(cpu_pc, cpu_pc, imm);
 tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
 
-if (!riscv_has_ext(env, RVC)) {
+if (!has_ext(ctx, RVC)) {
 misaligned = gen_new_label();
 tcg_gen_andi_tl(t0, cpu_pc, 0x2);
 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
@@ -572,8 +577,8 @@ static void gen_jalr(CPURISCVState *env, DisasContext *ctx, 
uint32_t opc,
 tcg_temp_free(t0);
 }
 
-static void gen_branch(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
-   int rs1, int rs2, target_long bimm)
+static void gen_branch(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
+   target_long bimm)
 {
 TCGLabel *l = gen_new_label();
 TCGv source1, source2;
@@ -610,7 +615,7 @@ static void gen_branch(CPURISCVState *env, DisasContext 
*ctx, uint32_t opc,
 
 gen_goto_tb(ctx, 1, ctx->next_pc);
 gen_set_label(l); /* branch taken */
-if (!riscv_has_ext(env, RVC) && ((ctx->pc + bimm) & 0x3)) {
+if (!has_ext(ctx, RVC) && ((ctx->pc + bimm) & 0x3)) {
 /* misaligned */
 gen_exception_inst_addr_mis(ctx);
 } else {
@@ -1313,8 +1318,8 @@ static void gen_fp_arith(DisasContext *ctx, uint32_t opc, 
int rd,
 }
 }
 
-static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
-  int rd, int rs1, int csr)
+static void gen_system(DisasContext *ctx, uint32_t opc, int rd, int rs1,
+   int csr)
 {
 TCGv source1, csr_store, dest, rs1_pass, imm_rs1;
 source1 = tcg_temp_new();
@@ -1356,7 +1361,7 @@ static void gen_system(CPURISCVState *env, DisasContext 
*ctx, uint32_t opc,
 gen_exception_illegal(ctx);
 break;
 case 0x102: /* SRET */
-if (riscv_has_ext(env, RVS)) {
+if (has_ext(ctx, RVS)) {
 gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
 tcg_gen_exit_tb(0); /* no chaining */
 ctx->bstate = BS_BRANCH;
@@ -1497,7 +1502,7 @@ static void decode_RV32_64C0(DisasContext *ctx)
 }
 }
 
-static void decode_RV32_64C1(CPURISCVState *env, DisasContext *ctx)
+static void decode_RV32_64C1(DisasContext *ctx)
 {
 uint8_t funct3 = extract32(ctx->opcode, 13, 3);
 uint8_t rd_rs1 = GET_C_RS1(ctx->opcode);
@@ -1517,7 +1522,7 @@ static void decode_RV32_64C1(CPURISCVState *env, 
DisasContext *ctx)
   GET_C_IMM(ctx->opcode));
 #else
 /* C.JAL(RV32) -> jal x1, offset[11:1] */
-gen_jal(env, ctx, 1, GET_C_J_IMM(ctx->opcode));
+gen_jal(ctx, 1, GET_C_J_IMM(ctx->opcode));
 #endif
 break;
 case 2:
@@ -1596,22 +1601,22 @@ static void decode_RV3

Re: [Qemu-devel] [PATCH 01/18] translator: merge max_insns into DisasContextBase

2018-05-09 Thread Michael Clark
On Sat, Apr 21, 2018 at 6:55 AM, Emilio G. Cota  wrote:

> While at it, use int for both num_insns and max_insns to make
> sure we have same-type comparisons.
>
> Reviewed-by: Richard Henderson 
> Signed-off-by: Emilio G. Cota 
>

Reviewed-by: Michael Clark 


> ---
>  accel/tcg/translator.c | 21 ++---
>  include/exec/translator.h  |  8 
>  target/alpha/translate.c   |  6 ++
>  target/arm/translate-a64.c |  8 +++-
>  target/arm/translate.c |  9 +++--
>  target/hppa/translate.c|  7 ++-
>  target/i386/translate.c|  5 +
>  target/ppc/translate.c |  5 ++---
>  8 files changed, 27 insertions(+), 42 deletions(-)
>
> diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
> index 23c6602..0f9dca9 100644
> --- a/accel/tcg/translator.c
> +++ b/accel/tcg/translator.c
> @@ -34,8 +34,6 @@ void translator_loop_temp_check(DisasContextBase *db)
>  void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
>   CPUState *cpu, TranslationBlock *tb)
>  {
> -int max_insns;
> -
>  /* Initialize DisasContext */
>  db->tb = tb;
>  db->pc_first = tb->pc;
> @@ -45,18 +43,18 @@ void translator_loop(const TranslatorOps *ops,
> DisasContextBase *db,
>  db->singlestep_enabled = cpu->singlestep_enabled;
>
>  /* Instruction counting */
> -max_insns = tb_cflags(db->tb) & CF_COUNT_MASK;
> -if (max_insns == 0) {
> -max_insns = CF_COUNT_MASK;
> +db->max_insns = tb_cflags(db->tb) & CF_COUNT_MASK;
> +if (db->max_insns == 0) {
> +db->max_insns = CF_COUNT_MASK;
>  }
> -if (max_insns > TCG_MAX_INSNS) {
> -max_insns = TCG_MAX_INSNS;
> +if (db->max_insns > TCG_MAX_INSNS) {
> +db->max_insns = TCG_MAX_INSNS;
>  }
>  if (db->singlestep_enabled || singlestep) {
> -max_insns = 1;
> +db->max_insns = 1;
>  }
>
> -max_insns = ops->init_disas_context(db, cpu, max_insns);
> +ops->init_disas_context(db, cpu);
>  tcg_debug_assert(db->is_jmp == DISAS_NEXT);  /* no early exit */
>
>  /* Reset the temp count so that we can identify leaks */
> @@ -95,7 +93,8 @@ void translator_loop(const TranslatorOps *ops,
> DisasContextBase *db,
> update db->pc_next and db->is_jmp to indicate what should be
> done next -- either exiting this loop or locate the start of
> the next instruction.  */
> -if (db->num_insns == max_insns && (tb_cflags(db->tb) &
> CF_LAST_IO)) {
> +if (db->num_insns == db->max_insns
> +&& (tb_cflags(db->tb) & CF_LAST_IO)) {
>  /* Accept I/O on the last instruction.  */
>  gen_io_start();
>  ops->translate_insn(db, cpu);
> @@ -111,7 +110,7 @@ void translator_loop(const TranslatorOps *ops,
> DisasContextBase *db,
>
>  /* Stop translation if the output buffer is full,
> or we have executed all of the allowed instructions.  */
> -if (tcg_op_buf_full() || db->num_insns >= max_insns) {
> +if (tcg_op_buf_full() || db->num_insns >= db->max_insns) {
>  db->is_jmp = DISAS_TOO_MANY;
>  break;
>  }
> diff --git a/include/exec/translator.h b/include/exec/translator.h
> index e2dc2a0..71e7b2c 100644
> --- a/include/exec/translator.h
> +++ b/include/exec/translator.h
> @@ -58,6 +58,7 @@ typedef enum DisasJumpType {
>   *   disassembly).
>   * @is_jmp: What instruction to disassemble next.
>   * @num_insns: Number of translated instructions (including current).
> + * @max_insns: Maximum number of instructions to be translated in this TB.
>   * @singlestep_enabled: "Hardware" single stepping enabled.
>   *
>   * Architecture-agnostic disassembly context.
> @@ -67,7 +68,8 @@ typedef struct DisasContextBase {
>  target_ulong pc_first;
>  target_ulong pc_next;
>  DisasJumpType is_jmp;
> -unsigned int num_insns;
> +int num_insns;
> +int max_insns;
>  bool singlestep_enabled;
>  } DisasContextBase;
>
> @@ -76,7 +78,6 @@ typedef struct DisasContextBase {
>   * @init_disas_context:
>   *  Initialize the target-specific portions of DisasContext struct.
>   *  The generic DisasContextBase has already been initialized.
> - *  Return max_insns, modified as necessary by db->tb->flags.
>   *
>   * @tb_start:
>   *  Emit any code required before the start of the main loop,
> @@ -106,8 +107,7 @@ typedef struct DisasContextBase {
>   *  Print instruction disassembly to 

Re: [Qemu-devel] [PATCH 18/18] target/riscv: convert to TranslatorOps

2018-05-09 Thread Michael Clark
On Sat, Apr 21, 2018 at 6:55 AM, Emilio G. Cota  wrote:

> Reviewed-by: Richard Henderson 
> Cc: Michael Clark 
> Cc: Palmer Dabbelt 
> Cc: Sagar Karandikar 
> Cc: Bastian Koppelmann 
> Signed-off-by: Emilio G. Cota 
>

Reviewed-by: Michael Clark 


> ---
>  target/riscv/translate.c | 158 --
> -
>  1 file changed, 80 insertions(+), 78 deletions(-)
>
> diff --git a/target/riscv/translate.c b/target/riscv/translate.c
> index 18ec1a7..fc9c659 100644
> --- a/target/riscv/translate.c
> +++ b/target/riscv/translate.c
> @@ -1836,78 +1836,71 @@ static void decode_opc(CPURISCVState *env,
> DisasContext *ctx)
>  }
>  }
>
> -void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
> +static void riscv_tr_init_disas_context(DisasContextBase *dcbase,
> CPUState *cs)
>  {
> -CPURISCVState *env = cs->env_ptr;
> -DisasContext ctx;
> -target_ulong page_start;
> -int num_insns;
> -int max_insns;
> -
> -ctx.base.pc_first = tb->pc;
> -ctx.base.pc_next = ctx.base.pc_first;
> -/* once we have GDB, the rest of the translate.c implementation
> should be
> -   ready for singlestep */
> -ctx.base.singlestep_enabled = cs->singlestep_enabled;
> -ctx.base.tb = tb;
> -ctx.base.is_jmp = DISAS_NEXT;
> -
> -page_start = ctx.base.pc_first & TARGET_PAGE_MASK;
> -ctx.pc_succ_insn = ctx.base.pc_first;
> -ctx.flags = tb->flags;
> -ctx.mem_idx = tb->flags & TB_FLAGS_MMU_MASK;
> -ctx.frm = -1;  /* unknown rounding mode */
> -
> -num_insns = 0;
> -max_insns = tb_cflags(ctx.base.tb) & CF_COUNT_MASK;
> -if (max_insns == 0) {
> -max_insns = CF_COUNT_MASK;
> -}
> -if (max_insns > TCG_MAX_INSNS) {
> -max_insns = TCG_MAX_INSNS;
> -}
> -gen_tb_start(tb);
> +DisasContext *ctx = container_of(dcbase, DisasContext, base);
>
> -while (ctx.base.is_jmp == DISAS_NEXT) {
> -tcg_gen_insn_start(ctx.base.pc_next);
> -num_insns++;
> +ctx->pc_succ_insn = ctx->base.pc_first;
> +ctx->flags = ctx->base.tb->flags;
> +ctx->mem_idx = ctx->base.tb->flags & TB_FLAGS_MMU_MASK;
> +ctx->frm = -1;  /* unknown rounding mode */
> +}
>
> -if (unlikely(cpu_breakpoint_test(cs, ctx.base.pc_next, BP_ANY)))
> {
> -tcg_gen_movi_tl(cpu_pc, ctx.base.pc_next);
> -ctx.base.is_jmp = DISAS_NORETURN;
> -gen_exception_debug();
> -/* The address covered by the breakpoint must be included in
> -   [tb->pc, tb->pc + tb->size) in order to for it to be
> -   properly cleared -- thus we increment the PC here so that
> -   the logic setting tb->size below does the right thing.  */
> -ctx.base.pc_next += 4;
> -goto done_generating;
> -}
> +static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
> +{
> +}
>
> -if (num_insns == max_insns && (tb_cflags(ctx.base.tb) &
> CF_LAST_IO)) {
> -gen_io_start();
> -}
> +static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
> +{
> +DisasContext *ctx = container_of(dcbase, DisasContext, base);
> +
> +tcg_gen_insn_start(ctx->base.pc_next);
> +}
> +
> +static bool riscv_tr_breakpoint_check(DisasContextBase *dcbase, CPUState
> *cpu,
> +  const CPUBreakpoint *bp)
> +{
> +DisasContext *ctx = container_of(dcbase, DisasContext, base);
> +
> +tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
> +ctx->base.is_jmp = DISAS_NORETURN;
> +gen_exception_debug();
> +/* The address covered by the breakpoint must be included in
> +   [tb->pc, tb->pc + tb->size) in order to for it to be
> +   properly cleared -- thus we increment the PC here so that
> +   the logic setting tb->size below does the right thing.  */
> +ctx->base.pc_next += 4;
> +return true;
> +}
> +
> +
> +static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState
> *cpu)
> +{
> +DisasContext *ctx = container_of(dcbase, DisasContext, base);
> +CPURISCVState *env = cpu->env_ptr;
> +
> +ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
> +decode_opc(env, ctx);
> +ctx->base.pc_next = ctx->pc_succ_insn;
> +
> +if (ctx->base.is_jmp == DISAS_NEXT) {
> +target_ulong page_start;
>
> -ctx.opcode = cpu_ldl_code(env, ctx.base.pc_next);
> -decode_opc(env, &ctx);
> -ctx.base.pc_next = ctx.pc_s

[Qemu-devel] [PATCH v1 0/6] Translation loop conversion for riscv

2018-05-09 Thread Michael Clark
This is the riscv subset of Emilio G. Cota's translation loop
conversion patches forward ported to master, with a patch from
https://github.com/riscv/riscv-qemu/tree/qemu-2.13-for-upstream

The last patch in the series adds misa to DisasContext and
removes CPURISCVState from gen methods. The intention is to
add additional patches to this series to check for the misa
M, A, F and D extensions in multiply/divide, atomics, single
and double precision floating point methods to throw illegal
instruction exceptions for extensions that are not enabled.
The first step is to move misa into DisasContext.

The misa change has been rebased against Emilio G. Cota's
translation loop series so that target/riscv/translate.c
merges can be done more easily and so that patches can be
moved between trees.

Cc: Palmer Dabbelt 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Alistair Francis 
Cc: Emilio G. Cota 
Signed-off-by: Michael Clark 

Emilio G. Cota (5):
  target/riscv: avoid integer overflow in next_page PC check
  translator: merge max_insns into DisasContextBase
  target/riscv: convert to DisasJumpType
  target/riscv: convert to DisasContextBase
  target/riscv: convert to TranslatorOps

Michael Clark (1):
  target/riscv: add misa to DisasContext

 accel/tcg/translator.c |  21 ++-
 include/exec/translator.h  |   8 +-
 target/alpha/translate.c   |   6 +-
 target/arm/translate-a64.c |   8 +-
 target/arm/translate.c |  11 +-
 target/hppa/translate.c|   7 +-
 target/i386/translate.c|   5 +-
 target/ppc/translate.c |   5 +-
 target/riscv/translate.c   | 326 ++---
 9 files changed, 187 insertions(+), 210 deletions(-)

-- 
2.7.0




[Qemu-devel] [PATCH v1 1/6] target/riscv: avoid integer overflow in next_page PC check

2018-05-09 Thread Michael Clark
From: "Emilio G. Cota" 

If the PC is in the last page of the address space, next_page_start
overflows to 0. Fix it.

Reported-by: Richard Henderson 
Suggested-by: Richard Henderson 
Reviewed-by: Richard Henderson 
Reviewed-by: Michael Clark 
Acked-by: Bastian Koppelmann 
Cc: Michael Clark 
Cc: Palmer Dabbelt 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Emilio G. Cota 
---
 target/riscv/translate.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index c0e6a044d383..a98033ca77ca 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1850,11 +1850,11 @@ void gen_intermediate_code(CPUState *cs, 
TranslationBlock *tb)
 CPURISCVState *env = cs->env_ptr;
 DisasContext ctx;
 target_ulong pc_start;
-target_ulong next_page_start;
+target_ulong page_start;
 int num_insns;
 int max_insns;
 pc_start = tb->pc;
-next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
+page_start = pc_start & TARGET_PAGE_MASK;
 ctx.pc = pc_start;
 
 /* once we have GDB, the rest of the translate.c implementation should be
@@ -1904,7 +1904,7 @@ void gen_intermediate_code(CPUState *cs, TranslationBlock 
*tb)
 if (cs->singlestep_enabled) {
 break;
 }
-if (ctx.pc >= next_page_start) {
+if (ctx.pc - page_start >= TARGET_PAGE_SIZE) {
 break;
 }
 if (tcg_op_buf_full()) {
-- 
2.7.0




[Qemu-devel] [PATCH v1 3/6] target/riscv: convert to DisasJumpType

2018-05-09 Thread Michael Clark
From: "Emilio G. Cota" 

Reviewed-by: Bastian Koppelmann 
Reviewed-by: Richard Henderson 
Cc: Michael Clark 
Cc: Palmer Dabbelt 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Emilio G. Cota 
---
 target/riscv/translate.c | 72 +++-
 1 file changed, 28 insertions(+), 44 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index a98033ca77ca..1fee5b51dc20 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -26,6 +26,7 @@
 #include "exec/helper-proto.h"
 #include "exec/helper-gen.h"
 
+#include "exec/translator.h"
 #include "exec/log.h"
 
 #include "instmap.h"
@@ -46,7 +47,7 @@ typedef struct DisasContext {
 uint32_t flags;
 uint32_t mem_idx;
 int singlestep_enabled;
-int bstate;
+DisasJumpType is_jmp;
 /* Remember the rounding mode encoded in the previous fp instruction,
which we have already installed into env->fp_status.  Or -1 for
no previous fp instruction.  Note that we exit the TB when writing
@@ -55,13 +56,6 @@ typedef struct DisasContext {
 int frm;
 } DisasContext;
 
-enum {
-BS_NONE = 0, /* When seen outside of translation while loop, indicates
- need to exit tb due to end of page. */
-BS_STOP = 1, /* Need to exit tb for syscall, sret, etc. */
-BS_BRANCH   = 2, /* Need to exit tb for branch, jal, etc. */
-};
-
 /* convert riscv funct3 to qemu memop for load/store */
 static const int tcg_memop_lookup[8] = {
 [0 ... 7] = -1,
@@ -88,7 +82,7 @@ static void generate_exception(DisasContext *ctx, int excp)
 TCGv_i32 helper_tmp = tcg_const_i32(excp);
 gen_helper_raise_exception(cpu_env, helper_tmp);
 tcg_temp_free_i32(helper_tmp);
-ctx->bstate = BS_BRANCH;
+ctx->is_jmp = DISAS_NORETURN;
 }
 
 static void generate_exception_mbadaddr(DisasContext *ctx, int excp)
@@ -98,7 +92,7 @@ static void generate_exception_mbadaddr(DisasContext *ctx, 
int excp)
 TCGv_i32 helper_tmp = tcg_const_i32(excp);
 gen_helper_raise_exception(cpu_env, helper_tmp);
 tcg_temp_free_i32(helper_tmp);
-ctx->bstate = BS_BRANCH;
+ctx->is_jmp = DISAS_NORETURN;
 }
 
 static void gen_exception_debug(void)
@@ -531,7 +525,7 @@ static void gen_jal(CPURISCVState *env, DisasContext *ctx, 
int rd,
 }
 
 gen_goto_tb(ctx, 0, ctx->pc + imm); /* must use this for safety */
-ctx->bstate = BS_BRANCH;
+ctx->is_jmp = DISAS_NORETURN;
 }
 
 static void gen_jalr(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
@@ -562,7 +556,7 @@ static void gen_jalr(CPURISCVState *env, DisasContext *ctx, 
uint32_t opc,
 gen_set_label(misaligned);
 gen_exception_inst_addr_mis(ctx);
 }
-ctx->bstate = BS_BRANCH;
+ctx->is_jmp = DISAS_NORETURN;
 break;
 
 default:
@@ -616,7 +610,7 @@ static void gen_branch(CPURISCVState *env, DisasContext 
*ctx, uint32_t opc,
 } else {
 gen_goto_tb(ctx, 0, ctx->pc + bimm);
 }
-ctx->bstate = BS_BRANCH;
+ctx->is_jmp = DISAS_NORETURN;
 }
 
 static void gen_load(DisasContext *ctx, uint32_t opc, int rd, int rs1,
@@ -1344,12 +1338,12 @@ static void gen_system(CPURISCVState *env, DisasContext 
*ctx, uint32_t opc,
 /* always generates U-level ECALL, fixed in do_interrupt handler */
 generate_exception(ctx, RISCV_EXCP_U_ECALL);
 tcg_gen_exit_tb(0); /* no chaining */
-ctx->bstate = BS_BRANCH;
+ctx->is_jmp = DISAS_NORETURN;
 break;
 case 0x1: /* EBREAK */
 generate_exception(ctx, RISCV_EXCP_BREAKPOINT);
 tcg_gen_exit_tb(0); /* no chaining */
-ctx->bstate = BS_BRANCH;
+ctx->is_jmp = DISAS_NORETURN;
 break;
 #ifndef CONFIG_USER_ONLY
 case 0x002: /* URET */
@@ -1359,7 +1353,7 @@ static void gen_system(CPURISCVState *env, DisasContext 
*ctx, uint32_t opc,
 if (riscv_has_ext(env, RVS)) {
 gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
 tcg_gen_exit_tb(0); /* no chaining */
-ctx->bstate = BS_BRANCH;
+ctx->is_jmp = DISAS_NORETURN;
 } else {
 gen_exception_illegal(ctx);
 }
@@ -1370,7 +1364,7 @@ static void gen_system(CPURISCVState *env, DisasContext 
*ctx, uint32_t opc,
 case 0x302: /* MRET */
 gen_helper_mret(cpu_pc, cpu_env, cpu_pc);
 tcg_gen_exit_tb(0); /* no chaining */
-ctx->bstate = BS_BRANCH;
+ctx->is_jmp = DISAS_NORETURN;
 break;
 case 0x7b2: /* DRET */
 gen_exception_illegal(ctx);
@@ -1419,7 +1413,7 @@ static void gen_system(CPURISCVState *env, DisasContext 
*ctx, uint32_t opc,
 /* end tb since we may be changing priv modes, to get mmu_index right 
*/

[Qemu-devel] [PATCH v1 4/6] target/riscv: convert to DisasContextBase

2018-05-09 Thread Michael Clark
From: "Emilio G. Cota" 

Notes:

- Did not convert {num,max}_insns, since the corresponding code
  will go away in the next patch.

- ctx->pc becomes ctx->base.pc_next, and ctx->next_pc becomes
  ctx->pc_succ_insn.

While at it, convert the remaining tb->cflags readers to tb_cflags().

Reviewed-by: Richard Henderson 
Cc: Michael Clark 
Cc: Palmer Dabbelt 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Emilio G. Cota 
---
 target/riscv/translate.c | 129 +++
 1 file changed, 64 insertions(+), 65 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 1fee5b51dc20..68979abfd7ed 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -40,14 +40,12 @@ static TCGv load_val;
 #include "exec/gen-icount.h"
 
 typedef struct DisasContext {
-struct TranslationBlock *tb;
-target_ulong pc;
-target_ulong next_pc;
+DisasContextBase base;
+/* pc_succ_insn points to the instruction following base.pc_next */
+target_ulong pc_succ_insn;
 uint32_t opcode;
 uint32_t flags;
 uint32_t mem_idx;
-int singlestep_enabled;
-DisasJumpType is_jmp;
 /* Remember the rounding mode encoded in the previous fp instruction,
which we have already installed into env->fp_status.  Or -1 for
no previous fp instruction.  Note that we exit the TB when writing
@@ -78,21 +76,21 @@ static const int tcg_memop_lookup[8] = {
 
 static void generate_exception(DisasContext *ctx, int excp)
 {
-tcg_gen_movi_tl(cpu_pc, ctx->pc);
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
 TCGv_i32 helper_tmp = tcg_const_i32(excp);
 gen_helper_raise_exception(cpu_env, helper_tmp);
 tcg_temp_free_i32(helper_tmp);
-ctx->is_jmp = DISAS_NORETURN;
+ctx->base.is_jmp = DISAS_NORETURN;
 }
 
 static void generate_exception_mbadaddr(DisasContext *ctx, int excp)
 {
-tcg_gen_movi_tl(cpu_pc, ctx->pc);
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
 tcg_gen_st_tl(cpu_pc, cpu_env, offsetof(CPURISCVState, badaddr));
 TCGv_i32 helper_tmp = tcg_const_i32(excp);
 gen_helper_raise_exception(cpu_env, helper_tmp);
 tcg_temp_free_i32(helper_tmp);
-ctx->is_jmp = DISAS_NORETURN;
+ctx->base.is_jmp = DISAS_NORETURN;
 }
 
 static void gen_exception_debug(void)
@@ -114,12 +112,12 @@ static void gen_exception_inst_addr_mis(DisasContext *ctx)
 
 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
 {
-if (unlikely(ctx->singlestep_enabled)) {
+if (unlikely(ctx->base.singlestep_enabled)) {
 return false;
 }
 
 #ifndef CONFIG_USER_ONLY
-return (ctx->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
+return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
 #else
 return true;
 #endif
@@ -131,10 +129,10 @@ static void gen_goto_tb(DisasContext *ctx, int n, 
target_ulong dest)
 /* chaining is only allowed when the jump is to the same page */
 tcg_gen_goto_tb(n);
 tcg_gen_movi_tl(cpu_pc, dest);
-tcg_gen_exit_tb((uintptr_t)ctx->tb + n);
+tcg_gen_exit_tb((uintptr_t)ctx->base.tb + n);
 } else {
 tcg_gen_movi_tl(cpu_pc, dest);
-if (ctx->singlestep_enabled) {
+if (ctx->base.singlestep_enabled) {
 gen_exception_debug();
 } else {
 tcg_gen_exit_tb(0);
@@ -513,7 +511,7 @@ static void gen_jal(CPURISCVState *env, DisasContext *ctx, 
int rd,
 target_ulong next_pc;
 
 /* check misaligned: */
-next_pc = ctx->pc + imm;
+next_pc = ctx->base.pc_next + imm;
 if (!riscv_has_ext(env, RVC)) {
 if ((next_pc & 0x3) != 0) {
 gen_exception_inst_addr_mis(ctx);
@@ -521,11 +519,11 @@ static void gen_jal(CPURISCVState *env, DisasContext 
*ctx, int rd,
 }
 }
 if (rd != 0) {
-tcg_gen_movi_tl(cpu_gpr[rd], ctx->next_pc);
+tcg_gen_movi_tl(cpu_gpr[rd], ctx->pc_succ_insn);
 }
 
-gen_goto_tb(ctx, 0, ctx->pc + imm); /* must use this for safety */
-ctx->is_jmp = DISAS_NORETURN;
+gen_goto_tb(ctx, 0, ctx->base.pc_next + imm); /* must use this for safety 
*/
+ctx->base.is_jmp = DISAS_NORETURN;
 }
 
 static void gen_jalr(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
@@ -548,7 +546,7 @@ static void gen_jalr(CPURISCVState *env, DisasContext *ctx, 
uint32_t opc,
 }
 
 if (rd != 0) {
-tcg_gen_movi_tl(cpu_gpr[rd], ctx->next_pc);
+tcg_gen_movi_tl(cpu_gpr[rd], ctx->pc_succ_insn);
 }
 tcg_gen_exit_tb(0);
 
@@ -556,7 +554,7 @@ static void gen_jalr(CPURISCVState *env, DisasContext *ctx, 
uint32_t opc,
 gen_set_label(misaligned);
 gen_exception_inst_addr_mis(ctx);
 }
-ctx->is_jmp = DISAS_NORETURN;
+ctx->base.is_jmp

[Qemu-devel] [PATCH v1 2/6] translator: merge max_insns into DisasContextBase

2018-05-09 Thread Michael Clark
From: "Emilio G. Cota" 

While at it, use int for both num_insns and max_insns to make
sure we have same-type comparisons.

Reviewed-by: Richard Henderson 
Signed-off-by: Emilio G. Cota 
---
 accel/tcg/translator.c | 21 ++---
 include/exec/translator.h  |  8 
 target/alpha/translate.c   |  6 ++
 target/arm/translate-a64.c |  8 +++-
 target/arm/translate.c | 11 ---
 target/hppa/translate.c|  7 ++-
 target/i386/translate.c|  5 +
 target/ppc/translate.c |  5 ++---
 8 files changed, 28 insertions(+), 43 deletions(-)

diff --git a/accel/tcg/translator.c b/accel/tcg/translator.c
index 23c6602cd921..0f9dca911399 100644
--- a/accel/tcg/translator.c
+++ b/accel/tcg/translator.c
@@ -34,8 +34,6 @@ void translator_loop_temp_check(DisasContextBase *db)
 void translator_loop(const TranslatorOps *ops, DisasContextBase *db,
  CPUState *cpu, TranslationBlock *tb)
 {
-int max_insns;
-
 /* Initialize DisasContext */
 db->tb = tb;
 db->pc_first = tb->pc;
@@ -45,18 +43,18 @@ void translator_loop(const TranslatorOps *ops, 
DisasContextBase *db,
 db->singlestep_enabled = cpu->singlestep_enabled;
 
 /* Instruction counting */
-max_insns = tb_cflags(db->tb) & CF_COUNT_MASK;
-if (max_insns == 0) {
-max_insns = CF_COUNT_MASK;
+db->max_insns = tb_cflags(db->tb) & CF_COUNT_MASK;
+if (db->max_insns == 0) {
+db->max_insns = CF_COUNT_MASK;
 }
-if (max_insns > TCG_MAX_INSNS) {
-max_insns = TCG_MAX_INSNS;
+if (db->max_insns > TCG_MAX_INSNS) {
+db->max_insns = TCG_MAX_INSNS;
 }
 if (db->singlestep_enabled || singlestep) {
-max_insns = 1;
+db->max_insns = 1;
 }
 
-max_insns = ops->init_disas_context(db, cpu, max_insns);
+ops->init_disas_context(db, cpu);
 tcg_debug_assert(db->is_jmp == DISAS_NEXT);  /* no early exit */
 
 /* Reset the temp count so that we can identify leaks */
@@ -95,7 +93,8 @@ void translator_loop(const TranslatorOps *ops, 
DisasContextBase *db,
update db->pc_next and db->is_jmp to indicate what should be
done next -- either exiting this loop or locate the start of
the next instruction.  */
-if (db->num_insns == max_insns && (tb_cflags(db->tb) & CF_LAST_IO)) {
+if (db->num_insns == db->max_insns
+&& (tb_cflags(db->tb) & CF_LAST_IO)) {
 /* Accept I/O on the last instruction.  */
 gen_io_start();
 ops->translate_insn(db, cpu);
@@ -111,7 +110,7 @@ void translator_loop(const TranslatorOps *ops, 
DisasContextBase *db,
 
 /* Stop translation if the output buffer is full,
or we have executed all of the allowed instructions.  */
-if (tcg_op_buf_full() || db->num_insns >= max_insns) {
+if (tcg_op_buf_full() || db->num_insns >= db->max_insns) {
 db->is_jmp = DISAS_TOO_MANY;
 break;
 }
diff --git a/include/exec/translator.h b/include/exec/translator.h
index e2dc2a04ae37..71e7b2c34714 100644
--- a/include/exec/translator.h
+++ b/include/exec/translator.h
@@ -58,6 +58,7 @@ typedef enum DisasJumpType {
  *   disassembly).
  * @is_jmp: What instruction to disassemble next.
  * @num_insns: Number of translated instructions (including current).
+ * @max_insns: Maximum number of instructions to be translated in this TB.
  * @singlestep_enabled: "Hardware" single stepping enabled.
  *
  * Architecture-agnostic disassembly context.
@@ -67,7 +68,8 @@ typedef struct DisasContextBase {
 target_ulong pc_first;
 target_ulong pc_next;
 DisasJumpType is_jmp;
-unsigned int num_insns;
+int num_insns;
+int max_insns;
 bool singlestep_enabled;
 } DisasContextBase;
 
@@ -76,7 +78,6 @@ typedef struct DisasContextBase {
  * @init_disas_context:
  *  Initialize the target-specific portions of DisasContext struct.
  *  The generic DisasContextBase has already been initialized.
- *  Return max_insns, modified as necessary by db->tb->flags.
  *
  * @tb_start:
  *  Emit any code required before the start of the main loop,
@@ -106,8 +107,7 @@ typedef struct DisasContextBase {
  *  Print instruction disassembly to log.
  */
 typedef struct TranslatorOps {
-int (*init_disas_context)(DisasContextBase *db, CPUState *cpu,
-  int max_insns);
+void (*init_disas_context)(DisasContextBase *db, CPUState *cpu);
 void (*tb_start)(DisasContextBase *db, CPUState *cpu);
 void (*insn_start)(DisasContextBase *db, CPUState *cpu);
 bool (*breakpoint_check)(DisasContextBase *db, CPUState *cpu,
diff --git a/target/alpha/translate.c b/target/alpha/translate.c
index 73a1b5e63ed1..15eca71d49f7 100644
--- a/target/alpha/translate.c
+++ b/target/alpha/translate.c
@@ -2919,8 +2919,7 @@ static DisasJumpType translate_one(DisasContext *ctx, 
uint32_t insn)
 return ret;
 }
 
-static int alpha_tr_init_disas_co

[Qemu-devel] [PATCH v1 6/6] target/riscv: add misa to DisasContext

2018-05-09 Thread Michael Clark
gen methods should access state from DisasContext. Add misa
field to the DisasContext struct and remove CPURISCVState
argument from all gen methods.

[Rebased against github.com/cota/qemu/tree/trloop-conv-v3]

Cc: Palmer Dabbelt 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Alistair Francis 
Cc: Emilio G. Cota 
Signed-off-by: Michael Clark 
---
 target/riscv/translate.c | 77 ++--
 1 file changed, 42 insertions(+), 35 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 1788668c6f28..507d74186293 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -45,6 +45,7 @@ typedef struct DisasContext {
 target_ulong pc_succ_insn;
 uint32_t opcode;
 uint32_t flags;
+uint32_t misa;
 uint32_t mem_idx;
 /* Remember the rounding mode encoded in the previous fp instruction,
which we have already installed into env->fp_status.  Or -1 for
@@ -74,6 +75,11 @@ static const int tcg_memop_lookup[8] = {
 #define CASE_OP_32_64(X) case X
 #endif
 
+static inline bool has_ext(DisasContext *ctx, uint32_t ext)
+{
+return ctx->misa & ext;
+}
+
 static void generate_exception(DisasContext *ctx, int excp)
 {
 tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
@@ -505,14 +511,13 @@ static void gen_arith_imm(DisasContext *ctx, uint32_t 
opc, int rd,
 tcg_temp_free(source1);
 }
 
-static void gen_jal(CPURISCVState *env, DisasContext *ctx, int rd,
-target_ulong imm)
+static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
 {
 target_ulong next_pc;
 
 /* check misaligned: */
 next_pc = ctx->base.pc_next + imm;
-if (!riscv_has_ext(env, RVC)) {
+if (!has_ext(ctx, RVC)) {
 if ((next_pc & 0x3) != 0) {
 gen_exception_inst_addr_mis(ctx);
 return;
@@ -526,8 +531,8 @@ static void gen_jal(CPURISCVState *env, DisasContext *ctx, 
int rd,
 ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-static void gen_jalr(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
- int rd, int rs1, target_long imm)
+static void gen_jalr(DisasContext *ctx, uint32_t opc, int rd, int rs1,
+ target_long imm)
 {
 /* no chaining with JALR */
 TCGLabel *misaligned = NULL;
@@ -539,7 +544,7 @@ static void gen_jalr(CPURISCVState *env, DisasContext *ctx, 
uint32_t opc,
 tcg_gen_addi_tl(cpu_pc, cpu_pc, imm);
 tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
 
-if (!riscv_has_ext(env, RVC)) {
+if (!has_ext(ctx, RVC)) {
 misaligned = gen_new_label();
 tcg_gen_andi_tl(t0, cpu_pc, 0x2);
 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
@@ -564,8 +569,8 @@ static void gen_jalr(CPURISCVState *env, DisasContext *ctx, 
uint32_t opc,
 tcg_temp_free(t0);
 }
 
-static void gen_branch(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
-   int rs1, int rs2, target_long bimm)
+static void gen_branch(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
+   target_long bimm)
 {
 TCGLabel *l = gen_new_label();
 TCGv source1, source2;
@@ -602,7 +607,7 @@ static void gen_branch(CPURISCVState *env, DisasContext 
*ctx, uint32_t opc,
 
 gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
 gen_set_label(l); /* branch taken */
-if (!riscv_has_ext(env, RVC) && ((ctx->base.pc_next + bimm) & 0x3)) {
+if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + bimm) & 0x3)) {
 /* misaligned */
 gen_exception_inst_addr_mis(ctx);
 } else {
@@ -1305,8 +1310,8 @@ static void gen_fp_arith(DisasContext *ctx, uint32_t opc, 
int rd,
 }
 }
 
-static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
-  int rd, int rs1, int csr)
+static void gen_system(DisasContext *ctx, uint32_t opc, int rd, int rs1,
+   int csr)
 {
 TCGv source1, csr_store, dest, rs1_pass, imm_rs1;
 source1 = tcg_temp_new();
@@ -1348,7 +1353,7 @@ static void gen_system(CPURISCVState *env, DisasContext 
*ctx, uint32_t opc,
 gen_exception_illegal(ctx);
 break;
 case 0x102: /* SRET */
-if (riscv_has_ext(env, RVS)) {
+if (has_ext(ctx, RVS)) {
 gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
 tcg_gen_exit_tb(0); /* no chaining */
 ctx->base.is_jmp = DISAS_NORETURN;
@@ -1489,7 +1494,7 @@ static void decode_RV32_64C0(DisasContext *ctx)
 }
 }
 
-static void decode_RV32_64C1(CPURISCVState *env, DisasContext *ctx)
+static void decode_RV32_64C1(DisasContext *ctx)
 {
 uint8_t funct3 = extract32(ctx->opcode, 13, 3);
 uint8_t rd_rs1 = GET_C_RS1(ctx->opcode);
@@ -1509,7 +1514,7 @@ static void decode_RV32_64C1(CPURISCVState *env, 
DisasContext *ctx)
   GET_C_IMM(ctx->opcode));
 #else
 /* C.JAL(RV32) ->

[Qemu-devel] [PATCH v1 5/6] target/riscv: convert to TranslatorOps

2018-05-09 Thread Michael Clark
From: "Emilio G. Cota" 

Reviewed-by: Richard Henderson 
Cc: Michael Clark 
Cc: Palmer Dabbelt 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Signed-off-by: Emilio G. Cota 
---
 target/riscv/translate.c | 158 ---
 1 file changed, 80 insertions(+), 78 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 68979abfd7ed..1788668c6f28 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -1837,78 +1837,71 @@ static void decode_opc(CPURISCVState *env, DisasContext 
*ctx)
 }
 }
 
-void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
+static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
 {
-CPURISCVState *env = cs->env_ptr;
-DisasContext ctx;
-target_ulong page_start;
-int num_insns;
-int max_insns;
-
-ctx.base.pc_first = tb->pc;
-ctx.base.pc_next = ctx.base.pc_first;
-/* once we have GDB, the rest of the translate.c implementation should be
-   ready for singlestep */
-ctx.base.singlestep_enabled = cs->singlestep_enabled;
-ctx.base.tb = tb;
-ctx.base.is_jmp = DISAS_NEXT;
-
-page_start = ctx.base.pc_first & TARGET_PAGE_MASK;
-ctx.pc_succ_insn = ctx.base.pc_first;
-ctx.flags = tb->flags;
-ctx.mem_idx = tb->flags & TB_FLAGS_MMU_MASK;
-ctx.frm = -1;  /* unknown rounding mode */
-
-num_insns = 0;
-max_insns = tb_cflags(ctx.base.tb) & CF_COUNT_MASK;
-if (max_insns == 0) {
-max_insns = CF_COUNT_MASK;
-}
-if (max_insns > TCG_MAX_INSNS) {
-max_insns = TCG_MAX_INSNS;
-}
-gen_tb_start(tb);
+DisasContext *ctx = container_of(dcbase, DisasContext, base);
 
-while (ctx.base.is_jmp == DISAS_NEXT) {
-tcg_gen_insn_start(ctx.base.pc_next);
-num_insns++;
+ctx->pc_succ_insn = ctx->base.pc_first;
+ctx->flags = ctx->base.tb->flags;
+ctx->mem_idx = ctx->base.tb->flags & TB_FLAGS_MMU_MASK;
+ctx->frm = -1;  /* unknown rounding mode */
+}
 
-if (unlikely(cpu_breakpoint_test(cs, ctx.base.pc_next, BP_ANY))) {
-tcg_gen_movi_tl(cpu_pc, ctx.base.pc_next);
-ctx.base.is_jmp = DISAS_NORETURN;
-gen_exception_debug();
-/* The address covered by the breakpoint must be included in
-   [tb->pc, tb->pc + tb->size) in order to for it to be
-   properly cleared -- thus we increment the PC here so that
-   the logic setting tb->size below does the right thing.  */
-ctx.base.pc_next += 4;
-goto done_generating;
-}
+static void riscv_tr_tb_start(DisasContextBase *db, CPUState *cpu)
+{
+}
 
-if (num_insns == max_insns && (tb_cflags(ctx.base.tb) & CF_LAST_IO)) {
-gen_io_start();
-}
+static void riscv_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
+{
+DisasContext *ctx = container_of(dcbase, DisasContext, base);
+
+tcg_gen_insn_start(ctx->base.pc_next);
+}
+
+static bool riscv_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
+  const CPUBreakpoint *bp)
+{
+DisasContext *ctx = container_of(dcbase, DisasContext, base);
+
+tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
+ctx->base.is_jmp = DISAS_NORETURN;
+gen_exception_debug();
+/* The address covered by the breakpoint must be included in
+   [tb->pc, tb->pc + tb->size) in order to for it to be
+   properly cleared -- thus we increment the PC here so that
+   the logic setting tb->size below does the right thing.  */
+ctx->base.pc_next += 4;
+return true;
+}
+
+
+static void riscv_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
+{
+DisasContext *ctx = container_of(dcbase, DisasContext, base);
+CPURISCVState *env = cpu->env_ptr;
 
-ctx.opcode = cpu_ldl_code(env, ctx.base.pc_next);
-decode_opc(env, &ctx);
-ctx.base.pc_next = ctx.pc_succ_insn;
-
-if (ctx.base.is_jmp == DISAS_NEXT &&
-(cs->singlestep_enabled ||
- ctx.base.pc_next - page_start >= TARGET_PAGE_SIZE ||
- tcg_op_buf_full() ||
- num_insns >= max_insns ||
- singlestep)) {
-ctx.base.is_jmp = DISAS_TOO_MANY;
+ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
+decode_opc(env, ctx);
+ctx->base.pc_next = ctx->pc_succ_insn;
+
+if (ctx->base.is_jmp == DISAS_NEXT) {
+target_ulong page_start;
+
+page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
+if (ctx->base.pc_next - page_start >= TARGET_PAGE_SIZE) {
+ctx->base.is_jmp = DISAS_TOO_MANY;
 }
 }
-if (tb_cflags(ctx.base.tb) & CF_LAST_IO) {
-gen_io_end();
-}
-switch (ctx.base.is_jmp) {
+}
+
+static

[Qemu-devel] [PULL 1/3] riscv: spike: allow base == 0

2018-05-09 Thread Michael Clark
From: KONRAD Frederic 

The sanity check on base doesn't allow htif to be mapped @0. Check if the
symbol exists instead so we can map it where we want.

Reviewed-by: Michael Clark 
Signed-off-by: KONRAD Frederic 
Signed-off-by: Michael Clark 

Message-Id: <1525360636-18229-2-git-send-email-frederic.kon...@adacore.com>
---
 hw/riscv/riscv_htif.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/riscv_htif.c b/hw/riscv/riscv_htif.c
index 3e17f3025106..be252ec8cce9 100644
--- a/hw/riscv/riscv_htif.c
+++ b/hw/riscv/riscv_htif.c
@@ -41,17 +41,20 @@
 } while (0)
 
 static uint64_t fromhost_addr, tohost_addr;
+static int address_symbol_set;
 
 void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value,
-uint64_t st_size)
+  uint64_t st_size)
 {
 if (strcmp("fromhost", st_name) == 0) {
+address_symbol_set |= 1;
 fromhost_addr = st_value;
 if (st_size != 8) {
 error_report("HTIF fromhost must be 8 bytes");
 exit(1);
 }
 } else if (strcmp("tohost", st_name) == 0) {
+address_symbol_set |= 2;
 tohost_addr = st_value;
 if (st_size != 8) {
 error_report("HTIF tohost must be 8 bytes");
@@ -248,7 +251,7 @@ HTIFState *htif_mm_init(MemoryRegion *address_space, 
MemoryRegion *main_mem,
 qemu_chr_fe_init(&s->chr, chr, &error_abort);
 qemu_chr_fe_set_handlers(&s->chr, htif_can_recv, htif_recv, htif_event,
 htif_be_change, s, NULL, true);
-if (base) {
+if (address_symbol_set == 3) {
 memory_region_init_io(&s->mmio, NULL, &htif_mm_ops, s,
 TYPE_HTIF_UART, size);
 memory_region_add_subregion(address_space, base, &s->mmio);
-- 
2.7.0




[Qemu-devel] [PULL 2/3] riscv: htif: increase the priority of the htif subregion

2018-05-09 Thread Michael Clark
From: KONRAD Frederic 

The htif device is supposed to be mapped over an other subregion. So increase
its priority to one to avoid any conflict.

Here is the output of info mtree:

Before:
(qemu) info mtree
 address-space: memory
   - (prio 0, i/o): system
 -000f (prio 0, i/o): riscv.htif.uart
 -00011fff (prio 0, ram): riscv.spike.bootrom
 0200-0200 (prio 0, i/o): riscv.sifive.clint
 8000-87ff (prio 0, ram): riscv.spike.ram

 address-space: I/O
   - (prio 0, i/o): io

 address-space: cpu-memory-0
   - (prio 0, i/o): system
 -000f (prio 0, i/o): riscv.htif.uart
 -00011fff (prio 0, ram): riscv.spike.bootrom
 0200-0200 (prio 0, i/o): riscv.sifive.clint
 8000-87ff (prio 0, ram): riscv.spike.ram

After:
 (qemu) info mtree
 address-space: memory
   - (prio 0, i/o): system
 -000f (prio 1, i/o): riscv.htif.uart
 -00011fff (prio 0, ram): riscv.spike.bootrom
 0200-0200 (prio 0, i/o): riscv.sifive.clint
 8000-87ff (prio 0, ram): riscv.spike.ram

 address-space: I/O
   - (prio 0, i/o): io

 address-space: cpu-memory-0
   - (prio 0, i/o): system
 -000f (prio 1, i/o): riscv.htif.uart
 -00011fff (prio 0, ram): riscv.spike.bootrom
 0200-0200 (prio 0, i/o): riscv.sifive.clint
 8000-87ff (prio 0, ram): riscv.spike.ram

Reviewed-by: Michael Clark 
Signed-off-by: KONRAD Frederic 
Signed-off-by: Michael Clark 

Message-Id: <1525360636-18229-3-git-send-email-frederic.kon...@adacore.com>
---
 hw/riscv/riscv_htif.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/riscv_htif.c b/hw/riscv/riscv_htif.c
index be252ec8cce9..f73512941fb6 100644
--- a/hw/riscv/riscv_htif.c
+++ b/hw/riscv/riscv_htif.c
@@ -253,8 +253,9 @@ HTIFState *htif_mm_init(MemoryRegion *address_space, 
MemoryRegion *main_mem,
 htif_be_change, s, NULL, true);
 if (address_symbol_set == 3) {
 memory_region_init_io(&s->mmio, NULL, &htif_mm_ops, s,
-TYPE_HTIF_UART, size);
-memory_region_add_subregion(address_space, base, &s->mmio);
+  TYPE_HTIF_UART, size);
+memory_region_add_subregion_overlap(address_space, base,
+&s->mmio, 1);
 }
 
 return s;
-- 
2.7.0




[Qemu-devel] [PULL 0/3] RISC-V: QEMU 2.13 Minor Fixes

2018-05-09 Thread Michael Clark
The following changes since commit c8b7e627b4269a3bc3ae41d9f420547a47e6d9b9:

  Merge remote-tracking branch 'remotes/ericb/tags/pull-nbd-2018-05-04' into 
staging (2018-05-04 14:42:46 +0100)

are available in the git repository at:

  https://github.com/riscv/riscv-qemu.git tags/riscv-qemu-2.13-minor-fixes-3

for you to fetch changes up to a666409f0df5dce113a5bd2c4c144a0792f2a4a3:

  riscv: requires libfdt (2018-05-09 22:14:28 +1200)


RISC-V: QEMU 2.13 Minor Fixes

* Require libfdt when configuring for 'riscv*-softmmu'
* Increase HTIF priority and allow zero base address


KONRAD Frederic (3):
  riscv: spike: allow base == 0
  riscv: htif: increase the priority of the htif subregion
  riscv: requires libfdt

 configure |  2 +-
 hw/riscv/riscv_htif.c | 12 
 2 files changed, 9 insertions(+), 5 deletions(-)

-- 
2.7.0




[Qemu-devel] [PULL 3/3] riscv: requires libfdt

2018-05-09 Thread Michael Clark
From: KONRAD Frederic 

When compiling on a machine without libfdt installed the configure script
should try to get libfdt from the git or should die because otherwise
CONFIG_LIBFDT is not set and the build process end in an error in the link
phase.. eg:

hw/riscv/virt.o: In function `riscv_virt_board_init':
qemu/src/hw/riscv/virt.c:317: undefined reference to `qemu_fdt_setprop_cell'
qemu/src/hw/riscv/virt.c:319: undefined reference to `qemu_fdt_setprop_cell'
qemu/src/hw/riscv/virt.c:345: undefined reference to `qemu_fdt_dumpdtb'
collect2: error: ld returned 1 exit status
make[1]: *** [qemu-system-riscv64] Error 1
make: *** [subdir-riscv64-softmmu] Error 2

Cc: qemu-sta...@nongnu.org
Reviewed-by: Bastian Koppelmann 
Reviewed-by: Philippe Mathieu-Daudé 
Reviewed-by: Michael Clark 
Signed-off-by: KONRAD Frederic 
Signed-off-by: Michael Clark 

Message-Id: <1525360636-18229-4-git-send-email-frederic.kon...@adacore.com>
---
 configure | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure b/configure
index 1443422e83f1..479e9a787e6e 100755
--- a/configure
+++ b/configure
@@ -3761,7 +3761,7 @@ fi
 fdt_required=no
 for target in $target_list; do
   case $target in
-
aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-softmmu|mips64el-softmmu)
+
aarch64*-softmmu|arm*-softmmu|ppc*-softmmu|microblaze*-softmmu|mips64el-softmmu|riscv*-softmmu)
   fdt_required=yes
 ;;
   esac
-- 
2.7.0




Re: [Qemu-devel] [PULL 0/3] RISC-V: QEMU 2.13 Minor Fixes

2018-05-09 Thread Michael Clark
On Wed, 9 May 2018 at 11:14 PM, Peter Maydell 
wrote:

> On 8 May 2018 at 23:05, Michael Clark  wrote:
> >
> >
> > On Wed, May 9, 2018 at 8:49 AM, Peter Maydell 
> > wrote:
> >>
> >> On 8 May 2018 at 21:07, Michael Clark  wrote:
> >> > The following changes since commit
> >> > c8b7e627b4269a3bc3ae41d9f420547a47e6d9b9:
> >> >
> >> >   Merge remote-tracking branch
> 'remotes/ericb/tags/pull-nbd-2018-05-04'
> >> > into staging (2018-05-04 14:42:46 +0100)
> >> >
> >> > are available in the git repository at:
> >> >
> >> >   https://github.com/riscv/riscv-qemu.git
> >> > tags/riscv-qemu-2.13-minor-fixes-2
> >> >
> >> > for you to fetch changes up to
> fc28db142ea9331d24d08a6418efa93e258a6876:
> >> >
> >> >   riscv: requires libfdt (2018-05-09 07:57:57 +1200)
> >> >
> >> > 
> >> > RISC-V: QEMU 2.13 Minor Fixes
> >> >
> >> > * Require libfdt when configuring for 'riscv*-softmmu'
> >> > * Increase HTIF priority and allow zero base address
> >> >
> >> > Consider backporting to stable branch for 2.12.1
> >>
> >> Ah, if you want something flagged to be backported to
> >> the stable branch, the way to do that is to include
> >> the line "Cc: qemu-sta...@nongnu.org" in the commit
> >> message. We use the same approach for flagging things
> >> for stable as the Linux kernel. (Individual submaintainers
> >> are generally in the best position to decide whether
> >> something should go into stable, and this system leaves
> >> that choice up to them. A patch submitter can also suggest
> >> something for stable when you submit the initial patch for
> >> review by adding the Cc: line and cc'ing qemu-stable on the
> >> patchmail.)
> >
> >
> > Okay. Given the 'Cc is missing in the commit (only on the cover) I could
> > send a separate patch.
> >
> > Or I can respin with the 'Cc on the configure libfdt dependency fix
> commit
> > and remove the backport message from the tag...
>
> Tag messages are just informational (we use them to help
> in writing up the changelog for releases), mostly. So I
> would recommend respinning the pullreq with the Cc: line
> in the relevant commit(s).


I respun the PR with a Cc: qemu-stable in the configure libfdt dependency
patch. You should have received a PR with the tag
‘riscv-qemu-2.13-minor-fixes-3’

Thanks,
Michael

>
>


Re: [Qemu-devel] [PATCH v2 1/7] hw/riscv/sifive_u: Create a U54 SoC object

2018-05-12 Thread Michael Clark
On Sat, May 12, 2018 at 11:27 AM, Alistair Francis  wrote:

> Create a SiFive Unleashed U54 SoC and use that in the sifive_u machine.
>
> We leave the SoC, RAM, device tree and reset/fdt loading as part of the
> machine. All the other device creation has been moved to the SoC.
>
> Signed-off-by: Alistair Francis 
>

This board currently supports U34 and U54 cores. The SOC names have 3
digits. e.g. FU540.

We are trying to keep the SiFive U Series board generic.

- Global search and replace the prefix "riscv_sifive_u54" to
"riscv_sifive_u_soc"
- Rename TYPE_RISCV_U54_SOC to TYPE_RISCV_U_SOC
- Rename SiFiveU54State SiFiveUSOC (I don't think we need the State suffix
for the SOC)

Assuming we can do the renames to keep the SiFive U Series machine/SOC
general:

Reviewed-by: Michael Clark 

---
>  hw/riscv/sifive_u.c | 90 -
>  include/hw/riscv/sifive_u.h | 16 ++-
>  2 files changed, 82 insertions(+), 24 deletions(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index c05dcbba95..26155e932d 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -116,10 +116,10 @@ static void create_fdt(SiFiveUState *s, const struct
> MemmapEntry *memmap,
>  qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0);
>  qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1);
>
> -for (cpu = s->soc.num_harts - 1; cpu >= 0; cpu--) {
> +for (cpu = s->soc.cpus.num_harts - 1; cpu >= 0; cpu--) {
>  nodename = g_strdup_printf("/cpus/cpu@%d", cpu);
>  char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller",
> cpu);
> -char *isa = riscv_isa_string(&s->soc.harts[cpu]);
> +char *isa = riscv_isa_string(&s->soc.cpus.harts[cpu]);
>  qemu_fdt_add_subnode(fdt, nodename);
>  qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency",
>SIFIVE_U_CLOCK_FREQ);
> @@ -140,8 +140,8 @@ static void create_fdt(SiFiveUState *s, const struct
> MemmapEntry *memmap,
>  g_free(nodename);
>  }
>
> -cells =  g_new0(uint32_t, s->soc.num_harts * 4);
> -for (cpu = 0; cpu < s->soc.num_harts; cpu++) {
> +cells =  g_new0(uint32_t, s->soc.cpus.num_harts * 4);
> +for (cpu = 0; cpu < s->soc.cpus.num_harts; cpu++) {
>  nodename =
>  g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
>  uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename);
> @@ -159,12 +159,12 @@ static void create_fdt(SiFiveUState *s, const struct
> MemmapEntry *memmap,
>  0x0, memmap[SIFIVE_U_CLINT].base,
>  0x0, memmap[SIFIVE_U_CLINT].size);
>  qemu_fdt_setprop(fdt, nodename, "interrupts-extended",
> -cells, s->soc.num_harts * sizeof(uint32_t) * 4);
> +cells, s->soc.cpus.num_harts * sizeof(uint32_t) * 4);
>  g_free(cells);
>  g_free(nodename);
>
> -cells =  g_new0(uint32_t, s->soc.num_harts * 4);
> -for (cpu = 0; cpu < s->soc.num_harts; cpu++) {
> +cells =  g_new0(uint32_t, s->soc.cpus.num_harts * 4);
> +for (cpu = 0; cpu < s->soc.cpus.num_harts; cpu++) {
>  nodename =
>  g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu);
>  uint32_t intc_phandle = qemu_fdt_get_phandle(fdt, nodename);
> @@ -181,7 +181,7 @@ static void create_fdt(SiFiveUState *s, const struct
> MemmapEntry *memmap,
>  qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv,plic0");
>  qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
>  qemu_fdt_setprop(fdt, nodename, "interrupts-extended",
> -cells, s->soc.num_harts * sizeof(uint32_t) * 4);
> +cells, s->soc.cpus.num_harts * sizeof(uint32_t) * 4);
>  qemu_fdt_setprop_cells(fdt, nodename, "reg",
>  0x0, memmap[SIFIVE_U_PLIC].base,
>  0x0, memmap[SIFIVE_U_PLIC].size);
> @@ -217,17 +217,12 @@ static void riscv_sifive_u_init(MachineState
> *machine)
>  SiFiveUState *s = g_new0(SiFiveUState, 1);
>  MemoryRegion *system_memory = get_system_memory();
>  MemoryRegion *main_mem = g_new(MemoryRegion, 1);
> -MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
>  int i;
>
> -/* Initialize SOC */
> -object_initialize(&s->soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY);
> +/* Initialize SoC */
> +object_initialize(&s->soc, sizeof(s->soc), TYPE_RISCV_U54_SOC);
>  object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
>  

Re: [Qemu-devel] [PATCH v2 6/7] hw/riscv/sifive_u: Move the uart device tree node under /soc/

2018-05-12 Thread Michael Clark
On Sat, May 12, 2018 at 11:28 AM, Alistair Francis  wrote:

> Signed-off-by: Alistair Francis 
>

Reviewed-by: Michael Clark 


> ---
>  hw/riscv/sifive_u.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 50389cdc90..540d53bf2f 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -194,7 +194,7 @@ static void create_fdt(SiFiveUState *s, const struct
> MemmapEntry *memmap,
>  g_free(cells);
>  g_free(nodename);
>
> -nodename = g_strdup_printf("/uart@%lx",
> +nodename = g_strdup_printf("/soc/uart@%lx",
>  (long)memmap[SIFIVE_U_UART0].base);
>  qemu_fdt_add_subnode(fdt, nodename);
>  qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,uart0");
> --
> 2.17.0
>
>


Re: [Qemu-devel] [PATCH v2 7/7] hw/riscv/sifive_u: Connect the Cadence GEM Ethernet device

2018-05-12 Thread Michael Clark
On Sat, May 12, 2018 at 11:28 AM, Alistair Francis  wrote:

> Connect the Cadence GEM ethernet device. This also requires us to
> expose the plic interrupt lines.
>
> Signed-off-by: Alistair Francis 
>

Reviewed-by: Michael Clark 


> ---
>  default-configs/riscv32-softmmu.mak |  1 +
>  default-configs/riscv64-softmmu.mak |  1 +
>  hw/riscv/sifive_u.c | 50 +
>  include/hw/riscv/sifive_u.h |  9 --
>  4 files changed, 59 insertions(+), 2 deletions(-)
>
> diff --git a/default-configs/riscv32-softmmu.mak
> b/default-configs/riscv32-softmmu.mak
> index f9e742120c..9a1c42e8b2 100644
> --- a/default-configs/riscv32-softmmu.mak
> +++ b/default-configs/riscv32-softmmu.mak
> @@ -2,3 +2,4 @@
>
>  CONFIG_SERIAL=y
>  CONFIG_VIRTIO=y
> +CONFIG_CADENCE=y
> diff --git a/default-configs/riscv64-softmmu.mak
> b/default-configs/riscv64-softmmu.mak
> index f9e742120c..9a1c42e8b2 100644
> --- a/default-configs/riscv64-softmmu.mak
> +++ b/default-configs/riscv64-softmmu.mak
> @@ -2,3 +2,4 @@
>
>  CONFIG_SERIAL=y
>  CONFIG_VIRTIO=y
> +CONFIG_CADENCE=y
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 540d53bf2f..fff36bd04d 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -60,8 +60,11 @@ static const struct MemmapEntry {
>  [SIFIVE_U_UART0] ={ 0x10013000, 0x1000 },
>  [SIFIVE_U_UART1] ={ 0x10023000, 0x1000 },
>  [SIFIVE_U_DRAM] = { 0x8000,0x0 },
> +[SIFIVE_U_GEM] =  { 0x100900FC, 0x2000 },
>  };
>
> +#define GEM_REVISION0x10070109
> +
>  static uint64_t load_kernel(const char *kernel_filename)
>  {
>  uint64_t kernel_entry, kernel_high;
> @@ -194,6 +197,27 @@ static void create_fdt(SiFiveUState *s, const struct
> MemmapEntry *memmap,
>  g_free(cells);
>  g_free(nodename);
>
> +nodename = g_strdup_printf("/soc/ethernet@%lx",
> +(long)memmap[SIFIVE_U_GEM].base);
> +qemu_fdt_add_subnode(fdt, nodename);
> +qemu_fdt_setprop_string(fdt, nodename, "compatible", "cdns,macb");
> +qemu_fdt_setprop_cells(fdt, nodename, "reg",
> +0x0, memmap[SIFIVE_U_GEM].base,
> +0x0, memmap[SIFIVE_U_GEM].size);
> +qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
> +qemu_fdt_setprop_string(fdt, nodename, "phy-mode", "gmii");
> +qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent",
> plic_phandle);
> +qemu_fdt_setprop_cells(fdt, nodename, "interrupts", SIFIVE_U_GEM_IRQ);
> +qemu_fdt_setprop_cells(fdt, nodename, "#address-cells", 1);
> +qemu_fdt_setprop_cells(fdt, nodename, "#size-cells", 0);
> +g_free(nodename);
> +
> +nodename = g_strdup_printf("/soc/ethernet@%lx/ethernet-phy@0",
> +(long)memmap[SIFIVE_U_GEM].base);
> +qemu_fdt_add_subnode(fdt, nodename);
> +qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x0);
> +g_free(nodename);
> +
>  nodename = g_strdup_printf("/soc/uart@%lx",
>  (long)memmap[SIFIVE_U_UART0].base);
>  qemu_fdt_add_subnode(fdt, nodename);
> @@ -296,6 +320,9 @@ static void riscv_sifive_u54_init(Object *obj)
> memmap[SIFIVE_U_MROM].size, &error_fatal);
>  memory_region_add_subregion(system_memory,
> memmap[SIFIVE_U_MROM].base,
>  mask_rom);
> +
> +object_initialize(&s->gem, sizeof(s->gem), TYPE_CADENCE_GEM);
> +qdev_set_parent_bus(DEVICE(&s->gem), sysbus_get_default());
>  }
>
>  static void riscv_sifive_u54_realize(DeviceState *dev, Error **errp)
> @@ -303,6 +330,10 @@ static void riscv_sifive_u54_realize(DeviceState
> *dev, Error **errp)
>  SiFiveU54State *s = RISCV_U54_SOC(dev);
>  const struct MemmapEntry *memmap = sifive_u_memmap;
>  MemoryRegion *system_memory = get_system_memory();
> +qemu_irq plic_gpios[SIFIVE_U_PLIC_NUM_SOURCES];
> +int i;
> +Error *err = NULL;
> +NICInfo *nd = &nd_table[0];
>
>  object_property_set_bool(OBJECT(&s->cpus), true, "realized",
>   &error_abort);
> @@ -327,6 +358,25 @@ static void riscv_sifive_u54_realize(DeviceState
> *dev, Error **errp)
>  sifive_clint_create(memmap[SIFIVE_U_CLINT].base,
>  memmap[SIFIVE_U_CLINT].size, smp_cpus,
>  SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
> +
> +for (i = 0; i < SIFIVE_U_PLIC_NUM_SOURCES; i++) {
> +plic_gpios[i] = qdev_get_gpio_in(DEVICE(s->plic), i);
> +}
> +
> +if

Re: [Qemu-devel] [PATCH v2 5/7] hw/riscv/sifive_u: Set the interrupt controler number of interrupts

2018-05-12 Thread Michael Clark
On Sat, May 12, 2018 at 11:28 AM, Alistair Francis  wrote:

> Set the interrupt-controller ndev to the correct number taken from the
> HiFive Unleashed board.
>
> Signed-off-by: Alistair Francis 
>

If you look at hw/riscv/virt.c we have removed hardcoding a few more
constants using in the device tree. e.g. we allocate and resolve phandles
vs hardcoding them. We can alwauys make a follow up commits to move some of
these magic numbers into constants in the headers, preferably with enum vs
#define.

Reviewed-by: Michael Clark 

---
>  hw/riscv/sifive_u.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 859f43c6f9..50389cdc90 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -187,7 +187,7 @@ static void create_fdt(SiFiveUState *s, const struct
> MemmapEntry *memmap,
>  0x0, memmap[SIFIVE_U_PLIC].size);
>  qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
>  qemu_fdt_setprop_cell(fdt, nodename, "riscv,max-priority", 7);
> -qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", 4);
> +qemu_fdt_setprop_cell(fdt, nodename, "riscv,ndev", 0x35);
>  qemu_fdt_setprop_cells(fdt, nodename, "phandle", 2);
>  qemu_fdt_setprop_cells(fdt, nodename, "linux,phandle", 2);
>  plic_phandle = qemu_fdt_get_phandle(fdt, nodename);
> --
> 2.17.0
>
>


Re: [Qemu-devel] [PATCH v2 20/27] target/riscv: Remove floatX_maybe_silence_nan from conversions

2018-05-12 Thread Michael Clark
On Sat, May 12, 2018 at 12:43 PM, Richard Henderson <
richard.hender...@linaro.org> wrote:

> This is now handled properly by the generic softfloat code.
>
> Cc: Michael Clark 
> Cc: Palmer Dabbelt 
> Cc: Sagar Karandikar 
> Cc: Bastian Koppelmann 
> Signed-off-by: Richard Henderson 
>

Reviewed-by: Michael Clark 

---
>  target/riscv/fpu_helper.c | 6 ++
>  1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
> index abbadead5c..fdb87d8d82 100644
> --- a/target/riscv/fpu_helper.c
> +++ b/target/riscv/fpu_helper.c
> @@ -279,14 +279,12 @@ uint64_t helper_fmax_d(CPURISCVState *env, uint64_t
> frs1, uint64_t frs2)
>
>  uint64_t helper_fcvt_s_d(CPURISCVState *env, uint64_t rs1)
>  {
> -rs1 = float64_to_float32(rs1, &env->fp_status);
> -return float32_maybe_silence_nan(rs1, &env->fp_status);
> +return float64_to_float32(rs1, &env->fp_status);
>  }
>
>  uint64_t helper_fcvt_d_s(CPURISCVState *env, uint64_t rs1)
>  {
> -rs1 = float32_to_float64(rs1, &env->fp_status);
> -return float64_maybe_silence_nan(rs1, &env->fp_status);
> +return float32_to_float64(rs1, &env->fp_status);
>  }
>
>  uint64_t helper_fsqrt_d(CPURISCVState *env, uint64_t frs1)
> --
> 2.17.0
>
>


Re: [Qemu-devel] [PATCH v2] riscv: remove define cpu_init()

2018-05-17 Thread Michael Clark
On Wed, May 16, 2018 at 4:00 AM, Igor Mammedov  wrote:

> cpu_init() was removed since 2.12, so drop the define that is now unused.
>
> Signed-off-by: Igor Mammedov 
> Reviewed-by: Philippe Mathieu-Daudé 
>

Reviewed-by: Michael Clark 

---
> v2:
>   * refine commit message (Eric Blake )
> ---
>  target/riscv/cpu.h | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 34abc38..0562a02 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -251,7 +251,6 @@ int riscv_cpu_handle_mmu_fault(CPUState *cpu, vaddr
> address, int size,
>  char *riscv_isa_string(RISCVCPU *cpu);
>  void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf);
>
> -#define cpu_init(cpu_model) cpu_generic_init(TYPE_RISCV_CPU, cpu_model)
>  #define cpu_signal_handler cpu_riscv_signal_handler
>  #define cpu_list riscv_cpu_list
>  #define cpu_mmu_index riscv_cpu_mmu_index
> --
> 2.7.4
>
>


Re: [Qemu-devel] [PATCH v3 2/7] hw/riscv/sifive_e: Create a SiFive E SoC object

2018-05-17 Thread Michael Clark
On Tue, May 15, 2018 at 12:07 PM, Alistair Francis  wrote:

> Signed-off-by: Alistair Francis 
>

Reviewed-by: Michael Clark 


> ---
>  hw/riscv/sifive_e.c | 97 +++--
>  include/hw/riscv/sifive_e.h | 16 +-
>  2 files changed, 86 insertions(+), 27 deletions(-)
>
> diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
> index e4ecb7aa4b..384b456540 100644
> --- a/hw/riscv/sifive_e.c
> +++ b/hw/riscv/sifive_e.c
> @@ -102,18 +102,12 @@ static void riscv_sifive_e_init(MachineState
> *machine)
>  SiFiveEState *s = g_new0(SiFiveEState, 1);
>  MemoryRegion *sys_mem = get_system_memory();
>  MemoryRegion *main_mem = g_new(MemoryRegion, 1);
> -MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
> -MemoryRegion *xip_mem = g_new(MemoryRegion, 1);
>  int i;
>
> -/* Initialize SOC */
> -object_initialize(&s->soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY);
> +/* Initialize SoC */
> +object_initialize(&s->soc, sizeof(s->soc), TYPE_RISCV_E_SOC);
>  object_property_add_child(OBJECT(machine), "soc", OBJECT(&s->soc),
>&error_abort);
> -object_property_set_str(OBJECT(&s->soc), SIFIVE_E_CPU, "cpu-type",
> -&error_abort);
> -object_property_set_int(OBJECT(&s->soc), smp_cpus, "num-harts",
> -&error_abort);
>  object_property_set_bool(OBJECT(&s->soc), true, "realized",
>  &error_abort);
>
> @@ -123,11 +117,57 @@ static void riscv_sifive_e_init(MachineState
> *machine)
>  memory_region_add_subregion(sys_mem,
>  memmap[SIFIVE_E_DTIM].base, main_mem);
>
> +/* Mask ROM reset vector */
> +uint32_t reset_vec[2] = {
> +0x204002b7,/* 0x1000: lui t0,0x20400 */
> +0x00028067,/* 0x1004: jr  t0 */
> +};
> +
> +/* copy in the reset vector in little_endian byte order */
> +for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
> +reset_vec[i] = cpu_to_le32(reset_vec[i]);
> +}
> +rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec),
> +  memmap[SIFIVE_E_MROM].base,
> &address_space_memory);
> +
> +if (machine->kernel_filename) {
> +load_kernel(machine->kernel_filename);
> +}
> +}
> +
> +static void riscv_sifive_e_soc_init(Object *obj)
> +{
> +const struct MemmapEntry *memmap = sifive_e_memmap;
> +
> +SiFiveESoCState *s = RISCV_E_SOC(obj);
> +MemoryRegion *sys_mem = get_system_memory();
> +MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
> +
> +object_initialize(&s->cpus, sizeof(s->cpus), TYPE_RISCV_HART_ARRAY);
> +object_property_add_child(obj, "cpus", OBJECT(&s->cpus),
> +  &error_abort);
> +object_property_set_str(OBJECT(&s->cpus), SIFIVE_E_CPU, "cpu-type",
> +&error_abort);
> +object_property_set_int(OBJECT(&s->cpus), smp_cpus, "num-harts",
> +&error_abort);
> +
>  /* Mask ROM */
>  memory_region_init_rom(mask_rom, NULL, "riscv.sifive.e.mrom",
>  memmap[SIFIVE_E_MROM].size, &error_fatal);
>  memory_region_add_subregion(sys_mem,
>  memmap[SIFIVE_E_MROM].base, mask_rom);
> +}
> +
> +static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp)
> +{
> +const struct MemmapEntry *memmap = sifive_e_memmap;
> +
> +SiFiveESoCState *s = RISCV_E_SOC(dev);
> +MemoryRegion *sys_mem = get_system_memory();
> +MemoryRegion *xip_mem = g_new(MemoryRegion, 1);
> +
> +object_property_set_bool(OBJECT(&s->cpus), true, "realized",
> +&error_abort);
>
>  /* MMIO */
>  s->plic = sifive_plic_create(memmap[SIFIVE_E_PLIC].base,
> @@ -171,23 +211,6 @@ static void riscv_sifive_e_init(MachineState
> *machine)
>  memmap[SIFIVE_E_XIP].size, &error_fatal);
>  memory_region_set_readonly(xip_mem, true);
>  memory_region_add_subregion(sys_mem, memmap[SIFIVE_E_XIP].base,
> xip_mem);
> -
> -/* Mask ROM reset vector */
> -uint32_t reset_vec[2] = {
> -0x204002b7,/* 0x1000: lui t0,0x20400 */
> -0x00028067,/* 0x1004: jr  t0 */
> -};
> -
> -/* copy in the reset vector in little_endian byte order */
> -for (i = 0; i < sizeof(reset_vec) >> 2; i++) {
> -reset_vec[i] = cpu

Re: [Qemu-devel] [PATCH v3 4/7] hw/riscv/sifive_u: Set the soc device tree node as a simple-bus

2018-05-17 Thread Michael Clark
On Tue, May 15, 2018 at 12:07 PM, Alistair Francis  wrote:

> To allow Linux to ennumerate devices on the /soc/ node set it as a
> "simple-bus".
>
> Signed-off-by: Alistair Francis 
>

Reviewed-by: Michael Clark 


> ---
>  hw/riscv/sifive_u.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 3883d7ff9c..f438a72c27 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -97,7 +97,7 @@ static void create_fdt(SiFiveUState *s, const struct
> MemmapEntry *memmap,
>
>  qemu_fdt_add_subnode(fdt, "/soc");
>  qemu_fdt_setprop(fdt, "/soc", "ranges", NULL, 0);
> -qemu_fdt_setprop_string(fdt, "/soc", "compatible",
> "ucbbar,spike-bare-soc");
> +qemu_fdt_setprop_string(fdt, "/soc", "compatible", "simple-bus");
>  qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2);
>  qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2);
>
> --
> 2.17.0
>
>


Re: [Qemu-devel] [PATCH 5/9] target/riscv: Honor CPU_DUMP_FPU

2018-05-17 Thread Michael Clark
On Sun, May 13, 2018 at 12:52 PM, Philippe Mathieu-Daudé 
wrote:

> On 05/11/2018 12:52 AM, Richard Henderson wrote:
> > Cc: Michael Clark 
> > Cc: Palmer Dabbelt 
> > Cc: Sagar Karandikar 
> > Cc: Bastian Koppelmann 
> > Signed-off-by: Richard Henderson 
>
> Reviewed-by: Philippe Mathieu-Daudé 


Reviewed-by: Michael Clark 


> > ---
> >  target/riscv/cpu.c | 16 +++-
> >  1 file changed, 11 insertions(+), 5 deletions(-)
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 4e5a56d4e3..4612f324c9 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -199,6 +199,10 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE
> *f,
> >  int i;
> >
> >  cpu_fprintf(f, " %s " TARGET_FMT_lx "\n", "pc  ", env->pc);
> > +if (flags & CPU_DUMP_FPU) {
> > +cpu_fprintf(f, " %s " TARGET_FMT_lx "\n", "fcsr",
> > +cpu_riscv_get_fcsr(env));
> > +}
> >  #ifndef CONFIG_USER_ONLY
> >  cpu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
> >  cpu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", env->mstatus);
> > @@ -219,11 +223,13 @@ static void riscv_cpu_dump_state(CPUState *cs,
> FILE *f,
> >  cpu_fprintf(f, "\n");
> >  }
> >  }
> > -for (i = 0; i < 32; i++) {
> > -cpu_fprintf(f, " %s %016" PRIx64,
> > -riscv_fpr_regnames[i], env->fpr[i]);
> > -if ((i & 3) == 3) {
> > -cpu_fprintf(f, "\n");
> > +if (flags & CPU_DUMP_FPU) {
> > +for (i = 0; i < 32; i++) {
> > +cpu_fprintf(f, " %s %016" PRIx64,
> > +riscv_fpr_regnames[i], env->fpr[i]);
> > +if ((i & 3) == 3) {
> > +cpu_fprintf(f, "\n");
> > +}
> >  }
> >  }
> >  }
> >
>


Re: [Qemu-devel] [PATCH 4/9] target/riscv: Introduce cpu_riscv_get_fcsr

2018-05-17 Thread Michael Clark
On Fri, May 11, 2018 at 3:52 PM, Richard Henderson <
richard.hender...@linaro.org> wrote:

> Cc: Michael Clark 
> Cc: Palmer Dabbelt 
> Cc: Sagar Karandikar 
> Cc: Bastian Koppelmann 
> Signed-off-by: Richard Henderson 
>

I'm not against this change but it conflicts with changes in the riscv
repo. I should post my patch queue to the list...

We have made a somewhat medium sized change and have unraveled two
monolithic switch statements out of csr_read_helper switch and
csr_write_helper into clearly decomposed functions for modifying control
and status registers, along with an interface to allow CPUs to hook custom
control and status registers. This was done to support atomic
read/modify/write CSRs which was not possible to achieve with the current
helpers which separately called via the csr_read_helper followed by
csr_write_helper. Given the only way to modify CSRs was via the switch
statements, we needed to move them out to provide a mechanism for CSRs that
wish to be truly atomic. e.g. 'mip'. The CSR functions are defined in The
RISC-V Instruction Set Manual Volume I: User-Level ISA Document Version 2.2
as "atomic" instructions:

- CSRRW (Atomic Read/Write CSR)
- CSRRS (Atomic Read and Set Bits in CSR)
- CSRRC (Atomic Read and Clear Bits in CSR)

We have thus changed QEMU to allow truly atomic CSR implementations. The
new implementation replaces the compiler doing compare/branch vs jump table
switch codegen for a sparse CSR address space with a single array of
function pointers. i.e. load, indirect jump. Along with this change we have
also renamed functions in target/riscv to use riscv_ prefix and added a
public interface to hook custom CSRs. The CSR changes will allow out of
tree code to hook custom CSRs without needing to change target/riscv code.

- riscv_cpu_ won over cpu_riscv_ given the number of functions conforming
with the former riscv_ prefix and the desire for consistency in target/riscv

In the riscv tree we now have riscv_csr_read(env, CSR_FCSR)
and riscv_csr_write(env, CSR_FCSR, fcsr) as the method to read and write
the composite. There is also a user in linux-user/riscv/signal.c that
should probably use the new interface. We could change
linux-user/riscv/signal.c to use your new interface however your interface
only provides a read method and no write method, so the write interface
remains in the (current) big CSR switch statement, leaving an inconsitency
between the encapsulation of read and write. We currently have the new fcsr
read and write encapsulated in static functions read_fcsr and write_fcsr in
a new csr module (which should perhaps be called csr_helper.c).

See:

- https://github.com/riscv/riscv-qemu/commits/qemu-2.13-for-upstream
-
https://github.com/riscv/riscv-qemu/commit/0783ce5ea580552b1f8e2f16a3e3cc1af19db69b
-
https://github.com/riscv/riscv-qemu/commit/fa17549fbc726e83a3c163b1534c7465147c6718


> ---
>  target/riscv/cpu.h| 1 +
>  target/riscv/fpu_helper.c | 6 ++
>  target/riscv/op_helper.c  | 3 +--
>  3 files changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 34abc383e3..f2bc243b95 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -265,6 +265,7 @@ void QEMU_NORETURN do_raise_exception_err(CPURISCVState
> *env,
>uint32_t exception, uintptr_t
> pc);
>
>  target_ulong cpu_riscv_get_fflags(CPURISCVState *env);
> +target_ulong cpu_riscv_get_fcsr(CPURISCVState *env);
>  void cpu_riscv_set_fflags(CPURISCVState *env, target_ulong);
>
>  #define TB_FLAGS_MMU_MASK  3
> diff --git a/target/riscv/fpu_helper.c b/target/riscv/fpu_helper.c
> index abbadead5c..41c7352115 100644
> --- a/target/riscv/fpu_helper.c
> +++ b/target/riscv/fpu_helper.c
> @@ -37,6 +37,12 @@ target_ulong cpu_riscv_get_fflags(CPURISCVState *env)
>  return hard;
>  }
>
> +target_ulong cpu_riscv_get_fcsr(CPURISCVState *env)
> +{
> +return (cpu_riscv_get_fflags(env) << FSR_AEXC_SHIFT)
> + | (env->frm << FSR_RD_SHIFT);
> +}
> +
>  void cpu_riscv_set_fflags(CPURISCVState *env, target_ulong hard)
>  {
>  int soft = 0;
> diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
> index 3abf52453c..fd2d8c0a9d 100644
> --- a/target/riscv/op_helper.c
> +++ b/target/riscv/op_helper.c
> @@ -423,8 +423,7 @@ target_ulong csr_read_helper(CPURISCVState *env,
> target_ulong csrno)
>  return env->frm;
>  case CSR_FCSR:
>  validate_mstatus_fs(env, GETPC());
> -return (cpu_riscv_get_fflags(env) << FSR_AEXC_SHIFT)
> -| (env->frm << FSR_RD_SHIFT);
> +return cpu_riscv_get_fcsr(env);
>  /* rdtime/rdtimeh is trapped and emulated by bbl in system mode */
>  #ifdef CONFIG_USER_ONLY
>  case CSR_TIME:
> --
> 2.17.0
>
>


Re: [Qemu-devel] [PATCH] RISC-V: make it possible to alter default reset vector

2018-05-17 Thread Michael Clark
On Tue, May 8, 2018 at 9:08 AM, Antony Pavlov 
wrote:

> The RISC-V Instruction Set Manual, Volume II:
> Privileged Architecture, Version 1.10 states
> that upon reset the pc is set to
> an implementation-defined reset vector
> (see chapter 3.3 Reset).
>
> This patch makes it possible to alter default
> reset vector by setting "rstvec" property
> for TYPE_RISCV_HART_ARRAY.
>

This one needs some thought. We have already made it possible for a CPU
class to override the reset vector, with consideration of this exact use
case.

The idea with the current approach is that you instantiate your specific
CPU model (target/riscv) in the hardware machine model (hw/riscv) and the
reset vector is a property of the CPU model you are using on your machine,
which is how it is now.

RISCVHartArray needs some work. First it is in 'hw/riscv' not
'target/riscv'. Secondly RISCVHartArray is commented as "heterogenous"
(nevertheless the current implementation is "homogeneous" so apologies if
this mislead you). The intention is that RISCVHartArray can construct a
heterogenous array of different cpu models with some topology. The current
shortcoming of homogeneity is in the current constructor which has only one
model property. The SiFive U54-MC for example has 5 cores, a 'e51' no-MMU
monitor core and 4 'u54' application cores e.g. "e51,u54,u54,u54,u54". The
reset vector should be a property of each CPU, given they can be different
models with different reset vectors. RISCVHartArray is a work in progress.

Background on whay RISCVHartArray exists, as a placeholder that will be
expanded to add support for configuration of "heterogeneous" core
complexes. There is some periphery that needs to reflect on the CPU array
properties. The SiFivePLIC memory layout is dependent on the cores in the "
heterogenous" core complex. We haven't yet wired the PLIC to RISCVHartArray
to get topoology information so it currently uses a mode list property
"M,MS,MS,MS,MS". The idea is that it can eventuall reflect on topology
configuration from the RISCVHartArray. Example: the 'e51' coreplex in the
U54-MC does not support S-mode but the 'u54' coreplex application cores do,
and the interrupt controller memory map is dependent on the topology. Our
idea was to re-use RISCVHartArray logic for instantiating "heterogenous"
core complexes as part of an SOC using some configuration e.g. an array of
cpu models. It's likely that individial CPUs will have different modes,
different reset vectors, different extensions, etc, etc.

Q1. Which CPU are you actually modelling?
Q2. Can you achieve your goal by defining your own CPU? I believe yes.
Q3. What object should have the property of a reset vector?

I believe the answer to Q3 is a specific cpu model, which is how we have
it, not a heterogenous array where some CPUs may indeed have different
reset vectors.

Apologies if RISCVHartArray gave you the idea the harts where homogeneous.
I believe moving a per cpu property onto the array is IMHO not the right
thing to do.

This leads into an RFC that I need to write on modelling dynamically
reconfigurable hardware models that can be produced by SiFive's core
generator. We want an interface that is kinder to the user than complex
command line options... or ones deemed inappropriate such as inferring
toplogy from a device-tree passed with -dtb e.g. an SOC class that
instantiates its cpu cores and hardware blocks as defined in the
device-tree at the given memory addresses with the given interrupt routing,
etc (we understand that this may work for some simple configurations, but
not for more complex configurations). The reset vector is a good example of
a property that is not available in device-tree. In any case the RFC on
configuration models for dynamically reconfigurable hardware will be
another email, however this serves as context for it. i.e. where a property
should be located. In fact we should fix the RISCVHartArray constructor or
possible move the class altogether until we have a good model for
constructing topology without hardcoding it in SOC structures, which for
SiFive's use of QEMU, would be a combinatorial explosion, given the
combinations of cores, extensions and blocks that can be generated by their
core generator, and that we wish to model in QEMU or some derivative, if we
have to maintain reconfigurable hardware support in a SiFive tree. I'll
leave the RFC proper for another email. This is just an abstract.

BTW - there are plently of others you can get to accept this patch ;-) See
the 'Cc.

Signed-off-by: Antony Pavlov 
> Cc: Michael Clark 
> Cc: Palmer Dabbelt 
> Cc: Sagar Karandikar 
> Cc: Bastian Koppelmann 
> Cc: Peter Crosthwaite 
> Cc: Peter Maydell 
> ---
>  hw/riscv/riscv_hart.c |  3 +++
>  include/hw/riscv/riscv

[Qemu-devel] [PATCH v1 00/30] QEMU 2.13 RISC-V updates

2018-05-22 Thread Michael Clark
This is a series of bug fixes, specification conformance
fixes and CPU feature modularily updates to allow more
precise modelling of the SiFive U Series CPUs (multi-core
application processors with MMU, Supervisor and User modes)
and SiFive E Series CPUs (embedded microcontroller cores
without MMU or Supervisor mode). This series adds several
updates to CPU features such as writable 'misa', minimal
hypervisor support for mstatus.TSR/TW/TVM, a new modular
interface for truly atomic CSRs, bug fixes and several
new features such as separate firmware and kernel payload.

These changes are available in the RISC-V GitHub repo:

- https://github.com/riscv/riscv-qemu/tree/qemu-2.13-for-upstream

Summary of changes

* Support separate firmware and kernel payload
  * Can use -bios bbl -kernel vmlinux on 'virt' machine
* Add infrastructure to support runtime 'misa' writes
* Implemented TSR, TW and TVM for privileged ISA v1.10
* Update floating-point to correctly mark mstatus.FS dirty.
* Made PMP (Physical Memory Protection) an optional CPU feature.
* Disabled access to s* CSRs on cores without misa.S set.
* Added CSR feature predicates to improve CPU emulation support
  and to allow for easier CPU model differentiation.
  * SiFive U series application processors (MMU, S-mode, U-mode)
  * SiFive E series embedded microcontrollers (no MMU, U-mode)
* Add non-trapping interface to CSRs so that gdbstub.c can
  accesses CSRs without longjmp being called.
* Implements an interface for atomic CSR accesses and convert
  accesses to 'mip' and 'sip' to the atomic interface:
  * The previous implementation using separate methods for
csr_read_helper and csr_write_helper was incompatible
with atomic CSR accesses. The previous implementation
used monolithic switch statements and was not modular.
  * Add public API so that CPUs can implement custom CSRs.
* Replaces locks with atomic lock-free updates for interrupt
  * Reduce idle Linux SMP CPU usage by up to 35%.
  * Increases CPU performance under load by up to 15%.
* Improved specification conformance of the page table walker
  * Change access checks from ternary operator to if statements.
  * Checks for misaligned PPNs.
  * Disallow M-mode or S-mode from fetching from User pages.
  * Adds reserved PTE flag check: W or W|X.
  * Set READ flag for PTE X flag if mstatus.mxr is in effect.
  * Improves page walker comments and code readability .

Testing Coverage

* Linux Fedora SMP mstatus.FS scheduler test: pass
* Linux Fedora SMP MTTCG tests (~22 hr GCC bootstrap): pass
* spike_v1.9.1 bbl/linux-4.6.2 board test: pass
* spike_v1.10 bbl/linux-4.14 board test: pass
* virt bbl/linux-4.16-rc2 board test: pass
* sifive_e board test (HiFive1 binaries): pass
* sifive_u board test (HiFive Unleashed): pass
* riscv-tests: pass
* checkpatch: pass

Kito Cheng (1):
  RISC-V: linux-user support for RVE ABI

Michael Clark (27):
  RISC-V: Update address bits to support sv39 and sv48
  RISC-V: Improve page table walker spec compliance
  RISC-V: Use atomic_cmpxchg to update PLIC bitmaps
  RISC-V: Simplify riscv_cpu_local_irqs_pending
  RISC-V: Allow setting and clearing multiple irqs
  RISC-V: Move non-ops from op_helper to cpu_helper
  RISC-V: Update CSR and interrupt definitions
  RISC-V: Implement modular CSR helper interface
  RISC-V: Implement atomic mip/sip CSR updates
  RISC-V: Implement existential predicates for CSRs
  RISC-V: Implement mstatus.TSR/TW/TVM
  RISC-V: Add public API for the CSR dispatch table
  RISC-V: Add hartid and \n to interrupt logging
  RISC-V: Use riscv prefix consistently on cpu helpers
  RISC-V: Replace __builtin_popcount with ctpop8 in PLIC
  RISC-V: Add missing free for plic_hart_config
  RISC-V: Allow interrupt controllers to claim interrupts
  RISC-V: Add misa to DisasContext
  RISC-V: Add misa.MAFD checks to translate
  RISC-V: Add misa runtime write support
  RISC-V: Fix CLINT timecmp low 32-bit writes
  RISC-V: Fix PLIC pending bitfield reads
  RISC-V: Enable second UART on sifive_e and sifive_u
  RISC-V: Remove unnecessary disassembler constraints
  elf: Add RISC-V PSABI ELF header defines
  RISC-V: Don't add NULL bootargs to device-tree
  RISC-V: Support separate firmware and kernel payload

Richard Henderson (2):
  RISC-V: Split out mstatus_fs from tb_flags
  RISC-V: Mark mstatus.fs dirty

 disas/riscv.c   | 138 -
 hw/riscv/Makefile.objs  |   1 +
 hw/riscv/boot.c | 172 ++
 hw/riscv/sifive_clint.c |  16 +-
 hw/riscv/sifive_e.c |   4 +-
 hw/riscv/sifive_plic.c  |  72 +--
 hw/riscv/sifive_u.c |   8 +-
 hw/riscv/spike.c|   6 +-
 hw/riscv/virt.c |  73 +--
 include/elf.h   |   8 +
 include/hw/riscv/boot.h |  30 ++
 include/hw/riscv/sifive_plic.h  |   1 -
 linux

[Qemu-devel] [PATCH v1 02/30] RISC-V: Improve page table walker spec compliance

2018-05-22 Thread Michael Clark
- Inline PTE_TABLE check for better readability
- Change access checks from ternary operator to if
- Improve readibility of User page U mode and SUM test
- Disallow non U mode from fetching from User pages
- Add reserved PTE flag check: W or W|X
- Add misaligned PPN check
- Set READ protection for PTE X flag and mstatus.mxr
- Use memory_region_is_ram in pte update

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu_bits.h |  2 --
 target/riscv/helper.c   | 64 ++---
 2 files changed, 45 insertions(+), 21 deletions(-)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 64aa097181fa..12b4757088f4 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -407,5 +407,3 @@
 #define PTE_SOFT  0x300 /* Reserved for Software */
 
 #define PTE_PPN_SHIFT 10
-
-#define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V)
diff --git a/target/riscv/helper.c b/target/riscv/helper.c
index 95889f23b94d..3b57e1360549 100644
--- a/target/riscv/helper.c
+++ b/target/riscv/helper.c
@@ -185,16 +185,39 @@ restart:
 #endif
 target_ulong ppn = pte >> PTE_PPN_SHIFT;
 
-if (PTE_TABLE(pte)) { /* next level of page table */
+if (!(pte & PTE_V)) {
+/* Invalid PTE */
+return TRANSLATE_FAIL;
+} else if (!(pte & (PTE_R | PTE_W | PTE_X))) {
+/* Inner PTE, continue walking */
 base = ppn << PGSHIFT;
-} else if ((pte & PTE_U) ? (mode == PRV_S) && !sum : !(mode == PRV_S)) 
{
-break;
-} else if (!(pte & PTE_V) || (!(pte & PTE_R) && (pte & PTE_W))) {
-break;
-} else if (access_type == MMU_INST_FETCH ? !(pte & PTE_X) :
-  access_type == MMU_DATA_LOAD ?  !(pte & PTE_R) &&
-  !(mxr && (pte & PTE_X)) : !((pte & PTE_R) && (pte & PTE_W))) 
{
-break;
+} else if ((pte & (PTE_R | PTE_W | PTE_X)) == PTE_W) {
+/* Reserved leaf PTE flags: PTE_W */
+return TRANSLATE_FAIL;
+} else if ((pte & (PTE_R | PTE_W | PTE_X)) == (PTE_W | PTE_X)) {
+/* Reserved leaf PTE flags: PTE_W + PTE_X */
+return TRANSLATE_FAIL;
+} else if ((pte & PTE_U) && ((mode != PRV_U) &&
+   (!sum || access_type == MMU_INST_FETCH))) {
+/* User PTE flags when not U mode and mstatus.SUM is not set,
+   or the access type is an instruction fetch */
+return TRANSLATE_FAIL;
+} else if (!(pte & PTE_U) && (mode != PRV_S)) {
+/* Supervisor PTE flags when not S mode */
+return TRANSLATE_FAIL;
+} else if (ppn & ((1ULL << ptshift) - 1)) {
+/* Misasligned PPN */
+return TRANSLATE_FAIL;
+} else if (access_type == MMU_DATA_LOAD && !((pte & PTE_R) ||
+   ((pte & PTE_X) && mxr))) {
+/* Read access check failed */
+return TRANSLATE_FAIL;
+} else if (access_type == MMU_DATA_STORE && !(pte & PTE_W)) {
+/* Write access check failed */
+return TRANSLATE_FAIL;
+} else if (access_type == MMU_INST_FETCH && !(pte & PTE_X)) {
+/* Fetch access check failed */
+return TRANSLATE_FAIL;
 } else {
 /* if necessary, set accessed and dirty bits. */
 target_ulong updated_pte = pte | PTE_A |
@@ -202,16 +225,19 @@ restart:
 
 /* Page table updates need to be atomic with MTTCG enabled */
 if (updated_pte != pte) {
-/* if accessed or dirty bits need updating, and the PTE is
- * in RAM, then we do so atomically with a compare and swap.
- * if the PTE is in IO space, then it can't be updated.
- * if the PTE changed, then we must re-walk the page table
-   as the PTE is no longer valid */
+/*
+ * - if accessed or dirty bits need updating, and the PTE is
+ *   in RAM, then we do so atomically with a compare and swap.
+ * - if the PTE is in IO space or ROM, then it can't be updated
+ *   and we return TRANSLATE_FAIL.
+ * - if the PTE changed by the time we went to update it, then
+ *   it is no longer valid and we must re-walk the page table.
+ */
 MemoryRegion *mr;
 hwaddr l = sizeof(target_ulong), addr1;
 mr = address_space_translate(cs->as, pte_addr,
 &addr1, &l, false);
-if (memory_access_is_direct(mr, tr

[Qemu-devel] [PATCH v1 04/30] RISC-V: Simplify riscv_cpu_local_irqs_pending

2018-05-22 Thread Michael Clark
This commit is intended to improve readability.
There is no change to the logic.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Alistair Francis 
---
 target/riscv/helper.c | 34 --
 1 file changed, 12 insertions(+), 22 deletions(-)

diff --git a/target/riscv/helper.c b/target/riscv/helper.c
index 3b57e1360549..47d116e9c13f 100644
--- a/target/riscv/helper.c
+++ b/target/riscv/helper.c
@@ -35,28 +35,18 @@ int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
 }
 
 #ifndef CONFIG_USER_ONLY
-/*
- * Return RISC-V IRQ number if an interrupt should be taken, else -1.
- * Used in cpu-exec.c
- *
- * Adapted from Spike's processor_t::take_interrupt()
- */
-static int riscv_cpu_hw_interrupts_pending(CPURISCVState *env)
+static int riscv_cpu_local_irq_pending(CPURISCVState *env)
 {
-target_ulong pending_interrupts = atomic_read(&env->mip) & env->mie;
-
-target_ulong mie = get_field(env->mstatus, MSTATUS_MIE);
-target_ulong m_enabled = env->priv < PRV_M || (env->priv == PRV_M && mie);
-target_ulong enabled_interrupts = pending_interrupts &
-  ~env->mideleg & -m_enabled;
-
-target_ulong sie = get_field(env->mstatus, MSTATUS_SIE);
-target_ulong s_enabled = env->priv < PRV_S || (env->priv == PRV_S && sie);
-enabled_interrupts |= pending_interrupts & env->mideleg &
-  -s_enabled;
-
-if (enabled_interrupts) {
-return ctz64(enabled_interrupts); /* since non-zero */
+target_ulong mstatus_mie = get_field(env->mstatus, MSTATUS_MIE);
+target_ulong mstatus_sie = get_field(env->mstatus, MSTATUS_SIE);
+target_ulong pending = atomic_read(&env->mip) & env->mie;
+target_ulong mie = env->priv < PRV_M || (env->priv == PRV_M && 
mstatus_mie);
+target_ulong sie = env->priv < PRV_S || (env->priv == PRV_S && 
mstatus_sie);
+target_ulong irqs = (pending & ~env->mideleg & -mie) |
+(pending &  env->mideleg & -sie);
+
+if (irqs) {
+return ctz64(irqs); /* since non-zero */
 } else {
 return EXCP_NONE; /* indicates no pending interrupt */
 }
@@ -69,7 +59,7 @@ bool riscv_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
 if (interrupt_request & CPU_INTERRUPT_HARD) {
 RISCVCPU *cpu = RISCV_CPU(cs);
 CPURISCVState *env = &cpu->env;
-int interruptno = riscv_cpu_hw_interrupts_pending(env);
+int interruptno = riscv_cpu_local_irq_pending(env);
 if (interruptno >= 0) {
 cs->exception_index = RISCV_EXCP_INT_FLAG | interruptno;
 riscv_cpu_do_interrupt(cs);
-- 
2.7.0




[Qemu-devel] [PATCH v1 08/30] RISC-V: Implement modular CSR helper interface

2018-05-22 Thread Michael Clark
Previous CSR code uses csr_read_helper and csr_write_helper
to update CSR registers however this interface prevents
atomic read/modify/write CSR operations; in addition
there is no trap-free method to access to CSRs due
to the monolithic CSR functions call longjmp.

The current iCSR interface is not safe to be called by
target/riscv/gdbstub.c as privilege checks or missing CSRs
may call longjmp to generate exceptions. It needs to
indicate existence so traps can be generated in the
CSR instruction helpers.

This commit moves CSR access from the monolithic switch
statements in target/riscv/op_helper.c into modular
read/write functions in target/riscv/csr.c using a new
function pointer table for dispatch (which can later
be used to allow CPUs to hook up model specific CSRs).

A read/modify/write interface is added to support atomic
CSR operations and a non-trapping interface is added
to allow exception-free access to CSRs by the debugger.

The CSR functions and CSR dispatch table are ordered
to match The RISC-V Instruction Set Manual, Volume II:
Privileged Architecture Version 1.10, 2.2 CSR Listing.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
---
 target/riscv/Makefile.objs |   2 +-
 target/riscv/cpu.h |  18 +-
 target/riscv/cpu_helper.c  |   4 +-
 target/riscv/csr.c | 857 +
 target/riscv/gdbstub.c |  10 +-
 target/riscv/op_helper.c   | 611 +---
 6 files changed, 898 insertions(+), 604 deletions(-)
 create mode 100644 target/riscv/csr.c

diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index fcc5d34c1f2e..4072abe3e45c 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -1 +1 @@
-obj-y += translate.o op_helper.o cpu_helper.o cpu.o fpu_helper.o gdbstub.o 
pmp.o
+obj-y += translate.o op_helper.o cpu_helper.o cpu.o csr.o fpu_helper.o 
gdbstub.o pmp.o
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index c5d485769cde..02c60c45631b 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -290,9 +290,21 @@ static inline void cpu_get_tb_cpu_state(CPURISCVState 
*env, target_ulong *pc,
 #endif
 }
 
-void csr_write_helper(CPURISCVState *env, target_ulong val_to_write,
-target_ulong csrno);
-target_ulong csr_read_helper(CPURISCVState *env, target_ulong csrno);
+int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
+target_ulong new_value, target_ulong write_mask);
+
+static inline void csr_write_helper(CPURISCVState *env, target_ulong val,
+int csrno)
+{
+riscv_csrrw(env, csrno, NULL, val, -1);
+}
+
+static inline target_ulong csr_read_helper(CPURISCVState *env, int csrno)
+{
+target_ulong val = 0;
+riscv_csrrw(env, csrno, &val, 0, 0);
+return val;
+}
 
 #include "exec/cpu-all.h"
 
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 6c886e99055a..1f523861b7cb 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -526,7 +526,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 get_field(s, MSTATUS_SIE) : get_field(s, MSTATUS_UIE << 
env->priv));
 s = set_field(s, MSTATUS_SPP, env->priv);
 s = set_field(s, MSTATUS_SIE, 0);
-csr_write_helper(env, s, CSR_MSTATUS);
+env->mstatus = s;
 riscv_set_mode(env, PRV_S);
 } else {
 /* No need to check MTVEC for misaligned - lower 2 bits cannot be set 
*/
@@ -551,7 +551,7 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 get_field(s, MSTATUS_MIE) : get_field(s, MSTATUS_UIE << 
env->priv));
 s = set_field(s, MSTATUS_MPP, env->priv);
 s = set_field(s, MSTATUS_MIE, 0);
-csr_write_helper(env, s, CSR_MSTATUS);
+env->mstatus = s;
 riscv_set_mode(env, PRV_M);
 }
 /* TODO yield load reservation  */
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
new file mode 100644
index ..e08f3523d854
--- /dev/null
+++ b/target/riscv/csr.c
@@ -0,0 +1,857 @@
+/*
+ * RISC-V Control and Status Registers.
+ *
+ * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
+ * Copyright (c) 2017-2018 SiFive, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qem

[Qemu-devel] [PATCH v1 01/30] RISC-V: Update address bits to support sv39 and sv48

2018-05-22 Thread Michael Clark
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Signed-off-by: Palmer Dabbelt 
---
 target/riscv/cpu.h | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 34abc383e3d4..e0608e6d5f08 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -24,12 +24,12 @@
 #define TARGET_PAGE_BITS 12 /* 4 KiB Pages */
 #if defined(TARGET_RISCV64)
 #define TARGET_LONG_BITS 64
-#define TARGET_PHYS_ADDR_SPACE_BITS 50
-#define TARGET_VIRT_ADDR_SPACE_BITS 39
+#define TARGET_PHYS_ADDR_SPACE_BITS 56 /* 44-bit PPN */
+#define TARGET_VIRT_ADDR_SPACE_BITS 48 /* sv48 */
 #elif defined(TARGET_RISCV32)
 #define TARGET_LONG_BITS 32
-#define TARGET_PHYS_ADDR_SPACE_BITS 34
-#define TARGET_VIRT_ADDR_SPACE_BITS 32
+#define TARGET_PHYS_ADDR_SPACE_BITS 34 /* 22-bit PPN */
+#define TARGET_VIRT_ADDR_SPACE_BITS 32 /* sv32 */
 #endif
 
 #define TCG_GUEST_DEFAULT_MO 0
-- 
2.7.0




[Qemu-devel] [PATCH v1 07/30] RISC-V: Update CSR and interrupt definitions

2018-05-22 Thread Michael Clark
* Add user-mode CSR defininitions.
* Reorder CSR definitions to match the specification.
* Change H mode interrupt comment to 'reserved'.
* Remove unused X_COP interrupt.
* Add user-mode and core-level interrupts.
* Remove erroneous until comemnts on machine mode interrupts.
* Move together paging mode and page table bit definitions.
* Move together interrupt and exception cause definitions.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Alistair Francis 
---
 target/riscv/cpu_bits.h  | 692 +--
 target/riscv/op_helper.c |   4 +-
 2 files changed, 376 insertions(+), 320 deletions(-)

diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 12b4757088f4..878de6233846 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -6,242 +6,283 @@
  (((target_ulong)(val) * ((mask) & ~((mask) << 1))) & \
  (target_ulong)(mask)))
 
-#define PGSHIFT 12
-
-#define FSR_RD_SHIFT 5
-#define FSR_RD   (0x7 << FSR_RD_SHIFT)
-
-#define FPEXC_NX 0x01
-#define FPEXC_UF 0x02
-#define FPEXC_OF 0x04
-#define FPEXC_DZ 0x08
-#define FPEXC_NV 0x10
-
-#define FSR_AEXC_SHIFT 0
-#define FSR_NVA  (FPEXC_NV << FSR_AEXC_SHIFT)
-#define FSR_OFA  (FPEXC_OF << FSR_AEXC_SHIFT)
-#define FSR_UFA  (FPEXC_UF << FSR_AEXC_SHIFT)
-#define FSR_DZA  (FPEXC_DZ << FSR_AEXC_SHIFT)
-#define FSR_NXA  (FPEXC_NX << FSR_AEXC_SHIFT)
-#define FSR_AEXC (FSR_NVA | FSR_OFA | FSR_UFA | FSR_DZA | FSR_NXA)
-
-/* CSR numbers */
-#define CSR_FFLAGS 0x1
-#define CSR_FRM 0x2
-#define CSR_FCSR 0x3
-#define CSR_CYCLE 0xc00
-#define CSR_TIME 0xc01
-#define CSR_INSTRET 0xc02
-#define CSR_HPMCOUNTER3 0xc03
-#define CSR_HPMCOUNTER4 0xc04
-#define CSR_HPMCOUNTER5 0xc05
-#define CSR_HPMCOUNTER6 0xc06
-#define CSR_HPMCOUNTER7 0xc07
-#define CSR_HPMCOUNTER8 0xc08
-#define CSR_HPMCOUNTER9 0xc09
-#define CSR_HPMCOUNTER10 0xc0a
-#define CSR_HPMCOUNTER11 0xc0b
-#define CSR_HPMCOUNTER12 0xc0c
-#define CSR_HPMCOUNTER13 0xc0d
-#define CSR_HPMCOUNTER14 0xc0e
-#define CSR_HPMCOUNTER15 0xc0f
-#define CSR_HPMCOUNTER16 0xc10
-#define CSR_HPMCOUNTER17 0xc11
-#define CSR_HPMCOUNTER18 0xc12
-#define CSR_HPMCOUNTER19 0xc13
-#define CSR_HPMCOUNTER20 0xc14
-#define CSR_HPMCOUNTER21 0xc15
-#define CSR_HPMCOUNTER22 0xc16
-#define CSR_HPMCOUNTER23 0xc17
-#define CSR_HPMCOUNTER24 0xc18
-#define CSR_HPMCOUNTER25 0xc19
-#define CSR_HPMCOUNTER26 0xc1a
-#define CSR_HPMCOUNTER27 0xc1b
-#define CSR_HPMCOUNTER28 0xc1c
-#define CSR_HPMCOUNTER29 0xc1d
-#define CSR_HPMCOUNTER30 0xc1e
-#define CSR_HPMCOUNTER31 0xc1f
-#define CSR_SSTATUS 0x100
-#define CSR_SIE 0x104
-#define CSR_STVEC 0x105
-#define CSR_SCOUNTEREN 0x106
-#define CSR_SSCRATCH 0x140
-#define CSR_SEPC 0x141
-#define CSR_SCAUSE 0x142
-#define CSR_SBADADDR 0x143
-#define CSR_SIP 0x144
-#define CSR_SPTBR 0x180
-#define CSR_SATP 0x180
-#define CSR_MSTATUS 0x300
-#define CSR_MISA 0x301
-#define CSR_MEDELEG 0x302
-#define CSR_MIDELEG 0x303
-#define CSR_MIE 0x304
-#define CSR_MTVEC 0x305
-#define CSR_MCOUNTEREN 0x306
-#define CSR_MSCRATCH 0x340
-#define CSR_MEPC 0x341
-#define CSR_MCAUSE 0x342
-#define CSR_MBADADDR 0x343
-#define CSR_MIP 0x344
-#define CSR_PMPCFG0 0x3a0
-#define CSR_PMPCFG1 0x3a1
-#define CSR_PMPCFG2 0x3a2
-#define CSR_PMPCFG3 0x3a3
-#define CSR_PMPADDR0 0x3b0
-#define CSR_PMPADDR1 0x3b1
-#define CSR_PMPADDR2 0x3b2
-#define CSR_PMPADDR3 0x3b3
-#define CSR_PMPADDR4 0x3b4
-#define CSR_PMPADDR5 0x3b5
-#define CSR_PMPADDR6 0x3b6
-#define CSR_PMPADDR7 0x3b7
-#define CSR_PMPADDR8 0x3b8
-#define CSR_PMPADDR9 0x3b9
-#define CSR_PMPADDR10 0x3ba
-#define CSR_PMPADDR11 0x3bb
-#define CSR_PMPADDR12 0x3bc
-#define CSR_PMPADDR13 0x3bd
-#define CSR_PMPADDR14 0x3be
-#define CSR_PMPADDR15 0x3bf
-#define CSR_TSELECT 0x7a0
-#define CSR_TDATA1 0x7a1
-#define CSR_TDATA2 0x7a2
-#define CSR_TDATA3 0x7a3
-#define CSR_DCSR 0x7b0
-#define CSR_DPC 0x7b1
-#define CSR_DSCRATCH 0x7b2
-#define CSR_MCYCLE 0xb00
-#define CSR_MINSTRET 0xb02
-#define CSR_MHPMCOUNTER3 0xb03
-#define CSR_MHPMCOUNTER4 0xb04
-#define CSR_MHPMCOUNTER5 0xb05
-#define CSR_MHPMCOUNTER6 0xb06
-#define CSR_MHPMCOUNTER7 0xb07
-#define CSR_MHPMCOUNTER8 0xb08
-#define CSR_MHPMCOUNTER9 0xb09
-#define CSR_MHPMCOUNTER10 0xb0a
-#define CSR_MHPMCOUNTER11 0xb0b
-#define CSR_MHPMCOUNTER12 0xb0c
-#define CSR_MHPMCOUNTER13 0xb0d
-#define CSR_MHPMCOUNTER14 0xb0e
-#define CSR_MHPMCOUNTER15 0xb0f
-#define CSR_MHPMCOUNTER16 0xb10
-#define CSR_MHPMCOUNTER17 0xb11
-#define CSR_MHPMCOUNTER18 0xb12
-#define CSR_MHPMCOUNTER19 0xb13
-#define CSR_MHPMCOUNTER20 0xb14
-#define CSR_MHPMCOUNTER21 0xb15
-#define CSR_MHPMCOUNTER22 0xb16
-#define CSR_MHPMCOUNTER23 0xb17
-#define CSR_MHPMCOUNTER24 0xb18
-#define CSR_MHPMCOUNTER25 0xb19
-#define CSR_MHPMCOUNTER26 0xb1a
-#define CSR_MHPMCOUNTER27 0xb1b
-#define CSR_MHPMCOUNTER28 0xb1c
-#define CSR_MHPMCOUNTER29 0xb1d
-#define CSR_M

[Qemu-devel] [PATCH v1 13/30] RISC-V: Implement mstatus.TSR/TW/TVM

2018-05-22 Thread Michael Clark
This adds the necessary minimum to support S-mode
virtualization for priv ISA >= v1.10

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Cc: Matthew Suozzo 
Signed-off-by: Michael Clark 

Co-authored-by: Matthew Suozzo 
Co-authored-by: Michael Clark 
---
 target/riscv/csr.c   | 17 +
 target/riscv/op_helper.c | 25 +
 2 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index b4452388ff02..509215327243 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -313,7 +313,8 @@ static int write_mstatus(CPURISCVState *env, int csrno, 
target_ulong val)
 }
 mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
 MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM |
-MSTATUS_MPP | MSTATUS_MXR;
+MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
+MSTATUS_TW;
 }
 
 /* silenty discard mstatus.mpp writes for unsupported modes */
@@ -654,7 +655,11 @@ static int read_satp(CPURISCVState *env, int csrno, 
target_ulong *val)
 if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
 *val = 0;
 } else if (env->priv_ver >= PRIV_VERSION_1_10_0) {
-*val = env->satp;
+if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
+return -1;
+} else {
+*val = env->satp;
+}
 } else {
 *val = env->sptbr;
 }
@@ -675,8 +680,12 @@ static int write_satp(CPURISCVState *env, int csrno, 
target_ulong val)
 validate_vm(env, get_field(val, SATP_MODE)) &&
 ((val ^ env->satp) & (SATP_MODE | SATP_ASID | SATP_PPN)))
 {
-tlb_flush(CPU(riscv_env_get_cpu(env)));
-env->satp = val;
+if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) {
+return -1;
+} else {
+tlb_flush(CPU(riscv_env_get_cpu(env)));
+env->satp = val;
+}
 }
 return 0;
 }
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 81bd1a77ea90..77c79ba36e0b 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -82,6 +82,11 @@ target_ulong helper_sret(CPURISCVState *env, target_ulong 
cpu_pc_deb)
 do_raise_exception_err(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
 }
 
+if (env->priv_ver >= PRIV_VERSION_1_10_0 &&
+get_field(env->mstatus, MSTATUS_TSR)) {
+do_raise_exception_err(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
+}
+
 target_ulong mstatus = env->mstatus;
 target_ulong prev_priv = get_field(mstatus, MSTATUS_SPP);
 mstatus = set_field(mstatus,
@@ -125,16 +130,28 @@ void helper_wfi(CPURISCVState *env)
 {
 CPUState *cs = CPU(riscv_env_get_cpu(env));
 
-cs->halted = 1;
-cs->exception_index = EXCP_HLT;
-cpu_loop_exit(cs);
+if (env->priv == PRV_S &&
+env->priv_ver >= PRIV_VERSION_1_10_0 &&
+get_field(env->mstatus, MSTATUS_TW)) {
+do_raise_exception_err(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
+} else {
+cs->halted = 1;
+cs->exception_index = EXCP_HLT;
+cpu_loop_exit(cs);
+}
 }
 
 void helper_tlb_flush(CPURISCVState *env)
 {
 RISCVCPU *cpu = riscv_env_get_cpu(env);
 CPUState *cs = CPU(cpu);
-tlb_flush(cs);
+if (env->priv == PRV_S &&
+env->priv_ver >= PRIV_VERSION_1_10_0 &&
+get_field(env->mstatus, MSTATUS_TVM)) {
+do_raise_exception_err(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
+} else {
+tlb_flush(cs);
+}
 }
 
 #endif /* !CONFIG_USER_ONLY */
-- 
2.7.0




[Qemu-devel] [PATCH v1 19/30] RISC-V: Allow interrupt controllers to claim interrupts

2018-05-22 Thread Michael Clark
We can't allow the supervisor to control SEIP as this would allow the
supervisor to clear a pending external interrupt which will result in
lost a interrupt in the case a PLIC is attached. The SEIP bit must be
hardware controlled when a PLIC is attached.

This logic was previously hard-coded so SEIP was always masked even
if no PLIC was attached. This patch adds riscv_cpu_claim_interrupts
so that the PLIC can register control of SEIP. In the case of models
without a PLIC (spike), the SEIP bit remains software controlled.

This interface allows for hardware control of supervisor timer and
software interrupts by other interrupt controller models.

Cc: Palmer Dabbelt 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
---
 hw/riscv/sifive_plic.c| 13 +
 target/riscv/cpu.h|  2 ++
 target/riscv/cpu_helper.c | 11 +++
 target/riscv/csr.c| 12 
 4 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/hw/riscv/sifive_plic.c b/hw/riscv/sifive_plic.c
index dc6f4924e282..28e28d932f7c 100644
--- a/hw/riscv/sifive_plic.c
+++ b/hw/riscv/sifive_plic.c
@@ -23,6 +23,7 @@
 #include "qemu/error-report.h"
 #include "hw/sysbus.h"
 #include "target/riscv/cpu.h"
+#include "sysemu/sysemu.h"
 #include "hw/riscv/sifive_plic.h"
 
 #define RISCV_DEBUG_PLIC 0
@@ -447,6 +448,18 @@ static void sifive_plic_realize(DeviceState *dev, Error 
**errp)
 for (i = 0; i <= plic->num_sources; i++) {
 plic->irqs[i] = qemu_allocate_irq(sifive_plic_irq_request, plic, i);
 }
+
+/* We can't allow the supervisor to control SEIP as this would allow the
+ * supervisor to clear a pending external interrupt which will result in
+ * lost a interrupt in the case a PLIC is attached. The SEIP bit must be
+ * hardware controlled when a PLIC is attached. */
+for (i = 0; i < smp_cpus; i++) {
+RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(i));
+if (riscv_cpu_claim_interrupts(cpu, MIP_SEIP) < 0) {
+error_report("sifive_plic_realize: SEIP already claimed");
+exit(1);
+}
+}
 }
 
 static void sifive_plic_class_init(ObjectClass *klass, void *data)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index d6bb3136db18..ae0e3f6a544d 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -138,6 +138,7 @@ struct CPURISCVState {
  * mip is 32-bits to allow atomic_read on 32-bit hosts.
  */
 uint32_t mip;
+uint32_t miclaim;
 
 target_ulong mie;
 target_ulong mideleg;
@@ -262,6 +263,7 @@ void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 #define cpu_mmu_index riscv_cpu_mmu_index
 
 #ifndef CONFIG_USER_ONLY
+int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts);
 uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value);
 #define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */
 #endif
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index b4bbf7a9fa0a..7c9f6c46c75a 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -72,6 +72,17 @@ bool riscv_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
 
 #if !defined(CONFIG_USER_ONLY)
 
+int riscv_cpu_claim_interrupts(RISCVCPU *cpu, uint32_t interrupts)
+{
+CPURISCVState *env = &cpu->env;
+if (env->miclaim & interrupts) {
+return -1;
+} else {
+env->miclaim |= interrupts;
+return 0;
+}
+}
+
 /* iothread_mutex must be held */
 uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value)
 {
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 45e33d876034..9bbe81a110a5 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -502,15 +502,11 @@ static int rmw_mip(CPURISCVState *env, int csrno, 
target_ulong *ret_value,
target_ulong new_value, target_ulong write_mask)
 {
 RISCVCPU *cpu = riscv_env_get_cpu(env);
-target_ulong mask = write_mask & delegable_ints;
-uint32_t old_mip;
 
-/* We can't allow the supervisor to control SEIP as this would allow the
- * supervisor to clear a pending external interrupt which will result in
- * lost a interrupt in the case a PLIC is attached. The SEIP bit must be
- * hardware controlled when a PLIC is attached. This should be an option
- * for CPUs with software-delegated Supervisor External Interrupts. */
-mask &= ~MIP_SEIP;
+/* Allow software control of delegable interrupts not claimed by hardware 
*/
+target_ulong mask = write_mask & delegable_ints & ~env->miclaim;
+
+uint32_t old_mip;
 
 if (mask) {
 qemu_mutex_lock_iothread();
-- 
2.7.0




[Qemu-devel] [PATCH v1 03/30] RISC-V: Use atomic_cmpxchg to update PLIC bitmaps

2018-05-22 Thread Michael Clark
The PLIC previously used a mutex to protect against concurrent
access to the claimed and pending bitfields. Instead of using
a mutex, we update the bitfields using atomic_cmpxchg.

Rename sifive_plic_num_irqs_pending to sifive_plic_irqs_pending
and add an early out if any interrupts are pending as the
count of pending interrupts is not used.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
---
 hw/riscv/sifive_plic.c | 49 +++---
 include/hw/riscv/sifive_plic.h |  1 -
 2 files changed, 22 insertions(+), 28 deletions(-)

diff --git a/hw/riscv/sifive_plic.c b/hw/riscv/sifive_plic.c
index 874de2ebaf77..1af23c76e603 100644
--- a/hw/riscv/sifive_plic.c
+++ b/hw/riscv/sifive_plic.c
@@ -81,36 +81,32 @@ static void sifive_plic_print_state(SiFivePLICState *plic)
 }
 }
 
-static
-void sifive_plic_set_pending(SiFivePLICState *plic, int irq, bool pending)
+static uint32_t atomic_set_masked(uint32_t *a, uint32_t mask, uint32_t value)
 {
-qemu_mutex_lock(&plic->lock);
-uint32_t word = irq >> 5;
-if (pending) {
-plic->pending[word] |= (1 << (irq & 31));
-} else {
-plic->pending[word] &= ~(1 << (irq & 31));
-}
-qemu_mutex_unlock(&plic->lock);
+uint32_t old, new, cmp = atomic_read(a);
+
+do {
+old = cmp;
+new = (old & ~mask) | (value & mask);
+cmp = atomic_cmpxchg(a, old, new);
+} while (old != cmp);
+
+return old;
 }
 
-static
-void sifive_plic_set_claimed(SiFivePLICState *plic, int irq, bool claimed)
+static void sifive_plic_set_pending(SiFivePLICState *plic, int irq, bool level)
 {
-qemu_mutex_lock(&plic->lock);
-uint32_t word = irq >> 5;
-if (claimed) {
-plic->claimed[word] |= (1 << (irq & 31));
-} else {
-plic->claimed[word] &= ~(1 << (irq & 31));
-}
-qemu_mutex_unlock(&plic->lock);
+atomic_set_masked(&plic->pending[irq >> 5], 1 << (irq & 31), -!!level);
 }
 
-static
-int sifive_plic_num_irqs_pending(SiFivePLICState *plic, uint32_t addrid)
+static void sifive_plic_set_claimed(SiFivePLICState *plic, int irq, bool level)
 {
-int i, j, count = 0;
+atomic_set_masked(&plic->claimed[irq >> 5], 1 << (irq & 31), -!!level);
+}
+
+static int sifive_plic_irqs_pending(SiFivePLICState *plic, uint32_t addrid)
+{
+int i, j;
 for (i = 0; i < plic->bitfield_words; i++) {
 uint32_t pending_enabled_not_claimed =
 (plic->pending[i] & ~plic->claimed[i]) &
@@ -123,11 +119,11 @@ int sifive_plic_num_irqs_pending(SiFivePLICState *plic, 
uint32_t addrid)
 uint32_t prio = plic->source_priority[irq];
 int enabled = pending_enabled_not_claimed & (1 << j);
 if (enabled && prio > plic->target_priority[addrid]) {
-count++;
+return 1;
 }
 }
 }
-return count;
+return 0;
 }
 
 static void sifive_plic_update(SiFivePLICState *plic)
@@ -143,7 +139,7 @@ static void sifive_plic_update(SiFivePLICState *plic)
 if (!env) {
 continue;
 }
-int level = sifive_plic_num_irqs_pending(plic, addrid) > 0;
+int level = sifive_plic_irqs_pending(plic, addrid);
 switch (mode) {
 case PLICMode_M:
 riscv_set_local_interrupt(RISCV_CPU(cpu), MIP_MEIP, level);
@@ -440,7 +436,6 @@ static void sifive_plic_realize(DeviceState *dev, Error 
**errp)
 memory_region_init_io(&plic->mmio, OBJECT(dev), &sifive_plic_ops, plic,
   TYPE_SIFIVE_PLIC, plic->aperture_size);
 parse_hart_config(plic);
-qemu_mutex_init(&plic->lock);
 plic->bitfield_words = (plic->num_sources + 31) >> 5;
 plic->source_priority = g_new0(uint32_t, plic->num_sources);
 plic->target_priority = g_new(uint32_t, plic->num_addrs);
diff --git a/include/hw/riscv/sifive_plic.h b/include/hw/riscv/sifive_plic.h
index 11a5a98df1f9..ff09a288261e 100644
--- a/include/hw/riscv/sifive_plic.h
+++ b/include/hw/riscv/sifive_plic.h
@@ -55,7 +55,6 @@ typedef struct SiFivePLICState {
 uint32_t *pending;
 uint32_t *claimed;
 uint32_t *enable;
-QemuMutex lock;
 qemu_irq *irqs;
 
 /* config */
-- 
2.7.0




[Qemu-devel] [PATCH v1 12/30] RISC-V: Mark mstatus.fs dirty

2018-05-22 Thread Michael Clark
From: Richard Henderson 

Modifed from Richard Henderson's patch [1] to integrate
with the new control and status register implementation.

[1] https://lists.nongnu.org/archive/html/qemu-devel/2018-03/msg07034.html

Note: the f* CSRs already mark mstatus.FS dirty using
env->mstatus |= mstatus.FS so the bug in the first
spin of this patch has been fixed in a prior commit.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Cc: Richard Henderson 
Signed-off-by: Michael Clark 
Reviewed-by: Michael Clark 

Co-authored-by: Richard Henderson 
Co-authored-by: Michael Clark 
---
 target/riscv/csr.c   | 12 
 target/riscv/translate.c | 40 +++-
 2 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 0e6c0c365154..b4452388ff02 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -325,18 +325,6 @@ static int write_mstatus(CPURISCVState *env, int csrno, 
target_ulong val)
 
 mstatus = (mstatus & ~mask) | (val & mask);
 
-/* Note: this is a workaround for an issue where mstatus.FS
-   does not report dirty after floating point operations
-   that modify floating point state. This workaround is
-   technically compliant with the RISC-V Privileged
-   specification as it is legal to return only off, or dirty.
-   at the expense of extra floating point save/restore. */
-
-/* FP is always dirty or off */
-if (mstatus & MSTATUS_FS) {
-mstatus |= MSTATUS_FS;
-}
-
 int dirty = ((mstatus & MSTATUS_FS) == MSTATUS_FS) |
 ((mstatus & MSTATUS_XS) == MSTATUS_XS);
 mstatus = set_field(mstatus, MSTATUS_SD, dirty);
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index 466b9551cbd9..a980611eb611 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -651,6 +651,31 @@ static void gen_store(DisasContext *ctx, uint32_t opc, int 
rs1, int rs2,
 tcg_temp_free(dat);
 }
 
+#ifndef CONFIG_USER_ONLY
+/* The states of mstatus_fs are:
+ * 0 = disabled, 1 = initial, 2 = clean, 3 = dirty
+ * We will have already diagnosed disabled state,
+ * and need to turn initial/clean into dirty.
+ */
+static void mark_fs_dirty(DisasContext *ctx)
+{
+TCGv tmp;
+if (ctx->mstatus_fs == MSTATUS_FS) {
+return;
+}
+/* Remember the state change for the rest of the TB.  */
+ctx->mstatus_fs = MSTATUS_FS;
+
+tmp = tcg_temp_new();
+tcg_gen_ld_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
+tcg_gen_ori_tl(tmp, tmp, MSTATUS_FS);
+tcg_gen_st_tl(tmp, cpu_env, offsetof(CPURISCVState, mstatus));
+tcg_temp_free(tmp);
+}
+#else
+static inline void mark_fs_dirty(DisasContext *ctx) { }
+#endif
+
 static void gen_fp_load(DisasContext *ctx, uint32_t opc, int rd,
 int rs1, target_long imm)
 {
@@ -679,6 +704,8 @@ static void gen_fp_load(DisasContext *ctx, uint32_t opc, 
int rd,
 break;
 }
 tcg_temp_free(t0);
+
+mark_fs_dirty(ctx);
 }
 
 static void gen_fp_store(DisasContext *ctx, uint32_t opc, int rs1,
@@ -944,6 +971,7 @@ static void gen_fp_arith(DisasContext *ctx, uint32_t opc, 
int rd,
  int rs1, int rs2, int rm)
 {
 TCGv t0 = NULL;
+bool fp_output = true;
 
 if (ctx->mstatus_fs == 0) {
 goto do_illegal;
@@ -1006,6 +1034,7 @@ static void gen_fp_arith(DisasContext *ctx, uint32_t opc, 
int rd,
 }
 gen_set_gpr(rd, t0);
 tcg_temp_free(t0);
+fp_output = false;
 break;
 
 case OPC_RISC_FCVT_W_S:
@@ -1035,6 +1064,7 @@ static void gen_fp_arith(DisasContext *ctx, uint32_t opc, 
int rd,
 }
 gen_set_gpr(rd, t0);
 tcg_temp_free(t0);
+fp_output = false;
 break;
 
 case OPC_RISC_FCVT_S_W:
@@ -1085,6 +1115,7 @@ static void gen_fp_arith(DisasContext *ctx, uint32_t opc, 
int rd,
 }
 gen_set_gpr(rd, t0);
 tcg_temp_free(t0);
+fp_output = false;
 break;
 
 case OPC_RISC_FMV_S_X:
@@ -1177,6 +1208,7 @@ static void gen_fp_arith(DisasContext *ctx, uint32_t opc, 
int rd,
 }
 gen_set_gpr(rd, t0);
 tcg_temp_free(t0);
+fp_output = false;
 break;
 
 case OPC_RISC_FCVT_W_D:
@@ -1206,6 +1238,7 @@ static void gen_fp_arith(DisasContext *ctx, uint32_t opc, 
int rd,
 }
 gen_set_gpr(rd, t0);
 tcg_temp_free(t0);
+fp_output = false;
 break;
 
 case OPC_RISC_FCVT_D_W:
@@ -1253,6 +1286,7 @@ static void gen_fp_arith(DisasContext *ctx, uint32_t opc, 
int rd,
 default:
 goto do_illegal;
 }
+fp_output = false;
 break;
 
 case OPC_RISC_FMV_D_X:
@@ -1269,7 +1303,11 @@ static void gen_fp_arith(DisasContext *ctx, uint32_t 
opc, int rd,
 tcg_temp_free(t0);
 }
 gen_exception_illegal(ctx);
-break;
+  

[Qemu-devel] [PATCH v1 16/30] RISC-V: Use riscv prefix consistently on cpu helpers

2018-05-22 Thread Michael Clark
* Add riscv prefix to raise_exception function
* Add riscv prefix to CSR read/write functions
* Add riscv prefix to signal handler function
* Add riscv prefix to get fflags function
* Remove redundant declaration of riscv_cpu_init
  and rename cpu_riscv_init to riscv_cpu_init
* rename riscv_set_mode to riscv_cpu_set_mode

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
---
 linux-user/riscv/signal.c |  4 ++--
 target/riscv/cpu.h| 21 ++---
 target/riscv/cpu_helper.c | 10 +-
 target/riscv/csr.c|  8 
 target/riscv/fpu_helper.c |  6 +++---
 target/riscv/op_helper.c  | 28 ++--
 6 files changed, 38 insertions(+), 39 deletions(-)

diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c
index ef599e319a10..f03bc7212b49 100644
--- a/linux-user/riscv/signal.c
+++ b/linux-user/riscv/signal.c
@@ -84,7 +84,7 @@ static void setup_sigcontext(struct target_sigcontext *sc, 
CPURISCVState *env)
 __put_user(env->fpr[i], &sc->fpr[i]);
 }
 
-uint32_t fcsr = csr_read_helper(env, CSR_FCSR); /*riscv_get_fcsr(env);*/
+uint32_t fcsr = riscv_csr_read(env, CSR_FCSR);
 __put_user(fcsr, &sc->fcsr);
 }
 
@@ -160,7 +160,7 @@ static void restore_sigcontext(CPURISCVState *env, struct 
target_sigcontext *sc)
 
 uint32_t fcsr;
 __get_user(fcsr, &sc->fcsr);
-csr_write_helper(env, fcsr, CSR_FCSR);
+riscv_csr_write(env, CSR_FCSR, fcsr);
 }
 
 static void restore_ucontext(CPURISCVState *env, struct target_ucontext *uc)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 1ade90d23bbc..d6bb3136db18 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -257,7 +257,7 @@ char *riscv_isa_string(RISCVCPU *cpu);
 void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 
 #define cpu_init(cpu_model) cpu_generic_init(TYPE_RISCV_CPU, cpu_model)
-#define cpu_signal_handler cpu_riscv_signal_handler
+#define cpu_signal_handler riscv_cpu_signal_handler
 #define cpu_list riscv_cpu_list
 #define cpu_mmu_index riscv_cpu_mmu_index
 
@@ -265,16 +265,15 @@ void riscv_cpu_list(FILE *f, fprintf_function 
cpu_fprintf);
 uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value);
 #define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */
 #endif
-void riscv_set_mode(CPURISCVState *env, target_ulong newpriv);
+void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv);
 
 void riscv_translate_init(void);
-RISCVCPU *cpu_riscv_init(const char *cpu_model);
-int cpu_riscv_signal_handler(int host_signum, void *pinfo, void *puc);
-void QEMU_NORETURN do_raise_exception_err(CPURISCVState *env,
-  uint32_t exception, uintptr_t pc);
+int riscv_cpu_signal_handler(int host_signum, void *pinfo, void *puc);
+void QEMU_NORETURN riscv_raise_exception(CPURISCVState *env,
+ uint32_t exception, uintptr_t pc);
 
-target_ulong cpu_riscv_get_fflags(CPURISCVState *env);
-void cpu_riscv_set_fflags(CPURISCVState *env, target_ulong);
+target_ulong riscv_cpu_get_fflags(CPURISCVState *env);
+void riscv_cpu_set_fflags(CPURISCVState *env, target_ulong);
 
 #define TB_FLAGS_MMU_MASK   3
 #define TB_FLAGS_MSTATUS_FS MSTATUS_FS
@@ -294,13 +293,13 @@ static inline void cpu_get_tb_cpu_state(CPURISCVState 
*env, target_ulong *pc,
 int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong *ret_value,
 target_ulong new_value, target_ulong write_mask);
 
-static inline void csr_write_helper(CPURISCVState *env, target_ulong val,
-int csrno)
+static inline void riscv_csr_write(CPURISCVState *env, int csrno,
+   target_ulong val)
 {
 riscv_csrrw(env, csrno, NULL, val, -1);
 }
 
-static inline target_ulong csr_read_helper(CPURISCVState *env, int csrno)
+static inline target_ulong riscv_csr_read(CPURISCVState *env, int csrno)
 {
 target_ulong val = 0;
 riscv_csrrw(env, csrno, &val, 0, 0);
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 69592c037042..b4bbf7a9fa0a 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -93,7 +93,7 @@ uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, 
uint32_t value)
 return old;
 }
 
-void riscv_set_mode(CPURISCVState *env, target_ulong newpriv)
+void riscv_cpu_set_mode(CPURISCVState *env, target_ulong newpriv)
 {
 if (newpriv > PRV_M) {
 g_assert_not_reached();
@@ -366,7 +366,7 @@ void riscv_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
 g_assert_not_reached();
 }
 env->badaddr = addr;
-do_raise_exception_err(env, cs->exception_index, retaddr);
+riscv_raise_exception(env, cs->exception_index, retaddr);
 }
 
 /* called by qemu's softmmu to fill the qemu tlb */
@@ -378,7 +378,7 @@ void tlb_fill(CPUState *

[Qemu-devel] [PATCH v1 05/30] RISC-V: Allow setting and clearing multiple irqs

2018-05-22 Thread Michael Clark
Change the API of riscv_set_local_interrupt to take a
write mask and value to allow setting and clearing of
multiple local interrupts atomically in a single call.
Rename the new function to riscv_cpu_update_mip.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
---
 hw/riscv/sifive_clint.c  |  8 
 hw/riscv/sifive_plic.c   |  4 ++--
 target/riscv/cpu.h   | 22 +-
 target/riscv/op_helper.c | 24 +++-
 4 files changed, 34 insertions(+), 24 deletions(-)

diff --git a/hw/riscv/sifive_clint.c b/hw/riscv/sifive_clint.c
index 7cc606e06546..0d2fd52487e6 100644
--- a/hw/riscv/sifive_clint.c
+++ b/hw/riscv/sifive_clint.c
@@ -47,12 +47,12 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, 
uint64_t value)
 if (cpu->env.timecmp <= rtc_r) {
 /* if we're setting an MTIMECMP value in the "past",
immediately raise the timer interrupt */
-riscv_set_local_interrupt(cpu, MIP_MTIP, 1);
+riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
 return;
 }
 
 /* otherwise, set up the future timer interrupt */
-riscv_set_local_interrupt(cpu, MIP_MTIP, 0);
+riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0));
 diff = cpu->env.timecmp - rtc_r;
 /* back to ns (note args switched in muldiv64) */
 next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
@@ -67,7 +67,7 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, 
uint64_t value)
 static void sifive_clint_timer_cb(void *opaque)
 {
 RISCVCPU *cpu = opaque;
-riscv_set_local_interrupt(cpu, MIP_MTIP, 1);
+riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
 }
 
 /* CPU wants to read rtc or timecmp register */
@@ -132,7 +132,7 @@ static void sifive_clint_write(void *opaque, hwaddr addr, 
uint64_t value,
 if (!env) {
 error_report("clint: invalid timecmp hartid: %zu", hartid);
 } else if ((addr & 0x3) == 0) {
-riscv_set_local_interrupt(RISCV_CPU(cpu), MIP_MSIP, value != 0);
+riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MSIP, 
BOOL_TO_MASK(value));
 } else {
 error_report("clint: invalid sip write: %08x", (uint32_t)addr);
 }
diff --git a/hw/riscv/sifive_plic.c b/hw/riscv/sifive_plic.c
index 1af23c76e603..b267ff88902d 100644
--- a/hw/riscv/sifive_plic.c
+++ b/hw/riscv/sifive_plic.c
@@ -142,10 +142,10 @@ static void sifive_plic_update(SiFivePLICState *plic)
 int level = sifive_plic_irqs_pending(plic, addrid);
 switch (mode) {
 case PLICMode_M:
-riscv_set_local_interrupt(RISCV_CPU(cpu), MIP_MEIP, level);
+riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, 
BOOL_TO_MASK(level));
 break;
 case PLICMode_S:
-riscv_set_local_interrupt(RISCV_CPU(cpu), MIP_SEIP, level);
+riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_SEIP, 
BOOL_TO_MASK(level));
 break;
 default:
 break;
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index e0608e6d5f08..c5d485769cde 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -126,13 +126,18 @@ struct CPURISCVState {
 
 target_ulong mhartid;
 target_ulong mstatus;
+
 /*
  * CAUTION! Unlike the rest of this struct, mip is accessed asynchonously
- * by I/O threads and other vCPUs, so hold the iothread mutex before
- * operating on it.  CPU_INTERRUPT_HARD should be in effect iff this is
- * non-zero.  Use riscv_cpu_set_local_interrupt.
+ * by I/O threads. It should be read with atomic_read. It should be updated
+ * using riscv_cpu_update_mip with the iothread mutex held. The iothread
+ * mutex must be held because mip must be consistent with the CPU inturrept
+ * state. riscv_cpu_update_mip calls cpu_interrupt or cpu_reset_interrupt
+ * wuth the invariant that CPU_INTERRUPT_HARD is set iff mip is non-zero.
+ * mip is 32-bits to allow atomic_read on 32-bit hosts.
  */
-uint32_t mip;/* allow atomic_read for >= 32-bit hosts */
+uint32_t mip;
+
 target_ulong mie;
 target_ulong mideleg;
 
@@ -247,7 +252,6 @@ void  riscv_cpu_do_unaligned_access(CPUState *cs, vaddr 
addr,
 uintptr_t retaddr);
 int riscv_cpu_handle_mmu_fault(CPUState *cpu, vaddr address, int size,
   int rw, int mmu_idx);
-
 char *riscv_isa_string(RISCVCPU *cpu);
 void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 
@@ -256,6 +260,10 @@ void riscv_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 #define cpu_list riscv_cpu_list
 #define cpu_mmu_index riscv_cpu_mmu_index
 
+#ifndef CONFIG_USER_ONLY
+uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value);
+#define BOOL_TO_MASK(x) (-!!(x)) /* helper for riscv_cpu_update_mip value */
+#endif
 void riscv_set_mode(CPURISCVState *env, targe

[Qemu-devel] [PATCH v1 14/30] RISC-V: Add public API for the CSR dispatch table

2018-05-22 Thread Michael Clark
This allows hardware and/or derived cpu instances
to override or implement new CSR operations.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
---
 target/riscv/cpu.h | 18 ++
 target/riscv/csr.c | 35 ++-
 2 files changed, 36 insertions(+), 17 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 242a8fcbe180..1ade90d23bbc 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -307,6 +307,24 @@ static inline target_ulong csr_read_helper(CPURISCVState 
*env, int csrno)
 return val;
 }
 
+typedef int (*riscv_csr_predicate_fn)(CPURISCVState *env, int csrno);
+typedef int (*riscv_csr_read_fn)(CPURISCVState *env, int csrno,
+target_ulong *ret_value);
+typedef int (*riscv_csr_write_fn)(CPURISCVState *env, int csrno,
+target_ulong new_value);
+typedef int (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
+target_ulong *ret_value, target_ulong new_value, target_ulong write_mask);
+
+typedef struct {
+riscv_csr_predicate_fn predicate;
+riscv_csr_read_fn read;
+riscv_csr_write_fn write;
+riscv_csr_op_fn op;
+} riscv_csr_operations;
+
+void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops);
+void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops);
+
 #include "exec/cpu-all.h"
 
 #endif /* RISCV_CPU_H */
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 509215327243..0f886e04b130 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -23,28 +23,29 @@
 #include "qemu/main-loop.h"
 #include "exec/exec-all.h"
 
+/* CSR function table */
 
-/* Control and Status Register function table forward declaration */
+static riscv_csr_operations csr_ops[];
 
-typedef int (*riscv_csr_predicate_fn)(CPURISCVState *env, int csrno);
-typedef int (*riscv_csr_read_fn)(CPURISCVState *env, int csrno,
-target_ulong *ret_value);
-typedef int (*riscv_csr_write_fn)(CPURISCVState *env, int csrno,
-target_ulong new_value);
-typedef int (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
-target_ulong *ret_value, target_ulong new_value, target_ulong write_mask);
+/* CSR function table constants */
 
-typedef struct {
-riscv_csr_predicate_fn predicate;
-riscv_csr_read_fn read;
-riscv_csr_write_fn write;
-riscv_csr_op_fn op;
-} riscv_csr_operations;
+enum {
+CSR_TABLE_SIZE = 0xfff
+};
+
+/* CSR function table public API */
 
-static const riscv_csr_operations csr_ops[];
+void riscv_get_csr_ops(int csrno, riscv_csr_operations *ops)
+{
+*ops = csr_ops[csrno & CSR_TABLE_SIZE];
+}
 
+void riscv_set_csr_ops(int csrno, riscv_csr_operations *ops)
+{
+csr_ops[csrno & CSR_TABLE_SIZE] = *ops;
+}
 
-/* Predicates */
+/* CSR function table predicates (private) */
 
 static int fs(CPURISCVState *env, int csrno)
 {
@@ -784,7 +785,7 @@ int riscv_csrrw(CPURISCVState *env, int csrno, target_ulong 
*ret_value,
 
 /* Control and Status Register function table */
 
-static const riscv_csr_operations csr_ops[0xfff] = {
+static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 /* User Floating-Point CSRs */
 [CSR_FFLAGS] =  { fs,   read_fflags,  write_fflags  },
 [CSR_FRM] = { fs,   read_frm, write_frm },
-- 
2.7.0




[Qemu-devel] [PATCH v1 17/30] RISC-V: Replace __builtin_popcount with ctpop8 in PLIC

2018-05-22 Thread Michael Clark
The mode variable only uses the lower 4-bits (M,H,S,U) so
replace the GCC specific __builtin_popcount with ctpop8.

Cc: Palmer Dabbelt 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
---
 hw/riscv/sifive_plic.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/riscv/sifive_plic.c b/hw/riscv/sifive_plic.c
index b267ff88902d..dc6f4924e282 100644
--- a/hw/riscv/sifive_plic.c
+++ b/hw/riscv/sifive_plic.c
@@ -383,7 +383,7 @@ static void parse_hart_config(SiFivePLICState *plic)
 p = plic->hart_config;
 while ((c = *p++)) {
 if (c == ',') {
-addrid += __builtin_popcount(modes);
+addrid += ctpop8(modes);
 modes = 0;
 hartid++;
 } else {
@@ -397,7 +397,7 @@ static void parse_hart_config(SiFivePLICState *plic)
 }
 }
 if (modes) {
-addrid += __builtin_popcount(modes);
+addrid += ctpop8(modes);
 }
 hartid++;
 
-- 
2.7.0




[Qemu-devel] [PATCH v1 15/30] RISC-V: Add hartid and \n to interrupt logging

2018-05-22 Thread Michael Clark
Add carriage return that was erroneously removed
when converting to qemu_log. Change hard coded
core number to the actual hartid.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
---
 target/riscv/cpu_helper.c | 18 ++
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index bc15e19022cc..69592c037042 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -446,11 +446,13 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 if (RISCV_DEBUG_INTERRUPT) {
 int log_cause = cs->exception_index & RISCV_EXCP_INT_MASK;
 if (cs->exception_index & RISCV_EXCP_INT_FLAG) {
-qemu_log_mask(LOG_TRACE, "core   0: trap %s, epc 0x" TARGET_FMT_lx,
-riscv_intr_names[log_cause], env->pc);
+qemu_log_mask(LOG_TRACE, "core "
+TARGET_FMT_ld ": trap %s, epc 0x" TARGET_FMT_lx "\n",
+env->mhartid, riscv_intr_names[log_cause], env->pc);
 } else {
-qemu_log_mask(LOG_TRACE, "core   0: intr %s, epc 0x" TARGET_FMT_lx,
-riscv_excp_names[log_cause], env->pc);
+qemu_log_mask(LOG_TRACE, "core "
+TARGET_FMT_ld ": intr %s, epc 0x" TARGET_FMT_lx "\n",
+env->mhartid, riscv_excp_names[log_cause], env->pc);
 }
 }
 
@@ -512,8 +514,8 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 
 if (hasbadaddr) {
 if (RISCV_DEBUG_INTERRUPT) {
-qemu_log_mask(LOG_TRACE, "core " TARGET_FMT_ld
-": badaddr 0x" TARGET_FMT_lx, env->mhartid, env->badaddr);
+qemu_log_mask(LOG_TRACE, "core " TARGET_FMT_ld ": badaddr 0x"
+TARGET_FMT_lx "\n", env->mhartid, env->badaddr);
 }
 env->sbadaddr = env->badaddr;
 } else {
@@ -537,8 +539,8 @@ void riscv_cpu_do_interrupt(CPUState *cs)
 
 if (hasbadaddr) {
 if (RISCV_DEBUG_INTERRUPT) {
-qemu_log_mask(LOG_TRACE, "core " TARGET_FMT_ld
-": badaddr 0x" TARGET_FMT_lx, env->mhartid, env->badaddr);
+qemu_log_mask(LOG_TRACE, "core " TARGET_FMT_ld ": badaddr 0x"
+TARGET_FMT_lx "\n", env->mhartid, env->badaddr);
 }
 env->mbadaddr = env->badaddr;
 } else {
-- 
2.7.0




[Qemu-devel] [PATCH v1 06/30] RISC-V: Move non-ops from op_helper to cpu_helper

2018-05-22 Thread Michael Clark
This patch makes op_helper.c contain only instruction
operation helpers used by translate.c and moves any
unrelated cpu helpers into cpu_helper.c. No logic is
changed by this patch.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
Reviewed-by: Alistair Francis 
---
 target/riscv/Makefile.objs  |  2 +-
 target/riscv/{helper.c => cpu_helper.c} | 35 -
 target/riscv/op_helper.c| 34 
 3 files changed, 35 insertions(+), 36 deletions(-)
 rename target/riscv/{helper.c => cpu_helper.c} (95%)

diff --git a/target/riscv/Makefile.objs b/target/riscv/Makefile.objs
index abd0a7cde333..fcc5d34c1f2e 100644
--- a/target/riscv/Makefile.objs
+++ b/target/riscv/Makefile.objs
@@ -1 +1 @@
-obj-y += translate.o op_helper.o helper.o cpu.o fpu_helper.o gdbstub.o pmp.o
+obj-y += translate.o op_helper.o cpu_helper.o cpu.o fpu_helper.o gdbstub.o 
pmp.o
diff --git a/target/riscv/helper.c b/target/riscv/cpu_helper.c
similarity index 95%
rename from target/riscv/helper.c
rename to target/riscv/cpu_helper.c
index 47d116e9c13f..6c886e99055a 100644
--- a/target/riscv/helper.c
+++ b/target/riscv/cpu_helper.c
@@ -1,5 +1,5 @@
 /*
- * RISC-V emulation helpers for qemu.
+ * RISC-V CPU helpers for qemu.
  *
  * Copyright (c) 2016-2017 Sagar Karandikar, sag...@eecs.berkeley.edu
  * Copyright (c) 2017-2018 SiFive, Inc.
@@ -72,6 +72,39 @@ bool riscv_cpu_exec_interrupt(CPUState *cs, int 
interrupt_request)
 
 #if !defined(CONFIG_USER_ONLY)
 
+/* iothread_mutex must be held */
+uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value)
+{
+CPURISCVState *env = &cpu->env;
+uint32_t old, new, cmp = atomic_read(&env->mip);
+
+do {
+old = cmp;
+new = (old & ~mask) | (value & mask);
+cmp = atomic_cmpxchg(&env->mip, old, new);
+} while (old != cmp);
+
+if (new && !old) {
+cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
+} else if (!new && old) {
+cpu_reset_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
+}
+
+return old;
+}
+
+void riscv_set_mode(CPURISCVState *env, target_ulong newpriv)
+{
+if (newpriv > PRV_M) {
+g_assert_not_reached();
+}
+if (newpriv == PRV_H) {
+newpriv = PRV_U;
+}
+/* tlb_flush is unnecessary as mode is contained in mmu_idx */
+env->priv = newpriv;
+}
+
 /* get_physical_address - get the physical address for this virtual address
  *
  * Do a page table walk to obtain the physical address corresponding to a
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 5a02795bf931..2b9dd9da6486 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -652,39 +652,6 @@ target_ulong helper_csrrc(CPURISCVState *env, target_ulong 
src,
 
 #ifndef CONFIG_USER_ONLY
 
-/* iothread_mutex must be held */
-uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value)
-{
-CPURISCVState *env = &cpu->env;
-uint32_t old, new, cmp = atomic_read(&env->mip);
-
-do {
-old = cmp;
-new = (old & ~mask) | (value & mask);
-cmp = atomic_cmpxchg(&env->mip, old, new);
-} while (old != cmp);
-
-if (new && !old) {
-cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
-} else if (!new && old) {
-cpu_reset_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
-}
-
-return old;
-}
-
-void riscv_set_mode(CPURISCVState *env, target_ulong newpriv)
-{
-if (newpriv > PRV_M) {
-g_assert_not_reached();
-}
-if (newpriv == PRV_H) {
-newpriv = PRV_U;
-}
-/* tlb_flush is unnecessary as mode is contained in mmu_idx */
-env->priv = newpriv;
-}
-
 target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
 {
 if (!(env->priv >= PRV_S)) {
@@ -735,7 +702,6 @@ target_ulong helper_mret(CPURISCVState *env, target_ulong 
cpu_pc_deb)
 return retpc;
 }
 
-
 void helper_wfi(CPURISCVState *env)
 {
 CPUState *cs = CPU(riscv_env_get_cpu(env));
-- 
2.7.0




[Qemu-devel] [PATCH v1 18/30] RISC-V: Add missing free for plic_hart_config

2018-05-22 Thread Michael Clark
Cc: Palmer Dabbelt 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
---
 hw/riscv/virt.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index ad03113e0f72..321fa6e8122a 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -385,6 +385,8 @@ static void riscv_virt_board_init(MachineState *machine)
 serial_mm_init(system_memory, memmap[VIRT_UART0].base,
 0, SIFIVE_PLIC(s->plic)->irqs[UART0_IRQ], 399193,
 serial_hd(0), DEVICE_LITTLE_ENDIAN);
+
+g_free(plic_hart_config);
 }
 
 static void riscv_virt_board_machine_init(MachineClass *mc)
-- 
2.7.0




[Qemu-devel] [PATCH v1 21/30] RISC-V: Add misa.MAFD checks to translate

2018-05-22 Thread Michael Clark
Add misa checks for M, A, F and D extensions and if they are
not present generate illegal instructions. This improves
emulation accurary for harts with a limited set of extensions.

Cc: Palmer Dabbelt 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Alistair Francis 
Cc: Emilio G. Cota 
Signed-off-by: Michael Clark 
---
 target/riscv/translate.c | 158 +++
 1 file changed, 158 insertions(+)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index fd21b133a5a4..e488101ff56d 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -290,24 +290,42 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, 
int rd, int rs1,
 tcg_gen_and_tl(source1, source1, source2);
 break;
 CASE_OP_32_64(OPC_RISC_MUL):
+if (!has_ext(ctx, RVM)) {
+goto do_illegal;
+}
 tcg_gen_mul_tl(source1, source1, source2);
 break;
 case OPC_RISC_MULH:
+if (!has_ext(ctx, RVM)) {
+goto do_illegal;
+}
 tcg_gen_muls2_tl(source2, source1, source1, source2);
 break;
 case OPC_RISC_MULHSU:
+if (!has_ext(ctx, RVM)) {
+goto do_illegal;
+}
 gen_mulhsu(source1, source1, source2);
 break;
 case OPC_RISC_MULHU:
+if (!has_ext(ctx, RVM)) {
+goto do_illegal;
+}
 tcg_gen_mulu2_tl(source2, source1, source1, source2);
 break;
 #if defined(TARGET_RISCV64)
 case OPC_RISC_DIVW:
+if (!has_ext(ctx, RVM)) {
+goto do_illegal;
+}
 tcg_gen_ext32s_tl(source1, source1);
 tcg_gen_ext32s_tl(source2, source2);
 /* fall through to DIV */
 #endif
 case OPC_RISC_DIV:
+if (!has_ext(ctx, RVM)) {
+goto do_illegal;
+}
 /* Handle by altering args to tcg_gen_div to produce req'd results:
  * For overflow: want source1 in source1 and 1 in source2
  * For div by zero: want -1 in source1 and 1 in source2 -> -1 result */
@@ -339,11 +357,17 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, 
int rd, int rs1,
 break;
 #if defined(TARGET_RISCV64)
 case OPC_RISC_DIVUW:
+if (!has_ext(ctx, RVM)) {
+goto do_illegal;
+}
 tcg_gen_ext32u_tl(source1, source1);
 tcg_gen_ext32u_tl(source2, source2);
 /* fall through to DIVU */
 #endif
 case OPC_RISC_DIVU:
+if (!has_ext(ctx, RVM)) {
+goto do_illegal;
+}
 cond1 = tcg_temp_new();
 zeroreg = tcg_const_tl(0);
 resultopt1 = tcg_temp_new();
@@ -363,11 +387,17 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, 
int rd, int rs1,
 break;
 #if defined(TARGET_RISCV64)
 case OPC_RISC_REMW:
+if (!has_ext(ctx, RVM)) {
+goto do_illegal;
+}
 tcg_gen_ext32s_tl(source1, source1);
 tcg_gen_ext32s_tl(source2, source2);
 /* fall through to REM */
 #endif
 case OPC_RISC_REM:
+if (!has_ext(ctx, RVM)) {
+goto do_illegal;
+}
 cond1 = tcg_temp_new();
 cond2 = tcg_temp_new();
 zeroreg = tcg_const_tl(0);
@@ -395,11 +425,17 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, 
int rd, int rs1,
 break;
 #if defined(TARGET_RISCV64)
 case OPC_RISC_REMUW:
+if (!has_ext(ctx, RVM)) {
+goto do_illegal;
+}
 tcg_gen_ext32u_tl(source1, source1);
 tcg_gen_ext32u_tl(source2, source2);
 /* fall through to REMU */
 #endif
 case OPC_RISC_REMU:
+if (!has_ext(ctx, RVM)) {
+goto do_illegal;
+}
 cond1 = tcg_temp_new();
 zeroreg = tcg_const_tl(0);
 resultopt1 = tcg_temp_new();
@@ -417,6 +453,7 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, int 
rd, int rs1,
 tcg_temp_free(zeroreg);
 tcg_temp_free(resultopt1);
 break;
+do_illegal:
 default:
 gen_exception_illegal(ctx);
 return;
@@ -697,13 +734,20 @@ static void gen_fp_load(DisasContext *ctx, uint32_t opc, 
int rd,
 
 switch (opc) {
 case OPC_RISC_FLW:
+if (!has_ext(ctx, RVF)) {
+goto do_illegal;
+}
 tcg_gen_qemu_ld_i64(cpu_fpr[rd], t0, ctx->mem_idx, MO_TEUL);
 /* RISC-V requires NaN-boxing of narrower width floating point values 
*/
 tcg_gen_ori_i64(cpu_fpr[rd], cpu_fpr[rd], 0xULL);
 break;
 case OPC_RISC_FLD:
+if (!has_ext(ctx, RVD)) {
+goto do_illegal;
+}
 tcg_gen_qemu_ld_i64(cpu_fpr[rd], t0, ctx->mem_idx, MO_TEQ);
 break;
+do_illegal:
 default:
 gen_exception_illegal(ctx);
 break;
@@ -729,11 +773,18 @@ static void gen_fp_store(DisasContext *ctx, uint32_t opc, 
int rs1,
 
 switch (opc) {
 case OPC_RISC_FSW:
+if (!has_ext(ctx, RVF)) {
+  

[Qemu-devel] [PATCH v1 09/30] RISC-V: Implement atomic mip/sip CSR updates

2018-05-22 Thread Michael Clark
Use the new CSR read/modify/write interface to implement
atomic updates to mip/sip.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
---
 target/riscv/csr.c | 56 +++---
 1 file changed, 28 insertions(+), 28 deletions(-)

diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index e08f3523d854..631a5ff9f7d8 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -493,25 +493,31 @@ static int write_mbadaddr(CPURISCVState *env, int csrno, 
target_ulong val)
 return 0;
 }
 
-static int read_mip(CPURISCVState *env, int csrno, target_ulong *val)
-{
-*val = atomic_read(&env->mip);
-return 0;
-}
-
-static int write_mip(CPURISCVState *env, int csrno, target_ulong val)
+static int rmw_mip(CPURISCVState *env, int csrno, target_ulong *ret_value,
+   target_ulong new_value, target_ulong write_mask)
 {
 RISCVCPU *cpu = riscv_env_get_cpu(env);
+target_ulong mask = write_mask & delegable_ints;
+uint32_t old_mip;
+
+/* We can't allow the supervisor to control SEIP as this would allow the
+ * supervisor to clear a pending external interrupt which will result in
+ * lost a interrupt in the case a PLIC is attached. The SEIP bit must be
+ * hardware controlled when a PLIC is attached. This should be an option
+ * for CPUs with software-delegated Supervisor External Interrupts. */
+mask &= ~MIP_SEIP;
+
+if (mask) {
+qemu_mutex_lock_iothread();
+old_mip = riscv_cpu_update_mip(cpu, mask, (new_value & mask));
+qemu_mutex_unlock_iothread();
+} else {
+old_mip = atomic_read(&env->mip);
+}
 
-/*
- * csrs, csrc on mip.SEIP is not decomposable into separate read and
- * write steps, so a different implementation is needed
- */
-
-qemu_mutex_lock_iothread();
-riscv_cpu_update_mip(cpu, MIP_SSIP | MIP_STIP,
- (val & (MIP_SSIP | MIP_STIP)));
-qemu_mutex_unlock_iothread();
+if (ret_value) {
+*ret_value = old_mip;
+}
 
 return 0;
 }
@@ -631,17 +637,11 @@ static int write_sbadaddr(CPURISCVState *env, int csrno, 
target_ulong val)
 return 0;
 }
 
-static int read_sip(CPURISCVState *env, int csrno, target_ulong *val)
-{
-*val = atomic_read(&env->mip) & env->mideleg;
-return 0;
-}
-
-static int write_sip(CPURISCVState *env, int csrno, target_ulong val)
+static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value,
+   target_ulong new_value, target_ulong write_mask)
 {
-target_ulong newval = (atomic_read(&env->mip) & ~env->mideleg)
-  | (val & env->mideleg);
-return write_mip(env, CSR_MIP, newval);
+return rmw_mip(env, CSR_MSTATUS, ret_value, new_value,
+   write_mask & env->mideleg);
 }
 
 /* Supervisor Protection and Translation */
@@ -823,7 +823,7 @@ static const riscv_csr_operations csr_ops[0xfff] = {
 [CSR_MEPC] ={ read_mepc,write_mepc},
 [CSR_MCAUSE] =  { read_mcause,  write_mcause  },
 [CSR_MBADADDR] ={ read_mbadaddr,write_mbadaddr},
-[CSR_MIP] = { read_mip, write_mip },
+[CSR_MIP] = { NULL, NULL, rmw_mip },
 
 /* Supervisor Trap Setup */
 [CSR_SSTATUS] = { read_sstatus, write_sstatus },
@@ -836,7 +836,7 @@ static const riscv_csr_operations csr_ops[0xfff] = {
 [CSR_SEPC] ={ read_sepc,write_sepc},
 [CSR_SCAUSE] =  { read_scause,  write_scause  },
 [CSR_SBADADDR] ={ read_sbadaddr,write_sbadaddr},
-[CSR_SIP] = { read_sip, write_sip },
+[CSR_SIP] = { NULL, NULL, rmw_sip },
 
 /* Supervisor Protection and Translation */
 [CSR_SATP] ={ read_satp,write_satp},
-- 
2.7.0




[Qemu-devel] [PATCH v1 25/30] RISC-V: Enable second UART on sifive_e and sifive_u

2018-05-22 Thread Michael Clark
Previously the second UARTs on the sifive_e and sifive_u machines
where disabled due to check-qtest-riscv32 and check-qtest-riscv64
failures. Recent changes in the QEMU core serial code have
resolved these failures so the second UARTs can be instantiated.

Cc: Palmer Dabbelt 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
---
 hw/riscv/sifive_e.c | 4 ++--
 hw/riscv/sifive_u.c | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index e4ecb7aa4bb6..159209199537 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -155,8 +155,8 @@ static void riscv_sifive_e_init(MachineState *machine)
 memmap[SIFIVE_E_QSPI0].base, memmap[SIFIVE_E_QSPI0].size);
 sifive_mmio_emulate(sys_mem, "riscv.sifive.e.pwm0",
 memmap[SIFIVE_E_PWM0].base, memmap[SIFIVE_E_PWM0].size);
-/* sifive_uart_create(sys_mem, memmap[SIFIVE_E_UART1].base,
-serial_hd(1), SIFIVE_PLIC(s->plic)->irqs[SIFIVE_E_UART1_IRQ]); */
+sifive_uart_create(sys_mem, memmap[SIFIVE_E_UART1].base,
+serial_hd(1), SIFIVE_PLIC(s->plic)->irqs[SIFIVE_E_UART1_IRQ]);
 sifive_mmio_emulate(sys_mem, "riscv.sifive.e.qspi1",
 memmap[SIFIVE_E_QSPI1].base, memmap[SIFIVE_E_QSPI1].size);
 sifive_mmio_emulate(sys_mem, "riscv.sifive.e.pwm1",
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index c05dcbba955e..326b0f434cff 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -299,8 +299,8 @@ static void riscv_sifive_u_init(MachineState *machine)
 memmap[SIFIVE_U_PLIC].size);
 sifive_uart_create(system_memory, memmap[SIFIVE_U_UART0].base,
 serial_hd(0), SIFIVE_PLIC(s->plic)->irqs[SIFIVE_U_UART0_IRQ]);
-/* sifive_uart_create(system_memory, memmap[SIFIVE_U_UART1].base,
-serial_hd(1), SIFIVE_PLIC(s->plic)->irqs[SIFIVE_U_UART1_IRQ]); */
+sifive_uart_create(system_memory, memmap[SIFIVE_U_UART1].base,
+serial_hd(1), SIFIVE_PLIC(s->plic)->irqs[SIFIVE_U_UART1_IRQ]);
 sifive_clint_create(memmap[SIFIVE_U_CLINT].base,
 memmap[SIFIVE_U_CLINT].size, smp_cpus,
 SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE);
-- 
2.7.0




[Qemu-devel] [PATCH v1 23/30] RISC-V: Fix CLINT timecmp low 32-bit writes

2018-05-22 Thread Michael Clark
A missing shift made updates to the low order bits
of timecmp erroneously copy the old low order bits
into the high order bits of the 64-bit timecmp
register. Add the missing shift and rename timecmp
local variables to timecmp_hi and timecmp_lo.

This bug didn't show up as the low order bits are
usually written first followed by the high order
bits meaning the high order bits contained an invalid
value between the timecmp_lo and timecmp_hi update.

Cc: Palmer Dabbelt 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Alistair Francis 
Co-Authored-by: Johannes Haring 
Signed-off-by: Michael Clark 
---
 hw/riscv/sifive_clint.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/hw/riscv/sifive_clint.c b/hw/riscv/sifive_clint.c
index 0d2fd52487e6..d4c159e93736 100644
--- a/hw/riscv/sifive_clint.c
+++ b/hw/riscv/sifive_clint.c
@@ -146,15 +146,15 @@ static void sifive_clint_write(void *opaque, hwaddr addr, 
uint64_t value,
 error_report("clint: invalid timecmp hartid: %zu", hartid);
 } else if ((addr & 0x7) == 0) {
 /* timecmp_lo */
-uint64_t timecmp = env->timecmp;
+uint64_t timecmp_hi = env->timecmp >> 32;
 sifive_clint_write_timecmp(RISCV_CPU(cpu),
-timecmp << 32 | (value & 0x));
+timecmp_hi << 32 | (value & 0x));
 return;
 } else if ((addr & 0x7) == 4) {
 /* timecmp_hi */
-uint64_t timecmp = env->timecmp;
+uint64_t timecmp_lo = env->timecmp;
 sifive_clint_write_timecmp(RISCV_CPU(cpu),
-value << 32 | (timecmp & 0x));
+value << 32 | (timecmp_lo & 0x));
 } else {
 error_report("clint: invalid timecmp write: %08x", (uint32_t)addr);
 }
-- 
2.7.0




[Qemu-devel] [PATCH v1 10/30] RISC-V: Implement existential predicates for CSRs

2018-05-22 Thread Michael Clark
CSR predicate functions are added to the CSR table.
mstatus.FS and counter enable checks are moved
to predicate functions and two new predicates are
added to check misa.S for s* CSRs and a new PMP
CPU feature for pmp* CSRs.

Processors that don't implement S-mode will trap
on access to s* CSRs and processors that don't
implement PMP will trap on accesses to pmp* CSRs.

PMP checks are disabled in riscv_cpu_handle_mmu_fault
when the PMP CPU feature is not present.

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
---
 target/riscv/cpu.c|   6 ++
 target/riscv/cpu.h|   5 +-
 target/riscv/cpu_helper.c |   3 +-
 target/riscv/csr.c| 172 ++
 4 files changed, 107 insertions(+), 79 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d630e8fd6c62..9f47f2072c56 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -124,6 +124,7 @@ static void rv32gcsu_priv1_09_1_cpu_init(Object *obj)
 set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_09_1);
 set_resetvec(env, DEFAULT_RSTVEC);
 set_feature(env, RISCV_FEATURE_MMU);
+set_feature(env, RISCV_FEATURE_PMP);
 }
 
 static void rv32gcsu_priv1_10_0_cpu_init(Object *obj)
@@ -133,6 +134,7 @@ static void rv32gcsu_priv1_10_0_cpu_init(Object *obj)
 set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
 set_resetvec(env, DEFAULT_RSTVEC);
 set_feature(env, RISCV_FEATURE_MMU);
+set_feature(env, RISCV_FEATURE_PMP);
 }
 
 static void rv32imacu_nommu_cpu_init(Object *obj)
@@ -141,6 +143,7 @@ static void rv32imacu_nommu_cpu_init(Object *obj)
 set_misa(env, RV32 | RVI | RVM | RVA | RVC | RVU);
 set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
 set_resetvec(env, DEFAULT_RSTVEC);
+set_feature(env, RISCV_FEATURE_PMP);
 }
 
 #elif defined(TARGET_RISCV64)
@@ -152,6 +155,7 @@ static void rv64gcsu_priv1_09_1_cpu_init(Object *obj)
 set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_09_1);
 set_resetvec(env, DEFAULT_RSTVEC);
 set_feature(env, RISCV_FEATURE_MMU);
+set_feature(env, RISCV_FEATURE_PMP);
 }
 
 static void rv64gcsu_priv1_10_0_cpu_init(Object *obj)
@@ -161,6 +165,7 @@ static void rv64gcsu_priv1_10_0_cpu_init(Object *obj)
 set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
 set_resetvec(env, DEFAULT_RSTVEC);
 set_feature(env, RISCV_FEATURE_MMU);
+set_feature(env, RISCV_FEATURE_PMP);
 }
 
 static void rv64imacu_nommu_cpu_init(Object *obj)
@@ -169,6 +174,7 @@ static void rv64imacu_nommu_cpu_init(Object *obj)
 set_misa(env, RV64 | RVI | RVM | RVA | RVC | RVU);
 set_versions(env, USER_VERSION_2_02_0, PRIV_VERSION_1_10_0);
 set_resetvec(env, DEFAULT_RSTVEC);
+set_feature(env, RISCV_FEATURE_PMP);
 }
 
 #endif
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 02c60c45631b..3a3d91447736 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -83,9 +83,10 @@
 /* S extension denotes that Supervisor mode exists, however it is possible
to have a core that support S mode but does not have an MMU and there
is currently no bit in misa to indicate whether an MMU exists or not
-   so a cpu features bitfield is required */
+   so a cpu features bitfield is required, likewise for optional PMP support */
 enum {
-RISCV_FEATURE_MMU
+RISCV_FEATURE_MMU,
+RISCV_FEATURE_PMP
 };
 
 #define USER_VERSION_2_02_0 0x00020200
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 1f523861b7cb..bc15e19022cc 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -404,7 +404,8 @@ int riscv_cpu_handle_mmu_fault(CPUState *cs, vaddr address, 
int size,
 qemu_log_mask(CPU_LOG_MMU,
 "%s address=%" VADDR_PRIx " ret %d physical " TARGET_FMT_plx
  " prot %d\n", __func__, address, ret, pa, prot);
-if (!pmp_hart_has_privs(env, pa, TARGET_PAGE_SIZE, 1 << rw)) {
+if (riscv_feature(env, RISCV_FEATURE_PMP) &&
+!pmp_hart_has_privs(env, pa, TARGET_PAGE_SIZE, 1 << rw)) {
 ret = TRANSLATE_FAIL;
 }
 if (ret == TRANSLATE_SUCCESS) {
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 631a5ff9f7d8..0e6c0c365154 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -26,6 +26,7 @@
 
 /* Control and Status Register function table forward declaration */
 
+typedef int (*riscv_csr_predicate_fn)(CPURISCVState *env, int csrno);
 typedef int (*riscv_csr_read_fn)(CPURISCVState *env, int csrno,
 target_ulong *ret_value);
 typedef int (*riscv_csr_write_fn)(CPURISCVState *env, int csrno,
@@ -34,6 +35,7 @@ typedef int (*riscv_csr_op_fn)(CPURISCVState *env, int csrno,
 target_ulong *ret_value, target_ulong new_value, target_ulong write_mask);
 
 typedef struct {
+riscv_csr_predicate_fn predicate;
 riscv_csr_read_fn read;
 riscv_csr_write_fn write

[Qemu-devel] [PATCH v1 27/30] elf: Add RISC-V PSABI ELF header defines

2018-05-22 Thread Michael Clark
Refer to the RISC-V PSABI specification for details:

- https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md

Cc: Michael Tokarev 
Cc: Laurent Vivier 
Cc: Richard Henderson 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
---
 include/elf.h | 8 
 1 file changed, 8 insertions(+)

diff --git a/include/elf.h b/include/elf.h
index 934dbbd6b3ae..d363ba85a688 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -1285,6 +1285,14 @@ typedef struct {
 #define R_IA64_DTPREL64LSB 0xb7/* @dtprel(sym + add), data8 LSB */
 #define R_IA64_LTOFF_DTPREL22  0xba/* @ltoff(@dtprel(s+a)), imm22 */
 
+/* RISC-V specific definitions.  */
+#define EF_RISCV_RVC 0x0001
+#define EF_RISCV_FLOAT_ABI_SINGLE 0x0002
+#define EF_RISCV_FLOAT_ABI_DOUBLE 0x0004
+#define EF_RISCV_FLOAT_ABI_QUAD (0x0006
+#define EF_RISCV_RVE 0x0008
+#define EF_RISCV_TSO 0x0010
+
 typedef struct elf32_rel {
   Elf32_Addr   r_offset;
   Elf32_Word   r_info;
-- 
2.7.0




[Qemu-devel] [PATCH v1 24/30] RISC-V: Fix PLIC pending bitfield reads

2018-05-22 Thread Michael Clark
The address calculation for the pending bitfield had
a copy paste bug. This bug went unnoticed because the Linux
PLIC driver does not read the pending bitfield, rather it
reads pending interrupt numbers from the claim register
and writes acknowledgements back to the claim register.

Cc: Palmer Dabbelt 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Alistair Francis 
Reported-by: Vincent Siles 
Signed-off-by: Michael Clark 
---
 hw/riscv/sifive_plic.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_plic.c b/hw/riscv/sifive_plic.c
index 28e28d932f7c..b81d29faff99 100644
--- a/hw/riscv/sifive_plic.c
+++ b/hw/riscv/sifive_plic.c
@@ -215,7 +215,7 @@ static uint64_t sifive_plic_read(void *opaque, hwaddr addr, 
unsigned size)
 } else if (addr >= plic->pending_base && /* 1 bit per source */
addr < plic->pending_base + (plic->num_sources >> 3))
 {
-uint32_t word = (addr - plic->priority_base) >> 2;
+uint32_t word = (addr - plic->pending_base) >> 2;
 if (RISCV_DEBUG_PLIC) {
 qemu_log("plic: read pending: word=%d value=%d\n",
 word, plic->pending[word]);
-- 
2.7.0




[Qemu-devel] [PATCH v1 11/30] RISC-V: Split out mstatus_fs from tb_flags

2018-05-22 Thread Michael Clark
From: Richard Henderson 

Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Palmer Dabbelt 
Cc: Alistair Francis 
Cc: Richard Henderson 
Signed-off-by: Michael Clark 
Reviewed-by: Michael Clark 
---
 target/riscv/cpu.h   |  6 +++---
 target/riscv/translate.c | 10 +-
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 3a3d91447736..242a8fcbe180 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -276,8 +276,8 @@ void QEMU_NORETURN do_raise_exception_err(CPURISCVState 
*env,
 target_ulong cpu_riscv_get_fflags(CPURISCVState *env);
 void cpu_riscv_set_fflags(CPURISCVState *env, target_ulong);
 
-#define TB_FLAGS_MMU_MASK  3
-#define TB_FLAGS_FP_ENABLE MSTATUS_FS
+#define TB_FLAGS_MMU_MASK   3
+#define TB_FLAGS_MSTATUS_FS MSTATUS_FS
 
 static inline void cpu_get_tb_cpu_state(CPURISCVState *env, target_ulong *pc,
 target_ulong *cs_base, uint32_t *flags)
@@ -285,7 +285,7 @@ static inline void cpu_get_tb_cpu_state(CPURISCVState *env, 
target_ulong *pc,
 *pc = env->pc;
 *cs_base = 0;
 #ifdef CONFIG_USER_ONLY
-*flags = TB_FLAGS_FP_ENABLE;
+*flags = TB_FLAGS_MSTATUS_FS;
 #else
 *flags = cpu_mmu_index(env, 0) | (env->mstatus & MSTATUS_FS);
 #endif
diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index ee2bbc55b051..466b9551cbd9 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -44,7 +44,7 @@ typedef struct DisasContext {
 /* pc_succ_insn points to the instruction following base.pc_next */
 target_ulong pc_succ_insn;
 uint32_t opcode;
-uint32_t flags;
+uint32_t mstatus_fs;
 uint32_t mem_idx;
 /* Remember the rounding mode encoded in the previous fp instruction,
which we have already installed into env->fp_status.  Or -1 for
@@ -656,7 +656,7 @@ static void gen_fp_load(DisasContext *ctx, uint32_t opc, 
int rd,
 {
 TCGv t0;
 
-if (!(ctx->flags & TB_FLAGS_FP_ENABLE)) {
+if (ctx->mstatus_fs == 0) {
 gen_exception_illegal(ctx);
 return;
 }
@@ -686,7 +686,7 @@ static void gen_fp_store(DisasContext *ctx, uint32_t opc, 
int rs1,
 {
 TCGv t0;
 
-if (!(ctx->flags & TB_FLAGS_FP_ENABLE)) {
+if (ctx->mstatus_fs == 0) {
 gen_exception_illegal(ctx);
 return;
 }
@@ -945,7 +945,7 @@ static void gen_fp_arith(DisasContext *ctx, uint32_t opc, 
int rd,
 {
 TCGv t0 = NULL;
 
-if (!(ctx->flags & TB_FLAGS_FP_ENABLE)) {
+if (ctx->mstatus_fs == 0) {
 goto do_illegal;
 }
 
@@ -1810,8 +1810,8 @@ static void riscv_tr_init_disas_context(DisasContextBase 
*dcbase, CPUState *cs)
 DisasContext *ctx = container_of(dcbase, DisasContext, base);
 
 ctx->pc_succ_insn = ctx->base.pc_first;
-ctx->flags = ctx->base.tb->flags;
 ctx->mem_idx = ctx->base.tb->flags & TB_FLAGS_MMU_MASK;
+ctx->mstatus_fs = ctx->base.tb->flags & TB_FLAGS_MSTATUS_FS;
 ctx->frm = -1;  /* unknown rounding mode */
 }
 
-- 
2.7.0




[Qemu-devel] [PATCH v1 20/30] RISC-V: Add misa to DisasContext

2018-05-22 Thread Michael Clark
gen methods should access state from DisasContext. Add misa
field to the DisasContext struct and remove CPURISCVState
argument from all gen methods.

Cc: Palmer Dabbelt 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Alistair Francis 
Cc: Emilio G. Cota 
Signed-off-by: Michael Clark 
Reviewed-by: Richard Henderson 
---
 target/riscv/translate.c | 78 ++--
 1 file changed, 42 insertions(+), 36 deletions(-)

diff --git a/target/riscv/translate.c b/target/riscv/translate.c
index a980611eb611..fd21b133a5a4 100644
--- a/target/riscv/translate.c
+++ b/target/riscv/translate.c
@@ -45,6 +45,7 @@ typedef struct DisasContext {
 target_ulong pc_succ_insn;
 uint32_t opcode;
 uint32_t mstatus_fs;
+uint32_t misa;
 uint32_t mem_idx;
 /* Remember the rounding mode encoded in the previous fp instruction,
which we have already installed into env->fp_status.  Or -1 for
@@ -74,6 +75,11 @@ static const int tcg_memop_lookup[8] = {
 #define CASE_OP_32_64(X) case X
 #endif
 
+static inline bool has_ext(DisasContext *ctx, uint32_t ext)
+{
+return ctx->misa & ext;
+}
+
 static void generate_exception(DisasContext *ctx, int excp)
 {
 tcg_gen_movi_tl(cpu_pc, ctx->base.pc_next);
@@ -505,14 +511,13 @@ static void gen_arith_imm(DisasContext *ctx, uint32_t 
opc, int rd,
 tcg_temp_free(source1);
 }
 
-static void gen_jal(CPURISCVState *env, DisasContext *ctx, int rd,
-target_ulong imm)
+static void gen_jal(DisasContext *ctx, int rd, target_ulong imm)
 {
 target_ulong next_pc;
 
 /* check misaligned: */
 next_pc = ctx->base.pc_next + imm;
-if (!riscv_has_ext(env, RVC)) {
+if (!has_ext(ctx, RVC)) {
 if ((next_pc & 0x3) != 0) {
 gen_exception_inst_addr_mis(ctx);
 return;
@@ -526,8 +531,8 @@ static void gen_jal(CPURISCVState *env, DisasContext *ctx, 
int rd,
 ctx->base.is_jmp = DISAS_NORETURN;
 }
 
-static void gen_jalr(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
- int rd, int rs1, target_long imm)
+static void gen_jalr(DisasContext *ctx, uint32_t opc, int rd, int rs1,
+ target_long imm)
 {
 /* no chaining with JALR */
 TCGLabel *misaligned = NULL;
@@ -539,7 +544,7 @@ static void gen_jalr(CPURISCVState *env, DisasContext *ctx, 
uint32_t opc,
 tcg_gen_addi_tl(cpu_pc, cpu_pc, imm);
 tcg_gen_andi_tl(cpu_pc, cpu_pc, (target_ulong)-2);
 
-if (!riscv_has_ext(env, RVC)) {
+if (!has_ext(ctx, RVC)) {
 misaligned = gen_new_label();
 tcg_gen_andi_tl(t0, cpu_pc, 0x2);
 tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0x0, misaligned);
@@ -564,8 +569,8 @@ static void gen_jalr(CPURISCVState *env, DisasContext *ctx, 
uint32_t opc,
 tcg_temp_free(t0);
 }
 
-static void gen_branch(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
-   int rs1, int rs2, target_long bimm)
+static void gen_branch(DisasContext *ctx, uint32_t opc, int rs1, int rs2,
+   target_long bimm)
 {
 TCGLabel *l = gen_new_label();
 TCGv source1, source2;
@@ -602,7 +607,7 @@ static void gen_branch(CPURISCVState *env, DisasContext 
*ctx, uint32_t opc,
 
 gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
 gen_set_label(l); /* branch taken */
-if (!riscv_has_ext(env, RVC) && ((ctx->base.pc_next + bimm) & 0x3)) {
+if (!has_ext(ctx, RVC) && ((ctx->base.pc_next + bimm) & 0x3)) {
 /* misaligned */
 gen_exception_inst_addr_mis(ctx);
 } else {
@@ -1311,8 +1316,8 @@ static void gen_fp_arith(DisasContext *ctx, uint32_t opc, 
int rd,
 }
 }
 
-static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc,
-  int rd, int rs1, int csr)
+static void gen_system(DisasContext *ctx, uint32_t opc, int rd, int rs1,
+   int csr)
 {
 TCGv source1, csr_store, dest, rs1_pass, imm_rs1;
 source1 = tcg_temp_new();
@@ -1354,7 +1359,7 @@ static void gen_system(CPURISCVState *env, DisasContext 
*ctx, uint32_t opc,
 gen_exception_illegal(ctx);
 break;
 case 0x102: /* SRET */
-if (riscv_has_ext(env, RVS)) {
+if (has_ext(ctx, RVS)) {
 gen_helper_sret(cpu_pc, cpu_env, cpu_pc);
 tcg_gen_exit_tb(0); /* no chaining */
 ctx->base.is_jmp = DISAS_NORETURN;
@@ -1495,7 +1500,7 @@ static void decode_RV32_64C0(DisasContext *ctx)
 }
 }
 
-static void decode_RV32_64C1(CPURISCVState *env, DisasContext *ctx)
+static void decode_RV32_64C1(DisasContext *ctx)
 {
 uint8_t funct3 = extract32(ctx->opcode, 13, 3);
 uint8_t rd_rs1 = GET_C_RS1(ctx->opcode);
@@ -1515,7 +1520,7 @@ static void decode_RV32_64C1(CPURISCVState *env, 
DisasContext *ctx)
   GET_C_IMM(ctx->opcode));
 #else
 /* C.JAL(RV32) -> jal x1

[Qemu-devel] [PATCH v1 22/30] RISC-V: Add misa runtime write support

2018-05-22 Thread Michael Clark
This patch adds support for writing misa. misa is validated based
on rules in the ISA specification. 'E' is mutually exclusive with
all other extensions. 'D' depends on 'F' so 'D' bit is dropped
if 'F' is not present. A conservative approach to consistency is
taken by flushing the translation cache on misa writes. misa_mask
is added to the CPU struct to store the original set of extensions.

Cc: Palmer Dabbelt 
Cc: Sagar Karandikar 
Cc: Bastian Koppelmann 
Cc: Alistair Francis 
Signed-off-by: Michael Clark 
---
 target/riscv/cpu.c  |  2 +-
 target/riscv/cpu.h  |  4 +++-
 target/riscv/cpu_bits.h | 11 +++
 target/riscv/csr.c  | 52 -
 4 files changed, 66 insertions(+), 3 deletions(-)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 9f47f2072c56..d59e1c0c146d 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -86,7 +86,7 @@ typedef struct RISCVCPUInfo {
 
 static void set_misa(CPURISCVState *env, target_ulong misa)
 {
-env->misa = misa;
+env->misa_mask = env->misa = misa;
 }
 
 static void set_versions(CPURISCVState *env, int user_ver, int priv_ver)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index ae0e3f6a544d..830a9d476dce 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -86,7 +86,8 @@
so a cpu features bitfield is required, likewise for optional PMP support */
 enum {
 RISCV_FEATURE_MMU,
-RISCV_FEATURE_PMP
+RISCV_FEATURE_PMP,
+RISCV_FEATURE_MISA_RW
 };
 
 #define USER_VERSION_2_02_0 0x00020200
@@ -118,6 +119,7 @@ struct CPURISCVState {
 target_ulong user_ver;
 target_ulong priv_ver;
 target_ulong misa;
+target_ulong misa_mask;
 
 uint32_t features;
 
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index 878de6233846..55b45a40ca3f 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -311,10 +311,21 @@
 #define MSTATUS32_SD0x8000
 #define MSTATUS64_SD0x8000ULL
 
+#define MISA32_MXL  0xC000
+#define MISA64_MXL  0xC000ULL
+
+#define MXL_RV321
+#define MXL_RV642
+#define MXL_RV128   3
+
 #if defined(TARGET_RISCV32)
 #define MSTATUS_SD MSTATUS32_SD
+#define MISA_MXL MISA32_MXL
+#define MXL_VAL MXL_RV32
 #elif defined(TARGET_RISCV64)
 #define MSTATUS_SD MSTATUS64_SD
+#define MISA_MXL MISA64_MXL
+#define MXL_VAL MXL_RV64
 #endif
 
 /* sstatus CSR bits */
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 9bbe81a110a5..0be973002ee2 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -341,6 +341,56 @@ static int read_misa(CPURISCVState *env, int csrno, 
target_ulong *val)
 return 0;
 }
 
+static int write_misa(CPURISCVState *env, int csrno, target_ulong val)
+{
+if (!riscv_feature(env, RISCV_FEATURE_MISA_RW)) {
+/* drop write to misa */
+return 0;
+}
+
+/* 'I' or 'E' must be present */
+if (!(val & (RVI | RVE))) {
+/* it not, drop write to misa */
+return 0;
+}
+
+/* 'E' excludes all other extensions */
+if (val & RVE) {
+/* when we support 'E' we can do "val = RVE;" however
+ * for now we just drop writes if 'E' is present */
+return 0;
+}
+
+/* Mask extensions that are not supported by this hart */
+val &= env->misa_mask;
+
+/* Mask extensions that are not supported by QEMU */
+val &= (RVI | RVE | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
+
+/* 'D' depends on 'F', so clear 'D' if 'F' is not present */
+if ((val & RVD) && !(val & RVF)) {
+val &= ~RVD;
+}
+
+/* Suppress 'C' if next instruction is not aligned
+   TODO: this should check next_pc */
+if ((val & RVC) && (GETPC() & ~3) != 0) {
+val &= ~RVC;
+}
+
+/* misa.MXL writes are not supported by QEMU */
+val = (env->misa & MISA_MXL) | (val & ~MISA_MXL);
+
+/* flush translation cache */
+if (val != env->misa) {
+tb_flush(CPU(riscv_env_get_cpu(env)));
+}
+
+env->misa = val;
+
+return 0;
+}
+
 static int read_medeleg(CPURISCVState *env, int csrno, target_ulong *val)
 {
 *val = env->medeleg;
@@ -821,7 +871,7 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
 
 /* Machine Trap Setup */
 [CSR_MSTATUS] = { any,  read_mstatus, write_mstatus },
-[CSR_MISA] ={ any,  read_misa   },
+[CSR_MISA] ={ any,  read_misa,write_misa},
 [CSR_MIDELEG] = { any,  read_mideleg, write_mideleg },
 [CSR_MEDELEG] = { any,  read_medeleg, write_medeleg },
 [CSR_MIE] = { any,  read_mie, write_mie },
-- 
2.7.0




  1   2   3   4   5   6   7   >