Re: [PATCH 0/3] Assorted fixes for PMU

2024-05-14 Thread Atish Kumar Patra
On Mon, May 13, 2024 at 11:29 PM Alistair Francis  wrote:
>
> On Tue, Apr 30, 2024 at 5:29 AM Atish Patra  wrote:
> >
> > This series contains few miscallenous fixes related to hpmcounters
> > and related code. The first patch fixes an issue with cycle/instret
> > counters overcouting while the remaining two are more for specification
> > compliance.
> >
> > Signed-off-by: Atish Patra 
> > ---
> > Atish Patra (3):
> >   target/riscv: Save counter values during countinhibit update
> >   target/riscv: Enforce WARL behavior for scounteren/hcounteren
> >   target/riscv: Fix the predicate functions for mhpmeventhX CSRs
>
> Thanks!
>
> Applied to riscv-to-apply.next
>

Hi Alistair,
Thanks for your review. But the patch 1 had some comments about
vmstate which needs updating.
We also found a few more fixes that I was planning to include in v2.

I can send a separate fixes series on top riscv-to-apply.next or this
series can be dropped for the time being.
You can queue it v2 later. Let me know what you prefer.


> Alistair
>
> >
> >  target/riscv/cpu.h |   1 -
> >  target/riscv/csr.c | 111 
> > ++---
> >  target/riscv/machine.c |   1 -
> >  3 files changed, 68 insertions(+), 45 deletions(-)
> > ---
> > base-commit: 1642f979a71a5667a05070be2df82f48bd43ad7a
> > change-id: 20240428-countinhibit_fix-c6a1c11f4375
> > --
> > Regards,
> > Atish patra
> >
> >



Re: [PATCH 1/3] target/riscv: Save counter values during countinhibit update

2024-05-09 Thread Atish Kumar Patra
On Thu, May 2, 2024 at 5:39 AM Andrew Jones  wrote:
>
> On Tue, Apr 30, 2024 at 03:00:45PM GMT, Daniel Henrique Barboza wrote:
> >
> >
> > On 4/29/24 16:28, Atish Patra wrote:
> > > Currently, if a counter monitoring cycle/instret is stopped via
> > > mcountinhibit we just update the state while the value is saved
> > > during the next read. This is not accurate as the read may happen
> > > many cycles after the counter is stopped. Ideally, the read should
> > > return the value saved when the counter is stopped.
> > >
> > > Thus, save the value of the counter during the inhibit update
> > > operation and return that value during the read if corresponding bit
> > > in mcountihibit is set.
> > >
> > > Signed-off-by: Atish Patra 
> > > ---
> > >   target/riscv/cpu.h |  1 -
> > >   target/riscv/csr.c | 32 
> > >   target/riscv/machine.c |  1 -
> > >   3 files changed, 20 insertions(+), 14 deletions(-)
> > >
> > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > > index 3b1a02b9449a..09bbf7ce9880 100644
> > > --- a/target/riscv/cpu.h
> > > +++ b/target/riscv/cpu.h
> > > @@ -153,7 +153,6 @@ typedef struct PMUCTRState {
> > >   target_ulong mhpmcounter_prev;
> > >   /* Snapshort value of a counter in RV32 */
> > >   target_ulong mhpmcounterh_prev;
> > > -bool started;
> > >   /* Value beyond UINT32_MAX/UINT64_MAX before overflow interrupt 
> > > trigger */
> > >   target_ulong irq_overflow_left;
> > >   } PMUCTRState;
> > > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > > index 726096444fae..68ca31aff47d 100644
> > > --- a/target/riscv/csr.c
> > > +++ b/target/riscv/csr.c
> > > @@ -929,17 +929,11 @@ static RISCVException 
> > > riscv_pmu_read_ctr(CPURISCVState *env, target_ulong *val,
> > >   if (get_field(env->mcountinhibit, BIT(ctr_idx))) {
> > >   /*
> > > - * Counter should not increment if inhibit bit is set. We can't 
> > > really
> > > - * stop the icount counting. Just return the counter value 
> > > written by
> > > - * the supervisor to indicate that counter was not incremented.
> > > + * Counter should not increment if inhibit bit is set. Just 
> > > return the
> > > + * current counter value.
> > >*/
> > > -if (!counter->started) {
> > > -*val = ctr_val;
> > > -return RISCV_EXCP_NONE;
> > > -} else {
> > > -/* Mark that the counter has been stopped */
> > > -counter->started = false;
> > > -}
> > > + *val = ctr_val;
> > > + return RISCV_EXCP_NONE;
> > >   }
> > >   /*
> > > @@ -1973,9 +1967,23 @@ static RISCVException 
> > > write_mcountinhibit(CPURISCVState *env, int csrno,
> > >   /* Check if any other counter is also monitoring 
> > > cycles/instructions */
> > >   for (cidx = 0; cidx < RV_MAX_MHPMCOUNTERS; cidx++) {
> > > -if (!get_field(env->mcountinhibit, BIT(cidx))) {
> > >   counter = >pmu_ctrs[cidx];
> > > -counter->started = true;
> > > +if (get_field(env->mcountinhibit, BIT(cidx)) && (val & 
> > > BIT(cidx))) {
> > > +   /*
> > > + * Update the counter value for cycle/instret as we can't 
> > > stop the
> > > + * host ticks. But we should show the current value at this 
> > > moment.
> > > + */
> > > +if (riscv_pmu_ctr_monitor_cycles(env, cidx) ||
> > > +riscv_pmu_ctr_monitor_instructions(env, cidx)) {
> > > +counter->mhpmcounter_val = get_ticks(false) -
> > > +   counter->mhpmcounter_prev +
> > > +   counter->mhpmcounter_val;
> > > +if (riscv_cpu_mxl(env) == MXL_RV32) {
> > > +counter->mhpmcounterh_val = get_ticks(false) -
> > > +
> > > counter->mhpmcounterh_prev +
> > > +
> > > counter->mhpmcounterh_val;
> > > +   }
> > > +}
> > >   }
> > >   }
> > > diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> > > index 76f2150f78b5..3e0f2dd2ce2a 100644
> > > --- a/target/riscv/machine.c
> > > +++ b/target/riscv/machine.c
> > > @@ -328,7 +328,6 @@ static const VMStateDescription vmstate_pmu_ctr_state 
> > > = {
> > >   VMSTATE_UINTTL(mhpmcounterh_val, PMUCTRState),
> > >   VMSTATE_UINTTL(mhpmcounter_prev, PMUCTRState),
> > >   VMSTATE_UINTTL(mhpmcounterh_prev, PMUCTRState),
> > > -VMSTATE_BOOL(started, PMUCTRState),
> >
> > Unfortunately we can't remove fields from the VMStateDescription without 
> > breaking
> > migration backward compatibility. Older QEMUs will attempt to read a field 
> > that
> > doesn't exist and migration will fail.
> >
> > I'm assuming that we care about backward compat. If we're not up to this 
> > point yet
> > then we 

Re: [PATCH] target/riscv: fix instructions count handling in icount mode

2024-04-11 Thread Atish Kumar Patra
On Thu, Apr 11, 2024 at 4:34 AM Clément Léger  wrote:
>
> When icount is enabled, rather than returning the virtual CPU time, we
> should return the instruction count itself. Add an instructions bool
> parameter to get_ticks() to correctly return icount_get_raw() when
> icount_enabled() == 1 and instruction count is queried. This will modify
> the existing behavior which was returning an instructions count close to
> the number of cycles (CPI ~= 1).
>
> Signed-off-by: Clément Léger 
>
> ---
>  target/riscv/csr.c | 29 -
>  1 file changed, 16 insertions(+), 13 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 726096444f..5f1dcee102 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -762,14 +762,17 @@ static RISCVException write_vcsr(CPURISCVState *env, 
> int csrno,
>  }
>
>  /* User Timers and Counters */
> -static target_ulong get_ticks(bool shift)
> +static target_ulong get_ticks(bool shift, bool instructions)
>  {
>  int64_t val;
>  target_ulong result;
>
>  #if !defined(CONFIG_USER_ONLY)
>  if (icount_enabled()) {
> -val = icount_get();
> +if (instructions)
> +val = icount_get_raw();
> +else
> +val = icount_get();
>  } else {
>  val = cpu_get_host_ticks();
>  }
> @@ -804,14 +807,14 @@ static RISCVException read_timeh(CPURISCVState *env, 
> int csrno,
>  static RISCVException read_hpmcounter(CPURISCVState *env, int csrno,
>target_ulong *val)
>  {
> -*val = get_ticks(false);
> +*val = get_ticks(false, (csrno == CSR_INSTRET));
>  return RISCV_EXCP_NONE;
>  }
>
>  static RISCVException read_hpmcounterh(CPURISCVState *env, int csrno,
> target_ulong *val)
>  {
> -*val = get_ticks(true);
> +*val = get_ticks(true, (csrno == CSR_INSTRETH));
>  return RISCV_EXCP_NONE;
>  }
>
> @@ -875,11 +878,11 @@ static RISCVException write_mhpmcounter(CPURISCVState 
> *env, int csrno,
>  int ctr_idx = csrno - CSR_MCYCLE;
>  PMUCTRState *counter = >pmu_ctrs[ctr_idx];
>  uint64_t mhpmctr_val = val;
> +bool instr = riscv_pmu_ctr_monitor_instructions(env, ctr_idx);
>
>  counter->mhpmcounter_val = val;
> -if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
> -riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
> -counter->mhpmcounter_prev = get_ticks(false);
> +if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) || instr) {
> +counter->mhpmcounter_prev = get_ticks(false, instr);
>  if (ctr_idx > 2) {
>  if (riscv_cpu_mxl(env) == MXL_RV32) {
>  mhpmctr_val = mhpmctr_val |
> @@ -902,12 +905,12 @@ static RISCVException write_mhpmcounterh(CPURISCVState 
> *env, int csrno,
>  PMUCTRState *counter = >pmu_ctrs[ctr_idx];
>  uint64_t mhpmctr_val = counter->mhpmcounter_val;
>  uint64_t mhpmctrh_val = val;
> +bool instr = riscv_pmu_ctr_monitor_instructions(env, ctr_idx);
>
>  counter->mhpmcounterh_val = val;
>  mhpmctr_val = mhpmctr_val | (mhpmctrh_val << 32);
> -if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
> -riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
> -counter->mhpmcounterh_prev = get_ticks(true);
> +if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) || instr) {
> +counter->mhpmcounterh_prev = get_ticks(true, instr);
>  if (ctr_idx > 2) {
>  riscv_pmu_setup_timer(env, mhpmctr_val, ctr_idx);
>  }
> @@ -926,6 +929,7 @@ static RISCVException riscv_pmu_read_ctr(CPURISCVState 
> *env, target_ulong *val,
>   counter->mhpmcounter_prev;
>  target_ulong ctr_val = upper_half ? counter->mhpmcounterh_val :
>  counter->mhpmcounter_val;
> +bool instr = riscv_pmu_ctr_monitor_instructions(env, ctr_idx);
>
>  if (get_field(env->mcountinhibit, BIT(ctr_idx))) {
>  /*
> @@ -946,9 +950,8 @@ static RISCVException riscv_pmu_read_ctr(CPURISCVState 
> *env, target_ulong *val,
>   * The kernel computes the perf delta by subtracting the current value 
> from
>   * the value it initialized previously (ctr_val).
>   */
> -if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) ||
> -riscv_pmu_ctr_monitor_instructions(env, ctr_idx)) {
> -*val = get_ticks(upper_half) - ctr_prev + ctr_val;
> +if (riscv_pmu_ctr_monitor_cycles(env, ctr_idx) || instr) {
> +*val = get_ticks(upper_half, instr) - ctr_prev + ctr_val;
>  } else {
>  *val = ctr_val;
>  }
> --
> 2.43.0
>


Reviewed-by: Atish Patra 



Re: [RFC v2 2/2] hw/riscv: Add server platform reference machine

2024-03-22 Thread Atish Kumar Patra
On Tue, Mar 12, 2024 at 6:53 AM Fei Wu  wrote:
>
> The RISC-V Server Platform specification[1] defines a standardized set
> of hardware and software capabilities, that portable system software,
> such as OS and hypervisors can rely on being present in a RISC-V server
> platform.
>
> A corresponding Qemu RISC-V server platform reference (rvsp-ref for
> short) machine type is added to provide a environment for firmware/OS
> development and testing. The main features included in rvsp-ref are:
>
>  - Based on riscv virt machine type
>  - A new memory map as close as virt machine as possible
>  - A new virt CPU type rvsp-ref-cpu for server platform compliance
>  - AIA
>  - PCIe AHCI
>  - PCIe NIC
>  - No virtio device
>  - No fw_cfg device
>  - No ACPI table provided
>  - Only minimal device tree nodes
>
> [1] https://github.com/riscv-non-isa/riscv-server-platform
>
> Signed-off-by: Fei Wu 
> ---
>  configs/devices/riscv64-softmmu/default.mak |1 +
>  hw/riscv/Kconfig|   12 +
>  hw/riscv/meson.build|1 +
>  hw/riscv/server_platform_ref.c  | 1276 +++
>  4 files changed, 1290 insertions(+)
>  create mode 100644 hw/riscv/server_platform_ref.c
>
> diff --git a/configs/devices/riscv64-softmmu/default.mak 
> b/configs/devices/riscv64-softmmu/default.mak
> index 3f68059448..a1d98e49ef 100644
> --- a/configs/devices/riscv64-softmmu/default.mak
> +++ b/configs/devices/riscv64-softmmu/default.mak
> @@ -10,5 +10,6 @@ CONFIG_SPIKE=y
>  CONFIG_SIFIVE_E=y
>  CONFIG_SIFIVE_U=y
>  CONFIG_RISCV_VIRT=y
> +CONFIG_SERVER_PLATFORM_REF=y
>  CONFIG_MICROCHIP_PFSOC=y
>  CONFIG_SHAKTI_C=y
> diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
> index 5d644eb7b1..5674589e66 100644
> --- a/hw/riscv/Kconfig
> +++ b/hw/riscv/Kconfig
> @@ -48,6 +48,18 @@ config RISCV_VIRT
>  select ACPI
>  select ACPI_PCI
>
> +config SERVER_PLATFORM_REF
> +bool
> +select RISCV_NUMA
> +select GOLDFISH_RTC
> +select PCI
> +select PCI_EXPRESS_GENERIC_BRIDGE
> +select PFLASH_CFI01
> +select SERIAL
> +select RISCV_ACLINT
> +select RISCV_APLIC
> +select RISCV_IMSIC
> +
>  config SHAKTI_C
>  bool
>  select RISCV_ACLINT
> diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
> index 2f7ee81be3..bb3aff91ea 100644
> --- a/hw/riscv/meson.build
> +++ b/hw/riscv/meson.build
> @@ -4,6 +4,7 @@ riscv_ss.add(when: 'CONFIG_RISCV_NUMA', if_true: 
> files('numa.c'))
>  riscv_ss.add(files('riscv_hart.c'))
>  riscv_ss.add(when: 'CONFIG_OPENTITAN', if_true: files('opentitan.c'))
>  riscv_ss.add(when: 'CONFIG_RISCV_VIRT', if_true: files('virt.c'))
> +riscv_ss.add(when: 'CONFIG_SERVER_PLATFORM_REF', if_true: 
> files('server_platform_ref.c'))
>  riscv_ss.add(when: 'CONFIG_SHAKTI_C', if_true: files('shakti_c.c'))
>  riscv_ss.add(when: 'CONFIG_SIFIVE_E', if_true: files('sifive_e.c'))
>  riscv_ss.add(when: 'CONFIG_SIFIVE_U', if_true: files('sifive_u.c'))
> diff --git a/hw/riscv/server_platform_ref.c b/hw/riscv/server_platform_ref.c
> new file mode 100644
> index 00..b552650265
> --- /dev/null
> +++ b/hw/riscv/server_platform_ref.c
> @@ -0,0 +1,1276 @@
> +/*
> + * QEMU RISC-V Server Platform (RVSP) Reference Board
> + *
> + * Copyright (c) 2024 Intel, Inc.
> + *
> + * This board is compliant RISC-V Server platform specification and 
> leveraging
> + * a lot of riscv virt code.
> + *
> + * 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 .
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/units.h"
> +#include "qemu/error-report.h"
> +#include "qemu/guest-random.h"
> +#include "qapi/error.h"
> +#include "qapi/qapi-visit-common.h"
> +#include "hw/boards.h"
> +#include "hw/loader.h"
> +#include "hw/sysbus.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/char/serial.h"
> +#include "hw/block/flash.h"
> +#include "hw/ide/pci.h"
> +#include "hw/ide/ahci-pci.h"
> +#include "hw/pci/pci.h"
> +#include "hw/pci-host/gpex.h"
> +#include "hw/core/sysbus-fdt.h"
> +#include "hw/riscv/riscv_hart.h"
> +#include "hw/riscv/boot.h"
> +#include "hw/riscv/numa.h"
> +#include "hw/intc/riscv_aclint.h"
> +#include "hw/intc/riscv_aplic.h"
> +#include "hw/intc/riscv_imsic.h"
> +#include "chardev/char.h"
> +#include "sysemu/device_tree.h"
> +#include "sysemu/runstate.h"
> +#include "sysemu/sysemu.h"
> +#include "sysemu/tcg.h"
> +#include "target/riscv/cpu.h"
> +#include 

Re: [RFC v2 2/2] hw/riscv: Add server platform reference machine

2024-03-22 Thread Atish Kumar Patra
On Fri, Mar 22, 2024 at 2:20 AM Marcin Juszkiewicz
 wrote:
>
> W dniu 22.03.2024 o 09:50, Heinrich Schuchardt pisze:
>  >>> I see no mention of device trees in the spec, but I do see ACPI. Do we
>  >>> really expect a server platform to use DTs?
>  >>
>  >> This platform "kind of" follows sbsa-ref where we have very
>  >> minimalistic device tree sharing information qemu->firmware.
>  >>
>  >> libfdt is small, format is known and describes hardware. Firmware is
>  >> free to make use of it in any way it wants.
>  >>
>  >> On sbsa-ref we parse DT in TF-A (base firmware) and provide hardware
>  >> information to higher level (edk2) via SMC mechanism. Then EDK2
>  >> creates ACPI tables and provide them to the Operating System.
>
>  > We should ensure that only either an ACPI table or a device-tree
>  > description is passed to the OS and not both, e.g. when using
>  >
>  >  qemu-system-riscv64 -kernel vmlinux -M sbsa-ref
>  >
>  > But that requirement is not machine specific.
>
> I would not call "qemu-system-* -M machinename -k kernel_image" a proper
> way to boot for several systems emulated by QEMU.
>
> DeviceTree is in rvsp-ref and sbsa-ref because it is easy to process in
> limited space 1st stage of firmware has.
>

OpenSBI also has DT support only. So a minimalistic DT generated by the machine
for the firmware is required for RISC-V as well.

> And if we knew how people will mention 'sbsa-ref uses DT' we would use
> something else instead. But that would require adding more code into
> existing firmware projects (libfdt is usually already there).
>
> I did not looked at DT generated for rvsp-ref. I know that sbsa-ref one
> is too minimalistic for kernel use as we added only those fields/nodes
> we need to provide data for firmware.



Re: [RISC-V][tech-server-soc] [RISC-V][tech-server-platform] [RFC 1/2] hw/riscv: Add server platform reference machine

2024-03-11 Thread Atish Kumar Patra
On Mon, Mar 11, 2024 at 7:38 AM Andrew Jones  wrote:
>
> On Mon, Mar 11, 2024 at 04:55:24AM -0700, Wu, Fei2 wrote:
> > On 3/8/2024 5:20 PM, Andrew Jones wrote:
> > > On Thu, Mar 07, 2024 at 02:26:18PM +0800, Wu, Fei wrote:
> > >> On 3/7/2024 8:48 AM, Alistair Francis wrote:
> > >>> On Thu, Mar 7, 2024 at 5:13 AM Atish Kumar Patra  
> > >>> wrote:
> > >>>>
> > >>>> On Wed, Mar 6, 2024 at 4:56 AM Wu, Fei  wrote:
> > >>>>>
> > >>>>> On 3/6/2024 8:19 AM, Alistair Francis wrote:
> > >>>>>> On Mon, Mar 4, 2024 at 8:28 PM Fei Wu  wrote:
> > > ...
> > >>>>>>> +config SERVER_PLATFORM_REF
> > >>>>>>> +bool
> > >>>>>>> +select RISCV_NUMA
> > >>>>>>> +select GOLDFISH_RTC
> > >>>>>>> +select PCI
> > >>>>>>> +select PCI_EXPRESS_GENERIC_BRIDGE
> > >>>>>>> +select PFLASH_CFI01
> > >>>>>>> +select SERIAL
> > >>>>>>> +select RISCV_ACLINT
> > >>>>>>> +select RISCV_APLIC
> > >>>>>>> +select RISCV_IMSIC
> > >>>>>>> +select SIFIVE_TEST
> > >>>>>>
> > >>>>>> Do we really need SiFive Test in the server platform?
> > >>>>>>
> > >>>>> It's used to reset the system, is there any better choice?
> > >>>
> > >>> If we add this now we are stuck with it forever (or at least a long
> > >>> time). So it'd be nice to think about these and decide if these really
> > >>> are the best way to do things. We don't have to just copy the existing
> > >>> virt machine.
> > >>>
> > >> We need a solution to poweroff/reboot, and sifive test is one of the
> > >> hardware implementations, so in general I think it's okay. But I agree
> > >> Sifive test looks a device for testing only.
> > >>
> > >>> There must be a more standard way to do this then MMIO mapped SiFive 
> > >>> hardware?
> > >>>
> > >> The mapped MMIO mechanism leveraged by Sifive test by itself is kinda
> > >> generic, the sbsa_ec for sbsa-ref is also an MMIO mapped device. These
> > >> two devices look very similar except different encodings of the
> > >> shutdown/reboot command.
> > >>
> > >> Probably we can have a generic shutdown/reboot device in QEMU for both
> > >> sifive test and sbsa_ec, and likely more (not in this patch series). In
> > >> this way, sifive test device will be replaced by this more generic
> > >> device. Any suggestions?
> > >
> > > Operating systems shouldn't need to implement odd-ball device drivers to
> > > function on a reference of a standard platform. So the reference platform
> > > should only be comprised of devices which have specifications and already,
> > > or will, have DT bindings. Generic devices would be best, but I don't
> > > think it should be a problem to use devices from multiple vendors. The
> > > devices just need to allow GPL drivers to be written. With all that in
> > > mind, what about adding a generic GPIO controller or using SiFive's GPIO
> > > controller. Then, we could add gpio-restart and gpio-poweroff.
> > >
> > I agree with most of what you said. Regarding generic devices, syscon
> > looks a better choice than gpio in the current situation.
> >
> > Linux kernel has these configurations enabled for virt, and I'm not
> > going to add a new soc for this new board currently, we can use the same
> > syscon interface for power, and it has already well supported.
> >
> > config SOC_VIRT
> >   bool "QEMU Virt Machine"
> >   select CLINT_TIMER if RISCV_M_MODE
> >   select POWER_RESET
> >   select POWER_RESET_SYSCON
> >   select POWER_RESET_SYSCON_POWEROFF
> >   select GOLDFISH
> >
> > For the qemu part, we can remove device 'sifive_test' and manage that
> > memory region directly with MemoryRegionOps, similar to what
> > hw/mips/boston.c does.
>
> OK, that sounds good. Also, I guess the real concern is whether firmware
> (e.g. OpenSBI) supports the platform's power-off device, since firmware
> will present the SRST SBI call to Linux, so Linux doesn't need to worry
> about it at all. However, if we want Linux to worry about it, then we

Syscon devices are already supported in OpenSBI. So syscon seems to be
the best option right now.

> can't forget to ensure we can implement the syscon interface in AML for
> ACPI too. Indeed, we should be introducing ACPI support for this reference
> machine type at the same time we introduce the machine in order to ensure
> all device selections have, or will have, both DT and ACPI support.
>

Yeah. In addition to that, this reference platform also needs to
generate minimalistic DT
for OpenSBI even though only ACPI is required for Linux. IIRC,
sbsa-ref also does something similar.

> Thanks,
> drew



Re: [RFC 1/2] hw/riscv: Add server platform reference machine

2024-03-06 Thread Atish Kumar Patra
On Wed, Mar 6, 2024 at 4:56 AM Wu, Fei  wrote:
>
> On 3/6/2024 8:19 AM, Alistair Francis wrote:
> > On Mon, Mar 4, 2024 at 8:28 PM Fei Wu  wrote:
> >>
> >> The RISC-V Server Platform specification[1] defines a standardized set
> >> of hardware and software capabilities, that portable system software,
> >> such as OS and hypervisors can rely on being present in a RISC-V server
> >> platform.
> >>
> >> A corresponding Qemu RISC-V server platform reference (rvsp-ref for
> >> short) machine type is added to provide a environment for firmware/OS
> >> development and testing. The main features included in rvsp-ref are:
> >>
> >>  - Based on riscv virt machine type
> >>  - A new memory map as close as virt machine as possible
> >>  - A new virt CPU type rvsp-ref-cpu for server platform compliance
> >>  - AIA
> >>  - PCIe AHCI
> >>  - PCIe NIC
> >>  - No virtio device
> >>  - No fw_cfg device
> >>  - No ACPI table provided
> >>  - Only minimal device tree nodes
> >>
> >> [1] https://github.com/riscv-non-isa/riscv-server-platform
> >
> > + Atish
> >
> >>
> >> Signed-off-by: Fei Wu 
> >> ---
> >>  configs/devices/riscv64-softmmu/default.mak |1 +
> >>  hw/riscv/Kconfig|   13 +
> >>  hw/riscv/meson.build|1 +
> >>  hw/riscv/server_platform_ref.c  | 1244 +++
> >>  4 files changed, 1259 insertions(+)
> >>  create mode 100644 hw/riscv/server_platform_ref.c
> >>
> >> diff --git a/configs/devices/riscv64-softmmu/default.mak 
> >> b/configs/devices/riscv64-softmmu/default.mak
> >> index 3f68059448..a1d98e49ef 100644
> >> --- a/configs/devices/riscv64-softmmu/default.mak
> >> +++ b/configs/devices/riscv64-softmmu/default.mak
> >> @@ -10,5 +10,6 @@ CONFIG_SPIKE=y
> >>  CONFIG_SIFIVE_E=y
> >>  CONFIG_SIFIVE_U=y
> >>  CONFIG_RISCV_VIRT=y
> >> +CONFIG_SERVER_PLATFORM_REF=y
> >>  CONFIG_MICROCHIP_PFSOC=y
> >>  CONFIG_SHAKTI_C=y
> >> diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig
> >> index 5d644eb7b1..debac5a7f5 100644
> >> --- a/hw/riscv/Kconfig
> >> +++ b/hw/riscv/Kconfig
> >> @@ -48,6 +48,19 @@ config RISCV_VIRT
> >>  select ACPI
> >>  select ACPI_PCI
> >>
> >> +config SERVER_PLATFORM_REF
> >> +bool
> >> +select RISCV_NUMA
> >> +select GOLDFISH_RTC
> >> +select PCI
> >> +select PCI_EXPRESS_GENERIC_BRIDGE
> >> +select PFLASH_CFI01
> >> +select SERIAL
> >> +select RISCV_ACLINT
> >> +select RISCV_APLIC
> >> +select RISCV_IMSIC
> >> +select SIFIVE_TEST
> >
> > Do we really need SiFive Test in the server platform?
> >
> It's used to reset the system, is there any better choice?
>
> Probably I can remove the "sifive,test1 sifive,test0" from the
> compatible list in fdt, and only keep "syscon", I see opensbi has
> already removed that support in commit c2e602707.
>
> > Same with the goldfish RTC?
> >
> Although the spec doesn't make RTC mandatory, it should be a common
> practice having a RTC on server, so I add a RTC here no matter it's
> goldfish or not.
>

The platform spec says
HPER_070 : A battery-backed RTC or analogous timekeeping mechanism
MUST be implemented.

Can we consider goldfish RTC in this category ?

But I want to discuss a larger point as the server platform/SoC spec
defines a bunch of optional requirement.
Does this platform intend to be a platform that is a superset of all
those options or allow optionality in
the platform as well ?

> >> +
> >>  config SHAKTI_C
> >>  bool
> >>  select RISCV_ACLINT
> >> diff --git a/hw/riscv/meson.build b/hw/riscv/meson.build
> >> index 2f7ee81be3..bb3aff91ea 100644
> >> --- a/hw/riscv/meson.build
> >> +++ b/hw/riscv/meson.build
> >> @@ -4,6 +4,7 @@ riscv_ss.add(when: 'CONFIG_RISCV_NUMA', if_true: 
> >> files('numa.c'))
> >>  riscv_ss.add(files('riscv_hart.c'))
> >>  riscv_ss.add(when: 'CONFIG_OPENTITAN', if_true: files('opentitan.c'))
> >>  riscv_ss.add(when: 'CONFIG_RISCV_VIRT', if_true: files('virt.c'))
> >> +riscv_ss.add(when: 'CONFIG_SERVER_PLATFORM_REF', if_true: 
> >> files('server_platform_ref.c'))
> >>  riscv_ss.add(when: 'CONFIG_SHAKTI_C', if_true: files('shakti_c.c'))
> >>  riscv_ss.add(when: 'CONFIG_SIFIVE_E', if_true: files('sifive_e.c'))
> >>  riscv_ss.add(when: 'CONFIG_SIFIVE_U', if_true: files('sifive_u.c'))
> >> diff --git a/hw/riscv/server_platform_ref.c 
> >> b/hw/riscv/server_platform_ref.c
> >> new file mode 100644
> >> index 00..ae90c4b27a
> >> --- /dev/null
> >> +++ b/hw/riscv/server_platform_ref.c
> >> @@ -0,0 +1,1244 @@
> >> +/*
> >> + * QEMU RISC-V Server Platfrom (RVSP) Reference Board
> >
> > Platform
> >
> OK.
>
> >> +static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
> >> +  DeviceState *irqchip,
> >> +  RVSPMachineState *s)
> >> +{
> >> +DeviceState *dev;
> >> +PCIHostState *pci;
> >> +PCIDevice *pdev_ahci;
> >> +AHCIPCIState *ich9;
> >> +DriveInfo *hd[NUM_SATA_PORTS];
> >> +

Re: [PATCH RFC 0/8] Add Counter delegation ISA extension support

2024-02-21 Thread Atish Kumar Patra
On Wed, Feb 21, 2024 at 6:58 AM Daniel Henrique Barboza <
dbarb...@ventanamicro.com> wrote:

> Hi Atish,
>
> This series and its dependency, which I assume it's
>
> "[PATCH v4 0/5] Add ISA extension smcntrpmf support"
>
> Doesn't apply in neither master nor riscv-to-apply.next because of this
> patch:
>
"target/riscv: Use RISCVException as return type for all csr ops"
>
> That changed some functions from 'int' to "RISCVException" type. The
> conflicts
> from the v4 series are rather trivial but the conflicts for this RFC are
> annoying
> to deal with. It would be better if you could re-send both series rebased
> with
> the latest changes.
>
>
I was waiting for Alistair's ACK on the smcntrpmf series as he had some
comments. It looks like he is okay
with the series now (no further questions).  Let me respin both the series.


> One more thing:
>
> On 2/16/24 21:01, Atish Patra wrote:
> > This series adds the counter delegation extension support. The counter
> > delegation ISA extension(Smcdeleg/Ssccfg) actually depends on multiple
> ISA
> > extensions.
> >
> > 1. S[m|s]csrind : The indirect CSR extension[1] which defines additional
> > 5 ([M|S|VS]IREG2-[M|S|VS]IREG6) register to address size limitation
> of
> > RISC-V CSR address space.
> > 2. Smstateen: The stateen bit[60] controls the access to the registers
> > indirectly via the above indirect registers.
> > 3. Smcdeleg/Ssccfg: The counter delegation extensions[2]
> >
> > The counter delegation extension allows Supervisor mode to program the
> > hpmevent and hpmcounters directly without needing the assistance from the
> > M-mode via SBI calls. This results in a faster perf profiling and very
> > few traps. This extension also introduces a scountinhibit CSR which
> allows
> > to stop/start any counter directly from the S-mode. As the counter
> > delegation extension potentially can have more than 100 CSRs, the
> specificaiton
> > leverages the indirect CSR extension to save the precious CSR address
> range.
> >
> > Due to the dependancy of these extensions, the following extensions must
> be
> > enabled to use the counter delegation feature in S-mode.
> >
> >
> "smstateen=true,sscofpmf=true,ssccfg=true,smcdeleg=true,smcsrind=true,sscsrind=true"
> >
> > This makes the qemu command line quite tedious. In stead of that, I
> think we
> > can enable these features by default if there is no objection.
>
> It wasn't need so far but, if needed, we can add specialized setters for
> extensions
> that has multiple dependencies. Instead of the usual setter we would do
> something
> like:
>
> cpu_set_ssccfg() {
>
>  if (enabled) {
>  smstateen=true
>  sscofpmf=true
>  smcdeleg=true
>  smcsrind=true
>  sscsrind=true
>  }
> }
>
>
> The advantage is that this setter would also work for CPUs that doesn't
> inherit defaults,
> like bare-cps and profile CPUs.
>
>
Your suggested approach looks good to me. But I was asking about concerns
about enabling these extensions
by default rather than the actual mechanism to implement it. Few of the
extensions listed here such as smstateen,smcsrind
sscsrind are independent ISA extensions which are used for other ISA
extensions as well.

It looks like you are okay with the use case also ?


> That doesn't mean we can't add defaults for rv64, but for this particular
> case I wonder if
> the 'max' CPU wouldn't be better.
>
>
Not sure what you mean here. What does 'max' cpu have to do with pmu
extensions ?


>
> Thanks,
>
>
> Daniel
>
> >
> > The first 2 patches decouple the indirect CSR usage from AIA
> implementation
> > while patch3 adds stateen bits validation for AIA.
> > The PATCH4 implements indirect CSR extensions while remaining patches
> > implement the counter delegation extensions.
> >
> > The Qemu patches can be found here:
> > https://github.com/atishp04/qemu/tree/counter_delegation_rfc
> >
> > The opensbi patch can be found here:
> > https://github.com/atishp04/opensbi/tree/counter_delegation_v1
> >
> > The Linux kernel patches can be found here:
> > https://github.com/atishp04/linux/tree/counter_delegation_rfc
> >
> > [1] https://github.com/riscv/riscv-indirect-csr-access
> > [2] https://github.com/riscv/riscv-smcdeleg-ssccfg
> >
> > Atish Patra (1):
> > target/riscv: Enable S*stateen bits for AIA
> >
> > Kaiwen Xue (7):
> > target/riscv: Add properties for Indirect CSR Access extension
> > target/riscv: Decouple AIA processing from xiselect and xireg
> > target/riscv: Support generic CSR indirect access
> > target/riscv: Add smcdeleg/ssccfg properties
> > target/riscv: Add counter delegation definitions
> > target/riscv: Add select value range check for counter delegation
> > target/riscv: Add counter delegation/configuration support
> >
> > target/riscv/cpu.c  |   8 +
> > target/riscv/cpu.h  |   1 +
> > target/riscv/cpu_bits.h |  34 +-
> > target/riscv/cpu_cfg.h  |   4 +
> > target/riscv/csr.c  | 713 +---
> > 

Re: [PATCH v4 5/5] target/riscv: Implement privilege mode filtering for cycle/instret

2024-02-05 Thread Atish Kumar Patra
On Tue, Jan 23, 2024 at 4:15 PM Atish Kumar Patra 
wrote:

> On Sun, Jan 21, 2024 at 9:04 PM Alistair Francis 
> wrote:
> >
> > On Tue, Jan 9, 2024 at 10:29 AM Atish Patra  wrote:
> > >
> > > Privilege mode filtering can also be emulated for cycle/instret by
> > > tracking host_ticks/icount during each privilege mode switch. This
> > > patch implements that for both cycle/instret and mhpmcounters. The
> > > first one requires Smcntrpmf while the other one requires Sscofpmf
> > > to be enabled.
> > >
> > > The cycle/instret are still computed using host ticks when icount
> > > is not enabled. Otherwise, they are computed using raw icount which
> > > is more accurate in icount mode.
> > >
> > > Reviewed-by: Daniel Henrique Barboza 
> > > Signed-off-by: Atish Patra 
> > > ---
> > >  target/riscv/cpu.h| 11 +
> > >  target/riscv/cpu_helper.c |  9 +++-
> > >  target/riscv/csr.c| 95 ++-
> > >  target/riscv/pmu.c| 43 ++
> > >  target/riscv/pmu.h|  2 +
> > >  5 files changed, 136 insertions(+), 24 deletions(-)
> > >
> > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > > index 34617c4c4bab..40d10726155b 100644
> > > --- a/target/riscv/cpu.h
> > > +++ b/target/riscv/cpu.h
> > > @@ -136,6 +136,15 @@ typedef struct PMUCTRState {
> > >  target_ulong irq_overflow_left;
> > >  } PMUCTRState;
> > >
> > > +typedef struct PMUFixedCtrState {
> > > +/* Track cycle and icount for each privilege mode */
> > > +uint64_t counter[4];
> > > +uint64_t counter_prev[4];
> >
> > Are these two used?
> >
>
> Yes. That's where it tracks the current/previous value cycle/instret.
> riscv_pmu_icount_update_priv/riscv_pmu_cycle_update_priv
>
> The priv mode based filtering is enabled in
> riscv_pmu_ctr_get_fixed_counters_val
> using "counter" afterwards.
>
> Did I misunderstand your question ?
>
>
ping ?


> > Alistair
> >
> > > +/* Track cycle and icount for each privilege mode when V = 1*/
> > > +uint64_t counter_virt[2];
> > > +uint64_t counter_virt_prev[2];
> > > +} PMUFixedCtrState;
> > > +
> > >  struct CPUArchState {
> > >  target_ulong gpr[32];
> > >  target_ulong gprh[32]; /* 64 top bits of the 128-bit registers */
> > > @@ -334,6 +343,8 @@ struct CPUArchState {
> > >  /* PMU event selector configured values for RV32 */
> > >  target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
> > >
> > > +PMUFixedCtrState pmu_fixed_ctrs[2];
> > > +
> > >  target_ulong sscratch;
> > >  target_ulong mscratch;
> > >
> > > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> > > index e7e23b34f455..3dddb1b433e8 100644
> > > --- a/target/riscv/cpu_helper.c
> > > +++ b/target/riscv/cpu_helper.c
> > > @@ -715,8 +715,13 @@ void riscv_cpu_set_mode(CPURISCVState *env,
> target_ulong newpriv)
> > >  {
> > >  g_assert(newpriv <= PRV_M && newpriv != PRV_RESERVED);
> > >
> > > -if (icount_enabled() && newpriv != env->priv) {
> > > -riscv_itrigger_update_priv(env);
> > > +if (newpriv != env->priv) {
> > > +if (icount_enabled()) {
> > > +riscv_itrigger_update_priv(env);
> > > +riscv_pmu_icount_update_priv(env, newpriv);
> > > +} else {
> > > +riscv_pmu_cycle_update_priv(env, newpriv);
> > > +}
> > >  }
> > >  /* tlb_flush is unnecessary as mode is contained in mmu_idx */
> > >  env->priv = newpriv;
> > > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > > index 3bd4aa22374f..307d052021c5 100644
> > > --- a/target/riscv/csr.c
> > > +++ b/target/riscv/csr.c
> > > @@ -782,32 +782,16 @@ static int write_vcsr(CPURISCVState *env, int
> csrno, target_ulong val)
> > >  return RISCV_EXCP_NONE;
> > >  }
> > >
> > > +#if defined(CONFIG_USER_ONLY)
> > >  /* User Timers and Counters */
> > >  static target_ulong get_ticks(bool shift)
> > >  {
> > > -int64_t val;
> > > -target_ulong result;
> > > -
> > > -#if !defined(CONFIG_USER_ONLY)
> >

Re: [PATCH v4 5/5] target/riscv: Implement privilege mode filtering for cycle/instret

2024-01-23 Thread Atish Kumar Patra
On Sun, Jan 21, 2024 at 9:04 PM Alistair Francis  wrote:
>
> On Tue, Jan 9, 2024 at 10:29 AM Atish Patra  wrote:
> >
> > Privilege mode filtering can also be emulated for cycle/instret by
> > tracking host_ticks/icount during each privilege mode switch. This
> > patch implements that for both cycle/instret and mhpmcounters. The
> > first one requires Smcntrpmf while the other one requires Sscofpmf
> > to be enabled.
> >
> > The cycle/instret are still computed using host ticks when icount
> > is not enabled. Otherwise, they are computed using raw icount which
> > is more accurate in icount mode.
> >
> > Reviewed-by: Daniel Henrique Barboza 
> > Signed-off-by: Atish Patra 
> > ---
> >  target/riscv/cpu.h| 11 +
> >  target/riscv/cpu_helper.c |  9 +++-
> >  target/riscv/csr.c| 95 ++-
> >  target/riscv/pmu.c| 43 ++
> >  target/riscv/pmu.h|  2 +
> >  5 files changed, 136 insertions(+), 24 deletions(-)
> >
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 34617c4c4bab..40d10726155b 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -136,6 +136,15 @@ typedef struct PMUCTRState {
> >  target_ulong irq_overflow_left;
> >  } PMUCTRState;
> >
> > +typedef struct PMUFixedCtrState {
> > +/* Track cycle and icount for each privilege mode */
> > +uint64_t counter[4];
> > +uint64_t counter_prev[4];
>
> Are these two used?
>

Yes. That's where it tracks the current/previous value cycle/instret.
riscv_pmu_icount_update_priv/riscv_pmu_cycle_update_priv

The priv mode based filtering is enabled in riscv_pmu_ctr_get_fixed_counters_val
using "counter" afterwards.

Did I misunderstand your question ?

> Alistair
>
> > +/* Track cycle and icount for each privilege mode when V = 1*/
> > +uint64_t counter_virt[2];
> > +uint64_t counter_virt_prev[2];
> > +} PMUFixedCtrState;
> > +
> >  struct CPUArchState {
> >  target_ulong gpr[32];
> >  target_ulong gprh[32]; /* 64 top bits of the 128-bit registers */
> > @@ -334,6 +343,8 @@ struct CPUArchState {
> >  /* PMU event selector configured values for RV32 */
> >  target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
> >
> > +PMUFixedCtrState pmu_fixed_ctrs[2];
> > +
> >  target_ulong sscratch;
> >  target_ulong mscratch;
> >
> > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> > index e7e23b34f455..3dddb1b433e8 100644
> > --- a/target/riscv/cpu_helper.c
> > +++ b/target/riscv/cpu_helper.c
> > @@ -715,8 +715,13 @@ void riscv_cpu_set_mode(CPURISCVState *env, 
> > target_ulong newpriv)
> >  {
> >  g_assert(newpriv <= PRV_M && newpriv != PRV_RESERVED);
> >
> > -if (icount_enabled() && newpriv != env->priv) {
> > -riscv_itrigger_update_priv(env);
> > +if (newpriv != env->priv) {
> > +if (icount_enabled()) {
> > +riscv_itrigger_update_priv(env);
> > +riscv_pmu_icount_update_priv(env, newpriv);
> > +} else {
> > +riscv_pmu_cycle_update_priv(env, newpriv);
> > +}
> >  }
> >  /* tlb_flush is unnecessary as mode is contained in mmu_idx */
> >  env->priv = newpriv;
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index 3bd4aa22374f..307d052021c5 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -782,32 +782,16 @@ static int write_vcsr(CPURISCVState *env, int csrno, 
> > target_ulong val)
> >  return RISCV_EXCP_NONE;
> >  }
> >
> > +#if defined(CONFIG_USER_ONLY)
> >  /* User Timers and Counters */
> >  static target_ulong get_ticks(bool shift)
> >  {
> > -int64_t val;
> > -target_ulong result;
> > -
> > -#if !defined(CONFIG_USER_ONLY)
> > -if (icount_enabled()) {
> > -val = icount_get();
> > -} else {
> > -val = cpu_get_host_ticks();
> > -}
> > -#else
> > -val = cpu_get_host_ticks();
> > -#endif
> > -
> > -if (shift) {
> > -result = val >> 32;
> > -} else {
> > -result = val;
> > -}
> > +int64_t val = cpu_get_host_ticks();
> > +target_ulong result = shift ? val >> 32 : val;
> >
> >  return result;
> >  }
> >
> > -#if defined(CONFIG_USER_ONLY)
> >  static RISCVException read_time(CPURISCVState *env, int csrno,
> >  target_ulong *val)
> >  {
> > @@ -932,6 +916,70 @@ static int write_mhpmeventh(CPURISCVState *env, int 
> > csrno, target_ulong val)
> >  return RISCV_EXCP_NONE;
> >  }
> >
> > +static target_ulong riscv_pmu_ctr_get_fixed_counters_val(CPURISCVState 
> > *env,
> > + int counter_idx,
> > + bool upper_half)
> > +{
> > +uint64_t curr_val = 0;
> > +target_ulong result = 0;
> > +uint64_t *counter_arr = icount_enabled() ? 
> > env->pmu_fixed_ctrs[1].counter :
> > +

Re: [PATCH v3 2/5] target/riscv: Add cycle & instret privilege mode filtering properties

2024-01-08 Thread Atish Kumar Patra
On Mon, Jan 8, 2024 at 10:10 AM Daniel Henrique Barboza
 wrote:
>
>
>
> On 1/5/24 19:13, Atish Patra wrote:
> > From: Kaiwen Xue 
> >
> > This adds the properties for ISA extension smcntrpmf. Patches
> > implementing it will follow.
> >
> > Signed-off-by: Atish Patra 
> > Signed-off-by: Kaiwen Xue 
> > ---
> >   target/riscv/cpu.c | 2 ++
> >   target/riscv/cpu_cfg.h | 1 +
> >   2 files changed, 3 insertions(+)
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 83c7c0cf07be..ea34ff2ae983 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -148,6 +148,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
> >   ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
> >   ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
> >   ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
> > +ISA_EXT_DATA_ENTRY(smcntrpmf, PRIV_VERSION_1_12_0, ext_smcntrpmf),
> >   ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
> >   ISA_EXT_DATA_ENTRY(svadu, PRIV_VERSION_1_12_0, ext_svadu),
> >   ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
>
> Sorry for not noticing this in the previous version. I believe we want the 
> "smcntrpmf"
> entry to be right after "smaia" because the isa_edata_arr[] ordering matters 
> when
> building the riscv,isa string in riscv_isa_string_ext().
>

Oops. Thanks for catching that. Fixed in v4.

>
> Thanks,
>
> Daniel
>
> > @@ -1296,6 +1297,7 @@ const char *riscv_get_misa_ext_description(uint32_t 
> > bit)
> >   const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
> >   /* Defaults for standard extensions */
> >   MULTI_EXT_CFG_BOOL("sscofpmf", ext_sscofpmf, false),
> > +MULTI_EXT_CFG_BOOL("smcntrpmf", ext_smcntrpmf, false),
> >   MULTI_EXT_CFG_BOOL("zifencei", ext_zifencei, true),
> >   MULTI_EXT_CFG_BOOL("zicsr", ext_zicsr, true),
> >   MULTI_EXT_CFG_BOOL("zihintntl", ext_zihintntl, true),
> > diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> > index f4605fb190b9..00c34fdd3209 100644
> > --- a/target/riscv/cpu_cfg.h
> > +++ b/target/riscv/cpu_cfg.h
> > @@ -72,6 +72,7 @@ struct RISCVCPUConfig {
> >   bool ext_zihpm;
> >   bool ext_smstateen;
> >   bool ext_sstc;
> > +bool ext_smcntrpmf;
> >   bool ext_svadu;
> >   bool ext_svinval;
> >   bool ext_svnapot;



Re: [v2 3/5] target/riscv: Add cycle & instret privilege mode filtering definitions

2024-01-05 Thread Atish Kumar Patra
On Thu, Jan 4, 2024 at 6:46 PM Alistair Francis  wrote:
>
> On Fri, Dec 29, 2023 at 12:08 PM Atish Patra  wrote:
> >
> > From: Kaiwen Xue 
> >
> > This adds the definitions for ISA extension smcntrpmf.
> >
> > Signed-off-by: Kaiwen Xue 
> > Signed-off-by: Atish Patra 
> > ---
> >  target/riscv/cpu.c  |  1 -
> >  target/riscv/cpu.h  |  6 ++
> >  target/riscv/cpu_bits.h | 29 +
> >  3 files changed, 35 insertions(+), 1 deletion(-)
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index da3f05cd5373..54395f95b299 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -1297,7 +1297,6 @@ const char *riscv_get_misa_ext_description(uint32_t 
> > bit)
> >  const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
> >  /* Defaults for standard extensions */
> >  MULTI_EXT_CFG_BOOL("sscofpmf", ext_sscofpmf, false),
> > -DEFINE_PROP_BOOL("smcntrpmf", RISCVCPU, cfg.ext_smcntrpmf, false),
>
> Can you explain why you are removing this in the commit message?
>

That is just a rebasing error I overlooked at first attempt. I fixed
it and sent a v3. Sorry for the confusion.

> Alistair
>
> >  MULTI_EXT_CFG_BOOL("zifencei", ext_zifencei, true),
> >  MULTI_EXT_CFG_BOOL("zicsr", ext_zicsr, true),
> >  MULTI_EXT_CFG_BOOL("zihintntl", ext_zihintntl, true),
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index d74b361be641..34617c4c4bab 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -319,6 +319,12 @@ struct CPUArchState {
> >
> >  target_ulong mcountinhibit;
> >
> > +/* PMU cycle & instret privilege mode filtering */
> > +target_ulong mcyclecfg;
> > +target_ulong mcyclecfgh;
> > +target_ulong minstretcfg;
> > +target_ulong minstretcfgh;
> > +
> >  /* PMU counter state */
> >  PMUCTRState pmu_ctrs[RV_MAX_MHPMCOUNTERS];
> >
> > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> > index ebd7917d490a..0ee91e502e8f 100644
> > --- a/target/riscv/cpu_bits.h
> > +++ b/target/riscv/cpu_bits.h
> > @@ -401,6 +401,10 @@
> >  /* Machine counter-inhibit register */
> >  #define CSR_MCOUNTINHIBIT   0x320
> >
> > +/* Machine counter configuration registers */
> > +#define CSR_MCYCLECFG   0x321
> > +#define CSR_MINSTRETCFG 0x322
> > +
> >  #define CSR_MHPMEVENT3  0x323
> >  #define CSR_MHPMEVENT4  0x324
> >  #define CSR_MHPMEVENT5  0x325
> > @@ -431,6 +435,9 @@
> >  #define CSR_MHPMEVENT30 0x33e
> >  #define CSR_MHPMEVENT31 0x33f
> >
> > +#define CSR_MCYCLECFGH  0x721
> > +#define CSR_MINSTRETCFGH0x722
> > +
> >  #define CSR_MHPMEVENT3H 0x723
> >  #define CSR_MHPMEVENT4H 0x724
> >  #define CSR_MHPMEVENT5H 0x725
> > @@ -885,6 +892,28 @@ typedef enum RISCVException {
> >  /* PMU related bits */
> >  #define MIE_LCOFIE (1 << IRQ_PMU_OVF)
> >
> > +#define MCYCLECFG_BIT_MINH BIT_ULL(62)
> > +#define MCYCLECFGH_BIT_MINHBIT(30)
> > +#define MCYCLECFG_BIT_SINH BIT_ULL(61)
> > +#define MCYCLECFGH_BIT_SINHBIT(29)
> > +#define MCYCLECFG_BIT_UINH BIT_ULL(60)
> > +#define MCYCLECFGH_BIT_UINHBIT(28)
> > +#define MCYCLECFG_BIT_VSINHBIT_ULL(59)
> > +#define MCYCLECFGH_BIT_VSINH   BIT(27)
> > +#define MCYCLECFG_BIT_VUINHBIT_ULL(58)
> > +#define MCYCLECFGH_BIT_VUINH   BIT(26)
> > +
> > +#define MINSTRETCFG_BIT_MINH   BIT_ULL(62)
> > +#define MINSTRETCFGH_BIT_MINH  BIT(30)
> > +#define MINSTRETCFG_BIT_SINH   BIT_ULL(61)
> > +#define MINSTRETCFGH_BIT_SINH  BIT(29)
> > +#define MINSTRETCFG_BIT_UINH   BIT_ULL(60)
> > +#define MINSTRETCFGH_BIT_UINH  BIT(28)
> > +#define MINSTRETCFG_BIT_VSINH  BIT_ULL(59)
> > +#define MINSTRETCFGH_BIT_VSINH BIT(27)
> > +#define MINSTRETCFG_BIT_VUINH  BIT_ULL(58)
> > +#define MINSTRETCFGH_BIT_VUINH BIT(26)
> > +
> >  #define MHPMEVENT_BIT_OF   BIT_ULL(63)
> >  #define MHPMEVENTH_BIT_OF  BIT(31)
> >  #define MHPMEVENT_BIT_MINH BIT_ULL(62)
> > --
> > 2.34.1
> >
> >



Re: [v2 4/5] target/riscv: Add cycle & instret privilege mode filtering support

2024-01-03 Thread Atish Kumar Patra
On Wed, Jan 3, 2024 at 12:18 PM Daniel Henrique Barboza
 wrote:
>
>
>
> On 12/28/23 21:49, Atish Patra wrote:
> > From: Kaiwen Xue 
> >
> > QEMU only calculates dummy cycles and instructions, so there is no
> > actual means to stop the icount in QEMU. Hence this patch merely adds
> > the functionality of accessing the cfg registers, and cause no actual
> > effects on the counting of cycle and instret counters.
> >
> > Signed-off-by: Atish Patra 
> > Signed-off-by: Kaiwen Xue 
> > ---
> >   target/riscv/cpu.c |  1 +
> >   target/riscv/csr.c | 83 ++
> >   2 files changed, 84 insertions(+)
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 54395f95b299..d24f7ff8b55b 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -1297,6 +1297,7 @@ const char *riscv_get_misa_ext_description(uint32_t 
> > bit)
> >   const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
> >   /* Defaults for standard extensions */
> >   MULTI_EXT_CFG_BOOL("sscofpmf", ext_sscofpmf, false),
> > +MULTI_EXT_CFG_BOOL("smcntrpmf", ext_smcntrpmf, false),
>
>
> As I said in patch 2 this declaration can happen there instead.
>

Yup. Will do it.

>
> >   MULTI_EXT_CFG_BOOL("zifencei", ext_zifencei, true),
> >   MULTI_EXT_CFG_BOOL("zicsr", ext_zicsr, true),
> >   MULTI_EXT_CFG_BOOL("zihintntl", ext_zihintntl, true),
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index 283468bbc652..618e801a7612 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -233,6 +233,27 @@ static RISCVException sscofpmf_32(CPURISCVState *env, 
> > int csrno)
> >   return sscofpmf(env, csrno);
> >   }
> >
> > +static RISCVException smcntrpmf(CPURISCVState *env, int csrno)
> > +{
> > +RISCVCPU *cpu = env_archcpu(env);
> > +
> > +if (!cpu->cfg.ext_smcntrpmf) {
> > +return RISCV_EXCP_ILLEGAL_INST;
> > +}
>
> env_archcpu() should be avoided when possible due to its overhead. You can use
> riscv_cpu_cfg() to retrieve cpu->cfg using 'env':
>

Sure. Will fix it.

> > +if (!riscv_cpu_cfg(env)->ext_smcntrpmf) {
> > +return RISCV_EXCP_ILLEGAL_INST;
> > +}
>
>
> Thanks,
>
> Daniel
>
> > +
> > +return RISCV_EXCP_NONE;
> > +}
> > +
> > +static RISCVException smcntrpmf_32(CPURISCVState *env, int csrno)
> > +{
> > +if (riscv_cpu_mxl(env) != MXL_RV32) {
> > +return RISCV_EXCP_ILLEGAL_INST;
> > +}
> > +
> > +return smcntrpmf(env, csrno);
> > +}
> > +
> > +
> >   static RISCVException any(CPURISCVState *env, int csrno)
> >   {
> >   return RISCV_EXCP_NONE;
> > @@ -818,6 +839,54 @@ static int read_hpmcounterh(CPURISCVState *env, int 
> > csrno, target_ulong *val)
> >
> >   #else /* CONFIG_USER_ONLY */
> >
> > +static int read_mcyclecfg(CPURISCVState *env, int csrno, target_ulong *val)
> > +{
> > +*val = env->mcyclecfg;
> > +return RISCV_EXCP_NONE;
> > +}
> > +
> > +static int write_mcyclecfg(CPURISCVState *env, int csrno, target_ulong val)
> > +{
> > +env->mcyclecfg = val;
> > +return RISCV_EXCP_NONE;
> > +}
> > +
> > +static int read_mcyclecfgh(CPURISCVState *env, int csrno, target_ulong 
> > *val)
> > +{
> > +*val = env->mcyclecfgh;
> > +return RISCV_EXCP_NONE;
> > +}
> > +
> > +static int write_mcyclecfgh(CPURISCVState *env, int csrno, target_ulong 
> > val)
> > +{
> > +env->mcyclecfgh = val;
> > +return RISCV_EXCP_NONE;
> > +}
> > +
> > +static int read_minstretcfg(CPURISCVState *env, int csrno, target_ulong 
> > *val)
> > +{
> > +*val = env->minstretcfg;
> > +return RISCV_EXCP_NONE;
> > +}
> > +
> > +static int write_minstretcfg(CPURISCVState *env, int csrno, target_ulong 
> > val)
> > +{
> > +env->minstretcfg = val;
> > +return RISCV_EXCP_NONE;
> > +}
> > +
> > +static int read_minstretcfgh(CPURISCVState *env, int csrno, target_ulong 
> > *val)
> > +{
> > +*val = env->minstretcfgh;
> > +return RISCV_EXCP_NONE;
> > +}
> > +
> > +static int write_minstretcfgh(CPURISCVState *env, int csrno, target_ulong 
> > val)
> > +{
> > +env->minstretcfgh = val;
> > +return RISCV_EXCP_NONE;
> > +}
> > +
> >   static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong 
> > *val)
> >   {
> >   int evt_index = csrno - CSR_MCOUNTINHIBIT;
> > @@ -4922,6 +4991,13 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
> >write_mcountinhibit,
> >.min_priv_ver = PRIV_VERSION_1_11_0   },
> >
> > +[CSR_MCYCLECFG]  = { "mcyclecfg",   smcntrpmf, read_mcyclecfg,
> > + write_mcyclecfg,
> > + .min_priv_ver = PRIV_VERSION_1_12_0   },
> > +[CSR_MINSTRETCFG]= { "minstretcfg", smcntrpmf, read_minstretcfg,
> > + write_minstretcfg,
> > + .min_priv_ver = PRIV_VERSION_1_12_0   },
> > +
> >   [CSR_MHPMEVENT3] = { "mhpmevent3", any,

Re: [v2 2/5] target/riscv: Add cycle & instret privilege mode filtering properties

2024-01-03 Thread Atish Kumar Patra
On Wed, Jan 3, 2024 at 12:11 PM Daniel Henrique Barboza
 wrote:
>
>
>
> On 12/28/23 21:49, Atish Patra wrote:
> > From: Kaiwen Xue 
> >
> > This adds the properties for ISA extension smcntrpmf. Patches
> > implementing it will follow.
> >
> > Signed-off-by: Atish Patra 
> > Signed-off-by: Kaiwen Xue 
> > ---
> >   target/riscv/cpu.c | 3 ++-
> >   target/riscv/cpu_cfg.h | 1 +
> >   2 files changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 83c7c0cf07be..da3f05cd5373 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -148,6 +148,7 @@ const RISCVIsaExtData isa_edata_arr[] = {
> >   ISA_EXT_DATA_ENTRY(smstateen, PRIV_VERSION_1_12_0, ext_smstateen),
> >   ISA_EXT_DATA_ENTRY(ssaia, PRIV_VERSION_1_12_0, ext_ssaia),
> >   ISA_EXT_DATA_ENTRY(sscofpmf, PRIV_VERSION_1_12_0, ext_sscofpmf),
> > +ISA_EXT_DATA_ENTRY(smcntrpmf, PRIV_VERSION_1_12_0, ext_smcntrpmf),
> >   ISA_EXT_DATA_ENTRY(sstc, PRIV_VERSION_1_12_0, ext_sstc),
> >   ISA_EXT_DATA_ENTRY(svadu, PRIV_VERSION_1_12_0, ext_svadu),
> >   ISA_EXT_DATA_ENTRY(svinval, PRIV_VERSION_1_12_0, ext_svinval),
> > @@ -1296,6 +1297,7 @@ const char *riscv_get_misa_ext_description(uint32_t 
> > bit)
> >   const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = {
> >   /* Defaults for standard extensions */
> >   MULTI_EXT_CFG_BOOL("sscofpmf", ext_sscofpmf, false),
> > +DEFINE_PROP_BOOL("smcntrpmf", RISCVCPU, cfg.ext_smcntrpmf, false),
>
> This will end up breaking the build since this macro is adding a Property 
> object
> inside a RISCVCPUMultiExtConfig array. Patch 3 is then fixing it by removing 
> this
> line, so in the end the build works fine. But having a patch that doesn't 
> build
> can make future bisects unpleasant.
>

This was a rebase error. I will fix it in the next version.

> I don't see a problem adding right now the actual flag:
>
> +MULTI_EXT_CFG_BOOL("smcntrpmf", ext_smcntrpmf, false),
>
> The flag will do nothing, sure, but the commit msg already mentions "Patches
> implementing it will follow", so it's fine to me.
>
>
>
> Thanks,
>
> Daniel
>
>
> >   MULTI_EXT_CFG_BOOL("zifencei", ext_zifencei, true),
> >   MULTI_EXT_CFG_BOOL("zicsr", ext_zicsr, true),
> >   MULTI_EXT_CFG_BOOL("zihintntl", ext_zihintntl, true),
> > @@ -1308,7 +1310,6 @@ const RISCVCPUMultiExtConfig riscv_cpu_extensions[] = 
> > {
> >   MULTI_EXT_CFG_BOOL("zve64f", ext_zve64f, false),
> >   MULTI_EXT_CFG_BOOL("zve64d", ext_zve64d, false),
> >   MULTI_EXT_CFG_BOOL("sstc", ext_sstc, true),
> > -
> >   MULTI_EXT_CFG_BOOL("smepmp", ext_smepmp, false),
> >   MULTI_EXT_CFG_BOOL("smstateen", ext_smstateen, false),
> >   MULTI_EXT_CFG_BOOL("svadu", ext_svadu, true),
> > diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> > index f4605fb190b9..00c34fdd3209 100644
> > --- a/target/riscv/cpu_cfg.h
> > +++ b/target/riscv/cpu_cfg.h
> > @@ -72,6 +72,7 @@ struct RISCVCPUConfig {
> >   bool ext_zihpm;
> >   bool ext_smstateen;
> >   bool ext_sstc;
> > +bool ext_smcntrpmf;
> >   bool ext_svadu;
> >   bool ext_svinval;
> >   bool ext_svnapot;



Re: [PATCH v4 6/6] target/riscv: Use MAKE_64BIT_MASK instead of custom macro

2023-10-23 Thread Atish Kumar Patra
On Wed, Oct 18, 2023 at 8:44 AM Rob Bradford  wrote:
>
> A 32-bit mask can be trivially created using the 64-bit macro so make
> use of that instead.
>
> Signed-off-by: Rob Bradford 
> Reviewed-by: Alistair Francis 
> ---
>  target/riscv/pmu.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
> index 5e89354bb9..81b25ec11a 100644
> --- a/target/riscv/pmu.c
> +++ b/target/riscv/pmu.c
> @@ -25,8 +25,6 @@
>  #include "sysemu/device_tree.h"
>
>  #define RISCV_TIMEBASE_FREQ 10 /* 1Ghz */
> -#define MAKE_32BIT_MASK(shift, length) \
> -(((uint32_t)(~0UL) >> (32 - (length))) << (shift))
>
>  /*
>   * To keep it simple, any event can be mapped to any programmable counters in
> @@ -455,7 +453,7 @@ void riscv_pmu_init(RISCVCPU *cpu, Error **errp)
>  if (pmu_num == 0) {
>  cpu->cfg.pmu_mask = 0;
>  } else if (pmu_num != 16) {
> -cpu->cfg.pmu_mask = MAKE_32BIT_MASK(3, pmu_num);
> +cpu->cfg.pmu_mask = MAKE_64BIT_MASK(3, pmu_num);
>  }
>
>  cpu->pmu_avail_ctrs = cpu->cfg.pmu_mask;
> --
> 2.41.0
>


Reviewed-by: Atish Patra 



Re: [PATCH v4 5/6] docs/about/deprecated: Document RISC-V "pmu-num" deprecation

2023-10-23 Thread Atish Kumar Patra
On Sun, Oct 22, 2023 at 7:04 PM Alistair Francis  wrote:
>
> On Thu, Oct 19, 2023 at 1:47 AM Rob Bradford  wrote:
> >
> > This has been replaced by a "pmu-mask" property that provides much more
> > flexibility.
> >
> > Signed-off-by: Rob Bradford 
> > Acked-by: LIU Zhiwei 
>
> Reviewed-by: Alistair Francis 
>
> Alistair
>
> > ---
> >  docs/about/deprecated.rst | 12 
> >  1 file changed, 12 insertions(+)
> >
> > diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
> > index 2febd2d12f..857b5d4fc4 100644
> > --- a/docs/about/deprecated.rst
> > +++ b/docs/about/deprecated.rst
> > @@ -405,6 +405,18 @@ Specifying the iSCSI password in plain text on the 
> > command line using the
> >  used instead, to refer to a ``--object secret...`` instance that provides
> >  a password via a file, or encrypted.
> >
> > +CPU device properties
> > +'
> > +
> > +``pmu-num=n`` on RISC-V CPUs (since 8.2)
> > +
> > +
> > +In order to support more flexible counter configurations this has been 
> > replaced
> > +by a ``pmu-mask`` property. If set of counters is continuous then the mask 
> > can
> > +be calculated with ``((2 ^ n) - 1) << 3``. The least significant three bits
> > +must be left clear.
> > +
> > +
> >  Backwards compatibility
> >  ---
> >
> > --
> > 2.41.0
> >
> >


Reviewed-by: Atish Patra 



Re: [PATCH v4 3/6] target/riscv: Use existing PMU counter mask in FDT generation

2023-10-23 Thread Atish Kumar Patra
On Wed, Oct 18, 2023 at 8:44 AM Rob Bradford  wrote:
>
> During the FDT generation use the existing mask containing the enabled
> counters rather then generating a new one. Using the existing mask will
> support the use of discontinuous counters.
>
> Signed-off-by: Rob Bradford 
> Reviewed-by: LIU Zhiwei 
> Reviewed-by: Alistair Francis 
> ---
>  hw/riscv/virt.c| 2 +-
>  target/riscv/pmu.c | 6 +-
>  target/riscv/pmu.h | 2 +-
>  3 files changed, 3 insertions(+), 7 deletions(-)
>
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 9de578c756..241681f98d 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -722,7 +722,7 @@ static void create_fdt_pmu(RISCVVirtState *s)
>  pmu_name = g_strdup_printf("/pmu");
>  qemu_fdt_add_subnode(ms->fdt, pmu_name);
>  qemu_fdt_setprop_string(ms->fdt, pmu_name, "compatible", "riscv,pmu");
> -riscv_pmu_generate_fdt_node(ms->fdt, hart.cfg.pmu_num, pmu_name);
> +riscv_pmu_generate_fdt_node(ms->fdt, hart.pmu_avail_ctrs, pmu_name);
>
>  g_free(pmu_name);
>  }
> diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
> index 13801ccb78..7ddf4977b1 100644
> --- a/target/riscv/pmu.c
> +++ b/target/riscv/pmu.c
> @@ -34,13 +34,9 @@
>   * to provide the correct value as well. Heterogeneous PMU per hart is not
>   * supported yet. Thus, number of counters are same across all harts.
>   */
> -void riscv_pmu_generate_fdt_node(void *fdt, int num_ctrs, char *pmu_name)
> +void riscv_pmu_generate_fdt_node(void *fdt, uint32_t cmask, char *pmu_name)
>  {
>  uint32_t fdt_event_ctr_map[15] = {};
> -uint32_t cmask;
> -
> -/* All the programmable counters can map to any event */
> -cmask = MAKE_32BIT_MASK(3, num_ctrs);
>
> /*
>  * The event encoding is specified in the SBI specification
> diff --git a/target/riscv/pmu.h b/target/riscv/pmu.h
> index 88e0713296..505fc850d3 100644
> --- a/target/riscv/pmu.h
> +++ b/target/riscv/pmu.h
> @@ -28,6 +28,6 @@ void riscv_pmu_init(RISCVCPU *cpu, Error **errp);
>  int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
> uint32_t ctr_idx);
>  int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx);
> -void riscv_pmu_generate_fdt_node(void *fdt, int num_counters, char 
> *pmu_name);
> +void riscv_pmu_generate_fdt_node(void *fdt, uint32_t cmask, char *pmu_name);
>  int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t value,
>uint32_t ctr_idx);
> --
> 2.41.0
>

Reviewed-by: Atish Patra 



Re: [PATCH v4 2/6] target/riscv: Don't assume PMU counters are continuous

2023-10-23 Thread Atish Kumar Patra
On Wed, Oct 18, 2023 at 8:44 AM Rob Bradford  wrote:
>
> Check the PMU available bitmask when checking if a counter is valid
> rather than comparing the index against the number of PMUs.
>
> Signed-off-by: Rob Bradford 
> Reviewed-by: LIU Zhiwei 
> Reviewed-by: Alistair Francis 
> ---
>  target/riscv/csr.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 4b4ab56c40..a6ea38e0ba 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -183,7 +183,8 @@ static RISCVException zcmt(CPURISCVState *env, int csrno)
>  #if !defined(CONFIG_USER_ONLY)
>  static RISCVException mctr(CPURISCVState *env, int csrno)
>  {
> -int pmu_num = riscv_cpu_cfg(env)->pmu_num;
> +RISCVCPU *cpu = env_archcpu(env);
> +uint32_t pmu_avail_ctrs = cpu->pmu_avail_ctrs;
>  int ctr_index;
>  int base_csrno = CSR_MHPMCOUNTER3;
>
> @@ -192,7 +193,7 @@ static RISCVException mctr(CPURISCVState *env, int csrno)
>  base_csrno += 0x80;
>  }
>  ctr_index = csrno - base_csrno;
> -if (!pmu_num || ctr_index >= pmu_num) {
> +if ((BIT(ctr_index) & pmu_avail_ctrs >> 3) == 0) {
>  /* The PMU is not enabled or counter is out of range */
>  return RISCV_EXCP_ILLEGAL_INST;
>  }
> --
> 2.41.0
>


Reviewed-by: Atish Patra 



Re: [PATCH v4 1/6] target/riscv: Propagate error from PMU setup

2023-10-23 Thread Atish Kumar Patra
On Wed, Oct 18, 2023 at 8:44 AM Rob Bradford  wrote:
>
> More closely follow the QEMU style by returning an Error and propagating
> it there is an error relating to the PMU setup.
>
> Further simplify the function by removing the num_counters parameter as
> this is available from the passed in cpu pointer.
>
> Signed-off-by: Rob Bradford 
> Reviewed-by: Alistair Francis 
> Reviewed-by: LIU Zhiwei 
> ---
>  target/riscv/pmu.c | 19 +--
>  target/riscv/pmu.h |  3 ++-
>  target/riscv/tcg/tcg-cpu.c |  8 +++-
>  3 files changed, 18 insertions(+), 12 deletions(-)
>
> diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
> index 36f6307d28..13801ccb78 100644
> --- a/target/riscv/pmu.c
> +++ b/target/riscv/pmu.c
> @@ -434,22 +434,21 @@ int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t 
> value, uint32_t ctr_idx)
>  }
>
>
> -int riscv_pmu_init(RISCVCPU *cpu, int num_counters)
> +void riscv_pmu_init(RISCVCPU *cpu, Error **errp)
>  {
> -if (num_counters > (RV_MAX_MHPMCOUNTERS - 3)) {
> -return -1;
> +uint8_t pmu_num = cpu->cfg.pmu_num;
> +
> +if (pmu_num > (RV_MAX_MHPMCOUNTERS - 3)) {
> +error_setg(errp, "Number of counters exceeds maximum available");
> +return;
>  }
>
>  cpu->pmu_event_ctr_map = g_hash_table_new(g_direct_hash, g_direct_equal);
>  if (!cpu->pmu_event_ctr_map) {
> -/* PMU support can not be enabled */
> -qemu_log_mask(LOG_UNIMP, "PMU events can't be supported\n");
> -cpu->cfg.pmu_num = 0;
> -return -1;
> +error_setg(errp, "Unable to allocate PMU event hash table");
> +return;
>  }
>
>  /* Create a bitmask of available programmable counters */
> -cpu->pmu_avail_ctrs = MAKE_32BIT_MASK(3, num_counters);
> -
> -return 0;
> +cpu->pmu_avail_ctrs = MAKE_32BIT_MASK(3, pmu_num);
>  }
> diff --git a/target/riscv/pmu.h b/target/riscv/pmu.h
> index 2bfb71ba87..88e0713296 100644
> --- a/target/riscv/pmu.h
> +++ b/target/riscv/pmu.h
> @@ -17,13 +17,14 @@
>   */
>
>  #include "cpu.h"
> +#include "qapi/error.h"
>
>  bool riscv_pmu_ctr_monitor_instructions(CPURISCVState *env,
>  uint32_t target_ctr);
>  bool riscv_pmu_ctr_monitor_cycles(CPURISCVState *env,
>uint32_t target_ctr);
>  void riscv_pmu_timer_cb(void *priv);
> -int riscv_pmu_init(RISCVCPU *cpu, int num_counters);
> +void riscv_pmu_init(RISCVCPU *cpu, Error **errp);
>  int riscv_pmu_update_event_map(CPURISCVState *env, uint64_t value,
> uint32_t ctr_idx);
>  int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum riscv_pmu_event_idx event_idx);
> diff --git a/target/riscv/tcg/tcg-cpu.c b/target/riscv/tcg/tcg-cpu.c
> index a28918ab30..ed3eb991c0 100644
> --- a/target/riscv/tcg/tcg-cpu.c
> +++ b/target/riscv/tcg/tcg-cpu.c
> @@ -614,7 +614,13 @@ static bool tcg_cpu_realize(CPUState *cs, Error **errp)
>  }
>
>  if (cpu->cfg.pmu_num) {
> -if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) 
> {
> +riscv_pmu_init(cpu, _err);
> +if (local_err != NULL) {
> +error_propagate(errp, local_err);
> +return false;
> +}
> +
> +if (cpu->cfg.ext_sscofpmf) {
>  cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
>riscv_pmu_timer_cb, cpu);
>  }
> --
> 2.41.0
>


Reviewed-by: Atish Patra 



Re: [PATCH 2/3] target/riscv: Support discontinuous PMU counters

2023-10-09 Thread Atish Kumar Patra
On Sun, Oct 8, 2023 at 5:58 PM Alistair Francis  wrote:
>
> On Wed, Oct 4, 2023 at 7:36 PM Rob Bradford  wrote:
> >
> > Hi Atish,
> >
> > On Tue, 2023-10-03 at 13:25 -0700, Atish Kumar Patra wrote:
> > > On Tue, Oct 3, 2023 at 5:51 AM Rob Bradford 
> > > wrote:
> > > >
> > > > There is no requirement that the enabled counters in the platform
> > > > are
> > > > continuously numbered. Add a "pmu-mask" property that, if
> > > > specified, can
> > > > be used to specify the enabled PMUs. In order to avoid ambiguity if
> > > > "pmu-mask" is specified then "pmu-num" must also match the number
> > > > of
> > > > bits set in the mask.
> > > >
> > > > Signed-off-by: Rob Bradford 
> > > > ---
> > > >  target/riscv/cpu.c |  1 +
> > > >  target/riscv/cpu_cfg.h |  1 +
> > > >  target/riscv/pmu.c | 15 +--
> > > >  3 files changed, 15 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > > > index 9d79c20c1a..b89b006a76 100644
> > > > --- a/target/riscv/cpu.c
> > > > +++ b/target/riscv/cpu.c
> > > > @@ -1817,6 +1817,7 @@ static void
> > > > riscv_cpu_add_misa_properties(Object *cpu_obj)
> > > >  static Property riscv_cpu_extensions[] = {
> > > >  /* Defaults for standard extensions */
> > > >  DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
> > > > +DEFINE_PROP_UINT32("pmu-mask", RISCVCPU, cfg.pmu_mask, 0),
> > > >  DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf,
> > > > false),
> > > >  DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
> > > >  DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
> > > > diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> > > > index 0e6a0f245c..40f7d970bc 100644
> > > > --- a/target/riscv/cpu_cfg.h
> > > > +++ b/target/riscv/cpu_cfg.h
> > > > @@ -124,6 +124,7 @@ struct RISCVCPUConfig {
> > > >  bool ext_XVentanaCondOps;
> > > >
> > > >  uint8_t pmu_num;
> > > > +uint32_t pmu_mask;
> > > >  char *priv_spec;
> > > >  char *user_spec;
> > > >  char *bext_spec;
> > > > diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
> > > > index 13801ccb78..f97e25a1f6 100644
> > > > --- a/target/riscv/pmu.c
> > > > +++ b/target/riscv/pmu.c
> > > > @@ -437,6 +437,13 @@ int riscv_pmu_setup_timer(CPURISCVState *env,
> > > > uint64_t value, uint32_t ctr_idx)
> > > >  void riscv_pmu_init(RISCVCPU *cpu, Error **errp)
> > > >  {
> > > >  uint8_t pmu_num = cpu->cfg.pmu_num;
> > > > +uint32_t pmu_mask = cpu->cfg.pmu_mask;
> > > > +
> > > > +if (pmu_mask && ctpop32(pmu_mask) != pmu_num) {
> > > > +error_setg(errp, "Mismatch between number of enabled
> > > > counters in "
> > > > + "\"pmu-mask\" and \"pmu-num\"");
> > > > +return;
> > > > +}
> > > >
> > >
> > > Is that necessary for the default case? I am thinking of marking
> > > pmu-num as deprecated and pmu-mask
> > > as the preferred way of doing things as it is more flexible. There is
> > > no real benefit carrying both.
> > > The default pmu-mask value will change in that case.
> > > We can just overwrite pmu-num with ctpop32(pmu_mask) if pmu-mask is
> > > available. Thoughts ?
> > >
> >
> > I agree it makes sense to me that there is only one way for the user to
> > adjust the PMU count. However i'm not sure how we can handle the
> > transition if we choose to deprecate "pmu-num".
> >
> > If we change the default "pmu-mask" to MAKE_32BIT_MASK(3, 16) then that
> > value in the config will always be set - you propose that we overwrite
> > "pmu-num" with the popcount of that property. But that will break if
>
> Couldn't we deprecate "pmu-num" and then throw an error if both are
> set? Then we can migrate away from "pmu-num"
>

Yeah. pmu-num should be only available as a command line property and
marked deprecated.
If only pmu-num is set, it gets conv

Re: [PATCH 2/3] target/riscv: Support discontinuous PMU counters

2023-10-03 Thread Atish Kumar Patra
On Tue, Oct 3, 2023 at 5:51 AM Rob Bradford  wrote:
>
> There is no requirement that the enabled counters in the platform are
> continuously numbered. Add a "pmu-mask" property that, if specified, can
> be used to specify the enabled PMUs. In order to avoid ambiguity if
> "pmu-mask" is specified then "pmu-num" must also match the number of
> bits set in the mask.
>
> Signed-off-by: Rob Bradford 
> ---
>  target/riscv/cpu.c |  1 +
>  target/riscv/cpu_cfg.h |  1 +
>  target/riscv/pmu.c | 15 +--
>  3 files changed, 15 insertions(+), 2 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 9d79c20c1a..b89b006a76 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -1817,6 +1817,7 @@ static void riscv_cpu_add_misa_properties(Object 
> *cpu_obj)
>  static Property riscv_cpu_extensions[] = {
>  /* Defaults for standard extensions */
>  DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
> +DEFINE_PROP_UINT32("pmu-mask", RISCVCPU, cfg.pmu_mask, 0),
>  DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
>  DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
>  DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
> diff --git a/target/riscv/cpu_cfg.h b/target/riscv/cpu_cfg.h
> index 0e6a0f245c..40f7d970bc 100644
> --- a/target/riscv/cpu_cfg.h
> +++ b/target/riscv/cpu_cfg.h
> @@ -124,6 +124,7 @@ struct RISCVCPUConfig {
>  bool ext_XVentanaCondOps;
>
>  uint8_t pmu_num;
> +uint32_t pmu_mask;
>  char *priv_spec;
>  char *user_spec;
>  char *bext_spec;
> diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
> index 13801ccb78..f97e25a1f6 100644
> --- a/target/riscv/pmu.c
> +++ b/target/riscv/pmu.c
> @@ -437,6 +437,13 @@ int riscv_pmu_setup_timer(CPURISCVState *env, uint64_t 
> value, uint32_t ctr_idx)
>  void riscv_pmu_init(RISCVCPU *cpu, Error **errp)
>  {
>  uint8_t pmu_num = cpu->cfg.pmu_num;
> +uint32_t pmu_mask = cpu->cfg.pmu_mask;
> +
> +if (pmu_mask && ctpop32(pmu_mask) != pmu_num) {
> +error_setg(errp, "Mismatch between number of enabled counters in "
> + "\"pmu-mask\" and \"pmu-num\"");
> +return;
> +}
>

Is that necessary for the default case? I am thinking of marking
pmu-num as deprecated and pmu-mask
as the preferred way of doing things as it is more flexible. There is
no real benefit carrying both.
The default pmu-mask value will change in that case.
We can just overwrite pmu-num with ctpop32(pmu_mask) if pmu-mask is
available. Thoughts ?

>  if (pmu_num > (RV_MAX_MHPMCOUNTERS - 3)) {
>  error_setg(errp, "Number of counters exceeds maximum available");
> @@ -449,6 +456,10 @@ void riscv_pmu_init(RISCVCPU *cpu, Error **errp)
>  return;
>  }
>
> -/* Create a bitmask of available programmable counters */
> -cpu->pmu_avail_ctrs = MAKE_32BIT_MASK(3, pmu_num);
> +/* Create a bitmask of available programmable counters if none supplied 
> */
> +if (pmu_mask) {
> +cpu->pmu_avail_ctrs = pmu_mask;
> +} else {
> +cpu->pmu_avail_ctrs = MAKE_32BIT_MASK(3, pmu_num);
> +}
>  }
> --
> 2.41.0
>



Re: [PATCH v14 4/5] hw/riscv: virt: Add PMU DT node to the device tree

2022-11-30 Thread Atish Kumar Patra
On Tue, Nov 29, 2022 at 3:54 PM  wrote:
>
> +CC Rob, which I probably should've done earlier, so
> context all preserved
>
> On 29/11/2022 09:42, Conor Dooley wrote:
> > On 29/11/2022 09:27, Atish Kumar Patra wrote:
> >> EXTERNAL EMAIL: Do not click links or open attachments unless you know the 
> >> content is safe
> >>
> >> On Mon, Nov 28, 2022 at 11:32 PM  wrote:
> >>>
> >>> On 29/11/2022 07:08, Andrew Jones wrote:
> >>>> EXTERNAL EMAIL: Do not click links or open attachments unless you know 
> >>>> the content is safe
> >>>>
> >>>> On Mon, Nov 28, 2022 at 09:10:03PM +, conor.doo...@microchip.com 
> >>>> wrote:
> >>>>> On 28/11/2022 20:41, Atish Kumar Patra wrote:
> >>>>>> EXTERNAL EMAIL: Do not click links or open attachments unless you know 
> >>>>>> the content is safe
> >>>>>>
> >>>>>> On Mon, Nov 28, 2022 at 12:38 PM  wrote:
> >>>>>>>
> >>>>>>> On 28/11/2022 20:16, Atish Kumar Patra wrote:
> >>>>>>>> On Thu, Nov 24, 2022 at 5:17 AM Conor Dooley 
> >>>>>>>>  wrote:
> >>>>>>>>>
> >>>>>>>>> On Wed, Aug 24, 2022 at 03:17:00PM -0700, Atish Patra wrote:
> >>>>>>>>>> Qemu virt machine can support few cache events and cycle/instret 
> >>>>>>>>>> counters.
> >>>>>>>>>> It also supports counter overflow for these events.
> >>>>>>>>>>
> >>>>>>>>>> Add a DT node so that OpenSBI/Linux kernel is aware of the virt 
> >>>>>>>>>> machine
> >>>>>>>>>> capabilities. There are some dummy nodes added for testing as well.
> >>>>>>>>>
> >>>>>>>>> Hey Atish!
> >>>>>>>>>
> >>>>>>>>> I was fiddling with dumping the virt machine dtb again today to 
> >>>>>>>>> check
> >>>>>>>>> some dt-binding changes I was making for the isa string would play
> >>>>>>>>> nicely with the virt machine & I noticed that this patch has 
> >>>>>>>>> introduced
> >>>>>>>>> a new validation failure:
> >>>>>>>>>
> >>>>>>>>> ./build/qemu-system-riscv64 -nographic -machine 
> >>>>>>>>> virt,dumpdtb=qemu.dtb
> >>>>>>>>>
> >>>>>>>>> dt-validate -p 
> >>>>>>>>> ../linux/Documentation/devicetree/bindings/processed-schema.json 
> >>>>>>>>> qemu.dtb
> >>>>>>>>> /home/conor/stuff/qemu/qemu.dtb: soc: pmu: 
> >>>>>>>>> {'riscv,event-to-mhpmcounters': [[1, 1, 524281, 2, 2, 524284, 
> >>>>>>>>> 65561, 65561, 524280, 65563, 65563, 524280, 65569, 65569, 524280, 
> >>>>>>>>> 0, 0, 0, 0, 0]], 'compatible': ['riscv,pmu']} should not be valid 
> >>>>>>>>> under {'type': 'object'}
> >>>>>>>>>   From schema: 
> >>>>>>>>> /home/conor/.local/lib/python3.10/site-packages/dtschema/schemas/simple-bus.yaml
> >>>>>>>>>
> >>>>>>>>> I assume this is the aforementioned "dummy" node & you have no 
> >>>>>>>>> intention
> >>>>>>>>> of creating a binding for this?
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>> It is a dummy node from Linux kernel perspective. OpenSbi use this
> >>>>>>>> node to figure out the hpmcounter mappings.
> >>>>>>>
> >>>>>>> Aye, but should it not have a binding anyway, since they're not
> >>>>>>> meant to be linux specific?
> >>>>>>>
> >>>>>> It is documented in OpenSBI.
> >>>>>> https://github.com/riscv-software-src/opensbi/blob/master/docs/pmu_support.md
> >>>>>>
> >>>>>> Are you suggesting that any non-Linux specific DT nodes should be part
> >>>>>> of Linux DT binding as well ?
> >>

Re: [PATCH v14 4/5] hw/riscv: virt: Add PMU DT node to the device tree

2022-11-29 Thread Atish Kumar Patra
On Mon, Nov 28, 2022 at 11:32 PM  wrote:
>
> On 29/11/2022 07:08, Andrew Jones wrote:
> > EXTERNAL EMAIL: Do not click links or open attachments unless you know the 
> > content is safe
> >
> > On Mon, Nov 28, 2022 at 09:10:03PM +, conor.doo...@microchip.com wrote:
> >> On 28/11/2022 20:41, Atish Kumar Patra wrote:
> >>> EXTERNAL EMAIL: Do not click links or open attachments unless you know 
> >>> the content is safe
> >>>
> >>> On Mon, Nov 28, 2022 at 12:38 PM  wrote:
> >>>>
> >>>> On 28/11/2022 20:16, Atish Kumar Patra wrote:
> >>>>> On Thu, Nov 24, 2022 at 5:17 AM Conor Dooley 
> >>>>>  wrote:
> >>>>>>
> >>>>>> On Wed, Aug 24, 2022 at 03:17:00PM -0700, Atish Patra wrote:
> >>>>>>> Qemu virt machine can support few cache events and cycle/instret 
> >>>>>>> counters.
> >>>>>>> It also supports counter overflow for these events.
> >>>>>>>
> >>>>>>> Add a DT node so that OpenSBI/Linux kernel is aware of the virt 
> >>>>>>> machine
> >>>>>>> capabilities. There are some dummy nodes added for testing as well.
> >>>>>>
> >>>>>> Hey Atish!
> >>>>>>
> >>>>>> I was fiddling with dumping the virt machine dtb again today to check
> >>>>>> some dt-binding changes I was making for the isa string would play
> >>>>>> nicely with the virt machine & I noticed that this patch has introduced
> >>>>>> a new validation failure:
> >>>>>>
> >>>>>> ./build/qemu-system-riscv64 -nographic -machine virt,dumpdtb=qemu.dtb
> >>>>>>
> >>>>>> dt-validate -p 
> >>>>>> ../linux/Documentation/devicetree/bindings/processed-schema.json 
> >>>>>> qemu.dtb
> >>>>>> /home/conor/stuff/qemu/qemu.dtb: soc: pmu: 
> >>>>>> {'riscv,event-to-mhpmcounters': [[1, 1, 524281, 2, 2, 524284, 65561, 
> >>>>>> 65561, 524280, 65563, 65563, 524280, 65569, 65569, 524280, 0, 0, 0, 0, 
> >>>>>> 0]], 'compatible': ['riscv,pmu']} should not be valid under {'type': 
> >>>>>> 'object'}
> >>>>>>  From schema: 
> >>>>>> /home/conor/.local/lib/python3.10/site-packages/dtschema/schemas/simple-bus.yaml
> >>>>>>
> >>>>>> I assume this is the aforementioned "dummy" node & you have no 
> >>>>>> intention
> >>>>>> of creating a binding for this?
> >>>>>>
> >>>>>
> >>>>> It is a dummy node from Linux kernel perspective. OpenSbi use this
> >>>>> node to figure out the hpmcounter mappings.
> >>>>
> >>>> Aye, but should it not have a binding anyway, since they're not
> >>>> meant to be linux specific?
> >>>>
> >>> It is documented in OpenSBI.
> >>> https://github.com/riscv-software-src/opensbi/blob/master/docs/pmu_support.md
> >>>
> >>> Are you suggesting that any non-Linux specific DT nodes should be part
> >>> of Linux DT binding as well ?
> >>
> >> I thought the point was that they were *not* meant to be linux specific,
> >> just happening to be housed there.
> >>
> >
> > I'm not sure if there's an official policy on where DT nodes should be
> > specified, but it looks like Samuel's opinion is that they should live
> > in the Linux kernel, whether they're used there or not [1].
> >
> > [1] http://lists.infradead.org/pipermail/opensbi/2022-October/003522.html
>
> Yah, that was also my understanding. See also U-Boot moving to unify
> their custom bindings into the linux repo:
> https://lore.kernel.org/linux-devicetree/20220930001410.2802843-1-...@chromium.org/
>

This adds the U-Boot specific DT properties to the dts schema itself,
not Linux kernel DT bindings.

I am not opposed to adding PMU DT bindings to Linux but there should
be a clear policy on this.
What about OpenSBI domain DT bindings ?
If every other DT based open source project starts adding their DT
binding to the Linux kernel, that may go downhill pretty soon.

>
>
>



Re: [PATCH v14 4/5] hw/riscv: virt: Add PMU DT node to the device tree

2022-11-28 Thread Atish Kumar Patra
On Mon, Nov 28, 2022 at 12:38 PM  wrote:
>
> On 28/11/2022 20:16, Atish Kumar Patra wrote:
> > On Thu, Nov 24, 2022 at 5:17 AM Conor Dooley  
> > wrote:
> >>
> >> On Wed, Aug 24, 2022 at 03:17:00PM -0700, Atish Patra wrote:
> >>> Qemu virt machine can support few cache events and cycle/instret counters.
> >>> It also supports counter overflow for these events.
> >>>
> >>> Add a DT node so that OpenSBI/Linux kernel is aware of the virt machine
> >>> capabilities. There are some dummy nodes added for testing as well.
> >>
> >> Hey Atish!
> >>
> >> I was fiddling with dumping the virt machine dtb again today to check
> >> some dt-binding changes I was making for the isa string would play
> >> nicely with the virt machine & I noticed that this patch has introduced
> >> a new validation failure:
> >>
> >> ./build/qemu-system-riscv64 -nographic -machine virt,dumpdtb=qemu.dtb
> >>
> >> dt-validate -p 
> >> ../linux/Documentation/devicetree/bindings/processed-schema.json qemu.dtb
> >> /home/conor/stuff/qemu/qemu.dtb: soc: pmu: {'riscv,event-to-mhpmcounters': 
> >> [[1, 1, 524281, 2, 2, 524284, 65561, 65561, 524280, 65563, 65563, 524280, 
> >> 65569, 65569, 524280, 0, 0, 0, 0, 0]], 'compatible': ['riscv,pmu']} should 
> >> not be valid under {'type': 'object'}
> >> From schema: 
> >> /home/conor/.local/lib/python3.10/site-packages/dtschema/schemas/simple-bus.yaml
> >>
> >> I assume this is the aforementioned "dummy" node & you have no intention
> >> of creating a binding for this?
> >>
> >
> > It is a dummy node from Linux kernel perspective. OpenSbi use this
> > node to figure out the hpmcounter mappings.
>
> Aye, but should it not have a binding anyway, since they're not
> meant to be linux specific?
>
It is documented in OpenSBI.
https://github.com/riscv-software-src/opensbi/blob/master/docs/pmu_support.md

Are you suggesting that any non-Linux specific DT nodes should be part
of Linux DT binding as well ?

> >>> Acked-by: Alistair Francis 
> >>> Signed-off-by: Atish Patra 
> >>> Signed-off-by: Atish Patra 
> >>> ---
> >>>  hw/riscv/virt.c| 16 +
> >>>  target/riscv/pmu.c | 57 ++
> >>>  target/riscv/pmu.h |  1 +
> >>>  3 files changed, 74 insertions(+)
> >>>
> >>> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> >>> index ff8c0df5cd47..befa9d2c26ac 100644
> >>> --- a/hw/riscv/virt.c
> >>> +++ b/hw/riscv/virt.c
> >>> @@ -30,6 +30,7 @@
> >>>  #include "hw/char/serial.h"
> >>>  #include "target/riscv/cpu.h"
> >>>  #include "hw/core/sysbus-fdt.h"
> >>> +#include "target/riscv/pmu.h"
> >>>  #include "hw/riscv/riscv_hart.h"
> >>>  #include "hw/riscv/virt.h"
> >>>  #include "hw/riscv/boot.h"
> >>> @@ -708,6 +709,20 @@ static void create_fdt_socket_aplic(RISCVVirtState 
> >>> *s,
> >>>  aplic_phandles[socket] = aplic_s_phandle;
> >>>  }
> >>>
> >>> +static void create_fdt_pmu(RISCVVirtState *s)
> >>> +{
> >>> +char *pmu_name;
> >>> +MachineState *mc = MACHINE(s);
> >>> +RISCVCPU hart = s->soc[0].harts[0];
> >>> +
> >>> +pmu_name = g_strdup_printf("/soc/pmu");
> >>> +qemu_fdt_add_subnode(mc->fdt, pmu_name);
> >>> +qemu_fdt_setprop_string(mc->fdt, pmu_name, "compatible", 
> >>> "riscv,pmu");
> >>> +riscv_pmu_generate_fdt_node(mc->fdt, hart.cfg.pmu_num, pmu_name);
> >>> +
> >>> +g_free(pmu_name);
> >>> +}
> >>> +
> >>>  static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry 
> >>> *memmap,
> >>> bool is_32_bit, uint32_t *phandle,
> >>> uint32_t *irq_mmio_phandle,
> >>> @@ -1036,6 +1051,7 @@ static void create_fdt(RISCVVirtState *s, const 
> >>> MemMapEntry *memmap,
> >>>
> >>>  create_fdt_flash(s, memmap);
> >>>  create_fdt_fw_cfg(s, memmap);
> >>> +create_fdt_pmu(s);
> >>>
> >>>  update_bootargs:
> >>>  if (cmdline && *cmdline) {
> >

Re: [PATCH v14 4/5] hw/riscv: virt: Add PMU DT node to the device tree

2022-11-28 Thread Atish Kumar Patra
On Thu, Nov 24, 2022 at 5:17 AM Conor Dooley  wrote:
>
> On Wed, Aug 24, 2022 at 03:17:00PM -0700, Atish Patra wrote:
> > Qemu virt machine can support few cache events and cycle/instret counters.
> > It also supports counter overflow for these events.
> >
> > Add a DT node so that OpenSBI/Linux kernel is aware of the virt machine
> > capabilities. There are some dummy nodes added for testing as well.
>
> Hey Atish!
>
> I was fiddling with dumping the virt machine dtb again today to check
> some dt-binding changes I was making for the isa string would play
> nicely with the virt machine & I noticed that this patch has introduced
> a new validation failure:
>
> ./build/qemu-system-riscv64 -nographic -machine virt,dumpdtb=qemu.dtb
>
> dt-validate -p 
> ../linux/Documentation/devicetree/bindings/processed-schema.json qemu.dtb
> /home/conor/stuff/qemu/qemu.dtb: soc: pmu: {'riscv,event-to-mhpmcounters': 
> [[1, 1, 524281, 2, 2, 524284, 65561, 65561, 524280, 65563, 65563, 524280, 
> 65569, 65569, 524280, 0, 0, 0, 0, 0]], 'compatible': ['riscv,pmu']} should 
> not be valid under {'type': 'object'}
> From schema: 
> /home/conor/.local/lib/python3.10/site-packages/dtschema/schemas/simple-bus.yaml
>
> I assume this is the aforementioned "dummy" node & you have no intention
> of creating a binding for this?
>

It is a dummy node from Linux kernel perspective. OpenSbi use this
node to figure out the hpmcounter mappings.

> Thanks,
> Conor.
>
> > Acked-by: Alistair Francis 
> > Signed-off-by: Atish Patra 
> > Signed-off-by: Atish Patra 
> > ---
> >  hw/riscv/virt.c| 16 +
> >  target/riscv/pmu.c | 57 ++
> >  target/riscv/pmu.h |  1 +
> >  3 files changed, 74 insertions(+)
> >
> > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > index ff8c0df5cd47..befa9d2c26ac 100644
> > --- a/hw/riscv/virt.c
> > +++ b/hw/riscv/virt.c
> > @@ -30,6 +30,7 @@
> >  #include "hw/char/serial.h"
> >  #include "target/riscv/cpu.h"
> >  #include "hw/core/sysbus-fdt.h"
> > +#include "target/riscv/pmu.h"
> >  #include "hw/riscv/riscv_hart.h"
> >  #include "hw/riscv/virt.h"
> >  #include "hw/riscv/boot.h"
> > @@ -708,6 +709,20 @@ static void create_fdt_socket_aplic(RISCVVirtState *s,
> >  aplic_phandles[socket] = aplic_s_phandle;
> >  }
> >
> > +static void create_fdt_pmu(RISCVVirtState *s)
> > +{
> > +char *pmu_name;
> > +MachineState *mc = MACHINE(s);
> > +RISCVCPU hart = s->soc[0].harts[0];
> > +
> > +pmu_name = g_strdup_printf("/soc/pmu");
> > +qemu_fdt_add_subnode(mc->fdt, pmu_name);
> > +qemu_fdt_setprop_string(mc->fdt, pmu_name, "compatible", "riscv,pmu");
> > +riscv_pmu_generate_fdt_node(mc->fdt, hart.cfg.pmu_num, pmu_name);
> > +
> > +g_free(pmu_name);
> > +}
> > +
> >  static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry 
> > *memmap,
> > bool is_32_bit, uint32_t *phandle,
> > uint32_t *irq_mmio_phandle,
> > @@ -1036,6 +1051,7 @@ static void create_fdt(RISCVVirtState *s, const 
> > MemMapEntry *memmap,
> >
> >  create_fdt_flash(s, memmap);
> >  create_fdt_fw_cfg(s, memmap);
> > +create_fdt_pmu(s);
> >
> >  update_bootargs:
> >  if (cmdline && *cmdline) {
> > diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
> > index a5f504e53c88..b8e56d2b7b8e 100644
> > --- a/target/riscv/pmu.c
> > +++ b/target/riscv/pmu.c
> > @@ -20,11 +20,68 @@
> >  #include "cpu.h"
> >  #include "pmu.h"
> >  #include "sysemu/cpu-timers.h"
> > +#include "sysemu/device_tree.h"
> >
> >  #define RISCV_TIMEBASE_FREQ 10 /* 1Ghz */
> >  #define MAKE_32BIT_MASK(shift, length) \
> >  (((uint32_t)(~0UL) >> (32 - (length))) << (shift))
> >
> > +/*
> > + * To keep it simple, any event can be mapped to any programmable counters 
> > in
> > + * QEMU. The generic cycle & instruction count events can also be monitored
> > + * using programmable counters. In that case, mcycle & minstret must 
> > continue
> > + * to provide the correct value as well. Heterogeneous PMU per hart is not
> > + * supported yet. Thus, number of counters are same across all harts.
> > + */
> > +void riscv_pmu_generate_fdt_node(void *fdt, int num_ctrs, char *pmu_name)
> > +{
> > +uint32_t fdt_event_ctr_map[20] = {};
> > +uint32_t cmask;
> > +
> > +/* All the programmable counters can map to any event */
> > +cmask = MAKE_32BIT_MASK(3, num_ctrs);
> > +
> > +   /*
> > +* The event encoding is specified in the SBI specification
> > +* Event idx is a 20bits wide number encoded as follows:
> > +* event_idx[19:16] = type
> > +* event_idx[15:0] = code
> > +* The code field in cache events are encoded as follows:
> > +* event_idx.code[15:3] = cache_id
> > +* event_idx.code[2:1] = op_id
> > +* event_idx.code[0:0] = result_id
> > +*/
> > +
> > +   /* SBI_PMU_HW_CPU_CYCLES: 0x01 : type(0x00) */
> > +   fdt_event_ctr_map[0] = cpu_to_be32(0x0001);
> 

Re: [PATCH v2] hw/riscv: virt: Remove the redundant ipi-id property

2022-11-22 Thread Atish Kumar Patra
On Mon, Nov 21, 2022 at 10:11 PM Alistair Francis  wrote:
>
> On Sun, Nov 13, 2022 at 7:52 PM Atish Patra  wrote:
> >
> > The imsic DT binding[1] has changed and no longer require an ipi-id.
> > The latest IMSIC driver dynamically allocates ipi id if slow-ipi
> > is not defined.
> >
> > Get rid of the unused dt property which may lead to confusion.
> >
> > [1] 
> > https://lore.kernel.org/lkml/2022044207.1478350-5-apa...@ventanamicro.com/
> >
> > Signed-off-by: Atish Patra 
> > ---
> >  hw/riscv/virt.c | 2 --
> >  include/hw/riscv/virt.h | 1 -
> >  2 files changed, 3 deletions(-)
> >
> > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > index a5bc7353b412..0bc0964e42a8 100644
> > --- a/hw/riscv/virt.c
> > +++ b/hw/riscv/virt.c
> > @@ -546,8 +546,6 @@ static void create_fdt_imsic(RISCVVirtState *s, const 
> > MemMapEntry *memmap,
> >  riscv_socket_count(mc) * sizeof(uint32_t) * 4);
> >  qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
> >  VIRT_IRQCHIP_NUM_MSIS);
> > -qemu_fdt_setprop_cells(mc->fdt, imsic_name, "riscv,ipi-id",
> > -VIRT_IRQCHIP_IPI_MSI);
> >  if (riscv_socket_count(mc) > 1) {
> >  qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,hart-index-bits",
> >  imsic_num_bits(imsic_max_hart_per_socket));
> > diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
> > index be4ab8fe7f71..62513e075c47 100644
> > --- a/include/hw/riscv/virt.h
> > +++ b/include/hw/riscv/virt.h
> > @@ -93,7 +93,6 @@ enum {
> >
> >  #define VIRT_PLATFORM_BUS_NUM_IRQS 32
> >
> > -#define VIRT_IRQCHIP_IPI_MSI 1
>
> This is used elsewhere with a different "riscv,ipi-id" and this fails to 
> compile
>

I am not sure what I was thinking when I sent the patch. It is such a
silly patch.
Anyways, I am really sorry for the breakage. I have sent the v3.

> I have dropped this patch
>
> Alistair
>
> >  #define VIRT_IRQCHIP_NUM_MSIS 255
> >  #define VIRT_IRQCHIP_NUM_SOURCES VIRTIO_NDEV
> >  #define VIRT_IRQCHIP_NUM_PRIO_BITS 3
> > --
> > 2.25.1
> >
> >



Re: [PATCH] hw/riscv: virt: Remove the redundant ipi-id property

2022-11-11 Thread Atish Kumar Patra
On Fri, Nov 11, 2022 at 4:39 PM Bin Meng  wrote:

> On Sat, Nov 12, 2022 at 4:14 AM Atish Patra  wrote:
> >
> > The imsic DT binding has changed and no longer require an ipi-id.
>
> requires
>
>
Sure. Will fix it.


> Could you please put a link here to the upstream imsic DT binding for
> reference?
>
>
It's not merged yet. Here is the latest version:

https://lore.kernel.org/lkml/2022044207.1478350-5-apa...@ventanamicro.com/


> > The latest IMSIC driver dynamically allocates ipi id if slow-ipi
> > is not defined.
> >
> > Get rid of the unused dt property which may lead to confusion.
> >
> > Signed-off-by: Atish Patra 
> > ---
> >  hw/riscv/virt.c | 2 --
> >  include/hw/riscv/virt.h | 1 -
> >  2 files changed, 3 deletions(-)
> >
> > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > index a5bc7353b412..0bc0964e42a8 100644
> > --- a/hw/riscv/virt.c
> > +++ b/hw/riscv/virt.c
> > @@ -546,8 +546,6 @@ static void create_fdt_imsic(RISCVVirtState *s,
> const MemMapEntry *memmap,
> >  riscv_socket_count(mc) * sizeof(uint32_t) * 4);
> >  qemu_fdt_setprop_cell(mc->fdt, imsic_name, "riscv,num-ids",
> >  VIRT_IRQCHIP_NUM_MSIS);
> > -qemu_fdt_setprop_cells(mc->fdt, imsic_name, "riscv,ipi-id",
> > -VIRT_IRQCHIP_IPI_MSI);
> >  if (riscv_socket_count(mc) > 1) {
> >  qemu_fdt_setprop_cell(mc->fdt, imsic_name,
> "riscv,hart-index-bits",
> >  imsic_num_bits(imsic_max_hart_per_socket));
> > diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
> > index be4ab8fe7f71..62513e075c47 100644
> > --- a/include/hw/riscv/virt.h
> > +++ b/include/hw/riscv/virt.h
> > @@ -93,7 +93,6 @@ enum {
> >
> >  #define VIRT_PLATFORM_BUS_NUM_IRQS 32
> >
> > -#define VIRT_IRQCHIP_IPI_MSI 1
> >  #define VIRT_IRQCHIP_NUM_MSIS 255
> >  #define VIRT_IRQCHIP_NUM_SOURCES VIRTIO_NDEV
> >  #define VIRT_IRQCHIP_NUM_PRIO_BITS 3
> > --
>
> Regards,
> Bin
>


Re: [PATCH v14 0/5] Improve PMU support

2022-09-20 Thread Atish Kumar Patra
On Mon, Sep 19, 2022 at 3:08 PM Alistair Francis 
wrote:

> On Thu, Aug 25, 2022 at 8:22 AM Atish Patra  wrote:
> >
> > The latest version of the SBI specification includes a Performance
> Monitoring
> > Unit(PMU) extension[1] which allows the supervisor to
> start/stop/configure
> > various PMU events. The Sscofpmf ('Ss' for Privileged arch and
> Supervisor-level
> > extensions, and 'cofpmf' for Count OverFlow and Privilege Mode Filtering)
> > extension[2] allows the perf like tool to handle overflow interrupts and
> > filtering support.
> >
> > This series implements remaining PMU infrastructure to support
> > PMU in virt machine. The first seven patches from the original series
> > have been merged already.
> >
> > This will allow us to add any PMU events in future.
> > Currently, this series enables the following omu events.
> > 1. cycle count
> > 2. instruction count
> > 3. DTLB load/store miss
> > 4. ITLB prefetch miss
> >
> > The first two are computed using host ticks while last three are counted
> during
> > cpu_tlb_fill. We can do both sampling and count from guest userspace.
> > This series has been tested on both RV64 and RV32. Both Linux[3] and
> Opensbi[4]
> > patches are required to get the perf working.
> >
> > Here is an output of perf stat/report while running hackbench with latest
> > OpenSBI & Linux kernel.
> >
> > Perf stat:
> > ==
> > [root@fedora-riscv ~]# perf stat -e cycles -e instructions -e
> dTLB-load-misses -e dTLB-store-misses -e iTLB-load-misses \
> > > perf bench sched messaging -g 1 -l 10
> > # Running 'sched/messaging' benchmark:
> > # 20 sender and receiver processes per group
> > # 1 groups == 40 processes run
> >
> >  Total time: 0.265 [sec]
> >
> >  Performance counter stats for 'perf bench sched messaging -g 1 -l 10':
> >
> >  4,167,825,362  cycles
> >  4,166,609,256  instructions  #1.00  insn per
> cycle
> >  3,092,026  dTLB-load-misses
> >258,280  dTLB-store-misses
> >  2,068,966  iTLB-load-misses
> >
> >0.585791767 seconds time elapsed
> >
> >0.373802000 seconds user
> >1.042359000 seconds sys
> >
> > Perf record:
> > 
> > [root@fedora-riscv ~]# perf record -e cycles -e instructions \
> > > -e dTLB-load-misses -e dTLB-store-misses -e iTLB-load-misses -c 1 \
> > > perf bench sched messaging -g 1 -l 10
> > # Running 'sched/messaging' benchmark:
> > # 20 sender and receiver processes per group
> > # 1 groups == 40 processes run
> >
> >  Total time: 1.397 [sec]
> > [ perf record: Woken up 10 times to write data ]
> > Check IO/CPU overload!
> > [ perf record: Captured and wrote 8.211 MB perf.data (214486 samples) ]
> >
> > [root@fedora-riscv riscv]# perf report
> > Available samples
> > 107K cycles
>   ◆
> > 107K instructions
>   ▒
> > 250 dTLB-load-misses
>▒
> > 13 dTLB-store-misses
>▒
> > 172 iTLB-load-misses
> > ..
> >
> > Changes from v13->v14:
> > 1. Added sanity check for the hashtable in pmu.c
> >
> > Changes from v12->v13:
> > 1. Rebased on top of the apply-next.
> > 2. Addressed comments about space & comment block.
> >
> > Changes from v11->v12:
> > 1. Rebased on top of the apply-next.
> > 2. Aligned the write function & .min_priv to the previous line.
> > 3. Fixed the FDT generations for multi-socket scenario.
> > 4. Dropped interrupt property from the DT.
> > 5. Generate illegal instruction fault instead of virtual instruction
> fault
> >for VS/VU access while mcounteren is not set.
> >
> > Changes from v10->v11:
> > 1. Rebased on top of the master where first 7 patches were already
> merged.
> > 2. Removed unnecessary additional check in ctr predicate function.
> > 3. Removed unnecessary priv version checks in mcountinhibit read/write.
> > 4. Added Heiko's reviewed-by/tested-by tags.
> >
> > Changes from v8->v9:
> > 1. Added the write_done flags to the vmstate.
> > 2. Fixed the hpmcounter read access from M-mode.
> >
> > Changes from v7->v8:
> > 1. Removeding ordering constraints for mhpmcounter & mhpmevent.
> >
> > Changes from v6->v7:
> > 1. Fixed all the compilation errors for the usermode.
> >
> > Changes from v5->v6:
> > 1. Fixed compilation issue with PATCH 1.
> > 2. Addressed other comments.
> >
> > Changes from v4->v5:
> > 1. Rebased on top of the -next with following patches.
> >- isa extension
> >- priv 1.12 spec
> > 2. Addressed all the comments on v4
> > 3. Removed additional isa-ext DT node in favor of riscv,isa string update
> >
> > Changes from v3->v4:
> > 1. Removed the dummy events from pmu DT node.
> > 2. Fixed pmu_avail_counters mask generation.
> > 3. Added a patch to simplify the predicate function for counters.
> >
> > Changes from v2->v3:
> > 1. Addressed all the comments on PATCH1-4.
> > 2. Split patch1 into two separate patches.
> > 3. Added explicit comments to explain the event types in DT node.
> > 4. Rebased on latest Qemu.
> >
> > Changes from v1->v2:
> > 1. Dropped 

Re: [PATCH v9 1/3] hw/intc: Move mtimer/mtimecmp to aclint

2022-08-24 Thread Atish Kumar Patra
On Tue, Aug 23, 2022 at 2:10 PM Alistair Francis 
wrote:

> On Thu, Aug 11, 2022 at 4:57 AM Atish Patra  wrote:
> >
> > Historically, The mtime/mtimecmp has been part of the CPU because
> > they are per hart entities. However, they actually belong to aclint
> > which is a MMIO device.
> >
> > Move them to the ACLINT device. This also emulates the real hardware
> > more closely.
> >
> > Reviewed-by: Anup Patel 
> > Reviewed-by: Alistair Francis 
> > Reviewed-by: Andrew Jones 
> > Signed-off-by: Atish Patra 
>
> This patch breaks my multi-socket boot.
>
> When using OpenSBI 1.1 and Linux 5.19-rc7
>
> qemu-system-riscv64 \
> -machine virt \
> -serial mon:stdio -serial null -nographic \
> -append "root=/dev/vda rw highres=off  console=ttyS0 ip=dhcp
> earlycon=sbi" \
> -device virtio-net-device,netdev=net0,mac=52:54:00:12:34:02 \
> -netdev user,id=net0 \
> -object rng-random,filename=/dev/urandom,id=rng0 \
> -device virtio-rng-device,rng=rng0 \
> -smp 4 \
> -d guest_errors \
> -m 2G \
> -object
> memory-backend-ram,size=1G,policy=bind,host-nodes=0,id=ram-node0 \
> -numa node,memdev=ram-node0 \
> -object
> memory-backend-ram,size=1G,policy=bind,host-nodes=0,id=ram-node1 \
> -numa node,memdev=ram-node1 \
> -numa cpu,node-id=0,core-id=0 \
> -numa cpu,node-id=0,core-id=1 \
> -numa cpu,node-id=1,core-id=2 \
> -numa cpu,node-id=1,core-id=3 \
> -kernel ./images/qemuriscv64/Image
> -bios default
>
> It looks like OpenSBI hangs when booting after applying this patch
>
>
Argh. It was due to relative hartid vs absolute hartid per socket. This
fixes the issue for me.
Sorry for the breakage!

diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
index a125c73d535c..eee04643cb19 100644
--- a/hw/intc/riscv_aclint.c
+++ b/hw/intc/riscv_aclint.c
@@ -66,18 +66,21 @@ static void
riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,

 uint64_t rtc_r = cpu_riscv_read_rtc(mtimer);

+/* Compute the relative hartid w.r.t the socket */
+hartid = hartid - mtimer->hartid_base;
+
 mtimer->timecmp[hartid] = value;
 if (mtimer->timecmp[hartid] <= rtc_r) {
 /*
  * If we're setting an MTIMECMP value in the "past",
  * immediately raise the timer interrupt
  */
-qemu_irq_raise(mtimer->timer_irqs[hartid - mtimer->hartid_base]);
+qemu_irq_raise(mtimer->timer_irqs[hartid]);
 return;
 }

 /* otherwise, set up the future timer interrupt */
-qemu_irq_lower(mtimer->timer_irqs[hartid - mtimer->hartid_base]);
+qemu_irq_lower(mtimer->timer_irqs[hartid]);
 diff = mtimer->timecmp[hartid] - rtc_r;
 /* back to ns (note args switched in muldiv64) */
 uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND,
timebase_freq);



Alistair
>
> > ---
> >  hw/intc/riscv_aclint.c | 41 --
> >  hw/timer/ibex_timer.c  | 18 ++-
> >  include/hw/intc/riscv_aclint.h |  2 ++
> >  include/hw/timer/ibex_timer.h  |  2 ++
> >  target/riscv/cpu.h |  2 --
> >  target/riscv/machine.c |  5 ++---
> >  6 files changed, 42 insertions(+), 28 deletions(-)
> >
> > diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c
> > index e7942c4e5a32..a125c73d535c 100644
> > --- a/hw/intc/riscv_aclint.c
> > +++ b/hw/intc/riscv_aclint.c
> > @@ -32,6 +32,7 @@
> >  #include "hw/intc/riscv_aclint.h"
> >  #include "qemu/timer.h"
> >  #include "hw/irq.h"
> > +#include "migration/vmstate.h"
> >
> >  typedef struct riscv_aclint_mtimer_callback {
> >  RISCVAclintMTimerState *s;
> > @@ -65,8 +66,8 @@ static void
> riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
> >
> >  uint64_t rtc_r = cpu_riscv_read_rtc(mtimer);
> >
> > -cpu->env.timecmp = value;
> > -if (cpu->env.timecmp <= rtc_r) {
> > +mtimer->timecmp[hartid] = value;
> > +if (mtimer->timecmp[hartid] <= rtc_r) {
> >  /*
> >   * If we're setting an MTIMECMP value in the "past",
> >   * immediately raise the timer interrupt
> > @@ -77,7 +78,7 @@ static void
> riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
> >
> >  /* otherwise, set up the future timer interrupt */
> >  qemu_irq_lower(mtimer->timer_irqs[hartid - mtimer->hartid_base]);
> > -diff = cpu->env.timecmp - rtc_r;
> > +diff = mtimer->timecmp[hartid] - rtc_r;
> >  /* back to ns (note args switched in muldiv64) */
> >  uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND,
> timebase_freq);
> >
> > @@ -102,7 +103,7 @@ static void
> riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer,
> >  next = MIN(next, INT64_MAX);
> >  }
> >
> > -timer_mod(cpu->env.timer, next);
> > +timer_mod(mtimer->timers[hartid], next);
> >  }
> >
> >  /*
> > @@ -133,11 +134,11 @@ static uint64_t riscv_aclint_mtimer_read(void
> *opaque, hwaddr addr,
> >"aclint-mtimer: 

Re: [PATCH v13 3/6] target/riscv: Add few cache related PMU events

2022-08-23 Thread Atish Kumar Patra
On Mon, Aug 22, 2022 at 5:38 PM Alistair Francis 
wrote:

> On Wed, Aug 17, 2022 at 9:24 AM Atish Patra  wrote:
> >
> > From: Atish Patra 
> >
> > Qemu can monitor the following cache related PMU events through
> > tlb_fill functions.
> >
> > 1. DTLB load/store miss
> > 3. ITLB prefetch miss
> >
> > Increment the PMU counter in tlb_fill function.
> >
> > Reviewed-by: Alistair Francis 
> > Tested-by: Heiko Stuebner 
> > Signed-off-by: Atish Patra 
> > Signed-off-by: Atish Patra 
>
> This patch causes a number of test failures.
>
> On some boots I see lots of these errors printed:
>
> qemu-system-riscv64: GLib: g_hash_table_lookup: assertion 'hash_table
> != NULL' failed
>
> and I'm unable to boot Linux.
>
> The command line is:
>
> qemu-system-riscv64 \
> -machine sifive_u \
> -serial mon:stdio -serial null -nographic \
> -append "root=/dev/ram rw highres=off console=ttySIF0 ip=dhcp
> earlycon=sbi" \
> -smp 5 \
> -d guest_errors \
> -kernel ./images/qemuriscv64/Image \
> -initrd ./images/qemuriscv64/buildroot/rootfs.cpio \
> -bios default -m 256M
>
> I see that faiulre with the 5.19-rc7 kernel and OpenSBI 1.1.
>
> I also see the same messages on other machines when running baremetal
> code. I'm going to drop these patches from my tree
>
>
Sorry for the breakage.  This should fix the issue. We just need to add few
sanity checks
for the platforms that don't support these events.

diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
index ad33b81b2ea0..0a473010cadd 100644
--- a/target/riscv/pmu.c
+++ b/target/riscv/pmu.c
@@ -187,6 +187,9 @@ int riscv_pmu_incr_ctr(RISCVCPU *cpu, enum
riscv_pmu_event_idx event_idx)
 CPURISCVState *env = >env;
 gpointer value;

+if (!cpu->cfg.pmu_num)
+return 0;
+
 value = g_hash_table_lookup(cpu->pmu_event_ctr_map,
 GUINT_TO_POINTER(event_idx));
 if (!value) {
@@ -221,6 +224,9 @@ bool riscv_pmu_ctr_monitor_instructions(CPURISCVState
*env,
 }

 cpu = RISCV_CPU(env_cpu(env));
+if (!cpu->pmu_event_ctr_map)
+return false;
+
 event_idx = RISCV_PMU_EVENT_HW_INSTRUCTIONS;
 ctr_idx = GPOINTER_TO_UINT(g_hash_table_lookup(cpu->pmu_event_ctr_map,
GUINT_TO_POINTER(event_idx)));
@@ -243,6 +249,9 @@ bool riscv_pmu_ctr_monitor_cycles(CPURISCVState *env,
uint32_t target_ctr)
 }

 cpu = RISCV_CPU(env_cpu(env));
+if (!cpu->pmu_event_ctr_map)
+return false;
+
 event_idx = RISCV_PMU_EVENT_HW_CPU_CYCLES;
 ctr_idx = GPOINTER_TO_UINT(g_hash_table_lookup(cpu->pmu_event_ctr_map,
GUINT_TO_POINTER(event_idx)));
@@ -280,7 +289,7 @@ int riscv_pmu_update_event_map(CPURISCVState *env,
uint64_t value,
 uint32_t event_idx;
 RISCVCPU *cpu = RISCV_CPU(env_cpu(env));

-if (!riscv_pmu_counter_valid(cpu, ctr_idx)) {
+if (!riscv_pmu_counter_valid(cpu, ctr_idx) || !cpu->pmu_event_ctr_map)
{
 return -1;
 }

Should I respin the series or send this as a fix ?

Alistair
>
> > ---
> >  target/riscv/cpu_helper.c | 25 +
> >  1 file changed, 25 insertions(+)
> >
> > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> > index 1e4faa84e839..81948b37dd9a 100644
> > --- a/target/riscv/cpu_helper.c
> > +++ b/target/riscv/cpu_helper.c
> > @@ -21,11 +21,13 @@
> >  #include "qemu/log.h"
> >  #include "qemu/main-loop.h"
> >  #include "cpu.h"
> > +#include "pmu.h"
> >  #include "exec/exec-all.h"
> >  #include "instmap.h"
> >  #include "tcg/tcg-op.h"
> >  #include "trace.h"
> >  #include "semihosting/common-semi.h"
> > +#include "cpu_bits.h"
> >
> >  int riscv_cpu_mmu_index(CPURISCVState *env, bool ifetch)
> >  {
> > @@ -1188,6 +1190,28 @@ void riscv_cpu_do_unaligned_access(CPUState *cs,
> vaddr addr,
> >  cpu_loop_exit_restore(cs, retaddr);
> >  }
> >
> > +
> > +static void pmu_tlb_fill_incr_ctr(RISCVCPU *cpu, MMUAccessType
> access_type)
> > +{
> > +enum riscv_pmu_event_idx pmu_event_type;
> > +
> > +switch (access_type) {
> > +case MMU_INST_FETCH:
> > +pmu_event_type = RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS;
> > +break;
> > +case MMU_DATA_LOAD:
> > +pmu_event_type = RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS;
> > +break;
> > +case MMU_DATA_STORE:
> > +pmu_event_type = RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS;
> > +break;
> > +default:
> > +return;
> > +}
> > +
> > +riscv_pmu_incr_ctr(cpu, pmu_event_type);
> > +}
> > +
> >  bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
> >  MMUAccessType access_type, int mmu_idx,
> >  bool probe, uintptr_t retaddr)
> > @@ -1286,6 +1310,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr
> address, int size,
> >  }
> >  }
> >  } else {
> > +pmu_tlb_fill_incr_ctr(cpu, access_type);
> >  /* Single stage lookup */
> >  ret = 

Re: [PATCH v12 0/6] Improve PMU support

2022-08-16 Thread Atish Kumar Patra
On Sun, Aug 14, 2022 at 5:02 PM Alistair Francis 
wrote:

> On Fri, Aug 12, 2022 at 12:05 PM Atish Patra 
> wrote:
> >
> > On Tue, Aug 2, 2022 at 4:33 PM Atish Patra  wrote:
> > >
> > > The latest version of the SBI specification includes a Performance
> Monitoring
> > > Unit(PMU) extension[1] which allows the supervisor to
> start/stop/configure
> > > various PMU events. The Sscofpmf ('Ss' for Privileged arch and
> Supervisor-level
> > > extensions, and 'cofpmf' for Count OverFlow and Privilege Mode
> Filtering)
> > > extension[2] allows the perf like tool to handle overflow interrupts
> and
> > > filtering support.
> > >
> > > This series implements remaining PMU infrastructure to support
> > > PMU in virt machine. The first seven patches from the original series
> > > have been merged already.
> > >
> > > This will allow us to add any PMU events in future.
> > > Currently, this series enables the following omu events.
> > > 1. cycle count
> > > 2. instruction count
> > > 3. DTLB load/store miss
> > > 4. ITLB prefetch miss
> > >
> > > The first two are computed using host ticks while last three are
> counted during
> > > cpu_tlb_fill. We can do both sampling and count from guest userspace.
> > > This series has been tested on both RV64 and RV32. Both Linux[3] and
> Opensbi[4]
> > > patches are required to get the perf working.
> > >
> > > Here is an output of perf stat/report while running hackbench with
> latest
> > > OpenSBI & Linux kernel.
> > >
> > > Perf stat:
> > > ==
> > > [root@fedora-riscv ~]# perf stat -e cycles -e instructions -e
> dTLB-load-misses -e dTLB-store-misses -e iTLB-load-misses \
> > > > perf bench sched messaging -g 1 -l 10
> > > # Running 'sched/messaging' benchmark:
> > > # 20 sender and receiver processes per group
> > > # 1 groups == 40 processes run
> > >
> > >  Total time: 0.265 [sec]
> > >
> > >  Performance counter stats for 'perf bench sched messaging -g 1 -l 10':
> > >
> > >  4,167,825,362  cycles
> > >  4,166,609,256  instructions  #1.00  insn per
> cycle
> > >  3,092,026  dTLB-load-misses
> > >258,280  dTLB-store-misses
> > >  2,068,966  iTLB-load-misses
> > >
> > >0.585791767 seconds time elapsed
> > >
> > >0.373802000 seconds user
> > >1.042359000 seconds sys
> > >
> > > Perf record:
> > > 
> > > [root@fedora-riscv ~]# perf record -e cycles -e instructions \
> > > > -e dTLB-load-misses -e dTLB-store-misses -e iTLB-load-misses -c
> 1 \
> > > > perf bench sched messaging -g 1 -l 10
> > > # Running 'sched/messaging' benchmark:
> > > # 20 sender and receiver processes per group
> > > # 1 groups == 40 processes run
> > >
> > >  Total time: 1.397 [sec]
> > > [ perf record: Woken up 10 times to write data ]
> > > Check IO/CPU overload!
> > > [ perf record: Captured and wrote 8.211 MB perf.data (214486 samples) ]
> > >
> > > [root@fedora-riscv riscv]# perf report
> > > Available samples
> > > 107K cycles
> ◆
> > > 107K instructions
> ▒
> > > 250 dTLB-load-misses
>  ▒
> > > 13 dTLB-store-misses
>  ▒
> > > 172 iTLB-load-misses
> > > ..
> > >
> > > Changes from v11->v12:
> > > 1. Rebased on top of the apply-next.
> > > 2. Aligned the write function & .min_priv to the previous line.
> > > 3. Fixed the FDT generations for multi-socket scenario.
> > > 4. Dropped interrupt property from the DT.
> > > 5. Generate illegal instruction fault instead of virtual instruction
> fault
> > >for VS/VU access while mcounteren is not set.
> > >
> > > Changes from v10->v11:
> > > 1. Rebased on top of the master where first 7 patches were already
> merged.
> > > 2. Removed unnecessary additional check in ctr predicate function.
> > > 3. Removed unnecessary priv version checks in mcountinhibit read/write.
> > > 4. Added Heiko's reviewed-by/tested-by tags.
> > >
> > > Changes from v8->v9:
> > > 1. Added the write_done flags to the vmstate.
> > > 2. Fixed the hpmcounter read access from M-mode.
> > >
> > > Changes from v7->v8:
> > > 1. Removeding ordering constraints for mhpmcounter & mhpmevent.
> > >
> > > Changes from v6->v7:
> > > 1. Fixed all the compilation errors for the usermode.
> > >
> > > Changes from v5->v6:
> > > 1. Fixed compilation issue with PATCH 1.
> > > 2. Addressed other comments.
> > >
> > > Changes from v4->v5:
> > > 1. Rebased on top of the -next with following patches.
> > >- isa extension
> > >- priv 1.12 spec
> > > 2. Addressed all the comments on v4
> > > 3. Removed additional isa-ext DT node in favor of riscv,isa string
> update
> > >
> > > Changes from v3->v4:
> > > 1. Removed the dummy events from pmu DT node.
> > > 2. Fixed pmu_avail_counters mask generation.
> > > 3. Added a patch to simplify the predicate function for counters.
> > >
> > > Changes from v2->v3:
> > > 1. Addressed all the comments on PATCH1-4.
> > > 2. Split patch1 into two separate patches.
> > > 3. Added explicit comments to explain 

Re: [PATCH v12 2/6] target/riscv: Simplify counter predicate function

2022-08-16 Thread Atish Kumar Patra
On Mon, Aug 15, 2022 at 12:54 AM Andrew Jones 
wrote:

> On Tue, Aug 02, 2022 at 04:33:03PM -0700, Atish Patra wrote:
> > All the hpmcounters and the fixed counters (CY, IR, TM) can be
> represented
> > as a unified counter. Thus, the predicate function doesn't need handle
> each
> > case separately.
> >
> > Simplify the predicate function so that we just handle things differently
> > between RV32/RV64 and S/HS mode.
> >
> > Reviewed-by: Bin Meng 
> > Acked-by: Alistair Francis 
> > Signed-off-by: Atish Patra 
> > ---
> >  target/riscv/csr.c | 110 -
> >  1 file changed, 9 insertions(+), 101 deletions(-)
> >
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index 9b45c49ab45f..6690b72ea0e7 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -74,6 +74,7 @@ static RISCVException ctr(CPURISCVState *env, int
> csrno)
> >  CPUState *cs = env_cpu(env);
> >  RISCVCPU *cpu = RISCV_CPU(cs);
> >  int ctr_index;
> > +target_ulong ctr_mask;
> >  int base_csrno = CSR_CYCLE;
> >  bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
> >
> > @@ -82,122 +83,29 @@ static RISCVException ctr(CPURISCVState *env, int
> csrno)
> >  base_csrno += 0x80;
> >  }
> >  ctr_index = csrno - base_csrno;
> > +ctr_mask = BIT(ctr_index);
> >
> >  if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
> >  (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
> >  goto skip_ext_pmu_check;
> >  }
> >
> > -if ((!cpu->cfg.pmu_num || !(cpu->pmu_avail_ctrs & BIT(ctr_index
> {
> > +if (!(cpu->pmu_avail_ctrs & ctr_mask)) {
> >  /* No counter is enabled in PMU or the counter is out of range
> */
> >  return RISCV_EXCP_ILLEGAL_INST;
> >  }
> >
> >  skip_ext_pmu_check:
> >
> > -if (env->priv == PRV_S) {
> > -switch (csrno) {
> > -case CSR_CYCLE:
> > -if (!get_field(env->mcounteren, COUNTEREN_CY)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -case CSR_TIME:
> > -if (!get_field(env->mcounteren, COUNTEREN_TM)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -case CSR_INSTRET:
> > -if (!get_field(env->mcounteren, COUNTEREN_IR)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
> > -if (!get_field(env->mcounteren, 1 << ctr_index)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -}
> > -if (rv32) {
> > -switch (csrno) {
> > -case CSR_CYCLEH:
> > -if (!get_field(env->mcounteren, COUNTEREN_CY)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -case CSR_TIMEH:
> > -if (!get_field(env->mcounteren, COUNTEREN_TM)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -case CSR_INSTRETH:
> > -if (!get_field(env->mcounteren, COUNTEREN_IR)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
> > -if (!get_field(env->mcounteren, 1 << ctr_index)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -}
> > -}
> > +if (((env->priv == PRV_S) && (!get_field(env->mcounteren,
> ctr_mask))) ||
> > +   ((env->priv == PRV_U) && (!get_field(env->scounteren,
> ctr_mask {
> ^ there should be another space here
>
> > +return RISCV_EXCP_ILLEGAL_INST;
> >  }
> >
> >  if (riscv_cpu_virt_enabled(env)) {
> > -switch (csrno) {
> > -case CSR_CYCLE:
> > -if (!get_field(env->hcounteren, COUNTEREN_CY) &&
> > -get_field(env->mcounteren, COUNTEREN_CY)) {
> > -return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -}
> > -break;
> > -case CSR_TIME:
> > -if (!get_field(env->hcounteren, COUNTEREN_TM) &&
> > -get_field(env->mcounteren, COUNTEREN_TM)) {
> > -return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -}
> > -break;
> > -case CSR_INSTRET:
> > -if (!get_field(env->hcounteren, COUNTEREN_IR) &&
> > -get_field(env->mcounteren, COUNTEREN_IR)) {
> > -return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -}
> > -break;
> > -case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
> > -if (!get_field(env->hcounteren, 1 << ctr_index) &&
> > - get_field(env->mcounteren, 1 << 

Re: [PATCH v8 3/3] target/riscv: Add vstimecmp support

2022-08-09 Thread Atish Kumar Patra
On Tue, Aug 9, 2022 at 6:33 PM Weiwei Li  wrote:

>
> 在 2022/8/10 上午3:34, Atish Kumar Patra 写道:
>
>
>
>
> On Tue, Aug 9, 2022 at 12:01 AM Weiwei Li  wrote:
>
>>
>> 在 2022/8/9 上午1:20, Atish Kumar Patra 写道:
>>
>>
>>
>> On Sun, Aug 7, 2022 at 6:50 PM Weiwei Li  wrote:
>>
>>>
>>> 在 2022/8/4 上午9:42, Atish Patra 写道:
>>> > vstimecmp CSR allows the guest OS or to program the next guest timer
>>> > interrupt directly. Thus, hypervisor no longer need to inject the
>>> > timer interrupt to the guest if vstimecmp is used. This was ratified
>>> > as a part of the Sstc extension.
>>> >
>>> > Signed-off-by: Atish Patra 
>>> > ---
>>> >   target/riscv/cpu.h |   4 ++
>>> >   target/riscv/cpu_bits.h|   4 ++
>>> >   target/riscv/cpu_helper.c  |  11 ++--
>>> >   target/riscv/csr.c | 102
>>> -
>>> >   target/riscv/machine.c |   1 +
>>> >   target/riscv/time_helper.c |  16 ++
>>> >   6 files changed, 133 insertions(+), 5 deletions(-)
>>> >
>>> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
>>> > index 4cda2905661e..1fd382b2717f 100644
>>> > --- a/target/riscv/cpu.h
>>> > +++ b/target/riscv/cpu.h
>>> > @@ -312,6 +312,8 @@ struct CPUArchState {
>>> >   /* Sstc CSRs */
>>> >   uint64_t stimecmp;
>>> >
>>> > +uint64_t vstimecmp;
>>> > +
>>> >   /* physical memory protection */
>>> >   pmp_table_t pmp_state;
>>> >   target_ulong mseccfg;
>>> > @@ -366,6 +368,8 @@ struct CPUArchState {
>>> >
>>> >   /* Fields from here on are preserved across CPU reset. */
>>> >   QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
>>> > +QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */
>>> > +bool vstime_irq;
>>> >
>>> >   hwaddr kernel_addr;
>>> >   hwaddr fdt_addr;
>>> > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
>>> > index ac17cf1515c0..095dab19f512 100644
>>> > --- a/target/riscv/cpu_bits.h
>>> > +++ b/target/riscv/cpu_bits.h
>>> > @@ -257,6 +257,10 @@
>>> >   #define CSR_VSIP0x244
>>> >   #define CSR_VSATP   0x280
>>> >
>>> > +/* Sstc virtual CSRs */
>>> > +#define CSR_VSTIMECMP   0x24D
>>> > +#define CSR_VSTIMECMPH  0x25D
>>> > +
>>> >   #define CSR_MTINST  0x34a
>>> >   #define CSR_MTVAL2  0x34b
>>> >
>>> > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
>>> > index 650574accf0a..1e4faa84e839 100644
>>> > --- a/target/riscv/cpu_helper.c
>>> > +++ b/target/riscv/cpu_helper.c
>>> > @@ -345,8 +345,9 @@ uint64_t riscv_cpu_all_pending(CPURISCVState *env)
>>> >   {
>>> >   uint32_t gein = get_field(env->hstatus, HSTATUS_VGEIN);
>>> >   uint64_t vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
>>> > +uint64_t vstip = (env->vstime_irq) ? MIP_VSTIP : 0;
>>> >
>>> > -return (env->mip | vsgein) & env->mie;
>>> > +return (env->mip | vsgein | vstip) & env->mie;
>>> >   }
>>> >
>>> >   int riscv_cpu_mirq_pending(CPURISCVState *env)
>>> > @@ -605,7 +606,7 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu,
>>> uint64_t mask, uint64_t value)
>>> >   {
>>> >   CPURISCVState *env = >env;
>>> >   CPUState *cs = CPU(cpu);
>>> > -uint64_t gein, vsgein = 0, old = env->mip;
>>> > +uint64_t gein, vsgein = 0, vstip = 0, old = env->mip;
>>> >   bool locked = false;
>>> >
>>> >   if (riscv_cpu_virt_enabled(env)) {
>>> > @@ -613,6 +614,10 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu,
>>> uint64_t mask, uint64_t value)
>>> >   vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
>>> >   }
>>> >
>>> > +/* No need to update mip for VSTIP */
>>> > +mask = ((mask == MIP_VSTIP) && env->vstime_irq) ? 0 : mask;
>>> > +vstip = env->vstime_irq ? MIP_VSTIP : 0;
>>> > +
>&

Re: [PATCH v8 3/3] target/riscv: Add vstimecmp support

2022-08-09 Thread Atish Kumar Patra
On Tue, Aug 9, 2022 at 12:01 AM Weiwei Li  wrote:

>
> 在 2022/8/9 上午1:20, Atish Kumar Patra 写道:
>
>
>
> On Sun, Aug 7, 2022 at 6:50 PM Weiwei Li  wrote:
>
>>
>> 在 2022/8/4 上午9:42, Atish Patra 写道:
>> > vstimecmp CSR allows the guest OS or to program the next guest timer
>> > interrupt directly. Thus, hypervisor no longer need to inject the
>> > timer interrupt to the guest if vstimecmp is used. This was ratified
>> > as a part of the Sstc extension.
>> >
>> > Signed-off-by: Atish Patra 
>> > ---
>> >   target/riscv/cpu.h |   4 ++
>> >   target/riscv/cpu_bits.h|   4 ++
>> >   target/riscv/cpu_helper.c  |  11 ++--
>> >   target/riscv/csr.c | 102 -
>> >   target/riscv/machine.c |   1 +
>> >   target/riscv/time_helper.c |  16 ++
>> >   6 files changed, 133 insertions(+), 5 deletions(-)
>> >
>> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
>> > index 4cda2905661e..1fd382b2717f 100644
>> > --- a/target/riscv/cpu.h
>> > +++ b/target/riscv/cpu.h
>> > @@ -312,6 +312,8 @@ struct CPUArchState {
>> >   /* Sstc CSRs */
>> >   uint64_t stimecmp;
>> >
>> > +uint64_t vstimecmp;
>> > +
>> >   /* physical memory protection */
>> >   pmp_table_t pmp_state;
>> >   target_ulong mseccfg;
>> > @@ -366,6 +368,8 @@ struct CPUArchState {
>> >
>> >   /* Fields from here on are preserved across CPU reset. */
>> >   QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
>> > +QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */
>> > +bool vstime_irq;
>> >
>> >   hwaddr kernel_addr;
>> >   hwaddr fdt_addr;
>> > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
>> > index ac17cf1515c0..095dab19f512 100644
>> > --- a/target/riscv/cpu_bits.h
>> > +++ b/target/riscv/cpu_bits.h
>> > @@ -257,6 +257,10 @@
>> >   #define CSR_VSIP0x244
>> >   #define CSR_VSATP   0x280
>> >
>> > +/* Sstc virtual CSRs */
>> > +#define CSR_VSTIMECMP   0x24D
>> > +#define CSR_VSTIMECMPH  0x25D
>> > +
>> >   #define CSR_MTINST  0x34a
>> >   #define CSR_MTVAL2  0x34b
>> >
>> > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
>> > index 650574accf0a..1e4faa84e839 100644
>> > --- a/target/riscv/cpu_helper.c
>> > +++ b/target/riscv/cpu_helper.c
>> > @@ -345,8 +345,9 @@ uint64_t riscv_cpu_all_pending(CPURISCVState *env)
>> >   {
>> >   uint32_t gein = get_field(env->hstatus, HSTATUS_VGEIN);
>> >   uint64_t vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
>> > +uint64_t vstip = (env->vstime_irq) ? MIP_VSTIP : 0;
>> >
>> > -return (env->mip | vsgein) & env->mie;
>> > +return (env->mip | vsgein | vstip) & env->mie;
>> >   }
>> >
>> >   int riscv_cpu_mirq_pending(CPURISCVState *env)
>> > @@ -605,7 +606,7 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu,
>> uint64_t mask, uint64_t value)
>> >   {
>> >   CPURISCVState *env = >env;
>> >   CPUState *cs = CPU(cpu);
>> > -uint64_t gein, vsgein = 0, old = env->mip;
>> > +uint64_t gein, vsgein = 0, vstip = 0, old = env->mip;
>> >   bool locked = false;
>> >
>> >   if (riscv_cpu_virt_enabled(env)) {
>> > @@ -613,6 +614,10 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu,
>> uint64_t mask, uint64_t value)
>> >   vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
>> >   }
>> >
>> > +/* No need to update mip for VSTIP */
>> > +mask = ((mask == MIP_VSTIP) && env->vstime_irq) ? 0 : mask;
>> > +vstip = env->vstime_irq ? MIP_VSTIP : 0;
>> > +
>> >   if (!qemu_mutex_iothread_locked()) {
>> >   locked = true;
>> >   qemu_mutex_lock_iothread();
>> > @@ -620,7 +625,7 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu,
>> uint64_t mask, uint64_t value)
>> >
>> >   env->mip = (env->mip & ~mask) | (value & mask);
>> >
>> > -if (env->mip | vsgein) {
>> > +if (env->mip | vsgein | vstip) {
>> >   cpu_interrupt(cs, CPU_INTERRUPT_HARD);
>> >   } els

Re: [PATCH v8 3/3] target/riscv: Add vstimecmp support

2022-08-08 Thread Atish Kumar Patra
On Sun, Aug 7, 2022 at 6:50 PM Weiwei Li  wrote:

>
> 在 2022/8/4 上午9:42, Atish Patra 写道:
> > vstimecmp CSR allows the guest OS or to program the next guest timer
> > interrupt directly. Thus, hypervisor no longer need to inject the
> > timer interrupt to the guest if vstimecmp is used. This was ratified
> > as a part of the Sstc extension.
> >
> > Signed-off-by: Atish Patra 
> > ---
> >   target/riscv/cpu.h |   4 ++
> >   target/riscv/cpu_bits.h|   4 ++
> >   target/riscv/cpu_helper.c  |  11 ++--
> >   target/riscv/csr.c | 102 -
> >   target/riscv/machine.c |   1 +
> >   target/riscv/time_helper.c |  16 ++
> >   6 files changed, 133 insertions(+), 5 deletions(-)
> >
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 4cda2905661e..1fd382b2717f 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -312,6 +312,8 @@ struct CPUArchState {
> >   /* Sstc CSRs */
> >   uint64_t stimecmp;
> >
> > +uint64_t vstimecmp;
> > +
> >   /* physical memory protection */
> >   pmp_table_t pmp_state;
> >   target_ulong mseccfg;
> > @@ -366,6 +368,8 @@ struct CPUArchState {
> >
> >   /* Fields from here on are preserved across CPU reset. */
> >   QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
> > +QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */
> > +bool vstime_irq;
> >
> >   hwaddr kernel_addr;
> >   hwaddr fdt_addr;
> > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> > index ac17cf1515c0..095dab19f512 100644
> > --- a/target/riscv/cpu_bits.h
> > +++ b/target/riscv/cpu_bits.h
> > @@ -257,6 +257,10 @@
> >   #define CSR_VSIP0x244
> >   #define CSR_VSATP   0x280
> >
> > +/* Sstc virtual CSRs */
> > +#define CSR_VSTIMECMP   0x24D
> > +#define CSR_VSTIMECMPH  0x25D
> > +
> >   #define CSR_MTINST  0x34a
> >   #define CSR_MTVAL2  0x34b
> >
> > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> > index 650574accf0a..1e4faa84e839 100644
> > --- a/target/riscv/cpu_helper.c
> > +++ b/target/riscv/cpu_helper.c
> > @@ -345,8 +345,9 @@ uint64_t riscv_cpu_all_pending(CPURISCVState *env)
> >   {
> >   uint32_t gein = get_field(env->hstatus, HSTATUS_VGEIN);
> >   uint64_t vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
> > +uint64_t vstip = (env->vstime_irq) ? MIP_VSTIP : 0;
> >
> > -return (env->mip | vsgein) & env->mie;
> > +return (env->mip | vsgein | vstip) & env->mie;
> >   }
> >
> >   int riscv_cpu_mirq_pending(CPURISCVState *env)
> > @@ -605,7 +606,7 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu,
> uint64_t mask, uint64_t value)
> >   {
> >   CPURISCVState *env = >env;
> >   CPUState *cs = CPU(cpu);
> > -uint64_t gein, vsgein = 0, old = env->mip;
> > +uint64_t gein, vsgein = 0, vstip = 0, old = env->mip;
> >   bool locked = false;
> >
> >   if (riscv_cpu_virt_enabled(env)) {
> > @@ -613,6 +614,10 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu,
> uint64_t mask, uint64_t value)
> >   vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
> >   }
> >
> > +/* No need to update mip for VSTIP */
> > +mask = ((mask == MIP_VSTIP) && env->vstime_irq) ? 0 : mask;
> > +vstip = env->vstime_irq ? MIP_VSTIP : 0;
> > +
> >   if (!qemu_mutex_iothread_locked()) {
> >   locked = true;
> >   qemu_mutex_lock_iothread();
> > @@ -620,7 +625,7 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu,
> uint64_t mask, uint64_t value)
> >
> >   env->mip = (env->mip & ~mask) | (value & mask);
> >
> > -if (env->mip | vsgein) {
> > +if (env->mip | vsgein | vstip) {
> >   cpu_interrupt(cs, CPU_INTERRUPT_HARD);
> >   } else {
> >   cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index e18b000700e4..9da4d6515e7b 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -829,17 +829,100 @@ static RISCVException sstc(CPURISCVState *env,
> int csrno)
> >   return smode(env, csrno);
> >   }
> >
> > +static RISCVException sstc_hmode(CPURISCVState *env, int csrno)
> > +{
> > +CPUState *cs = env_cpu(env);
> > +RISCVCPU *cpu = RISCV_CPU(cs);
> > +
> > +if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {
> > +return RISCV_EXCP_ILLEGAL_INST;
> > +}
> > +
> > +if (env->priv == PRV_M) {
> > +return RISCV_EXCP_NONE;
> > +}
> > +
> > +if (!(get_field(env->mcounteren, COUNTEREN_TM) &
> > +  get_field(env->menvcfg, MENVCFG_STCE))) {
> > +return RISCV_EXCP_ILLEGAL_INST;
> > +}
> > +
> > +if (riscv_cpu_virt_enabled(env)) {
> > +if (!(get_field(env->hcounteren, COUNTEREN_TM) &
> > +  get_field(env->henvcfg, HENVCFG_STCE))) {
> > +return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > +}
> > +}
> > +
>
> I think this check on hcounteren and henvcfg 

Re: [PATCH v7 2/3] target/riscv: Add stimecmp support

2022-08-03 Thread Atish Kumar Patra
On Wed, Aug 3, 2022 at 3:26 AM Ben Dooks  wrote:

> On 03/08/2022 09:25, Atish Patra wrote:
> > stimecmp allows the supervisor mode to update stimecmp CSR directly
> > to program the next timer interrupt. This CSR is part of the Sstc
> > extension which was ratified recently.
> >
> > Signed-off-by: Atish Patra 
> > ---
> >   target/riscv/cpu.c | 12 +
> >   target/riscv/cpu.h |  5 ++
> >   target/riscv/cpu_bits.h|  4 ++
> >   target/riscv/csr.c | 81 +++
> >   target/riscv/machine.c |  1 +
> >   target/riscv/meson.build   |  3 +-
> >   target/riscv/time_helper.c | 98 ++
> >   target/riscv/time_helper.h | 30 
> >   8 files changed, 233 insertions(+), 1 deletion(-)
> >   create mode 100644 target/riscv/time_helper.c
> >   create mode 100644 target/riscv/time_helper.h
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index d4635c7df46b..e0c3e786849f 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -23,6 +23,7 @@
> >   #include "qemu/log.h"
> >   #include "cpu.h"
> >   #include "internals.h"
> > +#include "time_helper.h"
> >   #include "exec/exec-all.h"
> >   #include "qapi/error.h"
> >   #include "qemu/error-report.h"
> > @@ -99,6 +100,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
> >   ISA_EXT_DATA_ENTRY(zve64f, true, PRIV_VERSION_1_12_0, ext_zve64f),
> >   ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
> >   ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0,
> ext_zhinxmin),
> > +ISA_EXT_DATA_ENTRY(sstc, true, PRIV_VERSION_1_12_0, ext_sstc),
> >   ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0,
> ext_svinval),
> >   ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0,
> ext_svnapot),
> >   ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
> > @@ -675,6 +677,13 @@ static void riscv_cpu_realize(DeviceState *dev,
> Error **errp)
> >
> >   set_resetvec(env, cpu->cfg.resetvec);
> >
> > +#ifndef CONFIG_USER_ONLY
> > +if (cpu->cfg.ext_sstc) {
> > +riscv_timer_init(cpu);
> > +}
> > +#endif /* CONFIG_USER_ONLY */
> > +
> > +
> >   /* Validate that MISA_MXL is set properly. */
> >   switch (env->misa_mxl_max) {
> >   #ifdef TARGET_RISCV64
> > @@ -968,7 +977,9 @@ static void riscv_cpu_init(Object *obj)
> >   #ifndef CONFIG_USER_ONLY
> >   qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq,
> > IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX);
> > +
> >   #endif /* CONFIG_USER_ONLY */
> > +
> >   }
> >
> >   static Property riscv_cpu_extensions[] = {
> > @@ -995,6 +1006,7 @@ static Property riscv_cpu_extensions[] = {
> >   DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false),
> >   DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
> >   DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
> > +DEFINE_PROP_BOOL("sstc", RISCVCPU, cfg.ext_sstc, true),
> >
> >   DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
> >   DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 0fae1569945c..4cda2905661e 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -309,6 +309,9 @@ struct CPUArchState {
> >   uint64_t mfromhost;
> >   uint64_t mtohost;
> >
> > +/* Sstc CSRs */
> > +uint64_t stimecmp;
> > +
> >   /* physical memory protection */
> >   pmp_table_t pmp_state;
> >   target_ulong mseccfg;
> > @@ -362,6 +365,7 @@ struct CPUArchState {
> >   float_status fp_status;
> >
> >   /* Fields from here on are preserved across CPU reset. */
> > +QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
> >
> >   hwaddr kernel_addr;
> >   hwaddr fdt_addr;
> > @@ -425,6 +429,7 @@ struct RISCVCPUConfig {
> >   bool ext_ifencei;
> >   bool ext_icsr;
> >   bool ext_zihintpause;
> > +bool ext_sstc;
> >   bool ext_svinval;
> >   bool ext_svnapot;
> >   bool ext_svpbmt;
> > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> > index 6be5a9e9f046..ac17cf1515c0 100644
> > --- a/target/riscv/cpu_bits.h
> > +++ b/target/riscv/cpu_bits.h
> > @@ -206,6 +206,10 @@
> >   #define CSR_STVAL   0x143
> >   #define CSR_SIP 0x144
> >
> > +/* Sstc supervisor CSRs */
> > +#define CSR_STIMECMP0x14D
> > +#define CSR_STIMECMPH   0x15D
> > +
> >   /* Supervisor Protection and Translation */
> >   #define CSR_SPTBR   0x180
> >   #define CSR_SATP0x180
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index 0fb042b2fd0f..b71e2509b64f 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -22,6 +22,7 @@
> >   #include "qemu/timer.h"
> >   #include "cpu.h"
> >   #include "pmu.h"
> > +#include "time_helper.h"
> >   #include "qemu/main-loop.h"
> >   #include "exec/exec-all.h"
> >   #include 

Re: [PATCH v7 2/3] target/riscv: Add stimecmp support

2022-08-03 Thread Atish Kumar Patra
On Wed, Aug 3, 2022 at 1:42 AM Weiwei Li  wrote:

>
> 在 2022/8/3 下午4:25, Atish Patra 写道:
> > stimecmp allows the supervisor mode to update stimecmp CSR directly
> > to program the next timer interrupt. This CSR is part of the Sstc
> > extension which was ratified recently.
> >
> > Signed-off-by: Atish Patra 
> > ---
> >   target/riscv/cpu.c | 12 +
> >   target/riscv/cpu.h |  5 ++
> >   target/riscv/cpu_bits.h|  4 ++
> >   target/riscv/csr.c | 81 +++
> >   target/riscv/machine.c |  1 +
> >   target/riscv/meson.build   |  3 +-
> >   target/riscv/time_helper.c | 98 ++
> >   target/riscv/time_helper.h | 30 
> >   8 files changed, 233 insertions(+), 1 deletion(-)
> >   create mode 100644 target/riscv/time_helper.c
> >   create mode 100644 target/riscv/time_helper.h
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index d4635c7df46b..e0c3e786849f 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -23,6 +23,7 @@
> >   #include "qemu/log.h"
> >   #include "cpu.h"
> >   #include "internals.h"
> > +#include "time_helper.h"
> >   #include "exec/exec-all.h"
> >   #include "qapi/error.h"
> >   #include "qemu/error-report.h"
> > @@ -99,6 +100,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
> >   ISA_EXT_DATA_ENTRY(zve64f, true, PRIV_VERSION_1_12_0, ext_zve64f),
> >   ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
> >   ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0,
> ext_zhinxmin),
> > +ISA_EXT_DATA_ENTRY(sstc, true, PRIV_VERSION_1_12_0, ext_sstc),
> >   ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0,
> ext_svinval),
> >   ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0,
> ext_svnapot),
> >   ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
> > @@ -675,6 +677,13 @@ static void riscv_cpu_realize(DeviceState *dev,
> Error **errp)
> >
> >   set_resetvec(env, cpu->cfg.resetvec);
> >
> > +#ifndef CONFIG_USER_ONLY
> > +if (cpu->cfg.ext_sstc) {
> > +riscv_timer_init(cpu);
> > +}
> > +#endif /* CONFIG_USER_ONLY */
> > +
> > +
>
> multi blink line here.
>
>
Fixed it.


> Regards,
>
> Weiwei Li
>
> >   /* Validate that MISA_MXL is set properly. */
> >   switch (env->misa_mxl_max) {
> >   #ifdef TARGET_RISCV64
> > @@ -968,7 +977,9 @@ static void riscv_cpu_init(Object *obj)
> >   #ifndef CONFIG_USER_ONLY
> >   qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq,
> > IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX);
> > +
> >   #endif /* CONFIG_USER_ONLY */
> > +
> >   }
> >
> >   static Property riscv_cpu_extensions[] = {
> > @@ -995,6 +1006,7 @@ static Property riscv_cpu_extensions[] = {
> >   DEFINE_PROP_BOOL("Zve64f", RISCVCPU, cfg.ext_zve64f, false),
> >   DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
> >   DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
> > +DEFINE_PROP_BOOL("sstc", RISCVCPU, cfg.ext_sstc, true),
> >
> >   DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
> >   DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 0fae1569945c..4cda2905661e 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -309,6 +309,9 @@ struct CPUArchState {
> >   uint64_t mfromhost;
> >   uint64_t mtohost;
> >
> > +/* Sstc CSRs */
> > +uint64_t stimecmp;
> > +
> >   /* physical memory protection */
> >   pmp_table_t pmp_state;
> >   target_ulong mseccfg;
> > @@ -362,6 +365,7 @@ struct CPUArchState {
> >   float_status fp_status;
> >
> >   /* Fields from here on are preserved across CPU reset. */
> > +QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
> >
> >   hwaddr kernel_addr;
> >   hwaddr fdt_addr;
> > @@ -425,6 +429,7 @@ struct RISCVCPUConfig {
> >   bool ext_ifencei;
> >   bool ext_icsr;
> >   bool ext_zihintpause;
> > +bool ext_sstc;
> >   bool ext_svinval;
> >   bool ext_svnapot;
> >   bool ext_svpbmt;
> > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> > index 6be5a9e9f046..ac17cf1515c0 100644
> > --- a/target/riscv/cpu_bits.h
> > +++ b/target/riscv/cpu_bits.h
> > @@ -206,6 +206,10 @@
> >   #define CSR_STVAL   0x143
> >   #define CSR_SIP 0x144
> >
> > +/* Sstc supervisor CSRs */
> > +#define CSR_STIMECMP0x14D
> > +#define CSR_STIMECMPH   0x15D
> > +
> >   /* Supervisor Protection and Translation */
> >   #define CSR_SPTBR   0x180
> >   #define CSR_SATP0x180
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index 0fb042b2fd0f..b71e2509b64f 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -22,6 +22,7 @@
> >   #include "qemu/timer.h"
> >   #include "cpu.h"
> >   #include "pmu.h"
> > +#include "time_helper.h"
> >   #include 

Re: [PATCH v7 3/3] target/riscv: Add vstimecmp support

2022-08-03 Thread Atish Kumar Patra
On Wed, Aug 3, 2022 at 1:49 AM Weiwei Li  wrote:

>
> 在 2022/8/3 下午4:25, Atish Patra 写道:
> > vstimecmp CSR allows the guest OS or to program the next guest timer
> > interrupt directly. Thus, hypervisor no longer need to inject the
> > timer interrupt to the guest if vstimecmp is used. This was ratified
> > as a part of the Sstc extension.
> >
> > Signed-off-by: Atish Patra 
> > ---
> >   target/riscv/cpu.h |   4 ++
> >   target/riscv/cpu_bits.h|   4 ++
> >   target/riscv/cpu_helper.c  |  11 ++--
> >   target/riscv/csr.c | 100 -
> >   target/riscv/machine.c |   1 +
> >   target/riscv/time_helper.c |  16 ++
> >   6 files changed, 131 insertions(+), 5 deletions(-)
> >
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 4cda2905661e..1fd382b2717f 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -312,6 +312,8 @@ struct CPUArchState {
> >   /* Sstc CSRs */
> >   uint64_t stimecmp;
> >
> > +uint64_t vstimecmp;
> > +
> >   /* physical memory protection */
> >   pmp_table_t pmp_state;
> >   target_ulong mseccfg;
> > @@ -366,6 +368,8 @@ struct CPUArchState {
> >
> >   /* Fields from here on are preserved across CPU reset. */
> >   QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
> > +QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */
> > +bool vstime_irq;
> >
> >   hwaddr kernel_addr;
> >   hwaddr fdt_addr;
> > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> > index ac17cf1515c0..095dab19f512 100644
> > --- a/target/riscv/cpu_bits.h
> > +++ b/target/riscv/cpu_bits.h
> > @@ -257,6 +257,10 @@
> >   #define CSR_VSIP0x244
> >   #define CSR_VSATP   0x280
> >
> > +/* Sstc virtual CSRs */
> > +#define CSR_VSTIMECMP   0x24D
> > +#define CSR_VSTIMECMPH  0x25D
> > +
> >   #define CSR_MTINST  0x34a
> >   #define CSR_MTVAL2  0x34b
> >
> > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> > index 650574accf0a..1e4faa84e839 100644
> > --- a/target/riscv/cpu_helper.c
> > +++ b/target/riscv/cpu_helper.c
> > @@ -345,8 +345,9 @@ uint64_t riscv_cpu_all_pending(CPURISCVState *env)
> >   {
> >   uint32_t gein = get_field(env->hstatus, HSTATUS_VGEIN);
> >   uint64_t vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
> > +uint64_t vstip = (env->vstime_irq) ? MIP_VSTIP : 0;
> >
> > -return (env->mip | vsgein) & env->mie;
> > +return (env->mip | vsgein | vstip) & env->mie;
> >   }
> >
> >   int riscv_cpu_mirq_pending(CPURISCVState *env)
> > @@ -605,7 +606,7 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu,
> uint64_t mask, uint64_t value)
> >   {
> >   CPURISCVState *env = >env;
> >   CPUState *cs = CPU(cpu);
> > -uint64_t gein, vsgein = 0, old = env->mip;
> > +uint64_t gein, vsgein = 0, vstip = 0, old = env->mip;
> >   bool locked = false;
> >
> >   if (riscv_cpu_virt_enabled(env)) {
> > @@ -613,6 +614,10 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu,
> uint64_t mask, uint64_t value)
> >   vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
> >   }
> >
> > +/* No need to update mip for VSTIP */
> > +mask = ((mask == MIP_VSTIP) && env->vstime_irq) ? 0 : mask;
> > +vstip = env->vstime_irq ? MIP_VSTIP : 0;
> > +
> >   if (!qemu_mutex_iothread_locked()) {
> >   locked = true;
> >   qemu_mutex_lock_iothread();
> > @@ -620,7 +625,7 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu,
> uint64_t mask, uint64_t value)
> >
> >   env->mip = (env->mip & ~mask) | (value & mask);
> >
> > -if (env->mip | vsgein) {
> > +if (env->mip | vsgein | vstip) {
> >   cpu_interrupt(cs, CPU_INTERRUPT_HARD);
> >   } else {
> >   cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index b71e2509b64f..d4265dd3cca2 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -833,17 +833,98 @@ static RISCVException sstc(CPURISCVState *env, int
> csrno)
> >   return RISCV_EXCP_NONE;
> >   }
> >
> > +static RISCVException sstc_hmode(CPURISCVState *env, int csrno)
> > +{
> > +CPUState *cs = env_cpu(env);
> > +RISCVCPU *cpu = RISCV_CPU(cs);
> > +
> > +if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {
> > +return RISCV_EXCP_ILLEGAL_INST;
> > +}
> > +
> > +if (env->priv == PRV_M) {
> > +return RISCV_EXCP_NONE;
> > +}
> > +
> > +if (!(get_field(env->mcounteren, COUNTEREN_TM) &
> > +  get_field(env->menvcfg, MENVCFG_STCE))) {
> > +return RISCV_EXCP_ILLEGAL_INST;
> > +}
> > +
> > +if (!(get_field(env->hcounteren, COUNTEREN_TM) &
> > +  get_field(env->henvcfg, HENVCFG_STCE))) {
> > +return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > +}
> > +
> I think hcounteren only works for VS mode here. So we should add check
> for virt  mode is enabled here.
>

vstimecmp can 

Re: [PATCH v12 1/6] target/riscv: Add sscofpmf extension support

2022-08-03 Thread Atish Kumar Patra
On Tue, Aug 2, 2022 at 7:13 PM Weiwei Li  wrote:

>
> 在 2022/8/3 上午7:33, Atish Patra 写道:
> > The Sscofpmf ('Ss' for Privileged arch and Supervisor-level extensions,
> > and 'cofpmf' for Count OverFlow and Privilege Mode Filtering)
> > extension allows the perf to handle overflow interrupts and filtering
> > support. This patch provides a framework for programmable
> > counters to leverage the extension. As the extension doesn't have any
> > provision for the overflow bit for fixed counters, the fixed events
> > can also be monitoring using programmable counters. The underlying
> > counters for cycle and instruction counters are always running. Thus,
> > a separate timer device is programmed to handle the overflow.
> >
> > Tested-by: Heiko Stuebner 
> > Signed-off-by: Atish Patra 
> > Signed-off-by: Atish Patra 
> > ---
> >   target/riscv/cpu.c  |  12 ++
> >   target/riscv/cpu.h  |  25 +++
> >   target/riscv/cpu_bits.h |  55 +++
> >   target/riscv/csr.c  | 166 ++-
> >   target/riscv/machine.c  |   1 +
> >   target/riscv/pmu.c  | 357 +++-
> >   target/riscv/pmu.h  |   7 +
> >   7 files changed, 612 insertions(+), 11 deletions(-)
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index d4635c7df46b..dc33b0dc9034 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -22,6 +22,7 @@
> >   #include "qemu/ctype.h"
> >   #include "qemu/log.h"
> >   #include "cpu.h"
> > +#include "pmu.h"
> >   #include "internals.h"
> >   #include "exec/exec-all.h"
> >   #include "qapi/error.h"
> > @@ -99,6 +100,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
> >   ISA_EXT_DATA_ENTRY(zve64f, true, PRIV_VERSION_1_12_0, ext_zve64f),
> >   ISA_EXT_DATA_ENTRY(zhinx, true, PRIV_VERSION_1_12_0, ext_zhinx),
> >   ISA_EXT_DATA_ENTRY(zhinxmin, true, PRIV_VERSION_1_12_0,
> ext_zhinxmin),
> > +ISA_EXT_DATA_ENTRY(sscofpmf, true, PRIV_VERSION_1_12_0,
> ext_sscofpmf),
> >   ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0,
> ext_svinval),
> >   ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0,
> ext_svnapot),
> >   ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
> > @@ -882,6 +884,15 @@ static void riscv_cpu_realize(DeviceState *dev,
> Error **errp)
> >   set_misa(env, env->misa_mxl, ext);
> >   }
> >
> > +#ifndef CONFIG_USER_ONLY
> > +if (cpu->cfg.pmu_num) {
> > +if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) &&
> cpu->cfg.ext_sscofpmf) {
> > +cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> > +  riscv_pmu_timer_cb, cpu);
> > +}
> > + }
> > +#endif
> > +
> >   riscv_cpu_register_gdb_regs_for_features(cs);
> >
> >   qemu_init_vcpu(cs);
> > @@ -986,6 +997,7 @@ static Property riscv_cpu_extensions[] = {
> >   DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
> >   DEFINE_PROP_BOOL("h", RISCVCPU, cfg.ext_h, true),
> >   DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
> > +DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
> >   DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
> >   DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
> >   DEFINE_PROP_BOOL("Zihintpause", RISCVCPU, cfg.ext_zihintpause,
> true),
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 4be4b82a837d..64d90586256d 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -137,6 +137,8 @@ typedef struct PMUCTRState {
> >   /* Snapshort value of a counter in RV32 */
> >   target_ulong mhpmcounterh_prev;
> >   bool started;
> > +/* Value beyond UINT32_MAX/UINT64_MAX before overflow interrupt
> trigger */
> > +target_ulong irq_overflow_left;
> >   } PMUCTRState;
> >
> >   struct CPUArchState {
> > @@ -302,6 +304,9 @@ struct CPUArchState {
> >   /* PMU event selector configured values. First three are unused*/
> >   target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
> >
> > +/* PMU event selector configured values for RV32*/
> > +target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
> > +
>
> I think mhpmeventh_val can be uint32_t directly. Or  use the usual way
> to implement this type of CSRs:
>
> change  the  type of mhpmevent_val to uint64_t and mhpmeventh csr reuse
> the high part of
>
> mhpmeventh_val for RV32
>
>
Yes. That can be done for mhpmcounter_[val/prev] as well. I would prefer to
merge this series first
and make another series for these changes if that's okay.
I would like to keep that change separate for core sscofpmf implementation.


> Regards,
> Weiwei Li
>
> >   target_ulong sscratch;
> >   target_ulong mscratch;
> >
> > @@ -439,6 +444,7 @@ struct RISCVCPUConfig {
> >   bool ext_zve32f;
> >   bool ext_zve64f;
> >   bool ext_zmmul;
> > +bool ext_sscofpmf;
> >   bool rvv_ta_all_1s;
> >   bool rvv_ma_all_1s;
> >
> > @@ -486,6 +492,12 @@ struct 

Re: [PATCH v11 2/6] target/riscv: Simplify counter predicate function

2022-08-02 Thread Atish Kumar Patra
On Wed, Jul 27, 2022 at 5:56 PM Weiwei Li  wrote:

>
> 在 2022/7/28 上午5:40, Atish Kumar Patra 写道:
>
>
>
> On Wed, Jul 27, 2022 at 1:35 AM Weiwei Li  wrote:
>
>>
>> 在 2022/7/27 下午2:49, Atish Patra 写道:
>> > All the hpmcounters and the fixed counters (CY, IR, TM) can be
>> represented
>> > as a unified counter. Thus, the predicate function doesn't need handle
>> each
>> > case separately.
>> >
>> > Simplify the predicate function so that we just handle things
>> differently
>> > between RV32/RV64 and S/HS mode.
>> >
>> > Reviewed-by: Bin Meng 
>> > Acked-by: Alistair Francis 
>> > Signed-off-by: Atish Patra 
>> > ---
>> >   target/riscv/csr.c | 112 +
>> >   1 file changed, 11 insertions(+), 101 deletions(-)
>> >
>> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
>> > index 1233bfa0a726..57dbbf9b09a0 100644
>> > --- a/target/riscv/csr.c
>> > +++ b/target/riscv/csr.c
>> > @@ -74,6 +74,7 @@ static RISCVException ctr(CPURISCVState *env, int
>> csrno)
>> >   CPUState *cs = env_cpu(env);
>> >   RISCVCPU *cpu = RISCV_CPU(cs);
>> >   int ctr_index;
>> > +target_ulong ctr_mask;
>> >   int base_csrno = CSR_CYCLE;
>> >   bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
>> >
>> > @@ -82,122 +83,31 @@ static RISCVException ctr(CPURISCVState *env, int
>> csrno)
>> >   base_csrno += 0x80;
>> >   }
>> >   ctr_index = csrno - base_csrno;
>> > +ctr_mask = BIT(ctr_index);
>> >
>> >   if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
>> >   (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
>> >   goto skip_ext_pmu_check;
>> >   }
>> >
>> > -if ((!cpu->cfg.pmu_num || !(cpu->pmu_avail_ctrs &
>> BIT(ctr_index {
>> > +if (!(cpu->pmu_avail_ctrs & ctr_mask)) {
>> >   /* No counter is enabled in PMU or the counter is out of
>> range */
>> >   return RISCV_EXCP_ILLEGAL_INST;
>> >   }
>> >
>> >   skip_ext_pmu_check:
>> >
>> > -if (env->priv == PRV_S) {
>> > -switch (csrno) {
>> > -case CSR_CYCLE:
>> > -if (!get_field(env->mcounteren, COUNTEREN_CY)) {
>> > -return RISCV_EXCP_ILLEGAL_INST;
>> > -}
>> > -break;
>> > -case CSR_TIME:
>> > -if (!get_field(env->mcounteren, COUNTEREN_TM)) {
>> > -return RISCV_EXCP_ILLEGAL_INST;
>> > -}
>> > -break;
>> > -case CSR_INSTRET:
>> > -if (!get_field(env->mcounteren, COUNTEREN_IR)) {
>> > -return RISCV_EXCP_ILLEGAL_INST;
>> > -}
>> > -break;
>> > -case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
>> > -if (!get_field(env->mcounteren, 1 << ctr_index)) {
>> > -return RISCV_EXCP_ILLEGAL_INST;
>> > -}
>> > -break;
>> > -}
>> > -if (rv32) {
>> > -switch (csrno) {
>> > -case CSR_CYCLEH:
>> > -if (!get_field(env->mcounteren, COUNTEREN_CY)) {
>> > -return RISCV_EXCP_ILLEGAL_INST;
>> > -}
>> > -break;
>> > -case CSR_TIMEH:
>> > -if (!get_field(env->mcounteren, COUNTEREN_TM)) {
>> > -return RISCV_EXCP_ILLEGAL_INST;
>> > -}
>> > -break;
>> > -case CSR_INSTRETH:
>> > -if (!get_field(env->mcounteren, COUNTEREN_IR)) {
>> > -return RISCV_EXCP_ILLEGAL_INST;
>> > -}
>> > -break;
>> > -case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
>> > -if (!get_field(env->mcounteren, 1 << ctr_index)) {
>> > -return RISCV_EXCP_ILLEGAL_INST;
>> > -}
>> > -break;
>> > -}
>> > -}
>> > +if (((env->priv == PRV_S) && (!get_field(env->mcounteren,
>

Re: [PATCH v11 1/6] target/riscv: Add sscofpmf extension support

2022-07-30 Thread Atish Kumar Patra
On Sat, Jul 30, 2022 at 9:11 PM Rahul Pathak 
wrote:

> Hi Atish,
>
> I tried your riscv_pmu_v12  branch but I couldn't made it working
> without below change -
> without this change qemu was not exporting the sscofpmf in the cpu dt nodes
>
> -
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index 2e0dd6ddb5..2b36830755 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -108,6 +108,7 @@ static const struct isa_ext_data isa_edata_arr[] = {
>  ISA_EXT_DATA_ENTRY(svinval, true, PRIV_VERSION_1_12_0, ext_svinval),
>  ISA_EXT_DATA_ENTRY(svnapot, true, PRIV_VERSION_1_12_0, ext_svnapot),
>  ISA_EXT_DATA_ENTRY(svpbmt, true, PRIV_VERSION_1_12_0, ext_svpbmt),
> +ISA_EXT_DATA_ENTRY(sscofpmf, true, PRIV_VERSION_1_12_0, ext_sscofpmf),
>  };
>
>  static bool isa_ext_is_enabled(RISCVCPU *cpu,
> --
>

Yeah. This happened while resolving the conflict. My bad. I will send v13
along with other suggested fixes.


> Thanks
> Rahul
>
> On Wed, Jul 27, 2022 at 12:26 PM Atish Patra  wrote:
> >
> > The Sscofpmf ('Ss' for Privileged arch and Supervisor-level extensions,
> > and 'cofpmf' for Count OverFlow and Privilege Mode Filtering)
> > extension allows the perf to handle overflow interrupts and filtering
> > support. This patch provides a framework for programmable
> > counters to leverage the extension. As the extension doesn't have any
> > provision for the overflow bit for fixed counters, the fixed events
> > can also be monitoring using programmable counters. The underlying
> > counters for cycle and instruction counters are always running. Thus,
> > a separate timer device is programmed to handle the overflow.
> >
> > Tested-by: Heiko Stuebner 
> > Signed-off-by: Atish Patra 
> > Signed-off-by: Atish Patra 
> > ---
> >  target/riscv/cpu.c  |  11 ++
> >  target/riscv/cpu.h  |  25 +++
> >  target/riscv/cpu_bits.h |  55 +++
> >  target/riscv/csr.c  | 166 ++-
> >  target/riscv/machine.c  |   1 +
> >  target/riscv/pmu.c  | 357 +++-
> >  target/riscv/pmu.h  |   7 +
> >  7 files changed, 611 insertions(+), 11 deletions(-)
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 1bb3973806d2..c1d62b81a725 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -22,6 +22,7 @@
> >  #include "qemu/ctype.h"
> >  #include "qemu/log.h"
> >  #include "cpu.h"
> > +#include "pmu.h"
> >  #include "internals.h"
> >  #include "exec/exec-all.h"
> >  #include "qapi/error.h"
> > @@ -779,6 +780,15 @@ static void riscv_cpu_realize(DeviceState *dev,
> Error **errp)
> >  set_misa(env, env->misa_mxl, ext);
> >  }
> >
> > +#ifndef CONFIG_USER_ONLY
> > +if (cpu->cfg.pmu_num) {
> > +if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) &&
> cpu->cfg.ext_sscofpmf) {
> > +cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> > +  riscv_pmu_timer_cb, cpu);
> > +}
> > + }
> > +#endif
> > +
> >  riscv_cpu_register_gdb_regs_for_features(cs);
> >
> >  qemu_init_vcpu(cs);
> > @@ -883,6 +893,7 @@ static Property riscv_cpu_extensions[] = {
> >  DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
> >  DEFINE_PROP_BOOL("h", RISCVCPU, cfg.ext_h, true),
> >  DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
> > +DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
> >  DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
> >  DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
> >  DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 5c7acc055ac9..db193c3d 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -137,6 +137,8 @@ typedef struct PMUCTRState {
> >  /* Snapshort value of a counter in RV32 */
> >  target_ulong mhpmcounterh_prev;
> >  bool started;
> > +/* Value beyond UINT32_MAX/UINT64_MAX before overflow interrupt
> trigger */
> > +target_ulong irq_overflow_left;
> >  } PMUCTRState;
> >
> >  struct CPUArchState {
> > @@ -297,6 +299,9 @@ struct CPUArchState {
> >  /* PMU event selector configured values. First three are unused*/
> >  target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
> >
> > +/* PMU event selector configured values for RV32*/
> > +target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
> > +
> >  target_ulong sscratch;
> >  target_ulong mscratch;
> >
> > @@ -433,6 +438,7 @@ struct RISCVCPUConfig {
> >  bool ext_zve32f;
> >  bool ext_zve64f;
> >  bool ext_zmmul;
> > +bool ext_sscofpmf;
> >  bool rvv_ta_all_1s;
> >
> >  uint32_t mvendorid;
> > @@ -479,6 +485,12 @@ struct ArchCPU {
> >
> >  /* Configuration Settings */
> >  RISCVCPUConfig cfg;
> > +
> > +QEMUTimer *pmu_timer;
> > +/* A bitmask of Available programmable counters */
> > +uint32_t pmu_avail_ctrs;
> > +

Re: [PATCH v11 5/6] target/riscv: Update the privilege field for sscofpmf CSRs

2022-07-27 Thread Atish Kumar Patra
On Wed, Jul 27, 2022 at 1:27 AM Weiwei Li  wrote:

>
> 在 2022/7/27 下午2:49, Atish Patra 写道:
> > The sscofpmf extension was ratified as a part of priv spec v1.12.
> > Mark the csr_ops accordingly.
> >
> > Reviewed-by: Alistair Francis 
> > Signed-off-by: Atish Patra 
> > ---
> >   target/riscv/csr.c | 90 ++
> >   1 file changed, 60 insertions(+), 30 deletions(-)
> >
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index 57dbbf9b09a0..ec6d7f022ad5 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -3859,63 +3859,92 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
> >  write_mhpmevent
> },
> >
> >   [CSR_MHPMEVENT3H]= { "mhpmevent3h",sscofpmf,
> read_mhpmeventh,
> > -
>  write_mhpmeventh},
> > +
> write_mhpmeventh,
> > + .min_priv_ver =
> PRIV_VERSION_1_12_0 },
>
> Similar to the first commit, it's better to align with the first element
> "mhpmevent3h" .Otherwise,
>
>
Fixed it. Thanks for the review.


> Reviewed-by: Weiwei Li 
>
> Regards,
>
> Weiwei Li
>
> >   [CSR_MHPMEVENT4H]= { "mhpmevent4h",sscofpmf,
> read_mhpmeventh,
> > -
>  write_mhpmeventh},
> > +
> write_mhpmeventh,
> > + .min_priv_ver =
> PRIV_VERSION_1_12_0 },
> >   [CSR_MHPMEVENT5H]= { "mhpmevent5h",sscofpmf,
> read_mhpmeventh,
> > -
>  write_mhpmeventh},
> > +
> write_mhpmeventh,
> > + .min_priv_ver =
> PRIV_VERSION_1_12_0 },
> >   [CSR_MHPMEVENT6H]= { "mhpmevent6h",sscofpmf,
> read_mhpmeventh,
> > -
>  write_mhpmeventh},
> > +
> write_mhpmeventh,
> > + .min_priv_ver =
> PRIV_VERSION_1_12_0 },
> >   [CSR_MHPMEVENT7H]= { "mhpmevent7h",sscofpmf,
> read_mhpmeventh,
> > -
>  write_mhpmeventh},
> > +
> write_mhpmeventh,
> > + .min_priv_ver =
> PRIV_VERSION_1_12_0 },
> >   [CSR_MHPMEVENT8H]= { "mhpmevent8h",sscofpmf,
> read_mhpmeventh,
> > -
>  write_mhpmeventh},
> > +
> write_mhpmeventh,
> > + .min_priv_ver =
> PRIV_VERSION_1_12_0 },
> >   [CSR_MHPMEVENT9H]= { "mhpmevent9h",sscofpmf,
> read_mhpmeventh,
> > -
>  write_mhpmeventh},
> > +
> write_mhpmeventh,
> > + .min_priv_ver =
> PRIV_VERSION_1_12_0 },
> >   [CSR_MHPMEVENT10H]   = { "mhpmevent10h",sscofpmf,
> read_mhpmeventh,
> > -
>  write_mhpmeventh},
> > +
>  write_mhpmeventh,
> > + .min_priv_ver =
> PRIV_VERSION_1_12_0 },
> >   [CSR_MHPMEVENT11H]   = { "mhpmevent11h",sscofpmf,
> read_mhpmeventh,
> > -
>  write_mhpmeventh},
> > +
>  write_mhpmeventh,
> > + .min_priv_ver =
> PRIV_VERSION_1_12_0 },
> >   [CSR_MHPMEVENT12H]   = { "mhpmevent12h",sscofpmf,
> read_mhpmeventh,
> > -
>  write_mhpmeventh},
> > +
>  write_mhpmeventh,
> > + .min_priv_ver =
> PRIV_VERSION_1_12_0 },
> >   [CSR_MHPMEVENT13H]   = { "mhpmevent13h",sscofpmf,
> read_mhpmeventh,
> > -
>  write_mhpmeventh},
> > +
>  write_mhpmeventh,
> > + .min_priv_ver =
> PRIV_VERSION_1_12_0 },
> >   [CSR_MHPMEVENT14H]   = { "mhpmevent14h",sscofpmf,
> read_mhpmeventh,
> > -
>  write_mhpmeventh},
> > +
>  write_mhpmeventh,
> > + .min_priv_ver =
> PRIV_VERSION_1_12_0 },
> >   [CSR_MHPMEVENT15H]   = { "mhpmevent15h",sscofpmf,
> read_mhpmeventh,
> > -
>  write_mhpmeventh},
> > +
>  write_mhpmeventh,
> > + .min_priv_ver =
> PRIV_VERSION_1_12_0 },
> >   [CSR_MHPMEVENT16H]   = { "mhpmevent16h",sscofpmf,
> read_mhpmeventh,
> > -
>  write_mhpmeventh},
> > +
>  write_mhpmeventh,
> > + .min_priv_ver =
> PRIV_VERSION_1_12_0 },
> >   [CSR_MHPMEVENT17H]   = { "mhpmevent17h",sscofpmf,
> read_mhpmeventh,
> > -
>  write_mhpmeventh},
> > +
>  write_mhpmeventh,
> > + .min_priv_ver =
> PRIV_VERSION_1_12_0 },
> >   [CSR_MHPMEVENT18H]   = { "mhpmevent18h",sscofpmf,
> read_mhpmeventh,
> > -
>  write_mhpmeventh},
> > +
>  write_mhpmeventh,
> > + .min_priv_ver =
> PRIV_VERSION_1_12_0 },
> >   [CSR_MHPMEVENT19H]   = { "mhpmevent19h",sscofpmf,
> read_mhpmeventh,
> > -
>  write_mhpmeventh},
> > +
>  write_mhpmeventh,
> > + .min_priv_ver =
> PRIV_VERSION_1_12_0 },
> >   [CSR_MHPMEVENT20H]   = { "mhpmevent20h",sscofpmf,
> read_mhpmeventh,
> > -
>  write_mhpmeventh},
> > +
>  write_mhpmeventh,
> > + .min_priv_ver =
> PRIV_VERSION_1_12_0 },
> >   [CSR_MHPMEVENT21H]   

Re: [PATCH v11 2/6] target/riscv: Simplify counter predicate function

2022-07-27 Thread Atish Kumar Patra
On Wed, Jul 27, 2022 at 1:35 AM Weiwei Li  wrote:

>
> 在 2022/7/27 下午2:49, Atish Patra 写道:
> > All the hpmcounters and the fixed counters (CY, IR, TM) can be
> represented
> > as a unified counter. Thus, the predicate function doesn't need handle
> each
> > case separately.
> >
> > Simplify the predicate function so that we just handle things differently
> > between RV32/RV64 and S/HS mode.
> >
> > Reviewed-by: Bin Meng 
> > Acked-by: Alistair Francis 
> > Signed-off-by: Atish Patra 
> > ---
> >   target/riscv/csr.c | 112 +
> >   1 file changed, 11 insertions(+), 101 deletions(-)
> >
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index 1233bfa0a726..57dbbf9b09a0 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -74,6 +74,7 @@ static RISCVException ctr(CPURISCVState *env, int
> csrno)
> >   CPUState *cs = env_cpu(env);
> >   RISCVCPU *cpu = RISCV_CPU(cs);
> >   int ctr_index;
> > +target_ulong ctr_mask;
> >   int base_csrno = CSR_CYCLE;
> >   bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
> >
> > @@ -82,122 +83,31 @@ static RISCVException ctr(CPURISCVState *env, int
> csrno)
> >   base_csrno += 0x80;
> >   }
> >   ctr_index = csrno - base_csrno;
> > +ctr_mask = BIT(ctr_index);
> >
> >   if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
> >   (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
> >   goto skip_ext_pmu_check;
> >   }
> >
> > -if ((!cpu->cfg.pmu_num || !(cpu->pmu_avail_ctrs & BIT(ctr_index
> {
> > +if (!(cpu->pmu_avail_ctrs & ctr_mask)) {
> >   /* No counter is enabled in PMU or the counter is out of range
> */
> >   return RISCV_EXCP_ILLEGAL_INST;
> >   }
> >
> >   skip_ext_pmu_check:
> >
> > -if (env->priv == PRV_S) {
> > -switch (csrno) {
> > -case CSR_CYCLE:
> > -if (!get_field(env->mcounteren, COUNTEREN_CY)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -case CSR_TIME:
> > -if (!get_field(env->mcounteren, COUNTEREN_TM)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -case CSR_INSTRET:
> > -if (!get_field(env->mcounteren, COUNTEREN_IR)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
> > -if (!get_field(env->mcounteren, 1 << ctr_index)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -}
> > -if (rv32) {
> > -switch (csrno) {
> > -case CSR_CYCLEH:
> > -if (!get_field(env->mcounteren, COUNTEREN_CY)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -case CSR_TIMEH:
> > -if (!get_field(env->mcounteren, COUNTEREN_TM)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -case CSR_INSTRETH:
> > -if (!get_field(env->mcounteren, COUNTEREN_IR)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
> > -if (!get_field(env->mcounteren, 1 << ctr_index)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -}
> > -}
> > +if (((env->priv == PRV_S) && (!get_field(env->mcounteren,
> ctr_mask))) ||
> > +   ((env->priv == PRV_U) && (!get_field(env->scounteren,
> ctr_mask {
> > +return RISCV_EXCP_ILLEGAL_INST;
> >   }
> >
> >   if (riscv_cpu_virt_enabled(env)) {
> > -switch (csrno) {
> > -case CSR_CYCLE:
> > -if (!get_field(env->hcounteren, COUNTEREN_CY) &&
> > -get_field(env->mcounteren, COUNTEREN_CY)) {
> > -return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -}
> > -break;
> > -case CSR_TIME:
> > -if (!get_field(env->hcounteren, COUNTEREN_TM) &&
> > -get_field(env->mcounteren, COUNTEREN_TM)) {
> > -return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -}
> > -break;
> > -case CSR_INSTRET:
> > -if (!get_field(env->hcounteren, COUNTEREN_IR) &&
> > -get_field(env->mcounteren, COUNTEREN_IR)) {
> > -return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -}
> > -break;
> > -case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
> > -if (!get_field(env->hcounteren, 1 << ctr_index) &&
> > - get_field(env->mcounteren, 1 << ctr_index)) {
> > -return 

Re: [PATCH v11 1/6] target/riscv: Add sscofpmf extension support

2022-07-27 Thread Atish Kumar Patra
On Wed, Jul 27, 2022 at 1:11 AM Weiwei Li  wrote:

>
> 在 2022/7/27 下午2:49, Atish Patra 写道:
> > The Sscofpmf ('Ss' for Privileged arch and Supervisor-level extensions,
> > and 'cofpmf' for Count OverFlow and Privilege Mode Filtering)
> > extension allows the perf to handle overflow interrupts and filtering
> > support. This patch provides a framework for programmable
> > counters to leverage the extension. As the extension doesn't have any
> > provision for the overflow bit for fixed counters, the fixed events
> > can also be monitoring using programmable counters. The underlying
> > counters for cycle and instruction counters are always running. Thus,
> > a separate timer device is programmed to handle the overflow.
> >
> > Tested-by: Heiko Stuebner 
> > Signed-off-by: Atish Patra 
> > Signed-off-by: Atish Patra 
> > ---
> >   target/riscv/cpu.c  |  11 ++
> >   target/riscv/cpu.h  |  25 +++
> >   target/riscv/cpu_bits.h |  55 +++
> >   target/riscv/csr.c  | 166 ++-
> >   target/riscv/machine.c  |   1 +
> >   target/riscv/pmu.c  | 357 +++-
> >   target/riscv/pmu.h  |   7 +
> >   7 files changed, 611 insertions(+), 11 deletions(-)
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 1bb3973806d2..c1d62b81a725 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -22,6 +22,7 @@
> >   #include "qemu/ctype.h"
> >   #include "qemu/log.h"
> >   #include "cpu.h"
> > +#include "pmu.h"
> >   #include "internals.h"
> >   #include "exec/exec-all.h"
> >   #include "qapi/error.h"
> > @@ -779,6 +780,15 @@ static void riscv_cpu_realize(DeviceState *dev,
> Error **errp)
> >   set_misa(env, env->misa_mxl, ext);
> >   }
> >
> > +#ifndef CONFIG_USER_ONLY
> > +if (cpu->cfg.pmu_num) {
> > +if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) &&
> cpu->cfg.ext_sscofpmf) {
> > +cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> > +  riscv_pmu_timer_cb, cpu);
> > +}
> > + }
> > +#endif
> > +
> >   riscv_cpu_register_gdb_regs_for_features(cs);
> >
> >   qemu_init_vcpu(cs);
> > @@ -883,6 +893,7 @@ static Property riscv_cpu_extensions[] = {
> >   DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
> >   DEFINE_PROP_BOOL("h", RISCVCPU, cfg.ext_h, true),
> >   DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
> > +DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
> >   DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
> >   DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
> >   DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 5c7acc055ac9..db193c3d 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -137,6 +137,8 @@ typedef struct PMUCTRState {
> >   /* Snapshort value of a counter in RV32 */
> >   target_ulong mhpmcounterh_prev;
> >   bool started;
> > +/* Value beyond UINT32_MAX/UINT64_MAX before overflow interrupt
> trigger */
> > +target_ulong irq_overflow_left;
> >   } PMUCTRState;
> >
> >   struct CPUArchState {
> > @@ -297,6 +299,9 @@ struct CPUArchState {
> >   /* PMU event selector configured values. First three are unused*/
> >   target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
> >
> > +/* PMU event selector configured values for RV32*/
> > +target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
> > +
> >   target_ulong sscratch;
> >   target_ulong mscratch;
> >
> > @@ -433,6 +438,7 @@ struct RISCVCPUConfig {
> >   bool ext_zve32f;
> >   bool ext_zve64f;
> >   bool ext_zmmul;
> > +bool ext_sscofpmf;
> >   bool rvv_ta_all_1s;
> >
> >   uint32_t mvendorid;
> > @@ -479,6 +485,12 @@ struct ArchCPU {
> >
> >   /* Configuration Settings */
> >   RISCVCPUConfig cfg;
> > +
> > +QEMUTimer *pmu_timer;
> > +/* A bitmask of Available programmable counters */
> > +uint32_t pmu_avail_ctrs;
> > +/* Mapping of events to counters */
> > +GHashTable *pmu_event_ctr_map;
> >   };
> >
> >   static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
> > @@ -738,6 +750,19 @@ enum {
> >   CSR_TABLE_SIZE = 0x1000
> >   };
> >
> > +/**
> > + * The event id are encoded based on the encoding specified in the
> > + * SBI specification v0.3
> > + */
> > +
> > +enum riscv_pmu_event_idx {
> > +RISCV_PMU_EVENT_HW_CPU_CYCLES = 0x01,
> > +RISCV_PMU_EVENT_HW_INSTRUCTIONS = 0x02,
> > +RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS = 0x10019,
> > +RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS = 0x1001B,
> > +RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS = 0x10021,
> > +};
> > +
> >   /* CSR function table */
> >   extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
> >
> > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> > index 6be5a9e9f046..b63c586be563 100644
> > --- 

Re: [PATCH] hw/intc: sifive_plic: Fix multi-socket plic configuraiton

2022-07-27 Thread Atish Kumar Patra
On Wed, Jul 27, 2022 at 5:23 AM Alistair Francis 
wrote:

> On Sat, Jul 23, 2022 at 7:22 PM Atish Patra  wrote:
> >
> > Since commit 40244040a7ac, multi-socket configuration with plic is
> > broken as the hartid for second socket is calculated incorrectly.
> > The hartid stored in addr_config already includes the offset
> > for the base hartid for that socket. Adding it again would lead
> > to segfault while creating the plic device for the virt machine.
> > qdev_connect_gpio_out was also invoked with incorrect number of gpio
> > lines.
> >
> > Fixes: 40244040a7ac (hw/intc: sifive_plic: Avoid overflowing the
> addr_config buffer)
> >
> > Signed-off-by: Atish Patra 
> > ---
> >  hw/intc/sifive_plic.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
> > index 56d60e9ac935..fdac028a521f 100644
> > --- a/hw/intc/sifive_plic.c
> > +++ b/hw/intc/sifive_plic.c
> > @@ -454,10 +454,10 @@ DeviceState *sifive_plic_create(hwaddr addr, char
> *hart_config,
> >
> >  for (i = 0; i < plic->num_addrs; i++) {
> >  int cpu_num = plic->addr_config[i].hartid;
> > -CPUState *cpu = qemu_get_cpu(hartid_base + cpu_num);
> > +CPUState *cpu = qemu_get_cpu(cpu_num);
> >
> >  if (plic->addr_config[i].mode == PLICMode_M) {
> > -qdev_connect_gpio_out(dev, num_harts + cpu_num,
> > +qdev_connect_gpio_out(dev, cpu_num,
>
> Argh!
>
> I was trying to get this ready to go into 7.1. I have been working on
> updating my tests to catch this failure in the future as well.
>
> While testing this change I noticed that it breaks the noMMU test case.
>
> I think the correct fix is actually this (on top of your patch):
>
> diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
> index fdac028a52..af4ae3630e 100644
> --- a/hw/intc/sifive_plic.c
> +++ b/hw/intc/sifive_plic.c
> @@ -457,7 +457,7 @@ DeviceState *sifive_plic_create(hwaddr addr, char
> *hart_config,
> CPUState *cpu = qemu_get_cpu(cpu_num);
>
> if (plic->addr_config[i].mode == PLICMode_M) {
> -qdev_connect_gpio_out(dev, cpu_num,
> +qdev_connect_gpio_out(dev, num_harts - plic->hartid_base +
> cpu_num,
>   qdev_get_gpio_in(DEVICE(cpu),
> IRQ_M_EXT));
> }
> if (plic->addr_config[i].mode == PLICMode_S) {
>
> The idea is that we need to increment the second argument to
> qdev_connect_gpio_out() for the PLICMode_M compared to the PLICMode_S
> case.
>
> This ensures that we do that correctly without breaking anything.
>
> How does that look to you?
>
>
Ahh yes. That makes sense.
Tested the updated change on multi-socket as well.


> Alistair
>
> >qdev_get_gpio_in(DEVICE(cpu),
> IRQ_M_EXT));
> >  }
> >  if (plic->addr_config[i].mode == PLICMode_S) {
> > --
> > 2.25.1
> >
> >
>


Re: [PATCH v11 4/6] hw/riscv: virt: Add PMU DT node to the device tree

2022-07-27 Thread Atish Kumar Patra
On Wed, Jul 27, 2022 at 12:27 AM Sunil V L  wrote:

> Hi Atish,
>
> On Tue, Jul 26, 2022 at 11:49:11PM -0700, Atish Patra wrote:
> > Qemu virt machine can support few cache events and cycle/instret
> counters.
> > It also supports counter overflow for these events.
> >
> > Add a DT node so that OpenSBI/Linux kernel is aware of the virt machine
> > capabilities. There are some dummy nodes added for testing as well.
> >
> > Acked-by: Alistair Francis 
> > Signed-off-by: Atish Patra 
> > Signed-off-by: Atish Patra 
> > ---
> >  hw/riscv/virt.c| 28 +++
> >  target/riscv/cpu.c |  1 +
> >  target/riscv/pmu.c | 57 ++
> >  target/riscv/pmu.h |  1 +
> >  4 files changed, 87 insertions(+)
> >
> > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > index bc424dd2f523..0f3fdb4908b8 100644
> > --- a/hw/riscv/virt.c
> > +++ b/hw/riscv/virt.c
> > @@ -29,6 +29,7 @@
> >  #include "hw/char/serial.h"
> >  #include "target/riscv/cpu.h"
> >  #include "hw/core/sysbus-fdt.h"
> > +#include "target/riscv/pmu.h"
> >  #include "hw/riscv/riscv_hart.h"
> >  #include "hw/riscv/virt.h"
> >  #include "hw/riscv/boot.h"
> > @@ -714,6 +715,32 @@ static void create_fdt_socket_aplic(RISCVVirtState
> *s,
> >  aplic_phandles[socket] = aplic_s_phandle;
> >  }
> >
> > +static void create_fdt_socket_pmu(RISCVVirtState *s,
> > +  int socket, uint32_t *phandle,
> > +  uint32_t *intc_phandles)
> > +{
> > +int cpu;
> > +char *pmu_name;
> > +uint32_t *pmu_cells;
> > +MachineState *mc = MACHINE(s);
> > +RISCVCPU hart = s->soc[socket].harts[0];
> > +
> > +pmu_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
> > +
> > +for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
> > +pmu_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
> > +pmu_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_PMU_OVF);
> > +}
> > +
> > +pmu_name = g_strdup_printf("/soc/pmu");
> > +qemu_fdt_add_subnode(mc->fdt, pmu_name);
>
> Does this work for you when there are more than 1 sockets? Shouldn't
> this be unique name for each socket?
>
>
Ahh. Sorry. I had fixed that when you last commented. But forgot to include
that fix. Will revise it.


> Thanks
> Sunil
>
> > +qemu_fdt_setprop_string(mc->fdt, pmu_name, "compatible",
> "riscv,pmu");
> > +riscv_pmu_generate_fdt_node(mc->fdt, hart.cfg.pmu_num, pmu_name);
> > +
> > +g_free(pmu_name);
> > +g_free(pmu_cells);
> > +}
> > +
> >  static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry
> *memmap,
> > bool is_32_bit, uint32_t *phandle,
> > uint32_t *irq_mmio_phandle,
> > @@ -759,6 +786,7 @@ static void create_fdt_sockets(RISCVVirtState *s,
> const MemMapEntry *memmap,
> >  _phandles[phandle_pos]);
> >  }
> >  }
> > +create_fdt_socket_pmu(s, socket, phandle, intc_phandles);
> >  }
> >
> >  if (s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) {
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index c1d62b81a725..5c8417a56e5b 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -1114,6 +1114,7 @@ static void riscv_isa_string_ext(RISCVCPU *cpu,
> char **isa_str, int max_str_len)
> >  ISA_EDATA_ENTRY(zve64f, ext_zve64f),
> >  ISA_EDATA_ENTRY(zhinx, ext_zhinx),
> >  ISA_EDATA_ENTRY(zhinxmin, ext_zhinxmin),
> > +ISA_EDATA_ENTRY(sscofpmf, ext_sscofpmf),
> >  ISA_EDATA_ENTRY(svinval, ext_svinval),
> >  ISA_EDATA_ENTRY(svnapot, ext_svnapot),
> >  ISA_EDATA_ENTRY(svpbmt, ext_svpbmt),
> > diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
> > index 34096941c0ce..59feb3c243dd 100644
> > --- a/target/riscv/pmu.c
> > +++ b/target/riscv/pmu.c
> > @@ -20,11 +20,68 @@
> >  #include "cpu.h"
> >  #include "pmu.h"
> >  #include "sysemu/cpu-timers.h"
> > +#include "sysemu/device_tree.h"
> >
> >  #define RISCV_TIMEBASE_FREQ 10 /* 1Ghz */
> >  #define MAKE_32BIT_MASK(shift, length) \
> >  (((uint32_t)(~0UL) >> (32 - (length))) << (shift))
> >
> > +/**
> > + * To keep it simple, any event can be mapped to any programmable
> counters in
> > + * QEMU. The generic cycle & instruction count events can also be
> monitored
> > + * using programmable counters. In that case, mcycle & minstret must
> continue
> > + * to provide the correct value as well. Heterogeneous PMU per hart is
> not
> > + * supported yet. Thus, number of counters are same across all harts.
> > + */
> > +void riscv_pmu_generate_fdt_node(void *fdt, int num_ctrs, char
> *pmu_name)
> > +{
> > +uint32_t fdt_event_ctr_map[20] = {};
> > +uint32_t cmask;
> > +
> > +/* All the programmable counters can map to any event */
> > +cmask = MAKE_32BIT_MASK(3, num_ctrs);
> > +
> > +   /**
> > +* The event encoding is specified in the SBI specification
> > +* 

Re: [PATCH] hw/intc: sifive_plic: Fix multi-socket plic configuraiton

2022-07-25 Thread Atish Kumar Patra
On Sun, Jul 24, 2022 at 6:14 PM Alistair Francis 
wrote:

> On Sat, Jul 23, 2022 at 7:22 PM Atish Patra  wrote:
> >
> > Since commit 40244040a7ac, multi-socket configuration with plic is
> > broken as the hartid for second socket is calculated incorrectly.
> > The hartid stored in addr_config already includes the offset
> > for the base hartid for that socket. Adding it again would lead
> > to segfault while creating the plic device for the virt machine.
> > qdev_connect_gpio_out was also invoked with incorrect number of gpio
> > lines.
> >
> > Fixes: 40244040a7ac (hw/intc: sifive_plic: Avoid overflowing the
> addr_config buffer)
> >
> > Signed-off-by: Atish Patra 
>
> Can you share the -cpu options that causes the segfault? I'll add it
> to my test case
>
>
"-cpu rv64 -M virt -m 2G -smp 4 -object
memory-backend-ram,size=1G,policy=bind,host-nodes=0,id=ram-node0  \
-numa node,memdev=ram-node0   \
-object memory-backend-ram,size=1G,policy=bind,host-nodes=0,id=ram-node1 \
-numa node,memdev=ram-node1"

You also need to enable  CONFIG_NUMA in kernel.

Reviewed-by: Alistair Francis 
>
> Alistair
>
> > ---
> >  hw/intc/sifive_plic.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> > diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
> > index 56d60e9ac935..fdac028a521f 100644
> > --- a/hw/intc/sifive_plic.c
> > +++ b/hw/intc/sifive_plic.c
> > @@ -454,10 +454,10 @@ DeviceState *sifive_plic_create(hwaddr addr, char
> *hart_config,
> >
> >  for (i = 0; i < plic->num_addrs; i++) {
> >  int cpu_num = plic->addr_config[i].hartid;
> > -CPUState *cpu = qemu_get_cpu(hartid_base + cpu_num);
> > +CPUState *cpu = qemu_get_cpu(cpu_num);
> >
> >  if (plic->addr_config[i].mode == PLICMode_M) {
> > -qdev_connect_gpio_out(dev, num_harts + cpu_num,
> > +qdev_connect_gpio_out(dev, cpu_num,
> >qdev_get_gpio_in(DEVICE(cpu),
> IRQ_M_EXT));
> >  }
> >  if (plic->addr_config[i].mode == PLICMode_S) {
> > --
> > 2.25.1
> >
> >
>


Re: [PATCH v10 09/12] target/riscv: Simplify counter predicate function

2022-07-05 Thread Atish Kumar Patra
On Mon, Jul 4, 2022 at 8:19 AM Weiwei Li  wrote:
>
>
> 在 2022/6/21 上午7:15, Atish Patra 写道:
>
> All the hpmcounters and the fixed counters (CY, IR, TM) can be represented
> as a unified counter. Thus, the predicate function doesn't need handle each
> case separately.
>
> Simplify the predicate function so that we just handle things differently
> between RV32/RV64 and S/HS mode.
>
> Reviewed-by: Bin Meng 
> Acked-by: Alistair Francis 
> Signed-off-by: Atish Patra 
> ---
>  target/riscv/csr.c | 112 +
>  1 file changed, 11 insertions(+), 101 deletions(-)
>
> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> index 2664ce265784..9367e2af9b90 100644
> --- a/target/riscv/csr.c
> +++ b/target/riscv/csr.c
> @@ -74,6 +74,7 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
>  CPUState *cs = env_cpu(env);
>  RISCVCPU *cpu = RISCV_CPU(cs);
>  int ctr_index;
> +target_ulong ctr_mask;
>  int base_csrno = CSR_CYCLE;
>  bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
>
> @@ -82,122 +83,31 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
>  base_csrno += 0x80;
>  }
>  ctr_index = csrno - base_csrno;
> +ctr_mask = BIT(ctr_index);
>
>  if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
>  (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
>  goto skip_ext_pmu_check;
>  }
>
> -if ((!cpu->cfg.pmu_num || !(cpu->pmu_avail_ctrs & BIT(ctr_index {
> +if ((!cpu->cfg.pmu_num || !(cpu->pmu_avail_ctrs & ctr_mask))) {
>  /* No counter is enabled in PMU or the counter is out of range */
>  return RISCV_EXCP_ILLEGAL_INST;
>  }
>
>  skip_ext_pmu_check:
>
> -if (env->priv == PRV_S) {
> -switch (csrno) {
> -case CSR_CYCLE:
> -if (!get_field(env->mcounteren, COUNTEREN_CY)) {
> -return RISCV_EXCP_ILLEGAL_INST;
> -}
> -break;
> -case CSR_TIME:
> -if (!get_field(env->mcounteren, COUNTEREN_TM)) {
> -return RISCV_EXCP_ILLEGAL_INST;
> -}
> -break;
> -case CSR_INSTRET:
> -if (!get_field(env->mcounteren, COUNTEREN_IR)) {
> -return RISCV_EXCP_ILLEGAL_INST;
> -}
> -break;
> -case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
> -if (!get_field(env->mcounteren, 1 << ctr_index)) {
> -return RISCV_EXCP_ILLEGAL_INST;
> -}
> -break;
> -}
> -if (rv32) {
> -switch (csrno) {
> -case CSR_CYCLEH:
> -if (!get_field(env->mcounteren, COUNTEREN_CY)) {
> -return RISCV_EXCP_ILLEGAL_INST;
> -}
> -break;
> -case CSR_TIMEH:
> -if (!get_field(env->mcounteren, COUNTEREN_TM)) {
> -return RISCV_EXCP_ILLEGAL_INST;
> -}
> -break;
> -case CSR_INSTRETH:
> -if (!get_field(env->mcounteren, COUNTEREN_IR)) {
> -return RISCV_EXCP_ILLEGAL_INST;
> -}
> -break;
> -case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
> -if (!get_field(env->mcounteren, 1 << ctr_index)) {
> -return RISCV_EXCP_ILLEGAL_INST;
> -}
> -break;
> -}
> -}
> +if (((env->priv == PRV_S) && (!get_field(env->mcounteren, ctr_mask))) ||
> +   ((env->priv == PRV_U) && (!get_field(env->scounteren, ctr_mask {
> +return RISCV_EXCP_ILLEGAL_INST;
>  }
>
> Sorry. I didn't realize this simplification and sent a similar patch to fix 
> the problems in Xcounteren
>
> related check I found when I tried to learn the patchset for state enable 
> extension two days ago.
>
> I think there are several difference between our understanding, following is 
> my modifications:
>
> +if (csrno <= CSR_HPMCOUNTER31 && csrno >= CSR_CYCLE) {
> +field = 1 << (csrno - CSR_CYCLE);
> +} else if (riscv_cpu_mxl(env) == MXL_RV32 && csrno <= CSR_HPMCOUNTER31H 
> &&
> +   csrno >= CSR_CYCLEH) {
> +field = 1 << (csrno - CSR_CYCLEH);
> +}
> +
> +if (env->priv < PRV_M && !get_field(env->mcounteren, field)) {
> +return RISCV_EXCP_ILLEGAL_INST;
> +}
> +
> +if (riscv_cpu_virt_enabled(env) && !get_field(env->hcounteren, field)) {
> +return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> +}
> +
> +if (riscv_has_ext(env, RVS) && env->priv == PRV_U &&
> +!get_field(env->scounteren, field)) {
> +if (riscv_cpu_virt_enabled(env)) {
> +return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> +} else {
> +return RISCV_EXCP_ILLEGAL_INST;
>  }
>  }
>
>
> 1) For any less-privileged mode under M, illegal exception is raised if 
> matching
> bit in mcounteren is zero.
>

As per 

Re: [PATCH v10 04/12] target/riscv: pmu: Make number of counters configurable

2022-07-05 Thread Atish Kumar Patra
On Mon, Jul 4, 2022 at 5:38 PM Weiwei Li  wrote:
>
>
> 在 2022/7/4 下午11:26, Weiwei Li 写道:
> >
> > 在 2022/6/21 上午7:15, Atish Patra 写道:
> >> The RISC-V privilege specification provides flexibility to implement
> >> any number of counters from 29 programmable counters. However, the QEMU
> >> implements all the counters.
> >>
> >> Make it configurable through pmu config parameter which now will
> >> indicate
> >> how many programmable counters should be implemented by the cpu.
> >>
> >> Reviewed-by: Bin Meng 
> >> Reviewed-by: Alistair Francis 
> >> Signed-off-by: Atish Patra 
> >> Signed-off-by: Atish Patra 
> >> ---
> >>   target/riscv/cpu.c |  3 +-
> >>   target/riscv/cpu.h |  2 +-
> >>   target/riscv/csr.c | 94 ++
> >>   3 files changed, 63 insertions(+), 36 deletions(-)
> >>
> >> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> >> index 1b57b3c43980..d12c6dc630ca 100644
> >> --- a/target/riscv/cpu.c
> >> +++ b/target/riscv/cpu.c
> >> @@ -851,7 +851,6 @@ static void riscv_cpu_init(Object *obj)
> >>   {
> >>   RISCVCPU *cpu = RISCV_CPU(obj);
> >>   -cpu->cfg.ext_pmu = true;
> >>   cpu->cfg.ext_ifencei = true;
> >>   cpu->cfg.ext_icsr = true;
> >>   cpu->cfg.mmu = true;
> >> @@ -879,7 +878,7 @@ static Property riscv_cpu_extensions[] = {
> >>   DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
> >>   DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
> >>   DEFINE_PROP_BOOL("h", RISCVCPU, cfg.ext_h, true),
> >> -DEFINE_PROP_BOOL("pmu", RISCVCPU, cfg.ext_pmu, true),
> >> +DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
> >
> > I think It's better to add  a check on cfg.pmu_num to  <= 29.
> >
> OK, I find this check in the following patch.
> >>   DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
> >>   DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
> >>   DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
> >> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> >> index 252c30a55d78..ffee54ea5c27 100644
> >> --- a/target/riscv/cpu.h
> >> +++ b/target/riscv/cpu.h
> >> @@ -397,7 +397,6 @@ struct RISCVCPUConfig {
> >>   bool ext_zksed;
> >>   bool ext_zksh;
> >>   bool ext_zkt;
> >> -bool ext_pmu;
> >>   bool ext_ifencei;
> >>   bool ext_icsr;
> >>   bool ext_svinval;
> >> @@ -421,6 +420,7 @@ struct RISCVCPUConfig {
> >>   /* Vendor-specific custom extensions */
> >>   bool ext_XVentanaCondOps;
> >>   +uint8_t pmu_num;
> >>   char *priv_spec;
> >>   char *user_spec;
> >>   char *bext_spec;
> >> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> >> index 0ca05c77883c..b4a8e15f498f 100644
> >> --- a/target/riscv/csr.c
> >> +++ b/target/riscv/csr.c
> >> @@ -73,9 +73,17 @@ static RISCVException ctr(CPURISCVState *env, int
> >> csrno)
> >>   CPUState *cs = env_cpu(env);
> >>   RISCVCPU *cpu = RISCV_CPU(cs);
> >>   int ctr_index;
> >> +int base_csrno = CSR_HPMCOUNTER3;
> >> +bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
> >>   -if (!cpu->cfg.ext_pmu) {
> >> -/* The PMU extension is not enabled */
> >> +if (rv32 && csrno >= CSR_CYCLEH) {
> >> +/* Offset for RV32 hpmcounternh counters */
> >> +base_csrno += 0x80;
> >> +}
> >> +ctr_index = csrno - base_csrno;
> >> +
> >> +if (!cpu->cfg.pmu_num || ctr_index >= (cpu->cfg.pmu_num)) {
> >> +/* No counter is enabled in PMU or the counter is out of
> >> range */
> >
> > I seems unnecessary to add '!cpu->cfg.pmu_num ' here, 'ctr_index >=
> > (cpu->cfg.pmu_num)' is true

The check is improved in the following patches as well.

> Typo.  I -> It
> >
> > when cpu->cfg.pmu_num is zero if the problem for base_csrno is fixed.
> >
> > Ragards,
> >
> > Weiwei Li
> >
> >>   return RISCV_EXCP_ILLEGAL_INST;
> >>   }
> >>   @@ -103,7 +111,7 @@ static RISCVException ctr(CPURISCVState *env,
> >> int csrno)
> >>   }
> >>   break;
> >>   }
> >> -if (riscv_cpu_mxl(env) == MXL_RV32) {
> >> +if (rv32) {
> >>   switch (csrno) {
> >>   case CSR_CYCLEH:
> >>   if (!get_field(env->mcounteren, COUNTEREN_CY)) {
> >> @@ -158,7 +166,7 @@ static RISCVException ctr(CPURISCVState *env, int
> >> csrno)
> >>   }
> >>   break;
> >>   }
> >> -if (riscv_cpu_mxl(env) == MXL_RV32) {
> >> +if (rv32) {
> >>   switch (csrno) {
> >>   case CSR_CYCLEH:
> >>   if (!get_field(env->hcounteren, COUNTEREN_CY) &&
> >> @@ -202,6 +210,26 @@ static RISCVException ctr32(CPURISCVState *env,
> >> int csrno)
> >>   }
> >> #if !defined(CONFIG_USER_ONLY)
> >> +static RISCVException mctr(CPURISCVState *env, int csrno)
> >> +{
> >> +CPUState *cs = env_cpu(env);
> >> +RISCVCPU *cpu = RISCV_CPU(cs);
> >> +int ctr_index;
> >> +int base_csrno = CSR_MHPMCOUNTER3;

Re: [PATCH v10 05/12] target/riscv: Implement mcountinhibit CSR

2022-07-05 Thread Atish Kumar Patra
On Mon, Jul 4, 2022 at 8:31 AM Weiwei Li  wrote:
>
>
> 在 2022/6/21 上午7:15, Atish Patra 写道:
> > From: Atish Patra 
> >
> > As per the privilege specification v1.11, mcountinhibit allows to start/stop
> > a pmu counter selectively.
> >
> > Reviewed-by: Bin Meng 
> > Reviewed-by: Alistair Francis 
> > Signed-off-by: Atish Patra 
> > Signed-off-by: Atish Patra 
> > ---
> >   target/riscv/cpu.h  |  2 ++
> >   target/riscv/cpu_bits.h |  4 
> >   target/riscv/csr.c  | 25 +
> >   target/riscv/machine.c  |  1 +
> >   4 files changed, 32 insertions(+)
> >
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index ffee54ea5c27..0a916db9f614 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -275,6 +275,8 @@ struct CPUArchState {
> >   target_ulong scounteren;
> >   target_ulong mcounteren;
> >
> > +target_ulong mcountinhibit;
> > +
> >   target_ulong sscratch;
> >   target_ulong mscratch;
> >
> > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> > index 4d04b20d064e..b3f7fa713000 100644
> > --- a/target/riscv/cpu_bits.h
> > +++ b/target/riscv/cpu_bits.h
> > @@ -367,6 +367,10 @@
> >   #define CSR_MHPMCOUNTER29   0xb1d
> >   #define CSR_MHPMCOUNTER30   0xb1e
> >   #define CSR_MHPMCOUNTER31   0xb1f
> > +
> > +/* Machine counter-inhibit register */
> > +#define CSR_MCOUNTINHIBIT   0x320
> > +
> >   #define CSR_MHPMEVENT3  0x323
> >   #define CSR_MHPMEVENT4  0x324
> >   #define CSR_MHPMEVENT5  0x325
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index b4a8e15f498f..94d39a4ce1c5 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -1475,6 +1475,28 @@ static RISCVException write_mtvec(CPURISCVState 
> > *env, int csrno,
> >   return RISCV_EXCP_NONE;
> >   }
> >
> > +static RISCVException read_mcountinhibit(CPURISCVState *env, int csrno,
> > + target_ulong *val)
> > +{
> > +if (env->priv_ver < PRIV_VERSION_1_11_0) {
> > +return RISCV_EXCP_ILLEGAL_INST;
> > +}
> > +
>
> This seems can be done by add  .min_priv_ver=PRIV_VERSION_1_11_0 in
> csr_ops table.
>

Yes. This can be dropped from both read/write_mcountihibit with min_priv_ver.
Thanks.

> Regards,
>
> Weiwei Li
>
> > +*val = env->mcountinhibit;
> > +return RISCV_EXCP_NONE;
> > +}
> > +
> > +static RISCVException write_mcountinhibit(CPURISCVState *env, int csrno,
> > +  target_ulong val)
> > +{
> > +if (env->priv_ver < PRIV_VERSION_1_11_0) {
> > +return RISCV_EXCP_ILLEGAL_INST;
> > +}
> > +
> > +env->mcountinhibit = val;
> > +return RISCV_EXCP_NONE;
> > +}
> > +
> >   static RISCVException read_mcounteren(CPURISCVState *env, int csrno,
> > target_ulong *val)
> >   {
> > @@ -3745,6 +3767,9 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
> >   [CSR_MHPMCOUNTER30]  = { "mhpmcounter30",  mctr,   read_zero },
> >   [CSR_MHPMCOUNTER31]  = { "mhpmcounter31",  mctr,   read_zero },
> >
> > +[CSR_MCOUNTINHIBIT]  = { "mcountinhibit",   any,read_mcountinhibit,
> > +   write_mcountinhibit 
> > },
> > +
> >   [CSR_MHPMEVENT3] = { "mhpmevent3", any,read_zero },
> >   [CSR_MHPMEVENT4] = { "mhpmevent4", any,read_zero },
> >   [CSR_MHPMEVENT5] = { "mhpmevent5", any,read_zero },
> > diff --git a/target/riscv/machine.c b/target/riscv/machine.c
> > index 2a437b29a1ce..87cd55bfd3a7 100644
> > --- a/target/riscv/machine.c
> > +++ b/target/riscv/machine.c
> > @@ -330,6 +330,7 @@ const VMStateDescription vmstate_riscv_cpu = {
> >   VMSTATE_UINTTL(env.siselect, RISCVCPU),
> >   VMSTATE_UINTTL(env.scounteren, RISCVCPU),
> >   VMSTATE_UINTTL(env.mcounteren, RISCVCPU),
> > +VMSTATE_UINTTL(env.mcountinhibit, RISCVCPU),
> >   VMSTATE_UINTTL(env.sscratch, RISCVCPU),
> >   VMSTATE_UINTTL(env.mscratch, RISCVCPU),
> >   VMSTATE_UINT64(env.mfromhost, RISCVCPU),
>



Re: [PATCH v10 08/12] target/riscv: Add sscofpmf extension support

2022-07-05 Thread Atish Kumar Patra
On Mon, Jul 4, 2022 at 6:31 PM Weiwei Li  wrote:
>
>
> 在 2022/6/21 上午7:15, Atish Patra 写道:
>
> The Sscofpmf ('Ss' for Privileged arch and Supervisor-level extensions,
> and 'cofpmf' for Count OverFlow and Privilege Mode Filtering)
> extension allows the perf to handle overflow interrupts and filtering
> support. This patch provides a framework for programmable
> counters to leverage the extension. As the extension doesn't have any
> provision for the overflow bit for fixed counters, the fixed events
> can also be monitoring using programmable counters. The underlying
> counters for cycle and instruction counters are always running. Thus,
> a separate timer device is programmed to handle the overflow.
>
> Signed-off-by: Atish Patra 
> Signed-off-by: Atish Patra 
> ---
>  target/riscv/cpu.c  |  11 ++
>  target/riscv/cpu.h  |  25 +++
>  target/riscv/cpu_bits.h |  55 +++
>  target/riscv/csr.c  | 165 ++-
>  target/riscv/machine.c  |   1 +
>  target/riscv/pmu.c  | 357 +++-
>  target/riscv/pmu.h  |   7 +
>  7 files changed, 610 insertions(+), 11 deletions(-)
>
> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> index d12c6dc630ca..7d9e2aca12a9 100644
> --- a/target/riscv/cpu.c
> +++ b/target/riscv/cpu.c
> @@ -22,6 +22,7 @@
>  #include "qemu/ctype.h"
>  #include "qemu/log.h"
>  #include "cpu.h"
> +#include "pmu.h"
>  #include "internals.h"
>  #include "exec/exec-all.h"
>  #include "qapi/error.h"
> @@ -775,6 +776,15 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
> **errp)
>  set_misa(env, env->misa_mxl, ext);
>  }
>
> +#ifndef CONFIG_USER_ONLY
> +if (cpu->cfg.pmu_num) {
> +if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscofpmf) 
> {
> +cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> +  riscv_pmu_timer_cb, cpu);
> +}
> + }
> +#endif
> +
>  riscv_cpu_register_gdb_regs_for_features(cs);
>
>  qemu_init_vcpu(cs);
> @@ -879,6 +889,7 @@ static Property riscv_cpu_extensions[] = {
>  DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
>  DEFINE_PROP_BOOL("h", RISCVCPU, cfg.ext_h, true),
>  DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
> +DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
>  DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
>  DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
>  DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 5c7acc055ac9..db193c3d 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -137,6 +137,8 @@ typedef struct PMUCTRState {
>  /* Snapshort value of a counter in RV32 */
>  target_ulong mhpmcounterh_prev;
>  bool started;
> +/* Value beyond UINT32_MAX/UINT64_MAX before overflow interrupt trigger 
> */
> +target_ulong irq_overflow_left;
>  } PMUCTRState;
>
>  struct CPUArchState {
> @@ -297,6 +299,9 @@ struct CPUArchState {
>  /* PMU event selector configured values. First three are unused*/
>  target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
>
> +/* PMU event selector configured values for RV32*/
> +target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
> +
>  target_ulong sscratch;
>  target_ulong mscratch;
>
> @@ -433,6 +438,7 @@ struct RISCVCPUConfig {
>  bool ext_zve32f;
>  bool ext_zve64f;
>  bool ext_zmmul;
> +bool ext_sscofpmf;
>  bool rvv_ta_all_1s;
>
>  uint32_t mvendorid;
> @@ -479,6 +485,12 @@ struct ArchCPU {
>
>  /* Configuration Settings */
>  RISCVCPUConfig cfg;
> +
> +QEMUTimer *pmu_timer;
> +/* A bitmask of Available programmable counters */
> +uint32_t pmu_avail_ctrs;
> +/* Mapping of events to counters */
> +GHashTable *pmu_event_ctr_map;
>  };
>
>  static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
> @@ -738,6 +750,19 @@ enum {
>  CSR_TABLE_SIZE = 0x1000
>  };
>
> +/**
> + * The event id are encoded based on the encoding specified in the
> + * SBI specification v0.3
> + */
> +
> +enum riscv_pmu_event_idx {
> +RISCV_PMU_EVENT_HW_CPU_CYCLES = 0x01,
> +RISCV_PMU_EVENT_HW_INSTRUCTIONS = 0x02,
> +RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS = 0x10019,
> +RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS = 0x1001B,
> +RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS = 0x10021,
> +};
> +
>  /* CSR function table */
>  extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
>
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index b3f7fa713000..d94abefdaa0f 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -400,6 +400,37 @@
>  #define CSR_MHPMEVENT29 0x33d
>  #define CSR_MHPMEVENT30 0x33e
>  #define CSR_MHPMEVENT31 0x33f
> +
> +#define CSR_MHPMEVENT3H 0x723
> +#define CSR_MHPMEVENT4H 0x724
> +#define CSR_MHPMEVENT5H 0x725
> +#define CSR_MHPMEVENT6H 

Re: [PATCH] hw/riscv: boot: Reduce FDT address alignment constraints

2022-06-22 Thread Atish Kumar Patra
On Wed, Jun 22, 2022 at 9:15 PM Alistair Francis  wrote:
>
> On Wed, Jun 8, 2022 at 4:41 PM Bin Meng  wrote:
> >
> > +Atish
> >
> > On Wed, Jun 8, 2022 at 2:20 PM Alistair Francis
> >  wrote:
> > >
> > > From: Alistair Francis 
> > >
> > > We previously stored the device tree at a 16MB alignment from the end of
> > > memory (or 3GB). This means we need at least 16MB of memory to be able
> > > to do this. We don't actually need the FDT to be 16MB aligned, so let's
> > > drop it down to 2MB so that we can support systems with less memory,
> > > while also allowing FDT size expansion.
> > >
> > > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/992
> > > Signed-off-by: Alistair Francis 
> > > ---
> > >  hw/riscv/boot.c | 4 ++--
> > >  1 file changed, 2 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
> > > index 57a41df8e9..e476d8f491 100644
> > > --- a/hw/riscv/boot.c
> > > +++ b/hw/riscv/boot.c
> > > @@ -226,11 +226,11 @@ uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t 
> > > mem_size, void *fdt)
> > >  /*
> > >   * We should put fdt as far as possible to avoid kernel/initrd 
> > > overwriting
> > >   * its content. But it should be addressable by 32 bit system as 
> > > well.
> > > - * Thus, put it at an 16MB aligned address that less than fdt size 
> > > from the
> > > + * Thus, put it at an 2MB aligned address that less than fdt size 
> > > from the
> > >   * end of dram or 3GB whichever is lesser.
> > >   */
> > >  temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : 
> > > dram_end;
> > > -fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 16 * MiB);
> > > +fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB);
> > >
> >
> > @Atish Patra  may have some pointers about the 16MiB alignment requirement.
>

Sorry. I missed this patch for some reason. 16MiB alignment was just
chosen as a safe option.
We couldn't put it at the end of DRAM and I just wanted to place it at
 a reasonable distance.

2MB should be totally okay.

> Any thoughts?
>
> Alistair
>
> >
> > Regards,
> > Bin



Re: [PATCH v5 2/3] target/riscv: Add stimecmp support

2022-06-15 Thread Atish Kumar Patra
On Wed, Jun 8, 2022 at 12:19 AM Alistair Francis  wrote:
>
> On Mon, Jun 6, 2022 at 2:23 AM Atish Patra  wrote:
> >
> > On Thu, Jun 2, 2022 at 12:02 AM Alistair Francis  
> > wrote:
> > >
> > > On Wed, Jun 1, 2022 at 4:16 AM Atish Patra  wrote:
> > > >
> > > > stimecmp allows the supervisor mode to update stimecmp CSR directly
> > > > to program the next timer interrupt. This CSR is part of the Sstc
> > > > extension which was ratified recently.
> > > >
> > > > Signed-off-by: Atish Patra 
> > > > ---
> > > >  target/riscv/cpu.c |  8 
> > > >  target/riscv/cpu.h |  5 ++
> > > >  target/riscv/cpu_bits.h|  4 ++
> > > >  target/riscv/csr.c | 81 +++
> > > >  target/riscv/machine.c |  1 +
> > > >  target/riscv/meson.build   |  3 +-
> > > >  target/riscv/time_helper.c | 98 ++
> > > >  target/riscv/time_helper.h | 30 
> > > >  8 files changed, 229 insertions(+), 1 deletion(-)
> > > >  create mode 100644 target/riscv/time_helper.c
> > > >  create mode 100644 target/riscv/time_helper.h
> > > >
> > > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > > > index 19f4e8294042..d58dd2f857a7 100644
> > > > --- a/target/riscv/cpu.c
> > > > +++ b/target/riscv/cpu.c
> > > > @@ -23,6 +23,7 @@
> > > >  #include "qemu/log.h"
> > > >  #include "cpu.h"
> > > >  #include "internals.h"
> > > > +#include "time_helper.h"
> > > >  #include "exec/exec-all.h"
> > > >  #include "qapi/error.h"
> > > >  #include "qemu/error-report.h"
> > > > @@ -779,7 +780,12 @@ static void riscv_cpu_init(Object *obj)
> > > >  #ifndef CONFIG_USER_ONLY
> > > >  qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq,
> > > >IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX);
> > > > +
> > > > +if (cpu->cfg.ext_sstc) {
> > > > +riscv_timer_init(cpu);
> > > > +}
> > > >  #endif /* CONFIG_USER_ONLY */
> > > > +
> > > >  }
> > > >
> > > >  static Property riscv_cpu_properties[] = {
> > > > @@ -806,6 +812,7 @@ static Property riscv_cpu_properties[] = {
> > > >  DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
> > > >  DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
> > > >  DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
> > > > +DEFINE_PROP_BOOL("sstc", RISCVCPU, cfg.ext_sstc, true),
> > >
> > > Do we want this enabled by default?
> > >
> >
> > sstc extension will result in performance improvements as it avoids
> > the SBI calls & interrupt forwarding
> > path. That's why I think it should be enabled by default.
> >
> > > >
> > > >  DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
> > > >  DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
> > > > @@ -965,6 +972,7 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, 
> > > > char **isa_str, int max_str_len)
> > > >  ISA_EDATA_ENTRY(zbs, ext_zbs),
> > > >  ISA_EDATA_ENTRY(zve32f, ext_zve32f),
> > > >  ISA_EDATA_ENTRY(zve64f, ext_zve64f),
> > > > +ISA_EDATA_ENTRY(sstc, ext_sstc),
> > > >  ISA_EDATA_ENTRY(svinval, ext_svinval),
> > > >  ISA_EDATA_ENTRY(svnapot, ext_svnapot),
> > > >  ISA_EDATA_ENTRY(svpbmt, ext_svpbmt),
> > > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > > > index 1119d5201066..9a5e02f217ba 100644
> > > > --- a/target/riscv/cpu.h
> > > > +++ b/target/riscv/cpu.h
> > > > @@ -276,6 +276,9 @@ struct CPUArchState {
> > > >  uint64_t mfromhost;
> > > >  uint64_t mtohost;
> > > >
> > > > +/* Sstc CSRs */
> > > > +uint64_t stimecmp;
> > > > +
> > > >  /* physical memory protection */
> > > >  pmp_table_t pmp_state;
> > > >  target_ulong mseccfg;
> > > > @@ -329,6 +332,7 @@ struct CPUArchState {
> > > >  float_status fp_status;
> > > >
> > > >  /* Fields from here on are preserved across CPU reset. */
> > > > +QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
> > > >
> > > >  hwaddr kernel_addr;
> > > >  hwaddr fdt_addr;
> > > > @@ -379,6 +383,7 @@ struct RISCVCPUConfig {
> > > >  bool ext_counters;
> > > >  bool ext_ifencei;
> > > >  bool ext_icsr;
> > > > +bool ext_sstc;
> > > >  bool ext_svinval;
> > > >  bool ext_svnapot;
> > > >  bool ext_svpbmt;
> > > > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> > > > index 4e5b630f5965..29d0e4a1be01 100644
> > > > --- a/target/riscv/cpu_bits.h
> > > > +++ b/target/riscv/cpu_bits.h
> > > > @@ -215,6 +215,10 @@
> > > >  #define CSR_STVAL   0x143
> > > >  #define CSR_SIP 0x144
> > > >
> > > > +/* Sstc supervisor CSRs */
> > > > +#define CSR_STIMECMP0x14D
> > > > +#define CSR_STIMECMPH   0x15D
> > > > +
> > > >  /* Supervisor Protection and Translation */
> > > >  #define CSR_SPTBR   0x180
> > > >  #define CSR_SATP0x180
> > > > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > > > index 245f007e66e1..48d07911ae14 100644
> > > > --- 

Re: [PATCH v4 2/3] target/riscv: Add stimecmp support

2022-05-27 Thread Atish Kumar Patra
On Thu, May 26, 2022 at 7:07 PM Alistair Francis  wrote:
>
> On Thu, May 26, 2022 at 5:16 PM Atish Patra  wrote:
> >
> > On Wed, May 25, 2022 at 10:11 PM Alistair Francis  
> > wrote:
> > >
> > > On Sat, May 14, 2022 at 4:39 AM Atish Patra  wrote:
> > > >
> > > > stimecmp allows the supervisor mode to update stimecmp CSR directly
> > > > to program the next timer interrupt. This CSR is part of the Sstc
> > > > extension which was ratified recently.
> > > >
> > > > Signed-off-by: Atish Patra 
> > > > ---
> > > >  target/riscv/cpu.c |  8 
> > > >  target/riscv/cpu.h |  7 +++
> > > >  target/riscv/cpu_bits.h|  4 ++
> > > >  target/riscv/csr.c | 92 +++
> > > >  target/riscv/machine.c |  2 +
> > > >  target/riscv/meson.build   |  3 +-
> > > >  target/riscv/time_helper.c | 98 ++
> > > >  target/riscv/time_helper.h | 30 
> > > >  8 files changed, 243 insertions(+), 1 deletion(-)
> > > >  create mode 100644 target/riscv/time_helper.c
> > > >  create mode 100644 target/riscv/time_helper.h
> > > >
> > > > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > > > index 19f4e8294042..d58dd2f857a7 100644
> > > > --- a/target/riscv/cpu.c
> > > > +++ b/target/riscv/cpu.c
> > > > @@ -23,6 +23,7 @@
> > > >  #include "qemu/log.h"
> > > >  #include "cpu.h"
> > > >  #include "internals.h"
> > > > +#include "time_helper.h"
> > > >  #include "exec/exec-all.h"
> > > >  #include "qapi/error.h"
> > > >  #include "qemu/error-report.h"
> > > > @@ -779,7 +780,12 @@ static void riscv_cpu_init(Object *obj)
> > > >  #ifndef CONFIG_USER_ONLY
> > > >  qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq,
> > > >IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX);
> > > > +
> > > > +if (cpu->cfg.ext_sstc) {
> > > > +riscv_timer_init(cpu);
> > > > +}
> > > >  #endif /* CONFIG_USER_ONLY */
> > > > +
> > > >  }
> > > >
> > > >  static Property riscv_cpu_properties[] = {
> > > > @@ -806,6 +812,7 @@ static Property riscv_cpu_properties[] = {
> > > >  DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
> > > >  DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
> > > >  DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
> > > > +DEFINE_PROP_BOOL("sstc", RISCVCPU, cfg.ext_sstc, true),
> > > >
> > > >  DEFINE_PROP_STRING("priv_spec", RISCVCPU, cfg.priv_spec),
> > > >  DEFINE_PROP_STRING("vext_spec", RISCVCPU, cfg.vext_spec),
> > > > @@ -965,6 +972,7 @@ static void riscv_isa_string_ext(RISCVCPU *cpu, 
> > > > char **isa_str, int max_str_len)
> > > >  ISA_EDATA_ENTRY(zbs, ext_zbs),
> > > >  ISA_EDATA_ENTRY(zve32f, ext_zve32f),
> > > >  ISA_EDATA_ENTRY(zve64f, ext_zve64f),
> > > > +ISA_EDATA_ENTRY(sstc, ext_sstc),
> > > >  ISA_EDATA_ENTRY(svinval, ext_svinval),
> > > >  ISA_EDATA_ENTRY(svnapot, ext_svnapot),
> > > >  ISA_EDATA_ENTRY(svpbmt, ext_svpbmt),
> > > > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > > > index 1119d5201066..9a01e6d0f587 100644
> > > > --- a/target/riscv/cpu.h
> > > > +++ b/target/riscv/cpu.h
> > > > @@ -276,6 +276,11 @@ struct CPUArchState {
> > > >  uint64_t mfromhost;
> > > >  uint64_t mtohost;
> > > >
> > > > +/* Sstc CSRs */
> > > > +uint64_t stimecmp;
> > > > +/* For RV32 only */
> > > > +uint8_t stimecmp_wr_done;
> > > > +
> > > >  /* physical memory protection */
> > > >  pmp_table_t pmp_state;
> > > >  target_ulong mseccfg;
> > > > @@ -329,6 +334,7 @@ struct CPUArchState {
> > > >  float_status fp_status;
> > > >
> > > >  /* Fields from here on are preserved across CPU reset. */
> > > > +QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
> > > >
> > > >  hwaddr kernel_addr;
> > > >  hwaddr fdt_addr;
> > > > @@ -379,6 +385,7 @@ struct RISCVCPUConfig {
> > > >  bool ext_counters;
> > > >  bool ext_ifencei;
> > > >  bool ext_icsr;
> > > > +bool ext_sstc;
> > > >  bool ext_svinval;
> > > >  bool ext_svnapot;
> > > >  bool ext_svpbmt;
> > > > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> > > > index 4e5b630f5965..29d0e4a1be01 100644
> > > > --- a/target/riscv/cpu_bits.h
> > > > +++ b/target/riscv/cpu_bits.h
> > > > @@ -215,6 +215,10 @@
> > > >  #define CSR_STVAL   0x143
> > > >  #define CSR_SIP 0x144
> > > >
> > > > +/* Sstc supervisor CSRs */
> > > > +#define CSR_STIMECMP0x14D
> > > > +#define CSR_STIMECMPH   0x15D
> > > > +
> > > >  /* Supervisor Protection and Translation */
> > > >  #define CSR_SPTBR   0x180
> > > >  #define CSR_SATP0x180
> > > > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > > > index 245f007e66e1..8952d1308008 100644
> > > > --- a/target/riscv/csr.c
> > > > +++ b/target/riscv/csr.c
> > > > @@ -21,6 +21,7 @@
> > > >  #include "qemu/log.h"
> > > >  #include "qemu/timer.h"
> > > >  #include "cpu.h"
> > 

Re: [RFC 0/3] Introduce a new Qemu machine for RISC-V

2022-05-19 Thread Atish Kumar Patra
On Wed, May 18, 2022 at 3:46 AM Peter Maydell  wrote:
>
> On Wed, 18 May 2022 at 09:25, Daniel P. Berrangé  wrote:
> > The fact that RISC-V ecosystem is so young & has relatively few
> > users, and even fewer expecting  long term stability, is precisely
> > why we should just modify the existing 'virt' machine now rather
> > than introducing a new 'virt-pcie'. We can afford to have the
> > limited incompatibility in the short term given the small userbase.
> > We went through this same exercise with aarch64 virt machine and
> > despite the short term disruption, it was a good success IMHO to
> > get it switched from MMIO to PCI, instead of having two machines
> > in parallel long term.
>
> The aarch64 virt board does still carry around the mmio devices,
> though...it's just that we have pci as well now.
>
> Personally I don't think that switching to a new machine type
> is likely to help escape from the "bloat" problem, which arises
> from two conflicting desires:
>
>  (1) people want this kind of board to be nice and small and
>  simple, with a minimal set of devices
>  (2) everybody has their own "but this specific one device is
>  really important and it should be in the minimal set"
>  (watchdog? acpi? ability to power the machine on and off?
>  second UART? i2c? etc etc etc)
>

Both acpi/device tree support should be there anyways.
MMIO based reset will probably needed as well (I listed that earlier
with mandatory MMIO devices)

AFAIK everything else can be PCIe based which the new board will mandate.
It must strictly enforce the rules about what can be added to it. The
bar to allow
new MMIO devices must be very high and must have a wide range of usage.
This will make life easier for the entire ecosystem as well. AFAIK,
libvirt uses PCIe devices only to build VMs.

I understand that is probably a big ask but if odd mmio devices sneak
into this platform, then that defeats the purpose.
On other hand, having a flag day for virt machines creates a lot of
incompatibility for the users until everyone transitions.
The transition also has to happen based on Qemu version as virt
machine doesn't have any versioning right now.

Do we make users' life difficult by having a flag date based on the
Qemu version or take additional responsibility of maintaining another
board ?
I hope the new board will continue to be small so the maintenance
burden is not too much. Personally, I feel the latter approach will
have minimum inconvenience for everybody
but I am okay with whatever is decided by the community.



> So either your 'minimal' board is only serving a small subset
> of the users who want a minimal board; or else it's not as
> minimal as any of them would like; or else it acquires a
> growing set of -machine options to turn various devices on
> and off...
>
> -- PMM



Re: [PATCH v8 07/12] target/riscv: Support mcycle/minstret write operation

2022-05-13 Thread Atish Kumar Patra
On Thu, May 12, 2022 at 11:29 PM Frank Chang  wrote:
>
> On Thu, May 12, 2022 at 6:01 AM Atish Patra  wrote:
>>
>> From: Atish Patra 
>>
>> mcycle/minstret are actually WARL registers and can be written with any
>> given value. With SBI PMU extension, it will be used to store a initial
>> value provided from supervisor OS. The Qemu also need prohibit the counter
>> increment if mcountinhibit is set.
>>
>> Support mcycle/minstret through generic counter infrastructure.
>>
>> Reviewed-by: Alistair Francis 
>> Signed-off-by: Atish Patra 
>> Signed-off-by: Atish Patra 
>> ---
>>  target/riscv/cpu.h   |  23 --
>>  target/riscv/csr.c   | 157 ---
>>  target/riscv/machine.c   |  25 ++-
>>  target/riscv/meson.build |   3 +-
>>  target/riscv/pmu.c   |  32 
>>  target/riscv/pmu.h   |  28 +++
>>  6 files changed, 214 insertions(+), 54 deletions(-)
>>  create mode 100644 target/riscv/pmu.c
>>  create mode 100644 target/riscv/pmu.h
>>
>> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
>> index 32cdd9070be5..f60072e0fd3d 100644
>> --- a/target/riscv/cpu.h
>> +++ b/target/riscv/cpu.h
>> @@ -111,7 +111,7 @@ typedef struct CPUArchState CPURISCVState;
>>  #endif
>>
>>  #define RV_VLEN_MAX 1024
>> -#define RV_MAX_MHPMEVENTS 29
>> +#define RV_MAX_MHPMEVENTS 32
>>  #define RV_MAX_MHPMCOUNTERS 32
>>
>>  FIELD(VTYPE, VLMUL, 0, 3)
>> @@ -121,6 +121,18 @@ FIELD(VTYPE, VMA, 7, 1)
>>  FIELD(VTYPE, VEDIV, 8, 2)
>>  FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
>>
>> +typedef struct PMUCTRState {
>> +/* Current value of a counter */
>> +target_ulong mhpmcounter_val;
>> +/* Current value of a counter in RV32*/
>> +target_ulong mhpmcounterh_val;
>> +/* Snapshot values of counter */
>> +target_ulong mhpmcounter_prev;
>> +/* Snapshort value of a counter in RV32 */
>> +target_ulong mhpmcounterh_prev;
>> +bool started;
>> +} PMUCTRState;
>> +
>>  struct CPUArchState {
>>  target_ulong gpr[32];
>>  target_ulong gprh[32]; /* 64 top bits of the 128-bit registers */
>> @@ -273,13 +285,10 @@ struct CPUArchState {
>>
>>  target_ulong mcountinhibit;
>>
>> -/* PMU counter configured values */
>> -target_ulong mhpmcounter_val[RV_MAX_MHPMCOUNTERS];
>> -
>> -/* for RV32 */
>> -target_ulong mhpmcounterh_val[RV_MAX_MHPMCOUNTERS];
>> +/* PMU counter state */
>> +PMUCTRState pmu_ctrs[RV_MAX_MHPMCOUNTERS];
>>
>> -/* PMU event selector configured values */
>> +/* PMU event selector configured values. First three are unused*/
>>  target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
>>
>>  target_ulong sscratch;
>> diff --git a/target/riscv/csr.c b/target/riscv/csr.c
>> index 87aa601e5ddb..c050ed2e2c1b 100644
>> --- a/target/riscv/csr.c
>> +++ b/target/riscv/csr.c
>> @@ -21,6 +21,7 @@
>>  #include "qemu/log.h"
>>  #include "qemu/timer.h"
>>  #include "cpu.h"
>> +#include "pmu.h"
>>  #include "qemu/main-loop.h"
>>  #include "exec/exec-all.h"
>>  #include "sysemu/cpu-timers.h"
>> @@ -597,34 +598,28 @@ static int write_vcsr(CPURISCVState *env, int csrno, 
>> target_ulong val)
>>  }
>>
>>  /* User Timers and Counters */
>> -static RISCVException read_instret(CPURISCVState *env, int csrno,
>> -   target_ulong *val)
>> +static target_ulong get_ticks(bool shift)
>>  {
>> +int64_t val;
>> +target_ulong result;
>> +
>>  #if !defined(CONFIG_USER_ONLY)
>>  if (icount_enabled()) {
>> -*val = icount_get();
>> +val = icount_get();
>>  } else {
>> -*val = cpu_get_host_ticks();
>> +val = cpu_get_host_ticks();
>>  }
>>  #else
>> -*val = cpu_get_host_ticks();
>> +val = cpu_get_host_ticks();
>>  #endif
>> -return RISCV_EXCP_NONE;
>> -}
>>
>> -static RISCVException read_instreth(CPURISCVState *env, int csrno,
>> -target_ulong *val)
>> -{
>> -#if !defined(CONFIG_USER_ONLY)
>> -if (icount_enabled()) {
>> -*val = icount_get() >> 32;
>> +if (shift) {
>> +result = val >> 32;
>>  } else {
>> -*val = cpu_get_host_ticks() >> 32;
>> +result = val;
>>  }
>> -#else
>> -*val = cpu_get_host_ticks() >> 32;
>> -#endif
>> -return RISCV_EXCP_NONE;
>> +
>> +return result;
>>  }
>>
>>  #if defined(CONFIG_USER_ONLY)
>> @@ -642,11 +637,23 @@ static RISCVException read_timeh(CPURISCVState *env, 
>> int csrno,
>>  return RISCV_EXCP_NONE;
>>  }
>>
>> +static int read_hpmcounter(CPURISCVState *env, int csrno, target_ulong *val)
>> +{
>> +*val = get_ticks(false);
>> +return RISCV_EXCP_NONE;
>> +}
>> +
>> +static int read_hpmcounterh(CPURISCVState *env, int csrno, target_ulong 
>> *val)
>> +{
>> +*val = get_ticks(true);
>> +return RISCV_EXCP_NONE;
>> +}
>> +
>>  #else /* CONFIG_USER_ONLY */
>>
>>  static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val)
>>  {
>> -int evt_index = csrno - CSR_MHPMEVENT3;
>> + 

Re: [PATCH v3 3/3] target/riscv: Add vstimecmp support

2022-05-12 Thread Atish Kumar Patra
On Wed, May 11, 2022 at 9:48 PM Anup Patel  wrote:
>
> On Tue, May 10, 2022 at 3:03 AM Atish Patra  wrote:
> >
> > vstimecmp CSR allows the guest OS or to program the next guest timer
> > interrupt directly. Thus, hypervisor no longer need to inject the
> > timer interrupt to the guest if vstimecmp is used. This was ratified
> > as a part of the Sstc extension.
> >
> > Signed-off-by: Atish Patra 
> > ---
> >  target/riscv/cpu.h |   5 ++
> >  target/riscv/cpu_bits.h|   4 ++
> >  target/riscv/cpu_helper.c  |  11 +++-
> >  target/riscv/csr.c | 112 -
> >  target/riscv/machine.c |   1 +
> >  target/riscv/time_helper.c |  16 ++
> >  6 files changed, 144 insertions(+), 5 deletions(-)
> >
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 9a01e6d0f587..798874d6189d 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -280,6 +280,9 @@ struct CPUArchState {
> >  uint64_t stimecmp;
> >  /* For RV32 only */
> >  uint8_t stimecmp_wr_done;
>
> Add new line here.
>
> > +uint64_t vstimecmp;
> > +/* For RV32 only */
> > +uint8_t vstimecmp_wr_done;
> >
> >  /* physical memory protection */
> >  pmp_table_t pmp_state;
> > @@ -335,6 +338,8 @@ struct CPUArchState {
> >
> >  /* Fields from here on are preserved across CPU reset. */
> >  QEMUTimer *stimer; /* Internal timer for S-mode interrupt */
> > +QEMUTimer *vstimer; /* Internal timer for VS-mode interrupt */
> > +bool vstime_irq;
> >
> >  hwaddr kernel_addr;
> >  hwaddr fdt_addr;
> > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> > index 29d0e4a1be01..5c9f512872e1 100644
> > --- a/target/riscv/cpu_bits.h
> > +++ b/target/riscv/cpu_bits.h
> > @@ -272,6 +272,10 @@
> >  #define CSR_VSIP0x244
> >  #define CSR_VSATP   0x280
> >
> > +/* Sstc virtual CSRs */
> > +#define CSR_VSTIMECMP   0x24D
> > +#define CSR_VSTIMECMPH  0x25D
> > +
> >  #define CSR_MTINST  0x34a
> >  #define CSR_MTVAL2  0x34b
> >
> > diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
> > index e1aa4f2097c1..2715021c022e 100644
> > --- a/target/riscv/cpu_helper.c
> > +++ b/target/riscv/cpu_helper.c
> > @@ -344,8 +344,9 @@ static uint64_t riscv_cpu_all_pending(CPURISCVState 
> > *env)
> >  {
> >  uint32_t gein = get_field(env->hstatus, HSTATUS_VGEIN);
> >  uint64_t vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
> > +uint64_t vstip = (env->vstime_irq) ? MIP_VSTIP : 0;
> >
> > -return (env->mip | vsgein) & env->mie;
> > +return (env->mip | vsgein | vstip) & env->mie;
> >  }
> >
> >  int riscv_cpu_mirq_pending(CPURISCVState *env)
> > @@ -604,7 +605,7 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t 
> > mask, uint64_t value)
> >  {
> >  CPURISCVState *env = >env;
> >  CPUState *cs = CPU(cpu);
> > -uint64_t gein, vsgein = 0, old = env->mip;
> > +uint64_t gein, vsgein = 0, vstip = 0, old = env->mip;
> >  bool locked = false;
> >
> >  if (riscv_cpu_virt_enabled(env)) {
> > @@ -612,6 +613,10 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t 
> > mask, uint64_t value)
> >  vsgein = (env->hgeip & (1ULL << gein)) ? MIP_VSEIP : 0;
> >  }
> >
> > +/* No need to update mip for VSTIP */
> > +mask = ((mask == MIP_VSTIP) && env->vstime_irq) ? 0 : mask;
> > +vstip = env->vstime_irq ? MIP_VSTIP : 0;
> > +
> >  if (!qemu_mutex_iothread_locked()) {
> >  locked = true;
> >  qemu_mutex_lock_iothread();
> > @@ -619,7 +624,7 @@ uint64_t riscv_cpu_update_mip(RISCVCPU *cpu, uint64_t 
> > mask, uint64_t value)
> >
> >  env->mip = (env->mip & ~mask) | (value & mask);
> >
> > -if (env->mip | vsgein) {
> > +if (env->mip | vsgein | vstip) {
> >  cpu_interrupt(cs, CPU_INTERRUPT_HARD);
> >  } else {
> >  cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index 8952d1308008..35eb2c4d84eb 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -567,17 +567,110 @@ static RISCVException sstc(CPURISCVState *env, int 
> > csrno)
> >  return RISCV_EXCP_NONE;
> >  }
> >
> > +static RISCVException sstc_hmode(CPURISCVState *env, int csrno)
> > +{
> > +CPUState *cs = env_cpu(env);
> > +RISCVCPU *cpu = RISCV_CPU(cs);
> > +
> > +if (!cpu->cfg.ext_sstc || !env->rdtime_fn) {
> > +return RISCV_EXCP_ILLEGAL_INST;
> > +}
> > +
> > +if (env->priv == PRV_M) {
> > +return RISCV_EXCP_NONE;
> > +}
> > +
> > +if (!(get_field(env->mcounteren, COUNTEREN_TM) &
> > +  get_field(env->menvcfg, MENVCFG_STCE))) {
> > +return RISCV_EXCP_ILLEGAL_INST;
> > +}
> > +
> > +if (!(get_field(env->hcounteren, COUNTEREN_TM) &
> > +  get_field(env->henvcfg, HENVCFG_STCE))) {
> > +return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > +}
> > +
> > +return 

Re: [RFC 0/3] Introduce a new Qemu machine for RISC-V

2022-05-06 Thread Atish Kumar Patra
On Fri, May 6, 2022 at 4:00 AM Peter Maydell  wrote:
>
> On Fri, 6 May 2022 at 09:18, Daniel P. Berrangé  wrote:
> >
> > On Fri, May 06, 2022 at 06:34:47AM +1000, Alistair Francis wrote:
> > > Even if we didn't worry about backwards compatibility the current virt
> > > machine would still be what most users want. It's just a small number
> > > of users who don't want MMIO devices and instead want to use PCIe for
> > > everything. Realistically it's only HPC users who would want this type
> > > of machine, at least that's my understanding.
> >
> > I'm not so sure about that. Every other architecture has ended up
> > standardizing on PCI for general purpose virtual machines. IIRC,
> > aarch64 started off with MMIO, but switched to PCI as it matured.
> >
> > In terms of having VM mgmt tools "just work" for risc-v, I think
> > it will be very compelling for the general 'virt' machine to be
> > PCI based, otherwise all the assumptions about PCI in mgmt apps
> > are going to break requiring never ending riscv fixes.
>
> Mmm, my experience with aarch64 virt is that PCI is much nicer
> as a general preference. aarch64 virt has some MMIO devices
> for historical reasons and some because you can't reasonably
> do the necessary things with PCI, but I'm actively trying to
> push people who submit new MMIO device features for virt to
> try to use a PCI-based solution instead if they possibly can.
>

Yeah. That was one of the primary goals of this series. If we have an
alternate PCI only machine,
folks will be more motivated to add only PCI based solutions in the
future. In that case, there will be minimal
or no change required to the machine code itself.

Just for clarification: We can achieve the same with the current virt
machine. But it is already bloated with a bunch of MMIO devices
and will probably continue to do so because of its flexibility. In
addition to that, any real PCI based platform emulation can not reuse
the virt machine code which will result in more vendor specific
implementations in the future..

> thanks
> -- PMM



Re: [RFC 0/3] Introduce a new Qemu machine for RISC-V

2022-05-05 Thread Atish Kumar Patra
On Thu, May 5, 2022 at 1:35 PM Alistair Francis  wrote:
>
> On Thu, May 5, 2022 at 8:04 PM Daniel P. Berrangé  wrote:
> >
> > On Thu, May 05, 2022 at 07:36:51PM +1000, Alistair Francis wrote:
> > > On Tue, May 3, 2022 at 5:57 PM Atish Patra  wrote:
> > > >
> > > > On Tue, Apr 19, 2022 at 5:26 PM Atish Patra  
> > > > wrote:
> > > > >
> > > > > On Tue, Apr 19, 2022 at 9:51 AM Daniel P. Berrangé 
> > > > >  wrote:
> > > > > >
> > > > > > On Mon, Apr 11, 2022 at 07:10:06PM -0700, Atish Patra wrote:
> > > > > > >
> > > > > > > The RISC-V virt machine has helped RISC-V software eco system to 
> > > > > > > evolve at a
> > > > > > > rapid pace even in absense of the real hardware. It is definitely 
> > > > > > > commendable.
> > > > > > > However, the number of devices & commandline options keeps 
> > > > > > > growing as a result
> > > > > > > of that as well. That adds flexibility but will also become bit 
> > > > > > > difficult
> > > > > > > to manage in the future as more extension support will be added. 
> > > > > > > As it is the
> > > > > > > most commonly used qemu machine, it needs to support all kinds of 
> > > > > > > device and
> > > > > > > interrupts as well. Moreover, virt machine has limitations on the 
> > > > > > > maximum
> > > > > > > number of harts it can support because of all the MMIO devices it 
> > > > > > > has to support.
> > > > > > >
> > > > > > > The RISC-V IMSIC specification allows to develop machines 
> > > > > > > completely relying
> > > > > > > on MSI and don't care about the wired interrupts at all. It just 
> > > > > > > requires
> > > > > > > all the devices to be present behind a PCI bus or present 
> > > > > > > themselves as platform
> > > > > > > MSI device. The former is a more common scenario in x86 world 
> > > > > > > where most
> > > > > > > of the devices are behind PCI bus. As there is very limited MMIO 
> > > > > > > device
> > > > > > > support, it can also scale to very large number of harts.
> > > > > > >
> > > > > > > That's why, this patch series introduces a minimalistic yet very 
> > > > > > > extensible
> > > > > > > forward looking machine called as "RISC-V Mini Computer" or 
> > > > > > > "minic". The
> > > > > > > idea is to build PC or server like systems with this machine. The 
> > > > > > > machine can
> > > > > > > work with or without virtio framework. The current implementation 
> > > > > > > only
> > > > > > > supports RV64. I am not sure if building a RV32 machine would be 
> > > > > > > of interest
> > > > > > > for such machines. The only mmio device it requires is clint to 
> > > > > > > emulate
> > > > > > > the mtimecmp.
> > > > > >
> > > >
> > > > Any other thoughts ?
> > >
> > > I don't *love* this idea. I think the virt machine is useful, but I'm
> > > not convinced we need a second one.
> > >
> > > This feels a little bit more like a "none" machine, as it contains
> > > just the bare minimum to work.
> > >
> > > >
> > > > > > I would ask what you see as the long term future usage for 'virt' vs
> > > > > > 'minic' machine types ? Would you expect all existing users of 
> > > > > > 'virt'
> > > > > > to ultimately switch to 'minic', or are there distinct 
> > > > > > non-overlapping
> > > > > > use cases for 'virt' vs 'minic' such that both end up widely used ?
> > > > > >
> > > > >
> > > > > Nope. I don't expect existing 'virt' users to switch to 'minic' as
> > > > > they aim to cater to different users.
> > > > >
> > > > > Here are the major differences
> > > > > 1. virt machine supports MMIO devices & wired interrupts. Minic 
> > > > > doesn't
> > >
> > > This seems like the main difference
> > >
> > > > > 2. virt machine doesn't support the MSI only option yet (can be added
> > > > > though[1]). Minic does.
> > >
> > > This could be fixed
> > >
> > > > > 3. Number of cpu supported by virt machine are limited because of the
> > > > > MMIO devices. Minic can scale to very
> > > > > large numbers of cpu.
> > >
> > > Similar to 1
> > >
> > > > > 4. 'Minic' only supports PCI based MSI capable devices. Thus, MSI is a
> > > > > mandatory requirement for 'minic' while
> > > > > it is optional for 'virt'.
> > >
> > > I'm not fully convinced we need this, but it also doesn't seem to cost
> > > us a lot in terms of maintenance. It would be beneficial if we could
> > > share a bit more of the code. Can we share the socket creation code as
> > > well?
> > >
> > > I don't like the name minic though. What about something like
> > > `virt-hpc`, `virt-pcie-minimal` or something like that? That way we
> > > indicate it's still a virt board
> >
> > We're not versioning the 'virt' machine type right so. IOW, we've not
> > made any promises about its long term featureset.
> >
> > If the virt machine type isn't the perfect match right now, should
> > we change it, in a potentially incompatible way, to give us the right
> > solution long term, rather than introducing a brand new machine type
> > with significant overlap.
>
> Even if we didn't worry 

Re: [RFC 0/3] Introduce a new Qemu machine for RISC-V

2022-05-05 Thread Atish Kumar Patra
On Thu, May 5, 2022 at 2:37 AM Alistair Francis  wrote:
>
> On Tue, May 3, 2022 at 5:57 PM Atish Patra  wrote:
> >
> > On Tue, Apr 19, 2022 at 5:26 PM Atish Patra  wrote:
> > >
> > > On Tue, Apr 19, 2022 at 9:51 AM Daniel P. Berrangé  
> > > wrote:
> > > >
> > > > On Mon, Apr 11, 2022 at 07:10:06PM -0700, Atish Patra wrote:
> > > > >
> > > > > The RISC-V virt machine has helped RISC-V software eco system to 
> > > > > evolve at a
> > > > > rapid pace even in absense of the real hardware. It is definitely 
> > > > > commendable.
> > > > > However, the number of devices & commandline options keeps growing as 
> > > > > a result
> > > > > of that as well. That adds flexibility but will also become bit 
> > > > > difficult
> > > > > to manage in the future as more extension support will be added. As 
> > > > > it is the
> > > > > most commonly used qemu machine, it needs to support all kinds of 
> > > > > device and
> > > > > interrupts as well. Moreover, virt machine has limitations on the 
> > > > > maximum
> > > > > number of harts it can support because of all the MMIO devices it has 
> > > > > to support.
> > > > >
> > > > > The RISC-V IMSIC specification allows to develop machines completely 
> > > > > relying
> > > > > on MSI and don't care about the wired interrupts at all. It just 
> > > > > requires
> > > > > all the devices to be present behind a PCI bus or present themselves 
> > > > > as platform
> > > > > MSI device. The former is a more common scenario in x86 world where 
> > > > > most
> > > > > of the devices are behind PCI bus. As there is very limited MMIO 
> > > > > device
> > > > > support, it can also scale to very large number of harts.
> > > > >
> > > > > That's why, this patch series introduces a minimalistic yet very 
> > > > > extensible
> > > > > forward looking machine called as "RISC-V Mini Computer" or "minic". 
> > > > > The
> > > > > idea is to build PC or server like systems with this machine. The 
> > > > > machine can
> > > > > work with or without virtio framework. The current implementation only
> > > > > supports RV64. I am not sure if building a RV32 machine would be of 
> > > > > interest
> > > > > for such machines. The only mmio device it requires is clint to 
> > > > > emulate
> > > > > the mtimecmp.
> > > >
> >
> > Any other thoughts ?
>
> I don't *love* this idea. I think the virt machine is useful, but I'm
> not convinced we need a second one.
>
> This feels a little bit more like a "none" machine, as it contains
> just the bare minimum to work.
>

Ha ha :). That was the whole point. To create a minimal machine that
is easy to maintain and emulate platforms in the real world.

> >
> > > > I would ask what you see as the long term future usage for 'virt' vs
> > > > 'minic' machine types ? Would you expect all existing users of 'virt'
> > > > to ultimately switch to 'minic', or are there distinct non-overlapping
> > > > use cases for 'virt' vs 'minic' such that both end up widely used ?
> > > >
> > >
> > > Nope. I don't expect existing 'virt' users to switch to 'minic' as
> > > they aim to cater to different users.
> > >
> > > Here are the major differences
> > > 1. virt machine supports MMIO devices & wired interrupts. Minic doesn't
>
> This seems like the main difference
>
> > > 2. virt machine doesn't support the MSI only option yet (can be added
> > > though[1]). Minic does.
>
> This could be fixed
>
> > > 3. Number of cpu supported by virt machine are limited because of the
> > > MMIO devices. Minic can scale to very
> > > large numbers of cpu.
>
> Similar to 1
>

Yes. I already had the patch to fix that in the virt machine in the
cover letter.
I did not send it to the mailing list to avoid confusion.

> > > 4. 'Minic' only supports PCI based MSI capable devices. Thus, MSI is a
> > > mandatory requirement for 'minic' while
> > > it is optional for 'virt'.
>
> I'm not fully convinced we need this, but it also doesn't seem to cost
> us a lot in terms of maintenance. It would be beneficial if we could
> share a bit more of the code. Can we share the socket creation code as
> well?
>

Yeah. We can move the socket creation to the common code as well.
There are few others small ones (virt_set/get_aia_guests) can be moved
to common code.

In the future, real world hpc machines may just build their machine
on top of this machine instead of developing from scratch if we allow
some configurability
(e.g memory map, machine name, max cpus etc.)

> I don't like the name minic though. What about something like
> `virt-hpc`, `virt-pcie-minimal` or something like that? That way we
> indicate it's still a virt board
>

Fair enough. I can rename it to virt-hpc or something similar.

> Alistair
>
> > >
> > > 'Minic' aims towards the users who want to create virtual machines
> > > that are MSI based and don't care about
> > > a million options that virt machines provide.  Virt machine is more
> > > complex so that it can be flexible in terms of
> > > what it supports. Minic is a 

Re: [PATCH v2 2/5] migration: Add 64bit variable array data type

2022-04-26 Thread Atish Kumar Patra
On Tue, Apr 26, 2022 at 5:50 PM Richard Henderson
 wrote:
>
> On 4/26/22 16:08, Atish Patra wrote:
> > +.num_offset = vmstate_offset_value(_state, _field_num, uint32_t),\
> ...
> >   } else if (field->flags & VMS_VARRAY_UINT32) {
> >   n_elems = *(uint32_t *)(opaque + field->num_offset);
> > +} else if (field->flags & VMS_VARRAY_UINT64) {
> > +n_elems = *(uint64_t *)(opaque + field->num_offset);
>
> Offset type mismatch.  Since num_harts is uint32_t, I don't believe you need 
> this patch at
> all.
>

Ahh yes. You are right. I read the function description wrong and
assumed that VMSTATE_VARRAY_UINT32
creates an variable array of uint32_t elements only. Thanks for the
clarification.

>
> r~



Re: [PATCH v2 1/5] hw/intc: Move mtimer/mtimecmp to aclint

2022-04-26 Thread Atish Kumar Patra
On Tue, Apr 26, 2022 at 5:50 PM Richard Henderson
 wrote:
>
> On 4/26/22 16:08, Atish Patra wrote:
> > @@ -334,7 +334,6 @@ const VMStateDescription vmstate_riscv_cpu = {
> >   VMSTATE_UINTTL(env.mscratch, RISCVCPU),
> >   VMSTATE_UINT64(env.mfromhost, RISCVCPU),
> >   VMSTATE_UINT64(env.mtohost, RISCVCPU),
> > -VMSTATE_UINT64(env.timecmp, RISCVCPU),
> >
>
> Must bump version_id and minimum_version_id.
>

Yeah. Fixed that. Thanks.

> r~



Re: [PATCH v7 08/12] target/riscv: Add sscofpmf extension support

2022-04-15 Thread Atish Kumar Patra
On Wed, Apr 13, 2022 at 12:08 AM Alistair Francis  wrote:
>
> On Thu, Mar 31, 2022 at 10:19 AM Atish Patra  wrote:
> >
> > The Sscofpmf ('Ss' for Privileged arch and Supervisor-level extensions,
> > and 'cofpmf' for Count OverFlow and Privilege Mode Filtering)
> > extension allows the perf to handle overflow interrupts and filtering
> > support. This patch provides a framework for programmable
> > counters to leverage the extension. As the extension doesn't have any
> > provision for the overflow bit for fixed counters, the fixed events
> > can also be monitoring using programmable counters. The underlying
> > counters for cycle and instruction counters are always running. Thus,
> > a separate timer device is programmed to handle the overflow.
> >
> > Signed-off-by: Atish Patra 
> > Signed-off-by: Atish Patra 
> > ---
> >  target/riscv/cpu.c  |  11 ++
> >  target/riscv/cpu.h  |  25 +++
> >  target/riscv/cpu_bits.h |  55 +++
> >  target/riscv/csr.c  | 156 --
> >  target/riscv/pmu.c  | 347 +++-
> >  target/riscv/pmu.h  |   7 +
> >  6 files changed, 590 insertions(+), 11 deletions(-)
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index f63602828680..9715eed2fc4e 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -22,6 +22,7 @@
> >  #include "qemu/ctype.h"
> >  #include "qemu/log.h"
> >  #include "cpu.h"
> > +#include "pmu.h"
> >  #include "internals.h"
> >  #include "exec/exec-all.h"
> >  #include "qapi/error.h"
> > @@ -696,6 +697,15 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
> > **errp)
> >  set_misa(env, env->misa_mxl, ext);
> >  }
> >
> > +#ifndef CONFIG_USER_ONLY
> > +if (cpu->cfg.pmu_num) {
> > +if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && 
> > cpu->cfg.ext_sscofpmf) {
> > +cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> > +  riscv_pmu_timer_cb, cpu);
> > +}
> > + }
> > +#endif
> > +
> >  riscv_cpu_register_gdb_regs_for_features(cs);
> >
> >  qemu_init_vcpu(cs);
> > @@ -795,6 +805,7 @@ static Property riscv_cpu_properties[] = {
> >  DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
> >  DEFINE_PROP_BOOL("h", RISCVCPU, cfg.ext_h, true),
> >  DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
> > +DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
> >  DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
> >  DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
> >  DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 0fa15595fb37..a0e2279ea5e6 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -131,6 +131,8 @@ typedef struct PMUCTRState {
> >  /* Snapshort value of a counter in RV32 */
> >  target_ulong mhpmcounterh_prev;
> >  bool started;
> > +/* Value beyond UINT32_MAX/UINT64_MAX before overflow interrupt 
> > trigger */
> > +target_ulong irq_overflow_left;
> >  } PMUCTRState;
> >
> >  struct CPUArchState {
> > @@ -291,6 +293,9 @@ struct CPUArchState {
> >  /* PMU event selector configured values. First three are unused*/
> >  target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
> >
> > +/* PMU event selector configured values for RV32*/
> > +target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
> > +
> >  target_ulong sscratch;
> >  target_ulong mscratch;
> >
> > @@ -413,6 +418,7 @@ struct RISCVCPUConfig {
> >  bool ext_zhinxmin;
> >  bool ext_zve32f;
> >  bool ext_zve64f;
> > +bool ext_sscofpmf;
> >
> >  /* Vendor-specific custom extensions */
> >  bool ext_XVentanaCondOps;
> > @@ -452,6 +458,12 @@ struct ArchCPU {
> >
> >  /* Configuration Settings */
> >  RISCVCPUConfig cfg;
> > +
> > +QEMUTimer *pmu_timer;
> > +/* A bitmask of Available programmable counters */
> > +uint32_t pmu_avail_ctrs;
> > +/* Mapping of events to counters */
> > +GHashTable *pmu_event_ctr_map;
> >  };
> >
> >  static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
> > @@ -709,6 +721,19 @@ enum {
> >  CSR_TABLE_SIZE = 0x1000
> >  };
> >
> > +/**
> > + * The event id are encoded based on the encoding specified in the
> > + * SBI specification v0.3
> > + */
> > +
> > +enum riscv_pmu_event_idx {
> > +RISCV_PMU_EVENT_HW_CPU_CYCLES = 0x01,
> > +RISCV_PMU_EVENT_HW_INSTRUCTIONS = 0x02,
> > +RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS = 0x10019,
> > +RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS = 0x1001B,
> > +RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS = 0x10021,
> > +};
> > +
> >  /* CSR function table */
> >  extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
> >
> > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> > index 48b39e6d52a7..d0b53e5ea072 100644
> > --- a/target/riscv/cpu_bits.h
> > +++ b/target/riscv/cpu_bits.h
> > @@ 

Re: [PATCH v5] target/riscv: Add isa extenstion strings to the device tree

2022-03-15 Thread Atish Kumar Patra
On Tue, Mar 15, 2022 at 2:17 AM Bin Meng  wrote:
>
> On Tue, Mar 15, 2022 at 7:43 AM Atish Patra  wrote:
> >
> > The Linux kernel parses the ISA extensions from "riscv,isa" DT
> > property. It used to parse only the single letter base extensions
> > until now. A generic ISA extension parsing framework was proposed[1]
> > recently that can parse multi-letter ISA extensions as well.
> >
> > Generate the extended ISA string by appending  the available ISA extensions
>
> nits: remove one space after "appending"
>

Will fix it.

> > to the "riscv,isa" string if it is enabled so that kernel can process it.
> >
> > [1] https://lkml.org/lkml/2022/2/15/263
>
> Could you please post a link to the "riscv,isa" DT bindings spec or
> discussion thread? It seems not mentioned in the above LKML thread.
>

Latest discussion on the discussion:
https://lkml.org/lkml/2022/3/10/1416

riscv,isa DT binding:
https://elixir.bootlin.com/linux/v5.17-rc8/source/Documentation/devicetree/bindings/riscv/cpus.yaml#L66

> >
> > Reviewed-by: Anup Patel 
> > Reviewed-by: Alistair Francis 
> > Suggested-by: Heiko Stubner 
> > Signed-off-by: Atish Patra 
> > ---
> > Changes from v4->v5:
> > 1. Fixed the order of Zxx extensions.
> > 2. Added a comment clearly describing the rules of extension order.
> >
> > Changes from v3->v4:
> > 1. Fixed the order of the extension names.
> > 2. Added all the available ISA extensions in Qemu.
> >
> > Changes from v2->v3:
> > 1. Used g_strconcat to replace snprintf & a max isa string length as
> > suggested by Anup.
> > 2. I have not included the Tested-by Tag from Heiko because the
> > implementation changed from v2 to v3.
> >
> > Changes from v1->v2:
> > 1. Improved the code redability by using arrays instead of individual check
> > ---
> >  target/riscv/cpu.c | 61 ++
> >  1 file changed, 61 insertions(+)
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index ddda4906ffb7..097c42f5c50f 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -34,6 +34,12 @@
> >
> >  /* RISC-V CPU definitions */
> >
> > +/* This includes the null terminated character '\0' */
> > +struct isa_ext_data {
> > +const char *name;
> > +bool enabled;
> > +};
> > +
> >  static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
> >
> >  const char * const riscv_int_regnames[] = {
> > @@ -898,6 +904,60 @@ static void riscv_cpu_class_init(ObjectClass *c, void 
> > *data)
> >  device_class_set_props(dc, riscv_cpu_properties);
> >  }
> >
> > +#define ISA_EDATA_ENTRY(name, prop) {#name, cpu->cfg.prop}
> > +
> > +static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, int 
> > max_str_len)
> > +{
> > +char *old = *isa_str;
> > +char *new = *isa_str;
> > +int i;
> > +
> > +/**
> > + * Here are the ordering rules of extension naming defined by RISC-V
> > + * specification :
> > + * 1. All extensions should be separated from other multi-letter 
> > extensions
> > + *from other multi-letter extensions by an underscore.
>
> redundant "from other multi-letter extensions"
>

Oops. Will fix it.

> > + * 2. The first letter following the 'Z' conventionally indicates the 
> > most
>
> Should this be lower case "z"?

Nope. I am just iterating the rules defined by the spec. The device
tree has lower case 'z'
as per the device binding which mandates all lower case.

>
> > + *closely related alphabetical extension category, IMAFDQLCBKJTPVH.
> > + *If multiple 'Z' extensions are named, they should be ordered 
> > first
> > + *by category, then alphabetically within a category.
> > + * 3. Standard supervisor-level extensions (starts with 'S') should be
>
> lower case "s"?

Same reasoning as above.

>
> > + *listed after standard unprivileged extensions.  If multiple
> > + *supervisor-level extensions are listed, they should be ordered
> > + *alphabetically.
> > + * 4. Non-standard extensions (starts with 'X') must be listed after 
> > all
> > + *standard extensions. They must be separated from other 
> > multi-letter
> > + *extensions by an underscore.
> > + */
> > +struct isa_ext_data isa_edata_arr[] = {
> > +ISA_EDATA_ENTRY(zfh, ext_zfhmin),
>
> This should be (zfh, ext_zfh)

Yeah. It's a typo. Thanks for catching it.

>
> > +ISA_EDATA_ENTRY(zfhmin, ext_zfhmin),
> > +ISA_EDATA_ENTRY(zfinx, ext_zfinx),
> > +ISA_EDATA_ENTRY(zdinx, ext_zdinx),
>
> Should "zdinx" come before "zfinx" *alphabetically* ?

As per the ISA naming rules,

"The first letter following the 'Z' conventionally indicates the most
closely related alphabetical extension category, IMAFDQLCBKJTPVH.
If multiple 'Z' extensions are named, they should be ordered first
by category, then alphabetically within a category."

That's why, zfinx comes before zdinx.
>
> > +ISA_EDATA_ENTRY(zba, ext_zba),
> > +ISA_EDATA_ENTRY(zbb, 

Re: [PATCH v4] target/riscv: Add isa extenstion strings to the device tree

2022-03-10 Thread Atish Kumar Patra
On Wed, Mar 9, 2022 at 5:47 AM Frank Chang  wrote:
>
> Atish Patra  於 2022年3月9日 週三 上午8:53寫道:
>>
>> The Linux kernel parses the ISA extensions from "riscv,isa" DT
>> property. It used to parse only the single letter base extensions
>> until now. A generic ISA extension parsing framework was proposed[1]
>> recently that can parse multi-letter ISA extensions as well.
>>
>> Generate the extended ISA string by appending  the available ISA extensions
>> to the "riscv,isa" string if it is enabled so that kernel can process it.
>>
>> [1] https://lkml.org/lkml/2022/2/15/263
>>
>> Reviewed-by: Anup Patel 
>> Reviewed-by: Alistair Francis 
>> Suggested-by: Heiko Stubner 
>> Signed-off-by: Atish Patra 
>> ---
>>
>> Changes from v3->v4:
>> 1. Fixed the order of the extension names.
>> 2. Added all the available ISA extensions in Qemu.
>>
>> Changes from v2->v3:
>> 1. Used g_strconcat to replace snprintf & a max isa string length as
>> suggested by Anup.
>> 2. I have not included the Tested-by Tag from Heiko because the
>> implementation changed from v2 to v3.
>>
>> Changes from v1->v2:
>> 1. Improved the code redability by using arrays instead of individual check
>> ---
>>  target/riscv/cpu.c | 43 +++
>>  1 file changed, 43 insertions(+)
>>
>> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>> index ddda4906ffb7..2521a6f31f9f 100644
>> --- a/target/riscv/cpu.c
>> +++ b/target/riscv/cpu.c
>> @@ -34,6 +34,12 @@
>>
>>  /* RISC-V CPU definitions */
>>
>> +/* This includes the null terminated character '\0' */
>> +struct isa_ext_data {
>> +const char *name;
>> +bool enabled;
>> +};
>> +
>>  static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
>>
>>  const char * const riscv_int_regnames[] = {
>> @@ -898,6 +904,42 @@ static void riscv_cpu_class_init(ObjectClass *c, void 
>> *data)
>>  device_class_set_props(dc, riscv_cpu_properties);
>>  }
>>
>> +#define ISA_EDATA_ENTRY(name, prop) {#name, cpu->cfg.prop}
>> +
>> +static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, int 
>> max_str_len)
>> +{
>> +char *old = *isa_str;
>> +char *new = *isa_str;
>> +int i;
>> +struct isa_ext_data isa_edata_arr[] = {
>> +ISA_EDATA_ENTRY(svinval, ext_svinval),
>> +ISA_EDATA_ENTRY(svnapot, ext_svnapot),
>> +ISA_EDATA_ENTRY(svpbmt, ext_svpbmt),
>> +ISA_EDATA_ENTRY(zba, ext_zba),
>> +ISA_EDATA_ENTRY(zbb, ext_zbb),
>> +ISA_EDATA_ENTRY(zbc, ext_zbc),
>> +ISA_EDATA_ENTRY(zbs, ext_zbs),
>> +ISA_EDATA_ENTRY(zdinx, ext_zdinx),
>> +ISA_EDATA_ENTRY(zfh, ext_zfhmin),
>> +ISA_EDATA_ENTRY(zfhmin, ext_zfhmin),
>> +ISA_EDATA_ENTRY(zfinx, ext_zfinx),
>> +ISA_EDATA_ENTRY(zhinx, ext_zhinx),
>> +ISA_EDATA_ENTRY(zhinxmin, ext_zhinxmin),
>> +ISA_EDATA_ENTRY(zve32f, ext_zve32f),
>> +ISA_EDATA_ENTRY(zve64f, ext_zve64f),
>> +};
>
>
> Hi Atish,
>
> According to RISC-V Unpriviledge spec, Section 28.6:
> https://github.com/riscv/riscv-isa-manual/blob/master/src/naming.tex#L85
>
> "The first letter following the “Z” conventionally indicates the most closely
> related alphabetical extension category, IMAFDQLCBKJTPV.
> For the “Zam” extension for misaligned atomics,
> for example, the letter “a” indicates the extension is related to the “A” 
> standard extension.
> If multiple “Z” extensions are named, they should be ordered first by 
> category,
> then alphabetically within a category—for example, “Zicsr Zifencei Zam”."
>

Yes. Sorry I missed that part. Will fix it.

> So I think the order of "Z" extensions should be:
> zfh, zfhmin, zfinx, zdinx, zba, zbb, zbc, zbs, zve32f, zve64f, zhinx, zhinxmin
>
> Also, I think "Zifencei" and "Zicsr" should also be covered as well,
> and all extensions should follow the order defined in Table 28.11:
> https://github.com/riscv/riscv-isa-manual/blob/master/src/naming.tex#L141
>

I thought about that earlier as well. Zifencei & Zicsr was already
part of the ISA and carved out as an extension later.
Qemu/Any supervisor support that by default and won't work without
that. We can't possibly disable those and boot anything.

Do you think there is any benefit adding it ?


> "The table also defines the canonical order in which extension names must 
> appear in the name string,
> with top-to-bottom in table indicating first-to-last in the name string,
> e.g., RV32IMACV is legal, whereas RV32IMAVC is not."
>
> So the overall order would be:
> zicsr, zifencei, zfh, zfhmin, zfinx, zdinx, zba, zbb, zbc, zbs, zve32f, 
> zve64f, zhinx, zhinxmin, svinval, svnapot, svpbmt,
>
> Regards,
> Frank Chang
>
>>
>> +
>> +for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
>> +if (isa_edata_arr[i].enabled) {
>> +new = g_strconcat(old, "_", isa_edata_arr[i].name, NULL);
>> +g_free(old);
>> +old = new;
>> +}
>> +}
>> +
>> +*isa_str = new;
>> +}
>> +
>>  char 

Re: [PATCH v3] target/riscv: Add isa extenstion strings to the device tree

2022-03-05 Thread Atish Kumar Patra
On Sat, Mar 5, 2022 at 9:36 PM Frank Chang  wrote:

> On Sun, Mar 6, 2022 at 7:42 AM Atish Kumar Patra 
> wrote:
>
>>
>>
>> On Sat, Mar 5, 2022 at 10:05 AM Heiko Stuebner  wrote:
>>
>>> Hi,
>>>
>>> Am Donnerstag, 3. März 2022, 19:58:38 CET schrieb Atish Patra:
>>> > On Fri, Feb 25, 2022 at 11:46 PM Frank Chang 
>>> wrote:
>>> > > Atish Patra  於 2022年2月23日 週三 上午6:39寫道:
>>> > >>
>>> > >> The Linux kernel parses the ISA extensions from "riscv,isa" DT
>>> > >> property. It used to parse only the single letter base extensions
>>> > >> until now. A generic ISA extension parsing framework was proposed[1]
>>> > >> recently that can parse multi-letter ISA extensions as well.
>>> > >>
>>> > >> Generate the extended ISA string by appending  the available ISA
>>> extensions
>>> > >> to the "riscv,isa" string if it is enabled so that kernel can
>>> process it.
>>> > >>
>>> > >> [1] https://lkml.org/lkml/2022/2/15/263
>>> > >>
>>> > >> Suggested-by: Heiko Stubner 
>>> > >> Signed-off-by: Atish Patra 
>>> > >> ---
>>> > >> Changes from v2->v3:
>>> > >> 1. Used g_strconcat to replace snprintf & a max isa string length as
>>> > >> suggested by Anup.
>>> > >> 2. I have not included the Tested-by Tag from Heiko because the
>>> > >> implementation changed from v2 to v3.
>>> > >>
>>> > >> Changes from v1->v2:
>>> > >> 1. Improved the code redability by using arrays instead of
>>> individual check
>>> > >> ---
>>> > >>  target/riscv/cpu.c | 29 +
>>> > >>  1 file changed, 29 insertions(+)
>>> > >>
>>> > >> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
>>> > >> index b0a40b83e7a8..2c7ff6ef555a 100644
>>> > >> --- a/target/riscv/cpu.c
>>> > >> +++ b/target/riscv/cpu.c
>>> > >> @@ -34,6 +34,12 @@
>>> > >>
>>> > >>  /* RISC-V CPU definitions */
>>> > >>
>>> > >> +/* This includes the null terminated character '\0' */
>>> > >> +struct isa_ext_data {
>>> > >> +const char *name;
>>> > >> +bool enabled;
>>> > >> +};
>>> > >> +
>>> > >>  static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
>>> > >>
>>> > >>  const char * const riscv_int_regnames[] = {
>>> > >> @@ -881,6 +887,28 @@ static void riscv_cpu_class_init(ObjectClass
>>> *c, void *data)
>>> > >>  device_class_set_props(dc, riscv_cpu_properties);
>>> > >>  }
>>> > >>
>>> > >> +static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str,
>>> int max_str_len)
>>> > >> +{
>>> > >> +char *old = *isa_str;
>>> > >> +char *new = *isa_str;
>>> > >> +int i;
>>> > >> +struct isa_ext_data isa_edata_arr[] = {
>>> > >> +{ "svpbmt", cpu->cfg.ext_svpbmt   },
>>> > >> +{ "svinval", cpu->cfg.ext_svinval },
>>> > >> +{ "svnapot", cpu->cfg.ext_svnapot },
>>> > >
>>> > >
>>> > > We still have other sub-extensions, e.g. Zfh, Zba, Zbb, Zbc, Zbs...
>>> etc.
>>> > > Do you mind adding them as well?
>>> > >
>>> >
>>> > Do we really need it ? Does any OS actually parse it from the device
>>> tree ?
>>> > AFAIK, Linux kernel doesn't use them. As the device tree is intended
>>> > to keep the information useful
>>> > for supervisor software,
>>>
>>> That actually isn't true ;-) .
>>>
>>> The devicetree is intended to _describe_ the hardware present in full
>>> and has really nothing to do with what the userspace needs.
>>> So the argument "Linux doesn't need this" is never true when talking
>>> about devicetrees ;-) .
>>>
>>
>> Yes. I didn’t mean that way. I was simply asking if these extensions
>> currently in use. I just mentioned Linux as an ex

Re: [PATCH v3] target/riscv: Add isa extenstion strings to the device tree

2022-03-05 Thread Atish Kumar Patra
On Sat, Mar 5, 2022 at 10:05 AM Heiko Stuebner  wrote:

> Hi,
>
> Am Donnerstag, 3. März 2022, 19:58:38 CET schrieb Atish Patra:
> > On Fri, Feb 25, 2022 at 11:46 PM Frank Chang 
> wrote:
> > > Atish Patra  於 2022年2月23日 週三 上午6:39寫道:
> > >>
> > >> The Linux kernel parses the ISA extensions from "riscv,isa" DT
> > >> property. It used to parse only the single letter base extensions
> > >> until now. A generic ISA extension parsing framework was proposed[1]
> > >> recently that can parse multi-letter ISA extensions as well.
> > >>
> > >> Generate the extended ISA string by appending  the available ISA
> extensions
> > >> to the "riscv,isa" string if it is enabled so that kernel can process
> it.
> > >>
> > >> [1] https://lkml.org/lkml/2022/2/15/263
> > >>
> > >> Suggested-by: Heiko Stubner 
> > >> Signed-off-by: Atish Patra 
> > >> ---
> > >> Changes from v2->v3:
> > >> 1. Used g_strconcat to replace snprintf & a max isa string length as
> > >> suggested by Anup.
> > >> 2. I have not included the Tested-by Tag from Heiko because the
> > >> implementation changed from v2 to v3.
> > >>
> > >> Changes from v1->v2:
> > >> 1. Improved the code redability by using arrays instead of individual
> check
> > >> ---
> > >>  target/riscv/cpu.c | 29 +
> > >>  1 file changed, 29 insertions(+)
> > >>
> > >> diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > >> index b0a40b83e7a8..2c7ff6ef555a 100644
> > >> --- a/target/riscv/cpu.c
> > >> +++ b/target/riscv/cpu.c
> > >> @@ -34,6 +34,12 @@
> > >>
> > >>  /* RISC-V CPU definitions */
> > >>
> > >> +/* This includes the null terminated character '\0' */
> > >> +struct isa_ext_data {
> > >> +const char *name;
> > >> +bool enabled;
> > >> +};
> > >> +
> > >>  static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG";
> > >>
> > >>  const char * const riscv_int_regnames[] = {
> > >> @@ -881,6 +887,28 @@ static void riscv_cpu_class_init(ObjectClass *c,
> void *data)
> > >>  device_class_set_props(dc, riscv_cpu_properties);
> > >>  }
> > >>
> > >> +static void riscv_isa_string_ext(RISCVCPU *cpu, char **isa_str, int
> max_str_len)
> > >> +{
> > >> +char *old = *isa_str;
> > >> +char *new = *isa_str;
> > >> +int i;
> > >> +struct isa_ext_data isa_edata_arr[] = {
> > >> +{ "svpbmt", cpu->cfg.ext_svpbmt   },
> > >> +{ "svinval", cpu->cfg.ext_svinval },
> > >> +{ "svnapot", cpu->cfg.ext_svnapot },
> > >
> > >
> > > We still have other sub-extensions, e.g. Zfh, Zba, Zbb, Zbc, Zbs...
> etc.
> > > Do you mind adding them as well?
> > >
> >
> > Do we really need it ? Does any OS actually parse it from the device
> tree ?
> > AFAIK, Linux kernel doesn't use them. As the device tree is intended
> > to keep the information useful
> > for supervisor software,
>
> That actually isn't true ;-) .
>
> The devicetree is intended to _describe_ the hardware present in full
> and has really nothing to do with what the userspace needs.
> So the argument "Linux doesn't need this" is never true when talking
> about devicetrees ;-) .
>

Yes. I didn’t mean that way. I was simply asking if these extensions
currently in use. I just mentioned Linux as an example.

The larger point I was trying to make if we should add all the supported
extensions when they are added to Qemu or on a need basis.

I don’t feel strongly either way. So I am okay with the former approach if
that’s what everyone prefers!

>
> On the other hand the devicetree user doesn't need to parse everything
> from DT. So adding code to parse things only really is needed if you
> need that information.
>

Agreed.


> So if some part of the kernel needs to know about those additional
> extensions, the array entries for them can also be added in a later patch.
>

Yes. That was the idea in isa extension framework series where the
extension specific array entries will only be added when support for that
extension is enabled.

>
>
> Heiko
>
> > > Also, I think the order of ISA strings should be alphabetical as
> described:
> > >
> https://github.com/riscv/riscv-isa-manual/blob/master/src/naming.tex#L96
> > >
> >
> > Ahh yes. I will order them in alphabetical order and leave a big
> > comment for future reference as well.
> >
> > > Regards,
> > > Frank Chang
> > >
> > >>
> > >> +};
> > >> +
> > >> +for (i = 0; i < ARRAY_SIZE(isa_edata_arr); i++) {
> > >> +if (isa_edata_arr[i].enabled) {
> > >> +new = g_strconcat(old, "_", isa_edata_arr[i].name, NULL);
> > >> +g_free(old);
> > >> +old = new;
> > >> +}
> > >> +}
> > >> +
> > >> +*isa_str = new;
> > >> +}
> > >> +
> > >>  char *riscv_isa_string(RISCVCPU *cpu)
> > >>  {
> > >>  int i;
> > >> @@ -893,6 +921,7 @@ char *riscv_isa_string(RISCVCPU *cpu)
> > >>  }
> > >>  }
> > >>  *p = '\0';
> > >> +riscv_isa_string_ext(cpu, _str, maxlen);
> > >>  return isa_str;
> > >>  }
> > >>
> > >> --
> > >> 2.30.2
> > >>
> >
> >

Re: [PATCH v5 08/12] target/riscv: Add sscofpmf extension support

2022-03-03 Thread Atish Kumar Patra
 fa

On Wed, Mar 2, 2022 at 2:37 PM Alistair Francis  wrote:
>
> On Sat, Feb 19, 2022 at 10:31 AM Atish Patra  wrote:
> >
> > The Sscofpmf ('Ss' for Privileged arch and Supervisor-level extensions,
> > and 'cofpmf' for Count OverFlow and Privilege Mode Filtering)
> > extension allows the perf to handle overflow interrupts and filtering
> > support. This patch provides a framework for programmable
> > counters to leverage the extension. As the extension doesn't have any
> > provision for the overflow bit for fixed counters, the fixed events
> > can also be monitoring using programmable counters. The underlying
> > counters for cycle and instruction counters are always running. Thus,
> > a separate timer device is programmed to handle the overflow.
> >
> > Signed-off-by: Atish Patra 
> > Signed-off-by: Atish Patra 
> > ---
> >  target/riscv/cpu.c  |  12 ++
> >  target/riscv/cpu.h  |  25 +++
> >  target/riscv/cpu_bits.h |  55 +++
> >  target/riscv/csr.c  | 159 --
> >  target/riscv/pmu.c  | 346 +++-
> >  target/riscv/pmu.h  |   8 +
> >  6 files changed, 593 insertions(+), 12 deletions(-)
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 02e089710a7e..677210bc6d94 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -22,6 +22,7 @@
> >  #include "qemu/ctype.h"
> >  #include "qemu/log.h"
> >  #include "cpu.h"
> > +#include "pmu.h"
> >  #include "internals.h"
> >  #include "exec/exec-all.h"
> >  #include "qapi/error.h"
> > @@ -678,6 +679,16 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
> > **errp)
> >  set_misa(env, env->misa_mxl, ext);
> >  }
> >
> > +if (cpu->cfg.pmu_num) {
> > +if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && 
> > cpu->cfg.ext_sscofpmf) {
> > +cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> > +  riscv_pmu_timer_cb, cpu);
> > +if (!cpu->pmu_timer) {
>
> Is this possible?
>

Only if g_malloc0 fails. At that point, we will probably have much
bigger problems.
I will remove it.

> Alistair
>
> > +cpu->cfg.ext_sscofpmf = false;
> > +}
> > +}
> > + }
> > +
> >  riscv_cpu_register_gdb_regs_for_features(cs);
> >
> >  qemu_init_vcpu(cs);
> > @@ -769,6 +780,7 @@ static Property riscv_cpu_properties[] = {
> >  DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
> >  DEFINE_PROP_BOOL("h", RISCVCPU, cfg.ext_h, true),
> >  DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
> > +DEFINE_PROP_BOOL("sscofpmf", RISCVCPU, cfg.ext_sscofpmf, false),
> >  DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
> >  DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
> >  DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 68522acda4d2..e2f92bb648d4 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -129,6 +129,8 @@ typedef struct PMUCTRState {
> >  /* Snapshort value of a counter in RV32 */
> >  target_ulong mhpmcounterh_prev;
> >  bool started;
> > +/* Value beyond UINT32_MAX/UINT64_MAX before overflow interrupt 
> > trigger */
> > +target_ulong irq_overflow_left;
> >  } PMUCTRState;
> >
> >  struct CPURISCVState {
> > @@ -281,6 +283,9 @@ struct CPURISCVState {
> >  /* PMU event selector configured values. First three are unused*/
> >  target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
> >
> > +/* PMU event selector configured values for RV32*/
> > +target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
> > +
> >  target_ulong sscratch;
> >  target_ulong mscratch;
> >
> > @@ -396,6 +401,7 @@ struct RISCVCPUConfig {
> >  bool ext_zfhmin;
> >  bool ext_zve32f;
> >  bool ext_zve64f;
> > +bool ext_sscofpmf;
> >
> >  /* Vendor-specific custom extensions */
> >  bool ext_XVentanaCondOps;
> > @@ -434,6 +440,12 @@ struct RISCVCPU {
> >
> >  /* Configuration Settings */
> >  RISCVCPUConfig cfg;
> > +
> > +QEMUTimer *pmu_timer;
> > +/* A bitmask of Available programmable counters */
> > +uint32_t pmu_avail_ctrs;
> > +/* Mapping of events to counters */
> > +GHashTable *pmu_event_ctr_map;
> >  };
> >
> >  static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
> > @@ -693,6 +705,19 @@ enum {
> >  CSR_TABLE_SIZE = 0x1000
> >  };
> >
> > +/**
> > + * The event id are encoded based on the encoding specified in the
> > + * SBI specification v0.3
> > + */
> > +
> > +enum riscv_pmu_event_idx {
> > +RISCV_PMU_EVENT_HW_CPU_CYCLES = 0x01,
> > +RISCV_PMU_EVENT_HW_INSTRUCTIONS = 0x02,
> > +RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS = 0x10019,
> > +RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS = 0x1001B,
> > +RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS = 0x10021,
> > +};
> > +
> >  /* CSR function table */
> >  extern riscv_csr_operations 

Re: [PATCH v5 07/12] target/riscv: Support mcycle/minstret write operation

2022-03-03 Thread Atish Kumar Patra
On Mon, Feb 28, 2022 at 10:14 PM Alistair Francis  wrote:
>
> On Sat, Feb 19, 2022 at 10:32 AM Atish Patra  wrote:
> >
> > From: Atish Patra 
> >
> > mcycle/minstret are actually WARL registers and can be written with any
> > given value. With SBI PMU extension, it will be used to store a initial
> > value provided from supervisor OS. The Qemu also need prohibit the counter
> > increment if mcountinhibit is set.
> >
> > Support mcycle/minstret through generic counter infrastructure.
> >
> > Signed-off-by: Atish Patra 
> > Signed-off-by: Atish Patra 
> > ---
> >  target/riscv/cpu.h   |  23 +--
> >  target/riscv/csr.c   | 145 +++
> >  target/riscv/machine.c   |  25 ++-
> >  target/riscv/meson.build |   1 +
> >  target/riscv/pmu.c   |  32 +
> >  target/riscv/pmu.h   |  28 
> >  6 files changed, 201 insertions(+), 53 deletions(-)
> >  create mode 100644 target/riscv/pmu.c
> >  create mode 100644 target/riscv/pmu.h
> >
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index cce5c3538c89..68522acda4d2 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -109,7 +109,7 @@ typedef struct CPURISCVState CPURISCVState;
> >  #endif
> >
> >  #define RV_VLEN_MAX 1024
> > -#define RV_MAX_MHPMEVENTS 29
> > +#define RV_MAX_MHPMEVENTS 32
> >  #define RV_MAX_MHPMCOUNTERS 32
> >
> >  FIELD(VTYPE, VLMUL, 0, 3)
> > @@ -119,6 +119,18 @@ FIELD(VTYPE, VMA, 7, 1)
> >  FIELD(VTYPE, VEDIV, 8, 2)
> >  FIELD(VTYPE, RESERVED, 10, sizeof(target_ulong) * 8 - 11)
> >
> > +typedef struct PMUCTRState {
> > +/* Current value of a counter */
> > +target_ulong mhpmcounter_val;
> > +/* Current value of a counter in RV32*/
> > +target_ulong mhpmcounterh_val;
> > +/* Snapshot values of counter */
> > +target_ulong mhpmcounter_prev;
> > +/* Snapshort value of a counter in RV32 */
> > +target_ulong mhpmcounterh_prev;
> > +bool started;
> > +} PMUCTRState;
> > +
> >  struct CPURISCVState {
> >  target_ulong gpr[32];
> >  target_ulong gprh[32]; /* 64 top bits of the 128-bit registers */
> > @@ -263,13 +275,10 @@ struct CPURISCVState {
> >
> >  target_ulong mcountinhibit;
> >
> > -/* PMU counter configured values */
> > -target_ulong mhpmcounter_val[RV_MAX_MHPMCOUNTERS];
> > -
> > -/* for RV32 */
> > -target_ulong mhpmcounterh_val[RV_MAX_MHPMCOUNTERS];
> > +/* PMU counter state */
> > +PMUCTRState pmu_ctrs[RV_MAX_MHPMCOUNTERS];
> >
> > -/* PMU event selector configured values */
> > +/* PMU event selector configured values. First three are unused*/
> >  target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
> >
> >  target_ulong sscratch;
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index dbb723a3307b..dc4d258205b3 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -20,6 +20,7 @@
> >  #include "qemu/osdep.h"
> >  #include "qemu/log.h"
> >  #include "cpu.h"
> > +#include "pmu.h"
> >  #include "qemu/main-loop.h"
> >  #include "exec/exec-all.h"
> >
> > @@ -539,39 +540,33 @@ static int write_vcsr(CPURISCVState *env, int csrno, 
> > target_ulong val)
> >  }
> >
> >  /* User Timers and Counters */
> > -static RISCVException read_instret(CPURISCVState *env, int csrno,
> > -   target_ulong *val)
> > +static target_ulong get_icount_ticks(bool rv32)
>
> Maybe get_ticks() instead?
>

Sure. Will rename it.


> Also rv32 could be something more descriptive, maybe just shift instead?
>

Sure. Will change it.

> Otherwise:
>
> Reviewed-by: Alistair Francis 
>
> Alistair
>
> >  {
> > +int64_t val;
> > +target_ulong result;
> > +
> >  #if !defined(CONFIG_USER_ONLY)
> >  if (icount_enabled()) {
> > -*val = icount_get();
> > +val = icount_get();
> >  } else {
> > -*val = cpu_get_host_ticks();
> > +val = cpu_get_host_ticks();
> >  }
> >  #else
> > -*val = cpu_get_host_ticks();
> > +val = cpu_get_host_ticks();
> >  #endif
> > -return RISCV_EXCP_NONE;
> > -}
> >
> > -static RISCVException read_instreth(CPURISCVState *env, int csrno,
> > -target_ulong *val)
> > -{
> > -#if !defined(CONFIG_USER_ONLY)
> > -if (icount_enabled()) {
> > -*val = icount_get() >> 32;
> > +if (rv32) {
> > +result = val >> 32;
> >  } else {
> > -*val = cpu_get_host_ticks() >> 32;
> > +result = val;
> >  }
> > -#else
> > -*val = cpu_get_host_ticks() >> 32;
> > -#endif
> > -return RISCV_EXCP_NONE;
> > +
> > +return result;
> >  }
> >
> >  static int read_mhpmevent(CPURISCVState *env, int csrno, target_ulong *val)
> >  {
> > -int evt_index = csrno - CSR_MHPMEVENT3;
> > +int evt_index = csrno - CSR_MCOUNTINHIBIT;
> >
> >  *val = env->mhpmevent_val[evt_index];
> >
> > @@ -580,7 +575,7 @@ static int read_mhpmevent(CPURISCVState *env, int 
> > csrno, target_ulong *val)
> >
> >  static int 

Re: [PATCH v5 01/12] target/riscv: Fix PMU CSR predicate function

2022-03-03 Thread Atish Kumar Patra
On Wed, Mar 2, 2022 at 9:22 PM Alistair Francis  wrote:
>
> On Sat, Feb 19, 2022 at 10:34 AM Atish Patra  wrote:
> >
> > From: Atish Patra 
> >
> > The predicate function calculates the counter index incorrectly for
> > hpmcounterx. Fix the counter index to reflect correct CSR number.
> >
> > Fixes: e39a8320b088 ("target/riscv: Support the Virtual Instruction fault")
> >
> > Reviewed-by: Alistair Francis 
> > Reviewed-by: Bin Meng 
> > Signed-off-by: Atish Patra 
> > Signed-off-by: Atish Patra 
> > ---
> >  target/riscv/csr.c | 10 ++
> >  1 file changed, 6 insertions(+), 4 deletions(-)
> >
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index b16881615997..3799ee850087 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -94,8 +94,9 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
> >  }
> >  break;
> >  case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
> > -if (!get_field(env->hcounteren, 1 << (csrno - 
> > CSR_HPMCOUNTER3)) &&
> > -get_field(env->mcounteren, 1 << (csrno - 
> > CSR_HPMCOUNTER3))) {
> > +ctr_index = csrno - CSR_CYCLE;
> > +if (!get_field(env->hcounteren, 1 << ctr_index) &&
> > + get_field(env->mcounteren, 1 << ctr_index)) {
>
> This fails to build:
>
> ../target/riscv/csr.c: In function ‘ctr’:
> ../target/riscv/csr.c:99:13: error: ‘ctr_index’ undeclared (first use
> in this function); did you mean ‘tlb_index’?
>   99 | ctr_index = csrno - CSR_CYCLE;
>  | ^
>  | tlb_index
>

My bad. The ctr_index is defined in PATCH 2. I think I forgot to move
it when I split this one
from PATCH 2. I will send a v6 after addressing your comments on other
patches in this series.

> Alistair
>
> >  return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> >  }
> >  break;
> > @@ -121,8 +122,9 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
> >  }
> >  break;
> >  case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
> > -if (!get_field(env->hcounteren, 1 << (csrno - 
> > CSR_HPMCOUNTER3H)) &&
> > -get_field(env->mcounteren, 1 << (csrno - 
> > CSR_HPMCOUNTER3H))) {
> > +ctr_index = csrno - CSR_CYCLEH;
> > +if (!get_field(env->hcounteren, 1 << ctr_index) &&
> > + get_field(env->mcounteren, 1 << ctr_index)) {
> >  return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> >  }
> >  break;
> > --
> > 2.30.2
> >
> >



Re: [RFC 4/5] target/riscv: Add *envcfg* CSRs support

2022-02-03 Thread Atish Kumar Patra
On Thu, Feb 3, 2022 at 4:23 AM Heiko Stübner  wrote:

> Hi Atish,
>
> Am Donnerstag, 20. Januar 2022, 21:07:34 CET schrieb Atish Patra:
> > The RISC-V privileged specification v1.12 defines few execution
> > environment configuration CSRs that can be used enable/disable
> > extensions per privilege levels.
> >
> > Add the basic support for these CSRs.
> >
> > Signed-off-by: Atish Patra 
> > ---
> >  target/riscv/cpu.h  |  8 
> >  target/riscv/cpu_bits.h | 31 +++
> >  target/riscv/csr.c  | 84 +
> >  target/riscv/machine.c  | 26 +
> >  4 files changed, 149 insertions(+)
> >
> > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> > index f6f90b5cbd52..afb237c2313b 100644
> > --- a/target/riscv/cpu_bits.h
> > +++ b/target/riscv/cpu_bits.h
>
> [...]
>
> > @@ -578,6 +589,26 @@ typedef enum RISCVException {
> >  #define PM_EXT_CLEAN0x0002ULL
> >  #define PM_EXT_DIRTY0x0003ULL
> >
> > +/* Execution enviornment configuration bits */
> > +#define MENVCFG_FIOM   (1 << 0)
>
> > +#define MENVCFG_CBE0x3ULL
>
> Looking both at the cmo spec as well as the most recent privileged spec
> (draft) the field is called CBIE it seems.
>
> Also the shift looks wrong. Both cmo as well as privileged spec show
> it at bits [5:4] and _not_ [17:16].
>
>
This looks like a typo from my side. These bits are reserved in the spec!
Apologies for such a silly mistake. Fixed it in v2.


> Also wouldn't doing it like (_UL(3) << 4) be better to catch such things?
>
>
Of course.


> > +#define MENVCFG_CBCFE  (1 << 6)
> > +#define MENVCFG_CBZE   (1 << 7)
> > +#define MENVCFG_PBMTE  (1 << 62)
> > +#define MENVCFG_STCE   (1 << 63)
> > +
> > +#define SENVCFG_FIOM   MENVCFG_FIOM
> > +#define SENVCFG_CBEMENVCFG_CBE
> > +#define SENVCFG_CBCFE  MENVCFG_CBCFE
> > +#define SENVCFG_CBZE   MENVCFG_CBZE
> > +
> > +#define HENVCFG_FIOM   MENVCFG_FIOM
> > +#define HENVCFG_CBEMENVCFG_CBE
> > +#define HENVCFG_CBCFE  MENVCFG_CBCFE
> > +#define HENVCFG_CBZE   MENVCFG_CBZE
> > +#define HENVCFG_PBMTE  MENVCFG_PBMTE
> > +#define HENVCFG_STCE   MENVCFG_STCE
> > +
> >  /* Offsets for every pair of control bits per each priv level */
> >  #define XS_OFFSET0ULL
> >  #define U_OFFSET 2ULL
>
>
> Heiko
>
>
>


Re: [RFC 4/5] target/riscv: Add *envcfg* CSRs support

2022-01-31 Thread Atish Kumar Patra
On Fri, Jan 28, 2022 at 5:50 PM angell1518  wrote:

>
> 在 2022/1/29 上午9:28, Atish Patra 写道:
>
>
>
> On Wed, Jan 26, 2022 at 12:37 AM Weiwei Li  wrote:
>
>>
>> 在 2022/1/21 上午4:07, Atish Patra 写道:
>> > The RISC-V privileged specification v1.12 defines few execution
>> > environment configuration CSRs that can be used enable/disable
>> > extensions per privilege levels.
>> >
>> > Add the basic support for these CSRs.
>> >
>> > Signed-off-by: Atish Patra 
>> > ---
>> >   target/riscv/cpu.h  |  8 
>> >   target/riscv/cpu_bits.h | 31 +++
>> >   target/riscv/csr.c  | 84 +
>> >   target/riscv/machine.c  | 26 +
>> >   4 files changed, 149 insertions(+)
>> >
>> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
>> > index 7f87917204c5..b9462300a472 100644
>> > --- a/target/riscv/cpu.h
>> > +++ b/target/riscv/cpu.h
>> > @@ -264,6 +264,14 @@ struct CPURISCVState {
>> >   target_ulong spmbase;
>> >   target_ulong upmmask;
>> >   target_ulong upmbase;
>> > +
>> > +/* CSRs for execution enviornment configuration */
>> > +
>> > +target_ulong menvcfg;
>> > +target_ulong menvcfgh;
>>
>> I think we needn't maintain seperate menvcfg and menvcfgh, just use
>> "uint64_t menvcfg" as the way of mstatus.
>>
>>
> unlike mstatush, menvcfgh/henvcfgh will be accessed directly to do runtime
> predicate for stimecmp/vstimecmp.
>
> We have to do the 32 bit shifting during every check which makes the code
> hard to read
> at the cost of 2 ulongs.
>
> IMO, having separate variables is much simpler.
>
> Do you mean check STCE/VSTCE bit in menvcfg/henvcfg?
>
> If so, I think use a simple "uint64_t menvcfg/henvcfg" may be better,
> then we can only check the 63 bit of them.
>

Which is a bit confusing as the STCE bit in mencfgh/henvcfgh is 31 not 63.
But that's my personal preference.

I will just leave a comment to clarify the confusion for now. I will send a
patch with unified menvcfg and wait for others's feedback.

> Or we should decide where to get this bit from(mencvfg/henvcfg, or
> mencfgh/henvcfgh) based on the MXLEN/HSXLEN.
>
> Regards,
>
> Weiwei Li
>
>
> Similar to  henvcfg and henvcfg.
>>
>> > +target_ulong senvcfg;
>> > +target_ulong henvcfg;
>> > +target_ulong henvcfgh;
>> >   #endif
>> >
>> >   float_status fp_status;
>> > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
>> > index f6f90b5cbd52..afb237c2313b 100644
>> > --- a/target/riscv/cpu_bits.h
>> > +++ b/target/riscv/cpu_bits.h
>> > @@ -177,6 +177,9 @@
>> >   #define CSR_STVEC   0x105
>> >   #define CSR_SCOUNTEREN  0x106
>> >
>> > +/* Supervisor Configuration CSRs */
>> > +#define CSR_SENVCFG 0x10A
>> > +
>> >   /* Supervisor Trap Handling */
>> >   #define CSR_SSCRATCH0x140
>> >   #define CSR_SEPC0x141
>> > @@ -204,6 +207,10 @@
>> >   #define CSR_HTIMEDELTA  0x605
>> >   #define CSR_HTIMEDELTAH 0x615
>> >
>> > +/* Hypervisor Configuration CSRs */
>> > +#define CSR_HENVCFG 0x60A
>> > +#define CSR_HENVCFGH0x61A
>> > +
>> >   /* Virtual CSRs */
>> >   #define CSR_VSSTATUS0x200
>> >   #define CSR_VSIE0x204
>> > @@ -218,6 +225,10 @@
>> >   #define CSR_MTINST  0x34a
>> >   #define CSR_MTVAL2  0x34b
>> >
>> > +/* Machine Configuration CSRs */
>> > +#define CSR_MENVCFG 0x30A
>> > +#define CSR_MENVCFGH0x31A
>> > +
>> >   /* Enhanced Physical Memory Protection (ePMP) */
>> >   #define CSR_MSECCFG 0x747
>> >   #define CSR_MSECCFGH0x757
>> > @@ -578,6 +589,26 @@ typedef enum RISCVException {
>> >   #define PM_EXT_CLEAN0x0002ULL
>> >   #define PM_EXT_DIRTY0x0003ULL
>> >
>> > +/* Execution enviornment configuration bits */
>> > +#define MENVCFG_FIOM   (1 << 0)
>> > +#define MENVCFG_CBE0x3ULL
>> > +#define MENVCFG_CBCFE  (1 << 6)
>> > +#define MENVCFG_CBZE   (1 << 7)
>> > +#define MENVCFG_PBMTE  (1 << 62)
>> > +#define MENVCFG_STCE   (1 << 63)
>> > +
>> > +#define SENVCFG_FIOM   MENVCFG_FIOM
>> > +#define SENVCFG_CBEMENVCFG_CBE
>> > +#define SENVCFG_CBCFE  MENVCFG_CBCFE
>> > +#define SENVCFG_CBZE   MENVCFG_CBZE
>> > +
>> > +#define HENVCFG_FIOM   MENVCFG_FIOM
>> > +#define HENVCFG_CBEMENVCFG_CBE
>> > +#define HENVCFG_CBCFE  MENVCFG_CBCFE
>> > +#define HENVCFG_CBZE   MENVCFG_CBZE
>> > +#define HENVCFG_PBMTE  MENVCFG_PBMTE
>> > +#define HENVCFG_STCE   MENVCFG_STCE
>> > +
>> >   /* Offsets for every pair of control bits per each priv level */
>> >   #define XS_OFFSET0ULL
>> >   #define U_OFFSET 2ULL
>> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
>> > index 

Re: [RFC 1/5] target/riscv: Add the privileged spec version 1.12.0

2022-01-28 Thread Atish Kumar Patra
On Sun, Jan 23, 2022 at 11:59 PM Richard Henderson <
richard.hender...@linaro.org> wrote:

> On 1/21/22 7:07 AM, Atish Patra wrote:
> > Add the definition for ratified privileged specification version v1.12
> >
> > Signed-off-by: Atish Patra 
> > ---
> >   target/riscv/cpu.h | 1 +
> >   1 file changed, 1 insertion(+)
> >
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 4d630867650a..671f65100b1a 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -82,6 +82,7 @@ enum {
> >
> >   #define PRIV_VERSION_1_10_0 0x00011000
> >   #define PRIV_VERSION_1_11_0 0x00011100
> > +#define PRIV_VERSION_1_12_0 0x00011200
>
> Is there any good reason for defining things this way, as opposed to a
> simple enumeration?
> A simple enum would eliminate the need for
>
>
Agreed. A simple enum would be much nicer. I was just following the
previous definition of
PRIV_VERSION_1_10_0 & PRIV_VERSION_1_11_0.

I am not sure about the reason behind this scheme.

@Alistair Francis  Is there any history behind
this scheme ?
or Are you okay if I change it ?


> > +/* The default privilege specification version supported is 1.10 */
> > +if (!csr_min_priv) {
> > +csr_min_priv = PRIV_VERSION_1_10_0;
> > +}
>
> in patch 5.
>
>
> r~
>


Re: [RFC 2/5] target/riscv: Introduce privilege version field in the CSR ops.

2022-01-28 Thread Atish Kumar Patra
On Sun, Jan 23, 2022 at 11:56 PM Richard Henderson <
richard.hender...@linaro.org> wrote:

> On 1/21/22 7:07 AM, Atish Patra wrote:
> > +[CSR_VSTART]   = { "vstart",   vs, read_vstart,  write_vstart,
> NULL,
> > +   NULL, NULL,
> PRIV_VERSION_1_12_0 },
>
> I think adding all of these NULLs are hard to read.
> Better to just add
>
>  .min_priv_ver = PRIV_VERSION_1_12_0
>
> to the existing entry.
>
>
Yeah. That's better. Fixed it.


>
> r~
>


Re: [PATCH v4 11/11] hw/riscv: virt: Add PMU DT node to the device tree

2022-01-10 Thread Atish Kumar Patra
On Sun, Jan 9, 2022 at 11:55 PM Bin Meng  wrote:
>
> On Fri, Jan 7, 2022 at 10:27 AM Atish Patra  wrote:
> >
> > Qemu virt machine can support few cache events and cycle/instret counters.
> > It also supports counter overflow for these events.
> >
> > Add a DT node so that OpenSBI/Linux kernel is aware of the virt machine
> > capabilities. There are some dummy nodes added for testing as well.
> >
> > Signed-off-by: Atish Patra 
> > Signed-off-by: Atish Patra 
> > ---
> >  hw/riscv/virt.c| 38 ++
> >  target/riscv/pmu.c | 45 +
> >  target/riscv/pmu.h |  1 +
> >  3 files changed, 84 insertions(+)
> >
> > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > index 3af074148ef4..99154199091c 100644
> > --- a/hw/riscv/virt.c
> > +++ b/hw/riscv/virt.c
> > @@ -28,6 +28,7 @@
> >  #include "hw/qdev-properties.h"
> >  #include "hw/char/serial.h"
> >  #include "target/riscv/cpu.h"
> > +#include "target/riscv/pmu.h"
> >  #include "hw/riscv/riscv_hart.h"
> >  #include "hw/riscv/virt.h"
> >  #include "hw/riscv/boot.h"
> > @@ -406,6 +407,33 @@ static void create_fdt_socket_plic(RISCVVirtState *s,
> >  g_free(plic_cells);
> >  }
> >
> > +static void create_fdt_socket_pmu(RISCVVirtState *s,
> > +  int socket, uint32_t *phandle,
> > +  uint32_t *intc_phandles)
> > +{
> > +int cpu;
> > +char *pmu_name;
> > +uint32_t *pmu_cells;
> > +MachineState *mc = MACHINE(s);
> > +RISCVCPU hart = s->soc[socket].harts[0];
> > +
> > +pmu_cells = g_new0(uint32_t, s->soc[socket].num_harts * 2);
> > +
> > +for (cpu = 0; cpu < s->soc[socket].num_harts; cpu++) {
> > +pmu_cells[cpu * 2 + 0] = cpu_to_be32(intc_phandles[cpu]);
> > +pmu_cells[cpu * 2 + 1] = cpu_to_be32(IRQ_PMU_OVF);
> > +}
> > +
> > +pmu_name = g_strdup_printf("/soc/pmu");
> > +qemu_fdt_add_subnode(mc->fdt, pmu_name);
> > +qemu_fdt_setprop_string(mc->fdt, pmu_name, "compatible", "riscv,pmu");
> > +riscv_pmu_generate_fdt_node(mc->fdt, hart.cfg.pmu_num, pmu_name);
> > +
> > +g_free(pmu_name);
> > +g_free(pmu_cells);
> > +}
> > +
> > +
> >  static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry 
> > *memmap,
> > bool is_32_bit, uint32_t *phandle,
> > uint32_t *irq_mmio_phandle,
> > @@ -417,12 +445,20 @@ static void create_fdt_sockets(RISCVVirtState *s, 
> > const MemMapEntry *memmap,
> >  uint32_t *intc_phandles;
> >  MachineState *mc = MACHINE(s);
> >  uint32_t xplic_phandles[MAX_NODES];
> > +RISCVCPU hart;
> >
> >  qemu_fdt_add_subnode(mc->fdt, "/cpus");
> >  qemu_fdt_setprop_cell(mc->fdt, "/cpus", "timebase-frequency",
> >RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ);
> >  qemu_fdt_setprop_cell(mc->fdt, "/cpus", "#size-cells", 0x0);
> >  qemu_fdt_setprop_cell(mc->fdt, "/cpus", "#address-cells", 0x1);
> > +
> > +/* Add the node for isa extensions discovery */
> > +qemu_fdt_add_subnode(mc->fdt, "/cpus/riscv,isa-ext");
>
> Looks like the ongoing discussion does not support this idea
> https://lore.kernel.org/linux-riscv/20211224211632.1698523-1-ati...@rivosinc.com/
>

Yes. Palmer's comment arrived after I sent out the Qemu series. I will
fix that in the next
version once we have string parsing (riscv,isa) ready.

> > +hart = s->soc[0].harts[0];
> > +if (hart.cfg.ext_sscof) {
> > +qemu_fdt_setprop(mc->fdt, "/cpus/riscv,isa-ext", "sscofpmf", NULL, 
> > 0);
> > +}
> >  qemu_fdt_add_subnode(mc->fdt, "/cpus/cpu-map");
> >
> >  for (socket = (riscv_socket_count(mc) - 1); socket >= 0; socket--) {
> > @@ -445,6 +481,8 @@ static void create_fdt_sockets(RISCVVirtState *s, const 
> > MemMapEntry *memmap,
> >  create_fdt_socket_plic(s, memmap, socket, phandle,
> >  intc_phandles, xplic_phandles);
> >
> > +create_fdt_socket_pmu(s, socket, phandle, intc_phandles);
> > +
> >  g_free(intc_phandles);
> >  g_free(clust_name);
> >  }
> > diff --git a/target/riscv/pmu.c b/target/riscv/pmu.c
> > index 15f161059fb7..b58a09c85616 100644
> > --- a/target/riscv/pmu.c
> > +++ b/target/riscv/pmu.c
> > @@ -19,11 +19,56 @@
> >  #include "qemu/osdep.h"
> >  #include "cpu.h"
> >  #include "pmu.h"
> > +#include "sysemu/device_tree.h"
> >
> >  #define RISCV_TIMEBASE_FREQ 10 /* 1Ghz */
> >  #define MAKE_32BIT_MASK(shift, length) \
> >  (((uint32_t)(~0UL) >> (32 - (length))) << (shift))
> >
> > +/**
> > + * To keep it simple, any event can be mapped to any programmable counters 
> > in
> > + * QEMU. The generic cycle & instruction count events can also be monitored
> > + * using programmable counters. In that case, mcycle & minstret must 
> > continue
> > + * to provide the correct value as well. Hetergenous PMU per hart is not
>
> typo of Heterogeneous
>
> > + * supported yet. 

Re: [PATCH v4 08/11] target/riscv: Add sscofpmf extension support

2022-01-10 Thread Atish Kumar Patra
On Mon, Jan 10, 2022 at 3:34 AM Anup Patel  wrote:
>
> On Fri, Jan 7, 2022 at 7:45 AM Atish Patra  wrote:
> >
> > The Sscofpmf ('Ss' for Privileged arch and Supervisor-level extensions,
> > and 'cofpmf' for Count OverFlow and Privilege Mode Filtering)
> > extension allows the perf to handle overflow interrupts and filtering
> > support. This patch provides a framework for programmable
> > counters to leverage the extension. As the extension doesn't have any
> > provision for the overflow bit for fixed counters, the fixed events
> > can also be monitoring using programmable counters. The underlying
> > counters for cycle and instruction counters are always running. Thus,
> > a separate timer device is programmed to handle the overflow.
> >
> > Signed-off-by: Atish Patra 
> > Signed-off-by: Atish Patra 
> > ---
> >  target/riscv/cpu.c  |  12 ++
> >  target/riscv/cpu.h  |  25 +++
> >  target/riscv/cpu_bits.h |  55 +++
> >  target/riscv/csr.c  | 156 --
> >  target/riscv/pmu.c  | 346 +++-
> >  target/riscv/pmu.h  |   8 +
> >  6 files changed, 591 insertions(+), 11 deletions(-)
> >
> > diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
> > index 9448c4335347..2ca9f8480b9d 100644
> > --- a/target/riscv/cpu.c
> > +++ b/target/riscv/cpu.c
> > @@ -22,6 +22,7 @@
> >  #include "qemu/ctype.h"
> >  #include "qemu/log.h"
> >  #include "cpu.h"
> > +#include "pmu.h"
> >  #include "internals.h"
> >  #include "exec/exec-all.h"
> >  #include "qapi/error.h"
> > @@ -569,6 +570,16 @@ static void riscv_cpu_realize(DeviceState *dev, Error 
> > **errp)
> >  set_misa(env, env->misa_mxl, ext);
> >  }
> >
> > +if (cpu->cfg.pmu_num) {
> > +if (!riscv_pmu_init(cpu, cpu->cfg.pmu_num) && cpu->cfg.ext_sscof) {
> > +cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> > +  riscv_pmu_timer_cb, cpu);
> > +if (!cpu->pmu_timer) {
> > +cpu->cfg.ext_sscof = false;
> > +}
> > +}
> > + }
> > +
> >  riscv_cpu_register_gdb_regs_for_features(cs);
> >
> >  qemu_init_vcpu(cs);
> > @@ -628,6 +639,7 @@ static Property riscv_cpu_properties[] = {
> >  DEFINE_PROP_BOOL("u", RISCVCPU, cfg.ext_u, true),
> >  DEFINE_PROP_BOOL("v", RISCVCPU, cfg.ext_v, false),
> >  DEFINE_PROP_UINT8("pmu-num", RISCVCPU, cfg.pmu_num, 16),
> > +DEFINE_PROP_BOOL("sscof", RISCVCPU, cfg.ext_sscof, false),
> >  DEFINE_PROP_BOOL("Zifencei", RISCVCPU, cfg.ext_ifencei, true),
> >  DEFINE_PROP_BOOL("Zicsr", RISCVCPU, cfg.ext_icsr, true),
> >  DEFINE_PROP_BOOL("Zfh", RISCVCPU, cfg.ext_zfh, false),
> > diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> > index 5fe9c51b38c7..1e5f307df919 100644
> > --- a/target/riscv/cpu.h
> > +++ b/target/riscv/cpu.h
> > @@ -123,6 +123,8 @@ struct PMUCTRState {
> >  /* Snapshort value of a counter in RV32 */
> >  target_ulong mhpmcounterh_prev;
> >  bool started;
> > +/* Value beyond UINT32_MAX/UINT64_MAX before overflow interrupt 
> > trigger */
> > +target_ulong irq_overflow_left;
> >  };
> >
> >  struct CPURISCVState {
> > @@ -245,6 +247,9 @@ struct CPURISCVState {
> >  /* PMU event selector configured values. First three are unused*/
> >  target_ulong mhpmevent_val[RV_MAX_MHPMEVENTS];
> >
> > +/* PMU event selector configured values for RV32*/
> > +target_ulong mhpmeventh_val[RV_MAX_MHPMEVENTS];
> > +
> >  target_ulong sscratch;
> >  target_ulong mscratch;
> >
> > @@ -339,6 +344,7 @@ struct RISCVCPU {
> >  bool ext_icsr;
> >  bool ext_zfh;
> >  bool ext_zfhmin;
> > +bool ext_sscof;
> >
> >  uint8_t pmu_num;
> >  char *priv_spec;
> > @@ -352,6 +358,12 @@ struct RISCVCPU {
> >  bool epmp;
> >  uint64_t resetvec;
> >  } cfg;
> > +
> > +QEMUTimer *pmu_timer;
> > +/* A bitmask of Available programmable counters */
> > +uint32_t pmu_avail_ctrs;
> > +/* Mapping of events to counters */
> > +GHashTable *pmu_event_ctr_map;
> >  };
> >
> >  static inline int riscv_has_ext(CPURISCVState *env, target_ulong ext)
> > @@ -526,6 +538,19 @@ enum {
> >  CSR_TABLE_SIZE = 0x1000
> >  };
> >
> > +/**
> > + * The event id are encoded based on the encoding specified in the
> > + * SBI specification v0.3
> > + */
> > +
> > +enum riscv_pmu_event_idx {
> > +RISCV_PMU_EVENT_HW_CPU_CYCLES = 0x01,
> > +RISCV_PMU_EVENT_HW_INSTRUCTIONS = 0x02,
> > +RISCV_PMU_EVENT_CACHE_DTLB_READ_MISS = 0x10019,
> > +RISCV_PMU_EVENT_CACHE_DTLB_WRITE_MISS = 0x1001B,
> > +RISCV_PMU_EVENT_CACHE_ITLB_PREFETCH_MISS = 0x10021,
> > +};
> > +
> >  /* CSR function table */
> >  extern riscv_csr_operations csr_ops[CSR_TABLE_SIZE];
> >
> > diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> > index dbd9ce9a85a3..559b60675132 100644
> > --- a/target/riscv/cpu_bits.h
> > +++ b/target/riscv/cpu_bits.h
> > 

Re: [PATCH v4 09/11] target/riscv: Simplify counter predicate function

2022-01-10 Thread Atish Kumar Patra
On Mon, Jan 10, 2022 at 12:27 AM Bin Meng  wrote:
>
> On Fri, Jan 7, 2022 at 10:22 AM Atish Patra  wrote:
> >
> > All the hpmcounters and the fixed counters (CY, IR, TM) can be represented
> > as a unified counter. Thus, the predicate function doesn't need handle each
> > case separately.
> >
> > Simplify the predicate function so that we just handle things differently
> > between RV32/RV64 and S/HS mode.
> >
> > Signed-off-by: Atish Patra 
> > ---
> >  target/riscv/csr.c | 111 -
> >  1 file changed, 10 insertions(+), 101 deletions(-)
> >
> > diff --git a/target/riscv/csr.c b/target/riscv/csr.c
> > index d3a8bba6a518..feb053eb3f7b 100644
> > --- a/target/riscv/csr.c
> > +++ b/target/riscv/csr.c
> > @@ -109,6 +109,7 @@ static RISCVException ctr(CPURISCVState *env, int csrno)
> >  CPUState *cs = env_cpu(env);
> >  RISCVCPU *cpu = RISCV_CPU(cs);
> >  int ctr_index;
> > +uint64_t ctr_mask;
>
> Use target_ulong should be enough?
>

Yeah. Will fix it in the next version.

> >  int base_csrno = CSR_CYCLE;
> >  bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false;
> >
> > @@ -117,122 +118,30 @@ static RISCVException ctr(CPURISCVState *env, int 
> > csrno)
> >  base_csrno += 0x80;
> >  }
> >  ctr_index = csrno - base_csrno;
> > +ctr_mask = BIT(ctr_index);
> >
> >  if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) ||
> >  (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) {
> >  goto skip_ext_pmu_check;
> >  }
> >
> > -if ((!cpu->cfg.pmu_num || !(cpu->pmu_avail_ctrs & BIT(ctr_index {
> > +if ((!cpu->cfg.pmu_num || !(cpu->pmu_avail_ctrs & ctr_mask))) {
> >  /* No counter is enabled in PMU or the counter is out of range */
> >  return RISCV_EXCP_ILLEGAL_INST;
> >  }
> >
> >  skip_ext_pmu_check:
> >
> > -if (env->priv == PRV_S) {
> > -switch (csrno) {
> > -case CSR_CYCLE:
> > -if (!get_field(env->mcounteren, COUNTEREN_CY)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -case CSR_TIME:
> > -if (!get_field(env->mcounteren, COUNTEREN_TM)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -case CSR_INSTRET:
> > -if (!get_field(env->mcounteren, COUNTEREN_IR)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
> > -if (!get_field(env->mcounteren, 1 << ctr_index)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -}
> > -if (rv32) {
> > -switch (csrno) {
> > -case CSR_CYCLEH:
> > -if (!get_field(env->mcounteren, COUNTEREN_CY)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -case CSR_TIMEH:
> > -if (!get_field(env->mcounteren, COUNTEREN_TM)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -case CSR_INSTRETH:
> > -if (!get_field(env->mcounteren, COUNTEREN_IR)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
> > -if (!get_field(env->mcounteren, 1 << ctr_index)) {
> > -return RISCV_EXCP_ILLEGAL_INST;
> > -}
> > -break;
> > -}
> > -}
> > +if ((env->priv == PRV_S) && (!get_field(env->mcounteren, ctr_mask))) {
> > +return RISCV_EXCP_ILLEGAL_INST;
> >  }
> >
> >  if (riscv_cpu_virt_enabled(env)) {
> > -switch (csrno) {
> > -case CSR_CYCLE:
> > -if (!get_field(env->hcounteren, COUNTEREN_CY) &&
> > -get_field(env->mcounteren, COUNTEREN_CY)) {
> > -return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -}
> > -break;
> > -case CSR_TIME:
> > -if (!get_field(env->hcounteren, COUNTEREN_TM) &&
> > -get_field(env->mcounteren, COUNTEREN_TM)) {
> > -return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -}
> > -break;
> > -case CSR_INSTRET:
> > -if (!get_field(env->hcounteren, COUNTEREN_IR) &&
> > -get_field(env->mcounteren, COUNTEREN_IR)) {
> > -return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -}
> > -break;
> > -case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31:
> > -if (!get_field(env->hcounteren, 1 << ctr_index) &&
> > - get_field(env->mcounteren, 1 << ctr_index)) {
> > -return RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
> > -}
> > -